Artifact d134d9668c7c5e41444cd9db08b5c4f2d392505dcea1e2d1188109d299c86f24:
- File
internal/content/cone_reference_prefix.go
— part of check-in
[d5eb1f3a5a]
at
2026-10-21 01:15:56
on branch feat/submanifest-reader
— fix(content): prove stored budgets before SQLite prefix materialization
Keep the first pass metadata-only: typeof and direct length(BLOB) retain SQLite OP_Column length/type flags. Reject other storage classes without reading content. A CAST or substr in this pass can materialize a whole value before its stored-byte budget, so prefix reads now follow the complete stored-total proof.
Charge prefix reads and potential SQLite bytes separately; prove aggregate declared inflation before full driver payload reads. Both-driver EXPLAIN regressions reject full-content OP_Column operations in metadata preflight. (user: [email protected], size: 1447) [annotate] [blame] [check-ins using] [more...]
package content import ( "context" "encoding/binary" "fmt" "github.com/danmestas/go-libfossil/db" ) // The metadata-only pass must prove total stored bytes first: substr(BLOB) can // materialize the entire value inside SQLite even though it returns six bytes. // Charge those reads separately from later full driver-payload reads. func referencePrefixes( ctx context.Context, q db.Querier, blobs []referenceBlob, budget ReferenceBudget, work *ReferenceWork, ) error { var inflated int64 for i := range blobs { if err := ctx.Err(); err != nil { return err } b := &blobs[i] if b.unreadable { continue } if b.stored > budget.StoredBytes-work.PrefixBytes { return fmt.Errorf("sparse preparation: prefix byte budget exceeded") } work.PrefixReads++ work.PrefixBytes += b.stored var prefix []byte err := q.QueryRow(`SELECT substr(content,1,6) FROM blob WHERE rid=? AND typeof(content)='blob' AND length(content)=?`, b.rid, b.stored).Scan(&prefix) if err != nil { return err } b.unreadable = len(prefix) != 6 if !b.unreadable { b.unreadable = prefix[4]&15 != 8 || prefix[4]>>4 > 7 || binary.BigEndian.Uint16(prefix[4:])%31 != 0 } if b.unreadable { continue } b.inflated = int64(binary.BigEndian.Uint32(prefix[:4])) if b.inflated > budget.InflatedBytes-inflated { return fmt.Errorf("sparse preparation: inflation budget exceeded") } inflated += b.inflated } return nil }