Fix Matcher.find and reset
- Matcher.find didn't call reset(), but according to the javadoc, it
should.
- reset() didn't obtain a fresh value from mutable CharSequence.
Given that the constructor uses CharSequence, it should obtain a new value
from the CharSequence and match it again
Added 2 tests to verify such behaviors accordingly
Bug: 33737213
Test: cts-tradefed run cts -m CtsLibcoreTestCases --primary-abi-only
Change-Id: I16ce01944b8c1baac9b7947d5551fb030eb95fc8
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
index 9f749c6..fc36eda 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java
@@ -158,6 +158,40 @@
public void testReset() {
}
+ public void testFind_invokeReset() {
+ // First, verify find() doesn't reset, and search for the subsequent pattern
+ Pattern p = Pattern.compile("a|c");
+ StringBuilder sb = new StringBuilder("abc");
+ Matcher m = p.matcher(sb);
+ assertTrue(m.find());
+ assertEquals(0, m.start());
+ assertTrue(m.find());
+ assertEquals(2, m.start());
+
+ // Second, find(int) resets the matcher
+ assertTrue(m.find(0));
+ assertEquals(0, m.start());
+ sb.replace(0, 3, "bac");
+
+ // Test find(0) reset the cached string value from the StringBuilder
+ assertTrue(m.find(0));
+ assertEquals(1, m.start());
+ }
+
+ /**
+ * Test reset() reset the cached string value from the StringBuilder
+ */
+ public void testReset_resetStringCache() {
+ Pattern p = Pattern.compile("a");
+ StringBuilder sb = new StringBuilder("a");
+ Matcher m = p.matcher(sb);
+ assertTrue(m.find());
+
+ sb.replace(0, 1, "c");
+ m.reset();
+ assertFalse(m.find());
+ }
+
public void testGroupint() {
String positiveTestString = "ababababbaaabb";
diff --git a/ojluni/src/main/java/java/util/regex/Matcher.java b/ojluni/src/main/java/java/util/regex/Matcher.java
index 9af28aa..382bbfd 100644
--- a/ojluni/src/main/java/java/util/regex/Matcher.java
+++ b/ojluni/src/main/java/java/util/regex/Matcher.java
@@ -124,6 +124,12 @@
Matcher.class.getClassLoader(), getNativeFinalizer(), nativeSize());
/**
+ * Holds the original CharSequence for {@link #reset} only. Any reference to the content after
+ * {@link #reset} can direct to {@link #input}.
+ */
+ private CharSequence originalInput;
+
+ /**
* Holds the input text.
*/
private String input;
@@ -490,6 +496,7 @@
* pattern
*/
public boolean find(int start) {
+ reset();
if (start < 0 || start > input.length()) {
throw new IndexOutOfBoundsException("start=" + start + "; length=" + input.length());
}
@@ -820,7 +827,7 @@
* @since 1.5
*/
public Matcher region(int start, int end) {
- return reset(input, start, end);
+ return reset(originalInput, start, end);
}
/**
@@ -1024,7 +1031,7 @@
* @return This matcher
*/
public Matcher reset() {
- return reset(input, 0, input.length());
+ return reset(originalInput, 0, originalInput.length());
}
/**
@@ -1070,6 +1077,7 @@
throw new IndexOutOfBoundsException();
}
+ this.originalInput = input;
this.input = input.toString();
this.regionStart = start;
this.regionEnd = end;