Artifact a9522c974162fb7c6b1b8c90521ef886dd0998c423f8339d28afa26926249af0:
- File
internal/content/cone_reference_budget_test.go
— part of check-in
[a08e7e9d71]
at
2026-10-21 01:08:01
on branch feat/submanifest-reader
— fix(content): preflight stored bytes with SQLite blob semantics
A BLOB-affinity column can hold TEXT; SQLite length(TEXT) stops at NUL and is not a byte-allocation bound. Cast content to BLOB in metadata and guarded payload reads so malformed dynamically typed values cannot bypass stored-byte preflight.
The adversarial TEXT fixture previously read a one-MiB payload and reserved sixteen MiB of inflation before rejecting corruption. Both drivers now reject before any payload read or inflation reservation. (user: [email protected], size: 4701) [annotate] [blame] [check-ins using]
package content import ( "bytes" "context" "encoding/binary" "testing" "github.com/danmestas/go-libfossil/db" "github.com/danmestas/go-libfossil/internal/delta" "github.com/danmestas/go-libfossil/internal/blob" ) func TestConeReferenceBudgetVerifiedDelta(t *testing.T) { d := setupTestDB(t) base := bytes.Repeat([]byte("0123456789abcdefghijklmnopqrstuv"), 2048) target := append([]byte(nil), base...) target[len(target)/2] = 'X' baseRID, _, err := blob.Store(d, base) if err != nil { t.Fatal(err) } targetRID, uuid, err := blob.Store(d, target) if err != nil { t.Fatal(err) } if err := d.WithTx(func(tx *db.Tx) error { saved, err := Deltify(tx, targetRID, baseRID) if err == nil && saved == 0 { t.Fatal("fixture did not store a delta") } return err }); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 1 << 20, InflatedBytes: 1 << 20, ExpandedBytes: 1 << 20, Cards: 100} facts, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err != nil || facts == nil { t.Fatal(err) } if facts.held[uuid] != targetRID || work.ExpandBytes != int64(len(target)) { t.Fatalf("valid delta not hash-verified within budget: %+v", work) } } func TestConeReferenceBudgetRejectsLyingInflationPrefix(t *testing.T) { d := setupTestDB(t) rid, _, err := blob.Store(d, bytes.Repeat([]byte{'x'}, 1<<20)) if err != nil { t.Fatal(err) } var packed []byte if err := d.QueryRow("SELECT content FROM blob WHERE rid=?", rid).Scan(&packed); err != nil { t.Fatal(err) } binary.BigEndian.PutUint32(packed[:4], 1) if _, err := d.Exec("UPDATE blob SET content=?,size=1 WHERE rid=?", packed, rid); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 4096, InflatedBytes: 1024, ExpandedBytes: 1024, Cards: 10} _, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err == nil || work.InflateBytes != 1 || work.ExpandBytes != 0 || work.Visits != 0 { t.Fatalf("lying prefix must not allocate actual expansion: work=%+v err=%v", work, err) } } func TestConeReferenceBudgetBeforeDeltaAllocation(t *testing.T) { d := setupTestDB(t) base := []byte("base content") baseRID, _, err := blob.Store(d, base) if err != nil { t.Fatal(err) } payload, err := delta.Create(base, bytes.Repeat([]byte{'x'}, 4096)) if err != nil { t.Fatal(err) } rid, _, err := blob.Store(d, payload) if err != nil { t.Fatal(err) } if _, err := d.Exec("INSERT INTO delta(rid,srcid) VALUES(?,?)", rid, baseRID); err != nil { t.Fatal(err) } if _, err := d.Exec("UPDATE blob SET size=1 WHERE rid=?", rid); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 4096, InflatedBytes: 4096, ExpandedBytes: 1024, Cards: 10} _, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err == nil || work.ExpandBytes != 0 { t.Fatalf("delta allocated before output bound: work=%+v err=%v", work, err) } } // SQLite permits TEXT in a BLOB-affinity column. length(TEXT) stops at NUL, // so only a BLOB cast proves the bytes a subsequent payload read allocates. func TestConeReferenceBudgetCountsStoredBytesNotText(t *testing.T) { d := setupTestDB(t) rid, _, err := blob.Store(d, []byte("original")) if err != nil { t.Fatal(err) } packed := append([]byte{1, 1, 1, 1, 0x78, 0x9c, 0}, bytes.Repeat([]byte{'x'}, 1<<20)...) if _, err := d.Exec("UPDATE blob SET content=CAST(? AS TEXT),size=1 WHERE rid=?", packed, rid); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 4096, InflatedBytes: 32 << 20, ExpandedBytes: 4096, Cards: 10} _, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err == nil || work.PayloadReads != 0 || work.InflateBytes != 0 { t.Fatalf("TEXT bypassed byte preflight: work=%+v err=%v", work, err) } } func TestConeReferenceBudgetBeforeExpansion(t *testing.T) { d := setupTestDB(t) if _, _, err := blob.Store(d, []byte("bounded raw facts")); err != nil { t.Fatal(err) } budget := ReferenceBudget{Artifacts: 10, StoredBytes: 1, InflatedBytes: 1024, ExpandedBytes: 1024, Cards: 10} _, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err == nil || work.PayloadReads != 0 || work.InflateBytes != 0 || work.Visits != 0 { t.Fatalf("preflight must reject before content read/allocation: work=%+v err=%v", work, err) } budget.StoredBytes = 1024 facts, work, err := LoadConeReferenceFactsBounded(context.Background(), d, budget) if err != nil || facts == nil || work.PayloadReads != 1 || work.Visits != 1 { t.Fatalf("valid bounded preparation: work=%+v err=%v", work, err) } }