+
+static void TestRefreshInput(void) {
+ /*
+ * RefreshInput changes out the input of a URegularExpression without
+ * changing anything else in the match state. Used with Java JNI,
+ * when Java moves the underlying string storage. This test
+ * runs a find() loop, moving the text after the first match.
+ * The right number of matches should still be found.
+ */
+ UChar testStr[] = {0x41, 0x20, 0x42, 0x20, 0x43, 0x0}; /* = "A B C" */
+ UChar movedStr[] = { 0, 0, 0, 0, 0, 0};
+ UErrorCode status = U_ZERO_ERROR;
+ URegularExpression *re;
+ UText ut1 = UTEXT_INITIALIZER;
+ UText ut2 = UTEXT_INITIALIZER;
+
+ re = uregex_openC("[ABC]", 0, 0, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ utext_openUChars(&ut1, testStr, -1, &status);
+ TEST_ASSERT_SUCCESS(status);
+ uregex_setUText(re, &ut1, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ /* Find the first match "A" in the original string */
+ TEST_ASSERT(uregex_findNext(re, &status));
+ TEST_ASSERT(uregex_start(re, 0, &status) == 0);
+
+ /* Move the string, kill the original string. */
+ u_strcpy(movedStr, testStr);
+ u_memset(testStr, 0, u_strlen(testStr));
+ utext_openUChars(&ut2, movedStr, -1, &status);
+ TEST_ASSERT_SUCCESS(status);
+ uregex_refreshUText(re, &ut2, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ /* Find the following two matches, now working in the moved string. */
+ TEST_ASSERT(uregex_findNext(re, &status));
+ TEST_ASSERT(uregex_start(re, 0, &status) == 2);
+ TEST_ASSERT(uregex_findNext(re, &status));
+ TEST_ASSERT(uregex_start(re, 0, &status) == 4);
+ TEST_ASSERT(FALSE == uregex_findNext(re, &status));
+
+ uregex_close(re);
+}
+
+
+static void TestBug8421(void) {
+ /* Bug 8421: setTimeLimit on a regular expresssion before setting text to be matched
+ * was failing.
+ */
+ URegularExpression *re;
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t limit = -1;
+
+ re = uregex_openC("abc", 0, 0, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ limit = uregex_getTimeLimit(re, &status);
+ TEST_ASSERT_SUCCESS(status);
+ TEST_ASSERT(limit == 0);
+
+ uregex_setTimeLimit(re, 100, &status);
+ TEST_ASSERT_SUCCESS(status);
+ limit = uregex_getTimeLimit(re, &status);
+ TEST_ASSERT_SUCCESS(status);
+ TEST_ASSERT(limit == 100);
+
+ uregex_close(re);
+}
+
+static UBool U_CALLCONV FindCallback(const void* context , int64_t matchIndex) {
+ return FALSE;
+}
+
+static UBool U_CALLCONV MatchCallback(const void *context, int32_t steps) {
+ return FALSE;
+}
+
+static void TestBug10815() {
+ /* Bug 10815: uregex_findNext() does not set U_REGEX_STOPPED_BY_CALLER
+ * when the callback function specified by uregex_setMatchCallback() returns FALSE
+ */
+ URegularExpression *re;
+ UErrorCode status = U_ZERO_ERROR;
+ UChar text[100];
+
+
+ // findNext() with a find progress callback function.
+
+ re = uregex_openC(".z", 0, 0, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ u_uastrncpy(text, "Hello, World.", UPRV_LENGTHOF(text));
+ uregex_setText(re, text, -1, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ uregex_setFindProgressCallback(re, FindCallback, NULL, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ uregex_findNext(re, &status);
+ TEST_ASSERT(status == U_REGEX_STOPPED_BY_CALLER);
+
+ uregex_close(re);
+
+ // findNext() with a match progress callback function.
+
+ status = U_ZERO_ERROR;
+ re = uregex_openC("((xxx)*)*y", 0, 0, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ // Pattern + this text gives an exponential time match. Without the callback to stop the match,
+ // it will appear to be stuck in a (near) infinite loop.
+ u_uastrncpy(text, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", UPRV_LENGTHOF(text));
+ uregex_setText(re, text, -1, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ uregex_setMatchCallback(re, MatchCallback, NULL, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ uregex_findNext(re, &status);
+ TEST_ASSERT(status == U_REGEX_STOPPED_BY_CALLER);
+
+ uregex_close(re);
+}
+
+static const UChar startLinePattern[] = { 0x5E, 0x78, 0 }; // "^x"
+
+static void TestMatchStartLineWithEmptyText() {
+ UErrorCode status = U_ZERO_ERROR;
+ UText* ut = utext_openUChars(NULL, NULL, 0, &status);
+ TEST_ASSERT_SUCCESS(status);
+ if (U_SUCCESS(status)) {
+ URegularExpression *re = uregex_open(startLinePattern, -1, 0, NULL, &status);
+ TEST_ASSERT_SUCCESS(status);
+ if (U_SUCCESS(status)) {
+ uregex_setUText(re, ut, &status);
+ TEST_ASSERT(U_SUCCESS(status));
+ if (U_SUCCESS(status)) {
+ UBool found = uregex_findNext(re, &status);
+ TEST_ASSERT(U_SUCCESS(status) && !found);
+ }
+ uregex_close(re);
+ }
+ utext_close(ut);
+ }
+}
+