From 252ecf7e8800f5f5e765972164791c5169617c5f Mon Sep 17 00:00:00 2001 From: yc111233 Date: Sun, 5 Apr 2026 06:39:37 +0800 Subject: [PATCH] test(crypto): add regression tests for decrypting short plaintext files Add tests covering the fix in PR #1163 where decrypt() raised 'Ciphertext too short' on plaintext files shorter than 4 bytes. Tests added: - test_decrypt_empty_plaintext: raw b'' returns b'' - test_decrypt_short_plaintext_less_than_4_bytes: b'X', b'AB', b'ABC' return as-is - test_decrypt_magic_prefix_without_full_header: b'OVE1' raises CorruptedCiphertextError --- tests/unit/crypto/test_encryptor.py | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/unit/crypto/test_encryptor.py b/tests/unit/crypto/test_encryptor.py index a4f4a61f5..bb394c243 100644 --- a/tests/unit/crypto/test_encryptor.py +++ b/tests/unit/crypto/test_encryptor.py @@ -85,6 +85,45 @@ async def test_encrypt_empty_data(encryptor): assert decrypted == b"" +@pytest.mark.asyncio +async def test_decrypt_empty_plaintext(encryptor): + """Test decrypting empty plaintext bytes (not encrypted-empty, but raw b''). + + Regression test: decrypt() used to raise 'Ciphertext too short' on empty + files because it checked length before the magic header. + """ + account_id = "test_account" + decrypted = await encryptor.decrypt(account_id, b"") + assert decrypted == b"" + + +@pytest.mark.asyncio +@pytest.mark.parametrize("data", [b"X", b"AB", b"ABC"]) +async def test_decrypt_short_plaintext_less_than_4_bytes(encryptor, data): + """Test decrypting plaintext shorter than 4 bytes (magic length). + + Regression test: these used to raise InvalidMagicError('Ciphertext too short') + because length was checked before the magic prefix. + """ + account_id = "test_account" + decrypted = await encryptor.decrypt(account_id, data) + assert decrypted == data + + +@pytest.mark.asyncio +async def test_decrypt_magic_prefix_without_full_header(encryptor): + """Test decrypting data that starts with 'OVE1' but has no valid envelope. + + Should raise CorruptedCiphertextError because the envelope header is + incomplete (needs at least 12 bytes). + """ + account_id = "test_account" + from openviking.crypto.exceptions import CorruptedCiphertextError + + with pytest.raises(CorruptedCiphertextError): + await encryptor.decrypt(account_id, b"OVE1") + + @pytest.mark.asyncio async def test_different_accounts(encryptor): """Test encryption/decryption across different accounts."""