ICU-13632 regex out-of-bounds memory reference fix.

X-SVN-Rev: 41088
This commit is contained in:
Andy Heninger 2018-03-09 18:39:14 +00:00
parent 8fe72cd82b
commit 0d32dd8f05
3 changed files with 25 additions and 3 deletions

View File

@ -1465,8 +1465,10 @@ int32_t RegexCImpl::appendReplacement(RegularExpression *regexp,
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();

View File

@ -103,6 +103,7 @@ void RegexTest::runIndexedTest( int32_t index, UBool exec, const char* &name, ch
TESTCASE_AUTO(NamedCaptureLimits);
TESTCASE_AUTO(TestBug12884);
TESTCASE_AUTO(TestBug13631);
TESTCASE_AUTO(TestBug13632);
TESTCASE_AUTO_END;
}
@ -5831,5 +5832,23 @@ void RegexTest::TestBug13631() {
}
}
// 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 */

View File

@ -58,7 +58,8 @@ public:
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);