package com.peachpasswords.ui.components import java.io.File import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Test class FaviconsTest { @Test fun unwraps_png_inside_ico_container() { val png = byteArrayOf(0x89.toByte(), 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 1, 2, 3) val ico = ByteArray(22 + png.size) ico[2] = 1 // ICO type ico[18] = 22 // data offset, little-endian png.copyInto(ico, 22) assertArrayEquals(png, decodeOrUnwrapIco(ico)) } @Test fun passes_non_ico_bytes_through_and_rejects_ico_without_png() { val png = byteArrayOf(0x89.toByte(), 0x50, 0x4E, 0x47, 1, 2, 3) assertArrayEquals(png, decodeOrUnwrapIco(png)) val icoBmp = ByteArray(22 + 4) icoBmp[2] = 1 icoBmp[18] = 22 assertNull(decodeOrUnwrapIco(icoBmp)) } @Test fun canonical_cache_file_stays_inside_favicon_directory() { val dir = File("/tmp/peach-favicon-test") assertEquals( File(dir, "example.com.png").canonicalPath, faviconCacheFile(dir, "EXAMPLE.com", ".png")?.path, ) assertEquals( File(dir, "xn--bcher-kva.de.miss").canonicalPath, faviconCacheFile(dir, "bücher.de", ".miss")?.path, ) } @Test fun invalid_host_material_never_becomes_a_cache_path() { listOf( "../vault", "example.com/../../vault", "example.com\\..\\vault", "/absolute.example", "example.com?x=y", "user@example.com", "example.com:443", "localhost", "127.0.0.1", "exa\u0000mple.com", "evil.com.", ).forEach { assertNull(it, faviconCacheFile(File("/tmp/cache"), it, ".png")) } } }