From 32aff32c73b108cd9554aaf22fd49cefd2d059af Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Thu, 14 Nov 2024 14:51:11 -0300 Subject: [PATCH] Fix FullRestore when Loader#loadFiles() throws an error for a later blob stream. --- .../transport/restore/FullRestore.kt | 2 +- .../transport/restore/FullRestoreTest.kt | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/restore/FullRestore.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/restore/FullRestore.kt index a5240362..9b70e64f 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/restore/FullRestore.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/restore/FullRestore.kt @@ -161,7 +161,7 @@ internal class FullRestore( return outputFactory.getOutputStream(pfd).use { outputStream -> try { copyInputStream(outputStream) - } catch (e: IOException) { + } catch (e: Exception) { Log.w(TAG, "Error copying stream for package $packageName.", e) return TRANSPORT_PACKAGE_REJECTED } diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/restore/FullRestoreTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/restore/FullRestoreTest.kt index 724d644f..c26a602f 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/restore/FullRestoreTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/restore/FullRestoreTest.kt @@ -15,6 +15,7 @@ import com.stevesoltys.seedvault.coAssertThrows import com.stevesoltys.seedvault.getRandomByteArray import com.stevesoltys.seedvault.header.MAX_SEGMENT_LENGTH import com.stevesoltys.seedvault.header.VERSION +import com.stevesoltys.seedvault.repo.HashMismatchException import com.stevesoltys.seedvault.repo.Loader import io.mockk.CapturingSlot import io.mockk.Runs @@ -32,7 +33,9 @@ import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream +import java.io.FilterInputStream import java.io.IOException +import java.io.SequenceInputStream import java.security.GeneralSecurityException import kotlin.random.Random @@ -114,6 +117,36 @@ internal class FullRestoreTest : RestoreTest() { verify { fileDescriptor.close() } } + @Test + fun `reading from stream throws HashMismatchException in SequenceInputStream`() = runBlocking { + restore.initializeState(VERSION, packageInfo, blobHandles) + val bytes = getRandomByteArray() + + val inputStream = SequenceInputStream( + ByteArrayInputStream(bytes), + object : FilterInputStream(ByteArrayInputStream(bytes)) { + override fun read(): Int { + throw HashMismatchException() + } + + override fun read(b: ByteArray, off: Int, len: Int): Int { + throw HashMismatchException() + } + }, + ) + coEvery { loader.loadFiles(blobHandles) } returns inputStream + every { outputFactory.getOutputStream(fileDescriptor) } returns outputStream + every { fileDescriptor.close() } just Runs + + assertEquals(bytes.size, restore.getNextFullRestoreDataChunk(fileDescriptor)) + assertEquals( + TRANSPORT_PACKAGE_REJECTED, + restore.getNextFullRestoreDataChunk(fileDescriptor), + ) + + verify { fileDescriptor.close() } + } + @Test fun `full chunk gets decrypted`() = runBlocking { restore.initializeState(VERSION, packageInfo, blobHandles)