package com.peachpasswords.ui.vault import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test /** * M-01: an import is attacker-shaped input. A provider stream longer than the * cap, or a parse that yields an absurd entry count / field size, must be * refused before anything is staged for the vault write. */ class ImportBoundsTest { @Test fun oversize_stream_is_rejected() { val over = ByteArray(1024) { 'a'.code.toByte() }.inputStream() assertNull(CsvImport.readBoundedUtf8(over, max = 512)) } @Test fun within_bound_stream_reads_fully() { val body = "name,url,username,password\nA,https://a.com,u,p\n" assertEquals(body, CsvImport.readBoundedUtf8(body.byteInputStream(), max = 512)) } @Test fun too_many_entries_is_rejected() { val rows = (0..CsvImport.MAX_IMPORT_ENTRIES) .joinToString("\n") { "T$it,https://a.com,u$it,p$it" } val csv = "name,url,username,password\n$rows\n" val r = CsvImport.detectAndParse(csv) assertTrue(r is ImportParseResult.Failure) assertEquals(ImportParseResult.Reason.TOO_LARGE, (r as ImportParseResult.Failure).reason) } @Test fun oversize_field_is_rejected() { val huge = "x".repeat(CsvImport.MAX_FIELD_CHARS + 1) val csv = "name,url,username,password\nA,https://a.com,u,$huge\n" val r = CsvImport.detectAndParse(csv) assertEquals( ImportParseResult.Reason.TOO_LARGE, (r as ImportParseResult.Failure).reason, ) } }