fix(backup): report trailing archive data as corruption

This commit is contained in:
MrAlders0n
2026-09-30 10:31:08 -04:00
committed by MrAlders0n
parent e1b78b6458
commit ab27334f15
2 changed files with 18 additions and 2 deletions
+7
View File
@@ -53,6 +53,10 @@ func Verify(ctx context.Context, input io.Reader, maxBytes int64) (*Manifest, er
// Bound Next itself: it otherwise hides and allocates extension records.
decoded.limit = before + padding + 3*512
h, err := tr.Next()
if errors.Is(err, ErrTooLarge) {
// The 3-block header budget is a structure check, not the size limit.
return nil, verificationError(ctx, nil, "tar header")
}
if err == io.EOF {
// tar.Reader also accepts EOF without both closing zero blocks.
if decoded.n-before != padding+2*512 {
@@ -106,6 +110,9 @@ func Verify(ctx context.Context, input io.Reader, maxBytes int64) (*Manifest, er
decoded.limit = decoded.n
var tail [1]byte
if _, err := decoded.Read(tail[:]); err != io.EOF {
if errors.Is(err, ErrTooLarge) {
err = nil // bytes after the tar terminator are corruption, not oversize
}
return nil, verificationError(ctx, err, "gzip completion or trailing tar data")
}
if _, err := buffered.ReadByte(); err != io.EOF {
+11 -2
View File
@@ -170,9 +170,14 @@ func TestVerifyRejectsInvalidMembersAndManifest(t *testing.T) {
} {
t.Run(tc.name, func(t *testing.T) {
data := verifyGzip(t, verifyTar(t, tc.change(verifyFixture(t))))
if _, err := Verify(context.Background(), bytes.NewReader(data), int64(len(testSQL))); err == nil || strings.Contains(err.Error(), "PRIVATE_CANARY") {
_, err := Verify(context.Background(), bytes.NewReader(data), int64(len(testSQL)))
if err == nil || strings.Contains(err.Error(), "PRIVATE_CANARY") {
t.Fatalf("expected a sanitized rejection, got %v", err)
}
// PAX header size errors should be corruption, not size limit.
if tc.name == "hidden oversized metadata" && errors.Is(err, ErrTooLarge) {
t.Fatalf("oversized header reported as size limit: %v", err)
}
})
}
}
@@ -190,9 +195,13 @@ func TestVerifyFraming(t *testing.T) {
}
for name, data := range cases {
t.Run(name, func(t *testing.T) {
if _, err := Verify(context.Background(), bytes.NewReader(data), DefaultMaxBytes); err == nil || strings.Contains(err.Error(), "PRIVATE_CANARY") {
_, err := Verify(context.Background(), bytes.NewReader(data), DefaultMaxBytes)
if err == nil || strings.Contains(err.Error(), "PRIVATE_CANARY") {
t.Fatalf("expected sanitized framing error, got %v", err)
}
if errors.Is(err, ErrTooLarge) {
t.Fatalf("framing corruption reported as size limit: %v", err)
}
})
}
}