Переглянути джерело

Fix race condition when decrypting notifications during lock disconnection

J. Nick Koston 4 днів тому
батько
коміт
b9acc15399
2 змінених файлів з 25 додано та 0 видалено
  1. 6 0
      switchbot/devices/device.py
  2. 19 0
      tests/test_encrypted_device.py

+ 6 - 0
switchbot/devices/device.py

@@ -955,6 +955,12 @@ class SwitchbotEncryptedDevice(SwitchbotDevice):
         if len(data) == 0:
             return b""
         if self._iv is None:
+            if self._expected_disconnect:
+                _LOGGER.debug(
+                    "%s: Cannot decrypt, IV is None during expected disconnect",
+                    self.name,
+                )
+                return b""
             raise RuntimeError("Cannot decrypt: IV is None")
         decryptor = self._get_cipher().decryptor()
         return decryptor.update(data) + decryptor.finalize()

+ 19 - 0
tests/test_encrypted_device.py

@@ -365,3 +365,22 @@ async def test_empty_data_encryption_decryption() -> None:
     # Test empty decryption
     decrypted = device._decrypt(bytearray())
     assert decrypted == b""
+
+
+@pytest.mark.asyncio
+async def test_decrypt_with_none_iv_during_disconnect() -> None:
+    """Test that decryption returns empty bytes when IV is None during expected disconnect."""
+    device = create_encrypted_device()
+
+    # Simulate disconnection in progress
+    device._expected_disconnect = True
+    device._iv = None
+
+    # Should return empty bytes instead of raising
+    result = device._decrypt(bytearray(b"encrypted_data"))
+    assert result == b""
+
+    # Verify it still raises when not disconnecting
+    device._expected_disconnect = False
+    with pytest.raises(RuntimeError, match="Cannot decrypt: IV is None"):
+        device._decrypt(bytearray(b"encrypted_data"))