1 /*
2 +----------------------------------------------------------------------+
3 | This source file is subject to version 3.01 of the PHP license, |
4 | that is bundled with this package in the file LICENSE, and is |
5 | available through the world-wide-web at the following url: |
6 | https://www.php.net/license/3_01.txt |
7 | If you did not receive a copy of the PHP license and are unable to |
8 | obtain it through the world-wide-web, please send a note to |
9 | license@php.net so we can mail you a copy immediately. |
10 +----------------------------------------------------------------------+
11 | Authors: Scott MacVicar <scottmac@php.net> |
12 +----------------------------------------------------------------------+
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include "php_intl.h"
20 #include "spoofchecker_class.h"
21
22 /* {{{ Checks if a given text contains any suspicious characters */
PHP_METHOD(Spoofchecker,isSuspicious)23 PHP_METHOD(Spoofchecker, isSuspicious)
24 {
25 int32_t ret, errmask;
26 char *text;
27 size_t text_len;
28 zval *error_code = NULL;
29 SPOOFCHECKER_METHOD_INIT_VARS;
30
31 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s|z", &text, &text_len, &error_code)) {
32 RETURN_THROWS();
33 }
34
35 SPOOFCHECKER_METHOD_FETCH_OBJECT;
36
37 #if U_ICU_VERSION_MAJOR_NUM >= 58
38 ret = uspoof_check2UTF8(co->uspoof, text, text_len, co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co));
39 #else
40 ret = uspoof_checkUTF8(co->uspoof, text, text_len, NULL, SPOOFCHECKER_ERROR_CODE_P(co));
41 #endif
42
43 if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) {
44 php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co)));
45 #if U_ICU_VERSION_MAJOR_NUM >= 58
46 errmask = uspoof_getCheckResultChecks(co->uspoofres, SPOOFCHECKER_ERROR_CODE_P(co));
47
48 if (errmask != ret) {
49 php_error_docref(NULL, E_WARNING, "unexpected error (%d), does not relate to the flags passed to setChecks (%d)", ret, errmask);
50 }
51 #endif
52 RETURN_TRUE;
53 }
54
55 if (error_code) {
56 ZEND_TRY_ASSIGN_REF_LONG(error_code, ret);
57 }
58 RETVAL_BOOL(ret != 0);
59 }
60 /* }}} */
61
62 /* {{{ Checks if a given text contains any confusable characters */
PHP_METHOD(Spoofchecker,areConfusable)63 PHP_METHOD(Spoofchecker, areConfusable)
64 {
65 int ret;
66 char *s1, *s2;
67 size_t s1_len, s2_len;
68 zval *error_code = NULL;
69 SPOOFCHECKER_METHOD_INIT_VARS;
70
71 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "ss|z", &s1, &s1_len,
72 &s2, &s2_len, &error_code)) {
73 RETURN_THROWS();
74 }
75
76 SPOOFCHECKER_METHOD_FETCH_OBJECT;
77 if(s1_len > INT32_MAX || s2_len > INT32_MAX) {
78 SPOOFCHECKER_ERROR_CODE(co) = U_BUFFER_OVERFLOW_ERROR;
79 } else {
80 ret = uspoof_areConfusableUTF8(co->uspoof, s1, (int32_t)s1_len, s2, (int32_t)s2_len, SPOOFCHECKER_ERROR_CODE_P(co));
81 }
82 if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) {
83 php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co)));
84 RETURN_TRUE;
85 }
86
87 if (error_code) {
88 ZEND_TRY_ASSIGN_REF_LONG(error_code, ret);
89 }
90 RETVAL_BOOL(ret != 0);
91 }
92 /* }}} */
93
94 /* {{{ Locales to use when running checks */
PHP_METHOD(Spoofchecker,setAllowedLocales)95 PHP_METHOD(Spoofchecker, setAllowedLocales)
96 {
97 char *locales;
98 size_t locales_len;
99 SPOOFCHECKER_METHOD_INIT_VARS;
100
101 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &locales, &locales_len)) {
102 RETURN_THROWS();
103 }
104
105 SPOOFCHECKER_METHOD_FETCH_OBJECT;
106
107 uspoof_setAllowedLocales(co->uspoof, locales, SPOOFCHECKER_ERROR_CODE_P(co));
108
109 if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) {
110 php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co)));
111 return;
112 }
113 }
114 /* }}} */
115
116 /* {{{ Set the checks to run */
PHP_METHOD(Spoofchecker,setChecks)117 PHP_METHOD(Spoofchecker, setChecks)
118 {
119 zend_long checks;
120 SPOOFCHECKER_METHOD_INIT_VARS;
121
122 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "l", &checks)) {
123 RETURN_THROWS();
124 }
125
126 SPOOFCHECKER_METHOD_FETCH_OBJECT;
127
128 uspoof_setChecks(co->uspoof, checks, SPOOFCHECKER_ERROR_CODE_P(co));
129
130 if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) {
131 php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co)));
132 }
133 }
134 /* }}} */
135
136 #if U_ICU_VERSION_MAJOR_NUM >= 58
137 /* TODO Document this method on PHP.net */
138 /* {{{ Set the loosest restriction level allowed for strings. */
PHP_METHOD(Spoofchecker,setRestrictionLevel)139 PHP_METHOD(Spoofchecker, setRestrictionLevel)
140 {
141 zend_long level;
142 SPOOFCHECKER_METHOD_INIT_VARS;
143
144 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "l", &level)) {
145 RETURN_THROWS();
146 }
147
148 SPOOFCHECKER_METHOD_FETCH_OBJECT;
149
150 if (USPOOF_ASCII != level &&
151 USPOOF_SINGLE_SCRIPT_RESTRICTIVE != level &&
152 USPOOF_HIGHLY_RESTRICTIVE != level &&
153 USPOOF_MODERATELY_RESTRICTIVE != level &&
154 USPOOF_MINIMALLY_RESTRICTIVE != level &&
155 USPOOF_UNRESTRICTIVE != level) {
156 zend_argument_value_error(1, "must be one of Spoofchecker::ASCII, Spoofchecker::SINGLE_SCRIPT_RESTRICTIVE, "
157 "Spoofchecker::SINGLE_HIGHLY_RESTRICTIVE, Spoofchecker::SINGLE_MODERATELY_RESTRICTIVE, "
158 "Spoofchecker::SINGLE_MINIMALLY_RESTRICTIVE, or Spoofchecker::UNRESTRICTIVE");
159 RETURN_THROWS();
160 }
161
162 uspoof_setRestrictionLevel(co->uspoof, (URestrictionLevel)level);
163 }
164 /* }}} */
165 #endif
166