diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index b60268a8ff547b970044d1dfe5c4a7013d7bbdb7..0585b72a2e90e7d2ad765fb5fc1b35b6eee34388 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -512,7 +512,9 @@ public class XmppConnectionService extends Service { public boolean isBlockedMediaSha1(@Nullable final String sha1sum) { if (sha1sum == null) return false; try { - return isBlockedMedia(CryptoHelper.cid(CryptoHelper.hexToBytes(sha1sum), "sha-1")); + final byte[] bytes = CryptoHelper.hexToBytes(sha1sum); + if (bytes.length != 20) return false; + return isBlockedMedia(CryptoHelper.cid(bytes, "sha-1")); } catch (final NoSuchAlgorithmException e) { return false; } diff --git a/src/test/java/eu/siacs/conversations/services/XmppConnectionServiceTest.java b/src/test/java/eu/siacs/conversations/services/XmppConnectionServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ee3c4bee377e736ab46a61a68f2e6604e5b2e1ad --- /dev/null +++ b/src/test/java/eu/siacs/conversations/services/XmppConnectionServiceTest.java @@ -0,0 +1,51 @@ +package eu.siacs.conversations.services; + +import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.os.Build; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.ConscryptMode; + +import eu.siacs.conversations.Conversations; +import io.ipfs.cid.Cid; + +@RunWith(RobolectricTestRunner.class) +@Config(sdk = Build.VERSION_CODES.TIRAMISU, application = Conversations.class) +@ConscryptMode(ConscryptMode.Mode.OFF) +public class XmppConnectionServiceTest { + + private XmppConnectionService service; + + @Before + public void setUp() { + service = mock(XmppConnectionService.class); + when(service.isBlockedMediaSha1(any())).thenCallRealMethod(); + when(service.isBlockedMedia(any(Cid.class))).thenReturn(false); + } + + @Test + public void testIsBlockedMediaSha1ReturnsFalseForNonSha1Length() { + // 36 hex chars = 18 bytes; valid SHA-1 is 40 hex chars = 20 bytes. + // Reproduces: IllegalStateException: Incorrect hash length: 18 != 20 + assertFalse(service.isBlockedMediaSha1("aabbccddee1122334455667788990011aabb")); + } + + @Test + public void testIsBlockedMediaSha1ReturnsFalseForNull() { + assertFalse(service.isBlockedMediaSha1(null)); + } + + @Test + public void testIsBlockedMediaSha1AcceptsValidSha1() { + // 40 hex chars = 20 bytes = valid SHA-1 + assertFalse(service.isBlockedMediaSha1("aabbccddee112233445566778899001122334455")); + } +}