Artifact fb3bfa08b03a5079d5d7c6443c0d0d3758bd1f63b863bbd255fbadbc5fabfcb4:
- File
internal/sync/delta_matches_test.go
— part of check-in
[b3914d95b3]
at
2026-10-13 11:14:19
on branch main
— fix(sync): verify a received delta against HASH before storing it (#410)
sync-protocol-01 Section 7.7 verifies a reconstructable non-clone file before storage, and SP-7.7-4 has every newly stored artifact whose bytes are available hashed before commit. The client and a clone stored a delta against a held basis as given, and the server checked only a file delta, so a delta that did not give HASH stayed stored under that name until something expanded it.
The check moves to storeReceived, the one choke point every receive path shares, so the client, the server (file and cfile) and a clone refuse a delta whose result is not HASH, or that does not apply. An unheld basis still leaves the delta stored dangling.
Tracked in #405. (user: [email protected], size: 1514) [annotate] [blame] [check-ins using]
package sync import ( "testing" "github.com/danmestas/go-libfossil/internal/blob" "github.com/danmestas/go-libfossil/internal/delta" "github.com/danmestas/go-libfossil/internal/hash" ) // TestDeltaMatches checks the pre-storage verification both receive sides // share (Section 7.7): a delta against a held basis must give HASH, a delta // that does not apply is a mismatch, and an unheld basis is not checked. func TestDeltaMatches(t *testing.T) { r := setupSyncTestRepo(t) basis := []byte("the basis of a delta: alpha beta gamma delta epsilon\n") target := []byte("the target of a delta: alpha beta gamma delta epsilon zeta\n") _, basisName, err := blob.Store(r.DB(), basis) if err != nil { t.Fatalf("blob.Store: %v", err) } d, err := delta.Create(basis, target) if err != nil { t.Fatalf("delta.Create: %v", err) } other := hash.SHA1([]byte("some other content")) unheld := hash.SHA1([]byte("a basis nobody holds")) for _, tt := range []struct { name, uuid, src string payload []byte want bool }{ {"result is HASH", hash.SHA1(target), basisName, d, true}, {"result is SHA3 HASH", hash.SHA3(target), basisName, d, true}, {"result is not HASH", other, basisName, d, false}, {"delta does not apply", other, basisName, []byte("not a delta"), false}, {"basis not held", other, unheld, d, true}, } { if got := deltaMatches(r.DB(), tt.uuid, tt.src, tt.payload); got != tt.want { t.Errorf("%s: deltaMatches = %v, want %v", tt.name, got, tt.want) } } }