From 98a1180f9a72d39b556b398ab3fd9891f502e1f9 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:45:53 -0800 Subject: [PATCH 1/2] MatcherTest: test double-digit group replacement Another test case we have verifies only that the first digit is over the group limit. --- javatests/com/google/re2j/MatcherTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/javatests/com/google/re2j/MatcherTest.java b/javatests/com/google/re2j/MatcherTest.java index 4f24ae2e..ff6bb6e1 100644 --- a/javatests/com/google/re2j/MatcherTest.java +++ b/javatests/com/google/re2j/MatcherTest.java @@ -166,6 +166,16 @@ public void testInvalidReplacement() { } } + @Test + public void testInvalidReplacementDoubleDigit() { + ApiTestUtils.testReplaceFirst("abc", "(abc)", "$10", "abc0"); + } + + @Test + public void testValidReplacementSingleDigitSeparated() { + ApiTestUtils.testReplaceFirst("abc", "(abc)", "$1\\0", "abc0"); + } + @Test public void testInvalidGroupNoMatch() { try { From 23a3ca84dfc82732845953f748708dcdb76284c3 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:51:54 -0800 Subject: [PATCH 2/2] Matcher: fix bug with over-limit multi-digit group --- java/com/google/re2j/Matcher.java | 2 +- javatests/com/google/re2j/MatcherTest.java | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/java/com/google/re2j/Matcher.java b/java/com/google/re2j/Matcher.java index 678186d0..e5c6d445 100644 --- a/java/com/google/re2j/Matcher.java +++ b/java/com/google/re2j/Matcher.java @@ -504,7 +504,7 @@ private void appendReplacementInternal(StringBuilder sb, String replacement) { } for (i += 2; i < m; i++) { c = replacement.charAt(i); - if (c < '0' || c > '9' || n * 10 + c - '0' > groupCount) { + if (c < '0' || c > '9') { break; } n = n * 10 + c - '0'; diff --git a/javatests/com/google/re2j/MatcherTest.java b/javatests/com/google/re2j/MatcherTest.java index ff6bb6e1..55fcd334 100644 --- a/javatests/com/google/re2j/MatcherTest.java +++ b/javatests/com/google/re2j/MatcherTest.java @@ -54,7 +54,7 @@ public void testReplaceAll() { ApiTestUtils.testReplaceAll( "abcdefghijklmnopqrstuvwxyz123", "(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)", - "$10$20", + "$10$2\\0", "jb0wo0123"); ApiTestUtils.testReplaceAll( "\u00e1\u0062\u00e7\u2655", "(.)", "<$1>", "<\u00e1><\u0062><\u00e7><\u2655>"); @@ -83,7 +83,7 @@ public void testReplaceFirst() { ApiTestUtils.testReplaceFirst( "abcdefghijklmnopqrstuvwxyz123", "(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)", - "$10$20", + "$10$2\\0", "jb0nopqrstuvwxyz123"); ApiTestUtils.testReplaceFirst( "\u00e1\u0062\u00e7\u2655", "(.)", "<$1>", "<\u00e1>\u0062\u00e7\u2655"); @@ -168,7 +168,13 @@ public void testInvalidReplacement() { @Test public void testInvalidReplacementDoubleDigit() { - ApiTestUtils.testReplaceFirst("abc", "(abc)", "$10", "abc0"); + try { + ApiTestUtils.testReplaceFirst("abc", "(abc)", "$10", "xxx"); + fail(); + } catch (IndexOutOfBoundsException e) { + /* ok */ + assertTrue(true); + } } @Test