From 06408157dfde2f40c6368c5ab03e46479428f566 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Tue, 13 Aug 2019 23:49:04 -0700 Subject: Use one stringbuilder per tag creation and add test --- .../com/pitchedapps/frost/injectors/JsInjector.kt | 37 ++++++++++------------ .../frost/injectors/TagObfuscatorTest.kt | 22 +++++++++++++ 2 files changed, 38 insertions(+), 21 deletions(-) create mode 100644 app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt index 5d8c55e6..eed2f819 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt @@ -16,13 +16,11 @@ */ package com.pitchedapps.frost.injectors -import android.util.Log import android.webkit.WebView -import com.pitchedapps.frost.BuildConfig +import androidx.annotation.VisibleForTesting import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.web.FrostWebViewClient import org.apache.commons.text.StringEscapeUtils -import java.util.Locale import kotlin.random.Random class JsBuilder { @@ -115,33 +113,30 @@ class JsInjector(val function: String) : InjectorContract { /** * Helper object to obfuscate window tags for JS injection. */ -private object TagObfuscator { +@VisibleForTesting +internal object TagObfuscator { - fun obfuscateTag(tag: String) : String { + fun obfuscateTag(tag: String): String { val rnd = Random(tag.hashCode() + salt) - val obfuscated = StringBuilder() - .append(prefix) - .append(randomChars(rnd, tag.length)) - L._d { "TagObfuscator: Obfuscating tag '$tag' to '$obfuscated'" } - //if (BuildConfig.DEBUG) { - // return "_frost_${tag.toLowerCase(Locale.CANADA)}" - //} else - return obfuscated.toString() + val obfuscated = buildString { + append(prefix) + append('_') + appendRandomChars(rnd, 16) + } + L.v { "TagObfuscator: Obfuscating tag '$tag' to '$obfuscated'" } + return obfuscated } - private val salt by lazy { System.currentTimeMillis() } + private val salt: Long = System.currentTimeMillis() - private val prefix by lazy { + private val prefix: String by lazy { val rnd = Random(System.currentTimeMillis()) - val length = rnd.nextInt(10, 16) - randomChars(rnd, length) + buildString { appendRandomChars(rnd, 8) } } - private fun randomChars(random: Random, count: Int) : String { - val result = StringBuilder() + private fun Appendable.appendRandomChars(random: Random, count: Int) { for (i in 1..count) { - result.append('a' + random.nextInt(0, 26)) + append('a' + random.nextInt(26)) } - return result.toString() } } \ No newline at end of file diff --git a/app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt new file mode 100644 index 00000000..5c316a4a --- /dev/null +++ b/app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt @@ -0,0 +1,22 @@ +package com.pitchedapps.frost.injectors + +import java.util.UUID +import kotlin.test.Test +import kotlin.test.assertEquals + +class TagObfuscatorTest { + + /** + * The same key should result in the same tag per session + */ + @Test + fun consistentTags() { + val keys = generateSequence { UUID.randomUUID().toString() }.take(10).toSet() + val tags = keys.map { + val tag = generateSequence { TagObfuscator.obfuscateTag(it) }.take(10).toSet() + assertEquals(1, tag.size, "Key $it produced multiple tags: $tag") + tag.first() + } + assertEquals(keys.size, tags.size, "Key set and tag set have different sizes") + } +} -- cgit v1.2.3