1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

[TextServer] Add ICU Unicode security and spoofing detection.

This commit is contained in:
bruvzg
2021-11-12 10:12:37 +02:00
parent 119b2874c3
commit 4373a0bb86
20 changed files with 4403 additions and 4 deletions

View File

@@ -347,6 +347,7 @@ bool TextServerAdvanced::has_feature(Feature p_feature) const {
case FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION:
case FEATURE_USE_SUPPORT_DATA:
case FEATURE_UNICODE_IDENTIFIERS:
case FEATURE_UNICODE_SECURITY:
return true;
default: {
}
@@ -5640,6 +5641,68 @@ String TextServerAdvanced::percent_sign(const String &p_language) const {
return "%";
}
int TextServerAdvanced::is_confusable(const String &p_string, const PackedStringArray &p_dict) const {
UErrorCode status = U_ZERO_ERROR;
int match_index = -1;
Char16String utf16 = p_string.utf16();
Vector<UChar *> skeletons;
skeletons.resize(p_dict.size());
USpoofChecker *sc = uspoof_open(&status);
uspoof_setChecks(sc, USPOOF_CONFUSABLE, &status);
for (int i = 0; i < p_dict.size(); i++) {
Char16String word = p_dict[i].utf16();
int32_t len = uspoof_getSkeleton(sc, 0, word.get_data(), -1, NULL, 0, &status);
skeletons.write[i] = (UChar *)memalloc(++len * sizeof(UChar));
status = U_ZERO_ERROR;
uspoof_getSkeleton(sc, 0, word.get_data(), -1, skeletons.write[i], len, &status);
}
int32_t len = uspoof_getSkeleton(sc, 0, utf16.get_data(), -1, NULL, 0, &status);
UChar *skel = (UChar *)memalloc(++len * sizeof(UChar));
status = U_ZERO_ERROR;
uspoof_getSkeleton(sc, 0, utf16.get_data(), -1, skel, len, &status);
for (int i = 0; i < skeletons.size(); i++) {
if (u_strcmp(skel, skeletons[i]) == 0) {
match_index = i;
break;
}
}
memfree(skel);
for (int i = 0; i < skeletons.size(); i++) {
memfree(skeletons.write[i]);
}
uspoof_close(sc);
ERR_FAIL_COND_V_MSG(U_FAILURE(status), -1, u_errorName(status));
return match_index;
}
bool TextServerAdvanced::spoof_check(const String &p_string) const {
UErrorCode status = U_ZERO_ERROR;
Char16String utf16 = p_string.utf16();
USet *allowed = uset_openEmpty();
uset_addAll(allowed, uspoof_getRecommendedSet(&status));
uset_addAll(allowed, uspoof_getInclusionSet(&status));
USpoofChecker *sc = uspoof_open(&status);
uspoof_setAllowedChars(sc, allowed, &status);
uspoof_setRestrictionLevel(sc, USPOOF_MODERATELY_RESTRICTIVE);
int32_t bitmask = uspoof_check(sc, utf16.get_data(), -1, NULL, &status);
uspoof_close(sc);
uset_close(allowed);
ERR_FAIL_COND_V_MSG(U_FAILURE(status), false, u_errorName(status));
return (bitmask != 0);
}
String TextServerAdvanced::strip_diacritics(const String &p_string) const {
UErrorCode err = U_ZERO_ERROR;