KotlinStringLiteralTextEscaper: provides offsets for already decoded (KT-27380)

This commit is contained in:
Nicolay Mitropolsky
2018-11-12 17:47:18 +03:00
parent 6342bc378e
commit 4a64edd610
2 changed files with 27 additions and 0 deletions
@@ -41,6 +41,9 @@ class KotlinStringLiteralTextEscaper(host: KtStringTemplateExpression) : Literal
is KtEscapeStringTemplateEntry -> {
if (!rangeInsideHost.contains(childRange)) {
//don't allow injection if its range starts or ends inside escaped sequence
//but still process offsets for the already decoded part
sourceOffsetsList.add(sourceOffset)
sourceOffsets = sourceOffsetsList.toNativeArray()
return false
}
val unescaped = child.unescapedValue
@@ -104,6 +104,28 @@ class StringInjectionHostTest : KotlinTestWithEnvironment() {
}
}
fun testProvideOffsetsForDecodablePartOfUndecodableString() {
val undecodable = stringExpression(""""{\\d\}"""")
val escaper = undecodable.createLiteralTextEscaper()
val undecodableRange = undecodable.text.rangeOf("""\\d\""")
val decoded = StringBuilder()
assertFalse(escaper.decode(undecodableRange, decoded))
assertEquals("""\d""", decoded.toString())
val mapping = (0..undecodableRange.length).keysToMap { escaper.getOffsetInHost(it, undecodableRange) }
assertEquals(
mapOf(
0 to 2,
1 to 4,
2 to 5,
3 to -1,
4 to -1
),
mapping
)
}
private fun quoted(s: String): KtStringTemplateExpression {
return stringExpression("\"$s\"")
}
@@ -163,3 +185,5 @@ class StringInjectionHostTest : KotlinTestWithEnvironment() {
override fun createEnvironment() = createEnvironmentWithMockJdk(ConfigurationKind.JDK_ONLY)
}
private fun String.rangeOf(inner: String): TextRange = indexOf(inner).let { TextRange.from(it, inner.length) }