//nolint:testpackage // exercises the unexported decodeManifest bounds package snapshot import ( "bytes" "strings" "testing" "github.com/stretchr/testify/require" "sneak.berlin/go/vaultik/internal/blobgen" ) // testSnapshotID is a stand-in snapshot ID reused across the bound cases. const testSnapshotID = "host_home_2026-01-01T00:00:00Z" // TestDecodeManifestRoundTrip is the baseline: with generous bounds a // manifest the writer produced decodes back unchanged. func TestDecodeManifestRoundTrip(t *testing.T) { t.Parallel() want := &Manifest{ SnapshotID: testSnapshotID, Timestamp: "2026-01-01T00:00:00Z", BlobCount: 2, TotalCompressedSize: 42, Blobs: []BlobInfo{ {Hash: "aa", CompressedSize: 21}, {Hash: "bb", CompressedSize: 21}, }, } compressed, err := EncodeManifest(want, 3) require.NoError(t, err) got, err := decodeManifest( bytes.NewReader(compressed), manifestMaxCompressed, manifestMaxDecompressed) require.NoError(t, err) require.Equal(t, want, got) } // TestDecodeManifestBoundsDecompressedOutput feeds a valid but highly // compressible manifest — one whose timestamp is a megabyte of the same // character — through a small decompressed bound. The compressed form is // tiny, so only the decompressed bound stops it; decoding must fail within // that bound rather than expanding the value in memory. func TestDecodeManifestBoundsDecompressedOutput(t *testing.T) { t.Parallel() bomb := &Manifest{ SnapshotID: testSnapshotID, Timestamp: strings.Repeat("a", 1<<20), } compressed, err := EncodeManifest(bomb, 3) require.NoError(t, err) require.Less(t, len(compressed), 4096, "the compressible manifest must be small compressed") _, err = decodeManifest(bytes.NewReader(compressed), 1<<20, 4096) require.ErrorIs(t, err, blobgen.ErrOutputTooLarge) } // TestDecodeManifestBoundsCompressedInput checks the compressed-input // bound fires independently: a valid manifest with a generous decompressed // bound but a tiny compressed bound still fails. func TestDecodeManifestBoundsCompressedInput(t *testing.T) { t.Parallel() manifest := &Manifest{ SnapshotID: testSnapshotID, Timestamp: strings.Repeat("a", 4096), } compressed, err := EncodeManifest(manifest, 3) require.NoError(t, err) _, err = decodeManifest(bytes.NewReader(compressed), 8, manifestMaxDecompressed) require.Error(t, err) }