ImportBoundsTest.kt

1.6 KB · raw

1package com.peachpasswords.ui.vault23import org.junit.Assert.assertEquals4import org.junit.Assert.assertNull5import org.junit.Assert.assertTrue6import org.junit.Test78/**9 * M-01: an import is attacker-shaped input. A provider stream longer than the10 * cap, or a parse that yields an absurd entry count / field size, must be11 * refused before anything is staged for the vault write.12 */13class ImportBoundsTest {1415    @Test fun oversize_stream_is_rejected() {16        val over = ByteArray(1024) { 'a'.code.toByte() }.inputStream()17        assertNull(CsvImport.readBoundedUtf8(over, max = 512))18    }1920    @Test fun within_bound_stream_reads_fully() {21        val body = "name,url,username,password\nA,https://a.com,u,p\n"22        assertEquals(body, CsvImport.readBoundedUtf8(body.byteInputStream(), max = 512))23    }2425    @Test fun too_many_entries_is_rejected() {26        val rows = (0..CsvImport.MAX_IMPORT_ENTRIES)27            .joinToString("\n") { "T$it,https://a.com,u$it,p$it" }28        val csv = "name,url,username,password\n$rows\n"29        val r = CsvImport.detectAndParse(csv)30        assertTrue(r is ImportParseResult.Failure)31        assertEquals(ImportParseResult.Reason.TOO_LARGE, (r as ImportParseResult.Failure).reason)32    }3334    @Test fun oversize_field_is_rejected() {35        val huge = "x".repeat(CsvImport.MAX_FIELD_CHARS + 1)36        val csv = "name,url,username,password\nA,https://a.com,u,$huge\n"37        val r = CsvImport.detectAndParse(csv)38        assertEquals(39            ImportParseResult.Reason.TOO_LARGE,40            (r as ImportParseResult.Failure).reason,41        )42    }43}