TESTCASE_AUTO(testBug12153);
TESTCASE_AUTO(testBug12825);
TESTCASE_AUTO(testBug12815);
+ TESTCASE_AUTO(testBug13314_MixedNumbers);
+ TESTCASE_AUTO(testBug13328_MixedCombiningMarks);
+ TESTCASE_AUTO(testCombiningDot);
TESTCASE_AUTO_END;
}
void IntlTestSpoof::testBug12153() {
UErrorCode status = U_ZERO_ERROR;
LocalUSpoofCheckerPointer sc(uspoof_open(&status));
- TEST_ASSERT_SUCCESS(status);
+ if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
int32_t checks = uspoof_getChecks(sc.getAlias(), &status);
TEST_ASSERT((checks & USPOOF_RESTRICTION_LEVEL) != 0);
checks &= ~USPOOF_RESTRICTION_LEVEL;
TEST_ASSERT_SUCCESS(status);
}
+void IntlTestSpoof::testBug13314_MixedNumbers() {
+ UErrorCode status = U_ZERO_ERROR;
+ LocalUSpoofCheckerPointer sc(uspoof_open(&status));
+ if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+ uspoof_setChecks(sc.getAlias(), USPOOF_ALL_CHECKS, &status);
+ TEST_ASSERT_SUCCESS(status);
+ int32_t failedChecks = uspoof_areConfusableUnicodeString(sc.getAlias(), u"列", u"列", &status);
+ TEST_ASSERT_SUCCESS(status);
+ assertEquals("The CJK strings should be confusable", USPOOF_SINGLE_SCRIPT_CONFUSABLE, failedChecks);
+ failedChecks = uspoof_check2UnicodeString(sc.getAlias(), u"3Ȝ", nullptr, &status);
+ TEST_ASSERT_SUCCESS(status);
+ assertEquals("The '33' string does not fail spoof", 0, failedChecks);
+}
+
+void IntlTestSpoof::testBug13328_MixedCombiningMarks() {
+ UErrorCode status = U_ZERO_ERROR;
+ LocalUSpoofCheckerPointer sc(uspoof_open(&status));
+ if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+ int32_t failedChecks = uspoof_check2UnicodeString(sc.getAlias(), u"\u0061\u0F84", nullptr, &status);
+ TEST_ASSERT_SUCCESS(status);
+ assertEquals(
+ "The mismatched combining marks string fails spoof",
+ USPOOF_RESTRICTION_LEVEL,
+ failedChecks);
+}
+
+void IntlTestSpoof::testCombiningDot() {
+ UErrorCode status = U_ZERO_ERROR;
+ LocalUSpoofCheckerPointer sc(uspoof_open(&status));
+ if (!assertSuccess("", status, true, __FILE__, __LINE__)) { return; }
+ uspoof_setChecks(sc.getAlias(), USPOOF_HIDDEN_OVERLAY, &status);
+ TEST_ASSERT_SUCCESS(status);
+
+ static const struct TestCase {
+ bool shouldFail;
+ const char16_t* input;
+ } cases[] = {
+ {false, u"i"},
+ {false, u"j"},
+ {false, u"l"},
+ {true, u"i\u0307"},
+ {true, u"j\u0307"},
+ {true, u"l\u0307"},
+ {true, u"ı\u0307"},
+ {true, u"ȷ\u0307"},
+ {true, u"𝚤\u0307"},
+ {true, u"𝑗\u0307"},
+ {false, u"m\u0307"},
+ {true, u"1\u0307"},
+ {true, u"ij\u0307"},
+ {true, u"i\u0307\u0307"},
+ {true, u"abci\u0307def"},
+ {false, u"i\u0301\u0307"}, // U+0301 has combining class ABOVE (230)
+ {true, u"i\u0320\u0307"}, // U+0320 has combining class BELOW
+ {true, u"i\u0320\u0321\u0307"}, // U+0321 also has combining class BELOW
+ {false, u"i\u0320\u0301\u0307"},
+ {false, u"iz\u0307"},
+ };
+
+ for (auto& cas : cases) {
+ int32_t failedChecks = uspoof_check2(sc.getAlias(), cas.input, -1, nullptr, &status);
+ TEST_ASSERT_SUCCESS(status);
+ int32_t expected = cas.shouldFail ? USPOOF_HIDDEN_OVERLAY : 0;
+ assertEquals(cas.input, expected, failedChecks);
+ }
+}
+
#endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS && !UCONFIG_NO_NORMALIZATION && !UCONFIG_NO_FILE_IO */