Tighten opaque plugin content boundaries

This commit is contained in:
npc0-hue
2026-09-03 18:24:39 +08:00
parent 80cddbf19d
commit 14cbc63e61
31 changed files with 452 additions and 558 deletions
@@ -99,6 +99,22 @@ func (svc *CoreService) executeDistributionBuild(job domain.Job) error {
return nil
}
builder := svc.configuredDistributionBuilder()
if fileBuilder, ok := builder.(distributionBuilderWithFileOutput); ok {
output, buildErr := fileBuilder.BuildFile(input, func(progress DistributionBuildProgress) {
_ = svc.updateDistributionBuildProgress(job, progress)
})
if buildErr != nil {
return svc.failDistributionBuildJob(job, builderJobFailureMessage(buildErr, input.AuthKey))
}
defer func() { _ = output.Cleanup() }()
if _, err := svc.platformDistributionBuildInput(job); err != nil {
return svc.failDistributionBuildJob(job, "platform builder discarded output because the component key is no longer current")
}
if err := svc.storeDistributionBuildArtifactFile(input.ArtifactID, job.ID, output); err != nil {
return svc.failDistributionBuildJob(job, "platform builder could not record the distribution artifact")
}
return svc.succeedDistributionBuildJob(job, input.ArtifactID)
}
var payload []byte
var buildErr error
if progressBuilder, ok := builder.(distributionBuilderWithProgress); ok {
@@ -422,6 +438,49 @@ func (svc *CoreService) storeDistributionBuildArtifact(artifactID string, jobID
return nil
}
func (svc *CoreService) storeDistributionBuildArtifactFile(artifactID string, jobID string, output DistributionBuildOutput) error {
if strings.TrimSpace(artifactID) == "" {
return validationError("distribution build artifact id is required")
}
if strings.TrimSpace(output.Path) == "" || output.SizeBytes <= 0 || output.Checksum == "" {
return validationError("distribution build produced no package file")
}
stamp := svc.now()
svc.artifactMu.Lock()
defer svc.artifactMu.Unlock()
artifact, err := svc.store.Artifacts().Get(artifactID)
if err != nil && !errors.Is(err, repo.ErrNotFound) {
return err
}
create := errors.Is(err, repo.ErrNotFound)
if create {
artifact = domain.Artifact{ID: artifactID, OwnerKind: domain.ArtifactOwnerKindJob, OwnerID: jobID, CreatedAt: stamp}
}
if artifact.OwnerKind != domain.ArtifactOwnerKindJob || artifact.OwnerID != jobID {
return validationError("distribution build artifact is outside the job scope")
}
artifact.SizeBytes = output.SizeBytes
artifact.Checksum = output.Checksum
artifact.State = domain.ArtifactStateAvailable
artifact.UpdatedAt = stamp
if err := validator.ValidateArtifact(artifact); err != nil {
return err
}
if err := svc.artifactStore.PutPayloadFromFile(artifact.ID, output.Path); err != nil {
return err
}
if create {
if err := svc.store.Artifacts().Create(artifact); err != nil {
return err
}
} else if err := svc.store.Artifacts().Update(artifact); err != nil {
return err
}
delete(svc.artifactPayloads, artifact.ID)
return nil
}
func (svc *CoreService) markDistributionBuildRunning(job *domain.Job) error {
stamp := svc.now()
svc.jobMu.Lock()