[K/N] String.indexOf matches byte sequences not on the char boundary #KT-56637

If the found index is odd, retry search from index + 1.

Merge-request: KT-MR-10364
Merged-by: Abduqodiri Qurbonzoda <abduqodiri.qurbonzoda@jetbrains.com>
This commit is contained in:
Abduqodiri Qurbonzoda
2023-06-01 12:56:32 +00:00
committed by Space Team
parent b11447ea6b
commit 7acaf6e473
2 changed files with 26 additions and 7 deletions
+13 -7
View File
@@ -398,14 +398,20 @@ KInt Kotlin_String_indexOfString(KString thiz, KString other, KInt fromIndex) {
if (other->count_ == 0) { if (other->count_ == 0) {
return fromIndex; return fromIndex;
} }
const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, fromIndex); const KChar* thizRaw = CharArrayAddressOfElementAt(thiz, 0);
const KChar* otherRaw = CharArrayAddressOfElementAt(other, 0); const KChar* otherRaw = CharArrayAddressOfElementAt(other, 0);
void* result = konan::memmem(thizRaw, (thiz->count_ - fromIndex) * sizeof(KChar), const auto otherSize = other->count_ * sizeof(KChar);
otherRaw, other->count_ * sizeof(KChar)); while (true) {
if (result == nullptr) return -1; void* result = konan::memmem(thizRaw + fromIndex, (thiz->count_ - fromIndex) * sizeof(KChar),
otherRaw, otherSize);
return (reinterpret_cast<intptr_t>(result) - reinterpret_cast<intptr_t>( if (result == nullptr) return -1;
CharArrayAddressOfElementAt(thiz, 0))) / sizeof(KChar); auto byteIndex = reinterpret_cast<intptr_t>(result) - reinterpret_cast<intptr_t>(thizRaw);
if (byteIndex % sizeof(KChar) == 0) {
return byteIndex / sizeof(KChar);
} else {
fromIndex = byteIndex / sizeof(KChar) + 1;
}
}
} }
KInt Kotlin_String_lastIndexOfString(KString thiz, KString other, KInt fromIndex) { KInt Kotlin_String_lastIndexOfString(KString thiz, KString other, KInt fromIndex) {
+13
View File
@@ -1856,4 +1856,17 @@ ${" "}
assertTrue(null.contentEquals(null, ignoreCase = true)) assertTrue(null.contentEquals(null, ignoreCase = true))
assertTrue(null.contentEquals(null, ignoreCase = false)) assertTrue(null.contentEquals(null, ignoreCase = false))
} }
@Test
fun indexOfRespectsCharBoundary() {
withOneCharSequenceArg("\u003a\u3b3c\u003d") { input ->
assertEquals(-1, input.indexOf("\u3c00"))
assertEquals(-1, input.indexOf("\u3d3b"))
assertEquals(-1, input.indexOf("\u3c00\u3d3b"))
}
// KT-56637
assertEquals("買っ", "買っ".replace("", "X"))
assertEquals("", "".replace("", "X"))
}
} }