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 zval_ptr_dtor(error_code);
57 ZVAL_LONG(Z_REFVAL_P(error_code), ret);
58 Z_TRY_ADDREF_P(error_code);
59 }
60 RETVAL_BOOL(ret != 0);
61 }
62 /* }}} */
63
64 /* {{{ Checks if a given text contains any confusable characters */
PHP_METHOD(Spoofchecker,areConfusable)65 PHP_METHOD(Spoofchecker, areConfusable)
66 {
67 int ret;
68 char *s1, *s2;
69 size_t s1_len, s2_len;
70 zval *error_code = NULL;
71 SPOOFCHECKER_METHOD_INIT_VARS;
72
73 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "ss|z", &s1, &s1_len,
74 &s2, &s2_len, &error_code)) {
75 RETURN_THROWS();
76 }
77
78 SPOOFCHECKER_METHOD_FETCH_OBJECT;
79 if(s1_len > INT32_MAX || s2_len > INT32_MAX) {
80 SPOOFCHECKER_ERROR_CODE(co) = U_BUFFER_OVERFLOW_ERROR;
81 } else {
82 ret = uspoof_areConfusableUTF8(co->uspoof, s1, (int32_t)s1_len, s2, (int32_t)s2_len, SPOOFCHECKER_ERROR_CODE_P(co));
83 }
84 if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) {
85 php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co)));
86 RETURN_TRUE;
87 }
88
89 if (error_code) {
90 zval_ptr_dtor(error_code);
91 ZVAL_LONG(Z_REFVAL_P(error_code), ret);
92 Z_TRY_ADDREF_P(error_code);
93 }
94 RETVAL_BOOL(ret != 0);
95 }
96 /* }}} */
97
98 /* {{{ Locales to use when running checks */
PHP_METHOD(Spoofchecker,setAllowedLocales)99 PHP_METHOD(Spoofchecker, setAllowedLocales)
100 {
101 char *locales;
102 size_t locales_len;
103 SPOOFCHECKER_METHOD_INIT_VARS;
104
105 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &locales, &locales_len)) {
106 RETURN_THROWS();
107 }
108
109 SPOOFCHECKER_METHOD_FETCH_OBJECT;
110
111 uspoof_setAllowedLocales(co->uspoof, locales, SPOOFCHECKER_ERROR_CODE_P(co));
112
113 if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) {
114 php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co)));
115 return;
116 }
117 }
118 /* }}} */
119
120 /* {{{ Set the checks to run */
PHP_METHOD(Spoofchecker,setChecks)121 PHP_METHOD(Spoofchecker, setChecks)
122 {
123 zend_long checks;
124 SPOOFCHECKER_METHOD_INIT_VARS;
125
126 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "l", &checks)) {
127 RETURN_THROWS();
128 }
129
130 SPOOFCHECKER_METHOD_FETCH_OBJECT;
131
132 uspoof_setChecks(co->uspoof, checks, SPOOFCHECKER_ERROR_CODE_P(co));
133
134 if (U_FAILURE(SPOOFCHECKER_ERROR_CODE(co))) {
135 php_error_docref(NULL, E_WARNING, "(%d) %s", SPOOFCHECKER_ERROR_CODE(co), u_errorName(SPOOFCHECKER_ERROR_CODE(co)));
136 }
137 }
138 /* }}} */
139
140 #if U_ICU_VERSION_MAJOR_NUM >= 58
141 /* TODO Document this method on PHP.net */
142 /* {{{ Set the loosest restriction level allowed for strings. */
PHP_METHOD(Spoofchecker,setRestrictionLevel)143 PHP_METHOD(Spoofchecker, setRestrictionLevel)
144 {
145 zend_long level;
146 SPOOFCHECKER_METHOD_INIT_VARS;
147
148 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "l", &level)) {
149 RETURN_THROWS();
150 }
151
152 SPOOFCHECKER_METHOD_FETCH_OBJECT;
153
154 if (USPOOF_ASCII != level &&
155 USPOOF_SINGLE_SCRIPT_RESTRICTIVE != level &&
156 USPOOF_HIGHLY_RESTRICTIVE != level &&
157 USPOOF_MODERATELY_RESTRICTIVE != level &&
158 USPOOF_MINIMALLY_RESTRICTIVE != level &&
159 USPOOF_UNRESTRICTIVE != level) {
160 zend_argument_value_error(1, "must be one of Spoofchecker::ASCII, Spoofchecker::SINGLE_SCRIPT_RESTRICTIVE, "
161 "Spoofchecker::SINGLE_HIGHLY_RESTRICTIVE, Spoofchecker::SINGLE_MODERATELY_RESTRICTIVE, "
162 "Spoofchecker::SINGLE_MINIMALLY_RESTRICTIVE, or Spoofchecker::UNRESTRICTIVE");
163 RETURN_THROWS();
164 }
165
166 uspoof_setRestrictionLevel(co->uspoof, (URestrictionLevel)level);
167 }
168 /* }}} */
169 #endif
170