package vaultik_test import ( "context" "io" "testing" "filippo.io/age" "github.com/stretchr/testify/require" "sneak.berlin/go/vaultik/internal/blobgen" "sneak.berlin/go/vaultik/internal/vaultik" ) // TestFetchAndDecryptBlobBoundsPlaintext feeds a small, highly // compressible blob (256 KiB of zeros) whose decompressed size far exceeds // the plaintext bound passed to FetchAndDecryptBlob. Decompression must // stop with blobgen.ErrOutputTooLarge within the bound rather than // expanding the whole blob into the restore cache. func TestFetchAndDecryptBlobBoundsPlaintext(t *testing.T) { t.Parallel() identity, err := age.GenerateX25519Identity() require.NoError(t, err) plaintext := make([]byte, 256*1024) encryptedData, correctHash := buildHashTestBlob(t, identity, plaintext) mockStorage := NewMockStorer() blobPath := "blobs/" + correctHash[:2] + "/" + correctHash[2:4] + "/" + correctHash mockStorage.mu.Lock() mockStorage.data[blobPath] = encryptedData mockStorage.mu.Unlock() tv := vaultik.NewForTesting(mockStorage) const maxPlaintext = 1024 rc, err := tv.FetchAndDecryptBlob( context.Background(), correctHash, maxPlaintext, identity) require.NoError(t, err) n, copyErr := io.Copy(io.Discard, rc) _ = rc.Close() require.ErrorIs(t, copyErr, blobgen.ErrOutputTooLarge) require.LessOrEqual(t, n, int64(maxPlaintext)+1, "decompression must stop within the recorded plaintext bound") }