int32_t groupNum = 0;
U_ASSERT(c == DOLLARSIGN);
- UChar32 c32;
- U16_GET(replacementText, 0, replIdx, replacementLength, c32);
+ UChar32 c32 = -1;
+ if (replIdx < replacementLength) {
+ U16_GET(replacementText, 0, replIdx, replacementLength, c32);
+ }
if (u_isdigit(c32)) {
int32_t numDigits = 0;
int32_t numCaptureGroups = m->fPattern->fGroupMap->size();
TESTCASE_AUTO(NamedCaptureLimits);
TESTCASE_AUTO(TestBug12884);
TESTCASE_AUTO(TestBug13631);
+ TESTCASE_AUTO(TestBug13632);
TESTCASE_AUTO_END;
}
}
}
+// Bug 13632 Out of bounds memory reference if a replacement string ends with a '$',
+// where a following group specification would be expected.
+// Failure shows when running the test under Clang's Address Sanitizer.
+
+void RegexTest::TestBug13632() {
+ UErrorCode status = U_ZERO_ERROR;
+ URegularExpression *re = uregex_openC(" ", 0, nullptr, &status);
+ const char16_t *sourceString = u"Hello, world.";
+ uregex_setText(re, sourceString, u_strlen(sourceString), &status);
+
+ const int32_t destCap = 20;
+ char16_t dest[destCap] = {};
+ const char16_t replacement[] = {u'x', u'$'}; // Not nul terminated string.
+ uregex_replaceAll(re, replacement, 2, dest, destCap, &status);
+
+ assertEquals("", U_REGEX_INVALID_CAPTURE_GROUP_NAME, status);
+ uregex_close(re);
+}
#endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */
virtual void TestBug11480();
virtual void TestBug12884();
virtual void TestBug13631();
-
+ virtual void TestBug13632();
+
// The following functions are internal to the regexp tests.
virtual void assertUText(const char *expected, UText *actual, const char *file, int line);
virtual void assertUTextInvariant(const char *invariant, UText *actual, const char *file, int line);