diff --git a/libraries/stdlib/native-wasm/src/kotlin/text/regex/Pattern.kt b/libraries/stdlib/native-wasm/src/kotlin/text/regex/Pattern.kt index 1ecf690e2dd..309d8da39ac 100644 --- a/libraries/stdlib/native-wasm/src/kotlin/text/regex/Pattern.kt +++ b/libraries/stdlib/native-wasm/src/kotlin/text/regex/Pattern.kt @@ -130,6 +130,9 @@ internal class Pattern(val pattern: String, flags: Int = 0) { if (ch == Lexer.CHAR_NAMED_GROUP) { val name = (lexemes.curSpecialToken as NamedGroup).name + if (groupNameToIndex.containsKey(name)) { + throw PatternSyntaxException("Named capturing group <$name> is already defined", pattern, lexemes.curTokenIndex) + } groupNameToIndex[name] = fSet.groupIndex } } diff --git a/libraries/stdlib/test/text/RegexTest.kt b/libraries/stdlib/test/text/RegexTest.kt index d91a6f4fa93..478bed971ec 100644 --- a/libraries/stdlib/test/text/RegexTest.kt +++ b/libraries/stdlib/test/text/RegexTest.kt @@ -174,6 +174,17 @@ class RegexTest { assertEquals("123", namedGroups["areaCode"]?.value) } + @Test fun matchDuplicateGroupName() { + if (!supportsNamedCapturingGroup) return + + assertFailsWith { + "(?hi)|(?bye)".toRegex() + } + assertFailsWith { + Regex("(?\\d+)-(?\\d+)") + } + } + @Test fun matchOptionalNamedGroup() { if (!supportsNamedCapturingGroup) return