Bound external result file reads

This commit is contained in:
2026-08-10 18:30:28 +00:00
parent 99b2e1cd81
commit ab5a7e8e3d
22 changed files with 215 additions and 84 deletions

View File

@@ -10,9 +10,13 @@ import (
"gitea.maximumdirect.net/eric/narratio/internal/artifactmodel"
"gitea.maximumdirect.net/eric/narratio/internal/artifactpolicy"
"gitea.maximumdirect.net/eric/narratio/internal/fileops"
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
)
// MaxResolvedArtifactBytes bounds externally generated artifact content before validation.
const MaxResolvedArtifactBytes int64 = 64 * 1024 * 1024
const (
ArtifactTranscriptBase = artifactmodel.SourceTranscriptBase
ArtifactTranscriptPolished = artifactmodel.SourceTranscriptPolished
@@ -445,9 +449,9 @@ func validateResolvedContent(path string, kind artifactContentKind) error {
}
func validateTranscriptSegmentsJSON(path string) error {
data, err := os.ReadFile(path)
data, err := readResolvedArtifact(path, "transcript JSON")
if err != nil {
return fmt.Errorf("read file: %w", err)
return err
}
var payload map[string]any
if err := json.Unmarshal(data, &payload); err != nil {
@@ -464,9 +468,9 @@ func validateTranscriptSegmentsJSON(path string) error {
}
func validateJSONContent(path string) error {
data, err := os.ReadFile(path)
data, err := readResolvedArtifact(path, "JSON artifact")
if err != nil {
return fmt.Errorf("read file: %w", err)
return err
}
var payload any
if err := json.Unmarshal(data, &payload); err != nil {
@@ -476,15 +480,20 @@ func validateJSONContent(path string) error {
}
func validateNonEmptyContent(path string) error {
info, err := os.Stat(path)
data, err := readResolvedArtifact(path, "text artifact")
if err != nil {
return fmt.Errorf("stat file: %w", err)
return err
}
if info.IsDir() {
return fmt.Errorf("path is a directory")
}
if info.Size() <= 0 {
if len(data) == 0 {
return fmt.Errorf("file is empty")
}
return nil
}
func readResolvedArtifact(path, category string) ([]byte, error) {
data, err := fileops.ReadRegularFile(path, MaxResolvedArtifactBytes)
if err != nil {
return nil, fmt.Errorf("resolved %s exceeds or cannot be read within %d-byte limit: %w", category, MaxResolvedArtifactBytes, err)
}
return data, nil
}

View File

@@ -7,9 +7,13 @@ import (
"strings"
"gitea.maximumdirect.net/eric/narratio/internal/artifactmodel"
"gitea.maximumdirect.net/eric/narratio/internal/fileops"
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
)
// MaxExtractionPayloadBytes bounds one validated Notarius lane or index payload.
const MaxExtractionPayloadBytes int64 = 64 * 1024 * 1024
const (
extractStageName = "extract"
extractionLaneKind = "notarius_lane"
@@ -131,7 +135,7 @@ func validExtractionPayload(bundleRoot, path, checksum string) bool {
if err != nil || actual != checksum {
return false
}
body, err := os.ReadFile(path)
body, err := fileops.ReadRegularFile(path, MaxExtractionPayloadBytes)
return err == nil && json.Valid(body)
}