From 939f2f82b1045d72043a95dc6ca4cc14b281a20e Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 1 Jul 2025 08:42:39 -0400 Subject: [PATCH] Fix crash when skipping in BetterCipherInputStream. --- .../api/crypto/BetterCipherInputStream.kt | 15 ----------- .../api/crypto/AttachmentCipherTest.kt | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/crypto/BetterCipherInputStream.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/crypto/BetterCipherInputStream.kt index 1755f23861..1bfc15af3a 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/crypto/BetterCipherInputStream.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/crypto/BetterCipherInputStream.kt @@ -58,21 +58,6 @@ class BetterCipherInputStream( override fun markSupported(): Boolean = false - @Throws(IOException::class) - override fun skip(byteCount: Long): Long { - val buffer = ByteArray(4096) - var skipped = 0L - - while (skipped < byteCount) { - val remaining = byteCount - skipped - val read = read(buffer, 0, remaining.toInt()) - - skipped += read.toLong() - } - - return skipped - } - @Throws(IOException::class) private fun readIncremental(outputBuffer: ByteArray, originalOffset: Int, originalLength: Int): Int { var offset = originalOffset diff --git a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.kt b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.kt index fa1645341d..f892410153 100644 --- a/libsignal-service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.kt +++ b/libsignal-service/src/test/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherTest.kt @@ -101,6 +101,32 @@ class AttachmentCipherTest { cipherFile.delete() } + @Test + fun attachment_encryptDecrypt_skipAll_manyFileSizes(){ + for (i in 0..99) { + attachment_encryptDecrypt_skipAll(incremental = false, fileSize = MEBIBYTE + Random().nextInt(1, 64 * 1024)) + } + } + + private fun attachment_encryptDecrypt_skipAll(incremental: Boolean, fileSize: Int) { + val key = Util.getSecretBytes(64) + val plaintextInput = Util.getSecretBytes(fileSize) + val plaintextHash = MessageDigest.getInstance("SHA-256").digest(plaintextInput) + + val encryptResult = encryptData(plaintextInput, key, incremental) + val cipherFile = writeToFile(encryptResult.ciphertext) + + val integrityCheck = IntegrityCheck( + encryptedDigest = encryptResult.digest, + plaintextHash = plaintextHash + ) + val inputStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.size.toLong(), key, integrityCheck, encryptResult.incrementalDigest, encryptResult.chunkSizeChoice) + while(inputStream.skip(cipherFile.length()) > 0) { + // Empty body, just skipping + } + cipherFile.delete() + } + private fun attachment_encryptDecrypt_plaintextHash(incremental: Boolean, fileSize: Int) { val key = Util.getSecretBytes(64) val plaintextInput = Util.getSecretBytes(fileSize)