diff options
Diffstat (limited to 'src/sp_utils.c')
| -rw-r--r-- | src/sp_utils.c | 147 |
1 files changed, 90 insertions, 57 deletions
diff --git a/src/sp_utils.c b/src/sp_utils.c index 8b7ce49..a94ab2a 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c | |||
| @@ -19,6 +19,14 @@ static inline void _sp_log_err(const char* fmt, ...) { | |||
| 19 | php_log_err(msg); | 19 | php_log_err(msg); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | static bool sp_zend_string_equals(const zend_string* s1, | ||
| 23 | const zend_string* s2) { | ||
| 24 | // We can't use `zend_string_equals` here because it doesn't work on | ||
| 25 | // `const` zend_string. | ||
| 26 | return ZSTR_LEN(s1) == ZSTR_LEN(s2) && | ||
| 27 | !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1)); | ||
| 28 | } | ||
| 29 | |||
| 22 | void sp_log_msg(char const* feature, char const* level, const char* fmt, ...) { | 30 | void sp_log_msg(char const* feature, char const* level, const char* fmt, ...) { |
| 23 | char* msg; | 31 | char* msg; |
| 24 | va_list args; | 32 | va_list args; |
| @@ -56,14 +64,15 @@ int compute_hash(const char* const filename, char* file_hash) { | |||
| 56 | return SUCCESS; | 64 | return SUCCESS; |
| 57 | } | 65 | } |
| 58 | 66 | ||
| 59 | static int construct_filename(char* filename, const char* folder, | 67 | static int construct_filename(char* filename, const zend_string* folder, |
| 60 | const char* textual) { | 68 | const zend_string* textual) { |
| 61 | PHP_SHA256_CTX context; | 69 | PHP_SHA256_CTX context; |
| 62 | unsigned char digest[SHA256_SIZE] = {0}; | 70 | unsigned char digest[SHA256_SIZE] = {0}; |
| 63 | char strhash[65] = {0}; | 71 | char strhash[65] = {0}; |
| 64 | 72 | ||
| 65 | if (-1 == mkdir(folder, 0700) && errno != EEXIST) { | 73 | if (-1 == mkdir(ZSTR_VAL(folder), 0700) && errno != EEXIST) { |
| 66 | sp_log_err("request_logging", "Unable to create the folder '%s'.", folder); | 74 | sp_log_err("request_logging", "Unable to create the folder '%s'.", |
| 75 | ZSTR_VAL(folder)); | ||
| 67 | return -1; | 76 | return -1; |
| 68 | } | 77 | } |
| 69 | 78 | ||
| @@ -71,15 +80,17 @@ static int construct_filename(char* filename, const char* folder, | |||
| 71 | * as filename, in order to only have one dump per rule, to migitate | 80 | * as filename, in order to only have one dump per rule, to migitate |
| 72 | * DoS attacks. */ | 81 | * DoS attacks. */ |
| 73 | PHP_SHA256Init(&context); | 82 | PHP_SHA256Init(&context); |
| 74 | PHP_SHA256Update(&context, (const unsigned char*)textual, strlen(textual)); | 83 | PHP_SHA256Update(&context, (const unsigned char*)ZSTR_VAL(textual), |
| 84 | ZSTR_LEN(textual)); | ||
| 75 | PHP_SHA256Final(digest, &context); | 85 | PHP_SHA256Final(digest, &context); |
| 76 | make_digest_ex(strhash, digest, SHA256_SIZE); | 86 | make_digest_ex(strhash, digest, SHA256_SIZE); |
| 77 | snprintf(filename, PATH_MAX - 1, "%s/sp_dump.%s", folder, strhash); | 87 | snprintf(filename, PATH_MAX - 1, "%s/sp_dump.%s", ZSTR_VAL(folder), strhash); |
| 78 | 88 | ||
| 79 | return 0; | 89 | return 0; |
| 80 | } | 90 | } |
| 81 | 91 | ||
| 82 | int sp_log_request(const char* folder, const char* text_repr, char* from) { | 92 | int sp_log_request(const zend_string* folder, const zend_string* text_repr, |
| 93 | char* from) { | ||
| 83 | FILE* file; | 94 | FILE* file; |
| 84 | const char* current_filename = zend_get_executed_filename(TSRMLS_C); | 95 | const char* current_filename = zend_get_executed_filename(TSRMLS_C); |
| 85 | const int current_line = zend_get_executed_lineno(TSRMLS_C); | 96 | const int current_line = zend_get_executed_lineno(TSRMLS_C); |
| @@ -100,7 +111,7 @@ int sp_log_request(const char* folder, const char* text_repr, char* from) { | |||
| 100 | return -1; | 111 | return -1; |
| 101 | } | 112 | } |
| 102 | 113 | ||
| 103 | fprintf(file, "RULE: sp%s%s\n", from, text_repr); | 114 | fprintf(file, "RULE: sp%s%s\n", from, ZSTR_VAL(text_repr)); |
| 104 | 115 | ||
| 105 | fprintf(file, "FILE: %s:%d\n", current_filename, current_line); | 116 | fprintf(file, "FILE: %s:%d\n", current_filename, current_line); |
| 106 | for (size_t i = 0; i < (sizeof(zones) / sizeof(zones[0])) - 1; i++) { | 117 | for (size_t i = 0; i < (sizeof(zones) / sizeof(zones[0])) - 1; i++) { |
| @@ -130,57 +141,65 @@ int sp_log_request(const char* folder, const char* text_repr, char* from) { | |||
| 130 | return 0; | 141 | return 0; |
| 131 | } | 142 | } |
| 132 | 143 | ||
| 133 | static char* zv_str_to_char(zval* zv) { | 144 | static char* zend_string_to_char(const zend_string* zs) { |
| 134 | zval copy; | 145 | // Remove \0 from the middle of a string |
| 146 | char* copy = emalloc(ZSTR_LEN(zs) + 1); | ||
| 135 | 147 | ||
| 136 | ZVAL_ZVAL(©, zv, 1, 0); | 148 | copy[ZSTR_LEN(zs)] = 0; |
| 137 | for (size_t i = 0; i < Z_STRLEN(copy); i++) { | 149 | for (size_t i = 0; i < ZSTR_LEN(zs); i++) { |
| 138 | if (Z_STRVAL(copy)[i] == '\0') { | 150 | if (ZSTR_VAL(zs)[i] == '\0') { |
| 139 | Z_STRVAL(copy)[i] = '0'; | 151 | copy[i] = '0'; |
| 152 | } else { | ||
| 153 | copy[i] = ZSTR_VAL(zs)[i]; | ||
| 140 | } | 154 | } |
| 141 | } | 155 | } |
| 142 | return estrdup(Z_STRVAL(copy)); | 156 | return copy; |
| 143 | } | 157 | } |
| 144 | 158 | ||
| 145 | char* sp_convert_to_string(zval* zv) { | 159 | const zend_string* sp_zval_to_zend_string(zval* zv) { |
| 146 | switch (Z_TYPE_P(zv)) { | 160 | switch (Z_TYPE_P(zv)) { |
| 147 | case IS_FALSE: | ||
| 148 | return estrdup("FALSE"); | ||
| 149 | case IS_TRUE: | ||
| 150 | return estrdup("TRUE"); | ||
| 151 | case IS_NULL: | ||
| 152 | return estrdup("NULL"); | ||
| 153 | case IS_LONG: { | 161 | case IS_LONG: { |
| 154 | char* msg; | 162 | char* msg; |
| 155 | spprintf(&msg, 0, ZEND_LONG_FMT, Z_LVAL_P(zv)); | 163 | spprintf(&msg, 0, ZEND_LONG_FMT, Z_LVAL_P(zv)); |
| 156 | return msg; | 164 | zend_string* zs = zend_string_init(msg, strlen(msg), 0); |
| 165 | efree(msg); | ||
| 166 | return zs; | ||
| 157 | } | 167 | } |
| 158 | case IS_DOUBLE: { | 168 | case IS_DOUBLE: { |
| 159 | char* msg; | 169 | char* msg; |
| 160 | spprintf(&msg, 0, "%f", Z_DVAL_P(zv)); | 170 | spprintf(&msg, 0, "%f", Z_DVAL_P(zv)); |
| 161 | return msg; | 171 | zend_string* zs = zend_string_init(msg, strlen(msg), 0); |
| 172 | efree(msg); | ||
| 173 | return zs; | ||
| 162 | } | 174 | } |
| 163 | case IS_STRING: { | 175 | case IS_STRING: { |
| 164 | return zv_str_to_char(zv); | 176 | return Z_STR_P(zv); |
| 165 | } | 177 | } |
| 178 | case IS_FALSE: | ||
| 179 | return zend_string_init("FALSE", 5, 0); | ||
| 180 | case IS_TRUE: | ||
| 181 | return zend_string_init("TRUE", 4, 0); | ||
| 182 | case IS_NULL: | ||
| 183 | return zend_string_init("NULL", 4, 0); | ||
| 166 | case IS_OBJECT: | 184 | case IS_OBJECT: |
| 167 | return estrdup("OBJECT"); | 185 | return zend_string_init("OBJECT", 6, 0); |
| 168 | case IS_ARRAY: | 186 | case IS_ARRAY: |
| 169 | return estrdup("ARRAY"); | 187 | return zend_string_init("ARRAY", 5, 0); |
| 170 | case IS_RESOURCE: | 188 | case IS_RESOURCE: |
| 171 | return estrdup("RESOURCE"); | 189 | return zend_string_init("RESOURCE", 8, 0); |
| 172 | } | 190 | } |
| 173 | return estrdup(""); | 191 | return zend_string_init("", 0, 0); |
| 174 | } | 192 | } |
| 175 | 193 | ||
| 176 | bool sp_match_value(const char* value, const char* to_match, | 194 | bool sp_match_value(const zend_string* value, const zend_string* to_match, |
| 177 | const sp_pcre* rx) { | 195 | const sp_pcre* rx) { |
| 178 | if (to_match) { | 196 | if (to_match) { |
| 179 | if (0 == strcmp(to_match, value)) { | 197 | return (sp_zend_string_equals(to_match, value)); |
| 180 | return true; | ||
| 181 | } | ||
| 182 | } else if (rx) { | 198 | } else if (rx) { |
| 183 | return sp_is_regexp_matching(rx, value); | 199 | char* tmp = zend_string_to_char(value); |
| 200 | bool ret = sp_is_regexp_matching(rx, tmp); | ||
| 201 | efree(tmp); | ||
| 202 | return ret; | ||
| 184 | } else { | 203 | } else { |
| 185 | return true; | 204 | return true; |
| 186 | } | 205 | } |
| @@ -188,35 +207,41 @@ bool sp_match_value(const char* value, const char* to_match, | |||
| 188 | } | 207 | } |
| 189 | 208 | ||
| 190 | void sp_log_disable(const char* restrict path, const char* restrict arg_name, | 209 | void sp_log_disable(const char* restrict path, const char* restrict arg_name, |
| 191 | const char* restrict arg_value, | 210 | const zend_string* restrict arg_value, |
| 192 | const sp_disabled_function* config_node, unsigned int line, | 211 | const sp_disabled_function* config_node, unsigned int line, |
| 193 | const char* restrict filename) { | 212 | const char* restrict filename) { |
| 194 | const char* dump = config_node->dump; | 213 | const zend_string* dump = config_node->dump; |
| 195 | const char* alias = config_node->alias; | 214 | const zend_string* alias = config_node->alias; |
| 196 | const int sim = config_node->simulation; | 215 | const int sim = config_node->simulation; |
| 197 | 216 | ||
| 198 | filename = filename ? filename : zend_get_executed_filename(TSRMLS_C); | 217 | filename = filename ? filename : zend_get_executed_filename(TSRMLS_C); |
| 199 | line = line ? line : zend_get_executed_lineno(TSRMLS_C); | 218 | line = line ? line : zend_get_executed_lineno(TSRMLS_C); |
| 200 | 219 | ||
| 201 | if (arg_name) { | 220 | if (arg_name) { |
| 221 | char* char_repr = NULL; | ||
| 222 | if (arg_value) { | ||
| 223 | char_repr = zend_string_to_char(arg_value); | ||
| 224 | } | ||
| 202 | if (alias) { | 225 | if (alias) { |
| 203 | sp_log_msg( | 226 | sp_log_msg( |
| 204 | "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 227 | "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 205 | "Aborted execution on call of the function '%s' in %s:%d, " | 228 | "Aborted execution on call of the function '%s' in %s:%d, " |
| 206 | "because its argument '%s' content (%s) matched the rule '%s'.", | 229 | "because its argument '%s' content (%s) matched the rule '%s'.", |
| 207 | path, filename, line, arg_name, arg_value ? arg_value : "?", alias); | 230 | path, filename, line, arg_name, char_repr ? char_repr : "?", |
| 231 | ZSTR_VAL(alias)); | ||
| 208 | } else { | 232 | } else { |
| 209 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 233 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 210 | "Aborted execution on call of the function '%s' in %s:%d, " | 234 | "Aborted execution on call of the function '%s' in %s:%d, " |
| 211 | "because its argument '%s' content (%s) matched a rule.", | 235 | "because its argument '%s' content (%s) matched a rule.", |
| 212 | path, filename, line, arg_name, arg_value ? arg_value : "?"); | 236 | path, filename, line, arg_name, char_repr ? char_repr : "?"); |
| 213 | } | 237 | } |
| 238 | efree(char_repr); | ||
| 214 | } else { | 239 | } else { |
| 215 | if (alias) { | 240 | if (alias) { |
| 216 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 241 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 217 | "Aborted execution on call of the function '%s' in %s:%d, " | 242 | "Aborted execution on call of the function '%s' in %s:%d, " |
| 218 | "because of the the rule '%s'.", | 243 | "because of the the rule '%s'.", |
| 219 | path, filename, line, alias); | 244 | path, filename, line, ZSTR_VAL(alias)); |
| 220 | } else { | 245 | } else { |
| 221 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 246 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 222 | "Aborted execution on call of the function '%s' in %s:%d.", | 247 | "Aborted execution on call of the function '%s' in %s:%d.", |
| @@ -230,45 +255,53 @@ void sp_log_disable(const char* restrict path, const char* restrict arg_name, | |||
| 230 | } | 255 | } |
| 231 | 256 | ||
| 232 | void sp_log_disable_ret(const char* restrict path, | 257 | void sp_log_disable_ret(const char* restrict path, |
| 233 | const char* restrict ret_value, | 258 | const zend_string* restrict ret_value, |
| 234 | const sp_disabled_function* config_node) { | 259 | const sp_disabled_function* config_node) { |
| 235 | const char* dump = config_node->dump; | 260 | const zend_string* dump = config_node->dump; |
| 236 | const char* alias = config_node->alias; | 261 | const zend_string* alias = config_node->alias; |
| 237 | const int sim = config_node->simulation; | 262 | const int sim = config_node->simulation; |
| 263 | char* char_repr = NULL; | ||
| 264 | |||
| 265 | if (ret_value) { | ||
| 266 | char_repr = zend_string_to_char(ret_value); | ||
| 267 | } | ||
| 238 | if (alias) { | 268 | if (alias) { |
| 239 | sp_log_msg( | 269 | sp_log_msg( |
| 240 | "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 270 | "disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 241 | "Aborted execution on return of the function '%s' in %s:%d, " | 271 | "Aborted execution on return of the function '%s' in %s:%d, " |
| 242 | "because the function returned '%s', which matched the rule '%s'.", | 272 | "because the function returned '%s', which matched the rule '%s'.", |
| 243 | path, zend_get_executed_filename(TSRMLS_C), | 273 | path, zend_get_executed_filename(TSRMLS_C), |
| 244 | zend_get_executed_lineno(TSRMLS_C), ret_value ? ret_value : "?", alias); | 274 | zend_get_executed_lineno(TSRMLS_C), char_repr ? char_repr : "?", |
| 275 | ZSTR_VAL(alias)); | ||
| 245 | } else { | 276 | } else { |
| 246 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, | 277 | sp_log_msg("disabled_function", sim ? SP_LOG_SIMULATION : SP_LOG_DROP, |
| 247 | "Aborted execution on return of the function '%s' in %s:%d, " | 278 | "Aborted execution on return of the function '%s' in %s:%d, " |
| 248 | "because the function returned '%s', which matched a rule.", | 279 | "because the function returned '%s', which matched a rule.", |
| 249 | path, zend_get_executed_filename(TSRMLS_C), | 280 | path, zend_get_executed_filename(TSRMLS_C), |
| 250 | zend_get_executed_lineno(TSRMLS_C), ret_value ? ret_value : "?"); | 281 | zend_get_executed_lineno(TSRMLS_C), char_repr ? char_repr : "?"); |
| 251 | } | 282 | } |
| 283 | efree(char_repr); | ||
| 252 | if (dump) { | 284 | if (dump) { |
| 253 | sp_log_request(dump, config_node->textual_representation, | 285 | sp_log_request(dump, config_node->textual_representation, |
| 254 | SP_TOKEN_DISABLE_FUNC); | 286 | SP_TOKEN_DISABLE_FUNC); |
| 255 | } | 287 | } |
| 256 | } | 288 | } |
| 257 | 289 | ||
| 258 | bool sp_match_array_key(const zval* zv, const char* to_match, | 290 | bool sp_match_array_key(const zval* zv, const zend_string* to_match, |
| 259 | const sp_pcre* rx) { | 291 | const sp_pcre* rx) { |
| 260 | zend_string* key; | 292 | zend_string* key; |
| 261 | zend_ulong idx; | 293 | zend_ulong idx; |
| 262 | 294 | ||
| 263 | ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(zv), idx, key) { | 295 | ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(zv), idx, key) { |
| 264 | if (key) { | 296 | if (key) { |
| 265 | if (sp_match_value(ZSTR_VAL(key), to_match, rx)) { | 297 | if (sp_match_value(key, to_match, rx)) { |
| 266 | return true; | 298 | return true; |
| 267 | } | 299 | } |
| 268 | } else { | 300 | } else { |
| 269 | char* idx_str = NULL; | 301 | char* idx_str = NULL; |
| 270 | spprintf(&idx_str, 0, "%lu", idx); | 302 | spprintf(&idx_str, 0, "%lu", idx); |
| 271 | if (sp_match_value(idx_str, to_match, rx)) { | 303 | zend_string* tmp = zend_string_init(idx_str, strlen(idx_str), 0); |
| 304 | if (sp_match_value(tmp, to_match, rx)) { | ||
| 272 | efree(idx_str); | 305 | efree(idx_str); |
| 273 | return true; | 306 | return true; |
| 274 | } | 307 | } |
| @@ -279,18 +312,16 @@ bool sp_match_array_key(const zval* zv, const char* to_match, | |||
| 279 | return false; | 312 | return false; |
| 280 | } | 313 | } |
| 281 | 314 | ||
| 282 | bool sp_match_array_value(const zval* arr, const char* to_match, | 315 | bool sp_match_array_value(const zval* arr, const zend_string* to_match, |
| 283 | const sp_pcre* rx) { | 316 | const sp_pcre* rx) { |
| 284 | zval* value; | 317 | zval* value; |
| 285 | 318 | ||
| 286 | ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), value) { | 319 | ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), value) { |
| 287 | if (Z_TYPE_P(value) != IS_ARRAY) { | 320 | if (Z_TYPE_P(value) != IS_ARRAY) { |
| 288 | char* value_str = sp_convert_to_string(value); | 321 | const zend_string* value_str = sp_zval_to_zend_string(value); |
| 289 | if (sp_match_value(value_str, to_match, rx)) { | 322 | if (sp_match_value(value_str, to_match, rx)) { |
| 290 | efree(value_str); | ||
| 291 | return true; | 323 | return true; |
| 292 | } else { | 324 | } else { |
| 293 | efree(value_str); | ||
| 294 | } | 325 | } |
| 295 | } else if (sp_match_array_value(value, to_match, rx)) { | 326 | } else if (sp_match_array_value(value, to_match, rx)) { |
| 296 | return true; | 327 | return true; |
| @@ -303,6 +334,7 @@ bool sp_match_array_value(const zval* arr, const char* to_match, | |||
| 303 | int hook_function(const char* original_name, HashTable* hook_table, | 334 | int hook_function(const char* original_name, HashTable* hook_table, |
| 304 | void (*new_function)(INTERNAL_FUNCTION_PARAMETERS)) { | 335 | void (*new_function)(INTERNAL_FUNCTION_PARAMETERS)) { |
| 305 | zend_internal_function* func; | 336 | zend_internal_function* func; |
| 337 | bool ret = FAILURE; | ||
| 306 | 338 | ||
| 307 | /* The `mb` module likes to hook functions, like strlen->mb_strlen, | 339 | /* The `mb` module likes to hook functions, like strlen->mb_strlen, |
| 308 | * so we have to hook both of them. */ | 340 | * so we have to hook both of them. */ |
| @@ -317,6 +349,7 @@ int hook_function(const char* original_name, HashTable* hook_table, | |||
| 317 | return FAILURE; | 349 | return FAILURE; |
| 318 | } | 350 | } |
| 319 | func->handler = new_function; | 351 | func->handler = new_function; |
| 352 | ret = SUCCESS; | ||
| 320 | } else { | 353 | } else { |
| 321 | return SUCCESS; | 354 | return SUCCESS; |
| 322 | } | 355 | } |
| @@ -326,7 +359,7 @@ int hook_function(const char* original_name, HashTable* hook_table, | |||
| 326 | CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; | 359 | CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; |
| 327 | if (zend_hash_str_find(CG(function_table), | 360 | if (zend_hash_str_find(CG(function_table), |
| 328 | VAR_AND_LEN(original_name + 3))) { | 361 | VAR_AND_LEN(original_name + 3))) { |
| 329 | hook_function(original_name + 3, hook_table, new_function); | 362 | return hook_function(original_name + 3, hook_table, new_function); |
| 330 | } | 363 | } |
| 331 | } else { // TODO this can be moved somewhere else to gain some marginal perfs | 364 | } else { // TODO this can be moved somewhere else to gain some marginal perfs |
| 332 | CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; | 365 | CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; |
| @@ -334,11 +367,11 @@ int hook_function(const char* original_name, HashTable* hook_table, | |||
| 334 | memcpy(mb_name, "mb_", 3); | 367 | memcpy(mb_name, "mb_", 3); |
| 335 | memcpy(mb_name + 3, VAR_AND_LEN(original_name)); | 368 | memcpy(mb_name + 3, VAR_AND_LEN(original_name)); |
| 336 | if (zend_hash_str_find(CG(function_table), VAR_AND_LEN(mb_name))) { | 369 | if (zend_hash_str_find(CG(function_table), VAR_AND_LEN(mb_name))) { |
| 337 | hook_function(mb_name, hook_table, new_function); | 370 | return hook_function(mb_name, hook_table, new_function); |
| 338 | } | 371 | } |
| 339 | } | 372 | } |
| 340 | 373 | ||
| 341 | return SUCCESS; | 374 | return ret; |
| 342 | } | 375 | } |
| 343 | 376 | ||
| 344 | int hook_regexp(const sp_pcre* regexp, HashTable* hook_table, | 377 | int hook_regexp(const sp_pcre* regexp, HashTable* hook_table, |
| @@ -356,7 +389,7 @@ int hook_regexp(const sp_pcre* regexp, HashTable* hook_table, | |||
| 356 | return SUCCESS; | 389 | return SUCCESS; |
| 357 | } | 390 | } |
| 358 | 391 | ||
| 359 | bool check_is_in_eval_whitelist(const char* const function_name) { | 392 | bool check_is_in_eval_whitelist(const zend_string* const function_name) { |
| 360 | const sp_list_node* it = SNUFFLEUPAGUS_G(config).config_eval->whitelist; | 393 | const sp_list_node* it = SNUFFLEUPAGUS_G(config).config_eval->whitelist; |
| 361 | 394 | ||
| 362 | if (!it) { | 395 | if (!it) { |
| @@ -366,7 +399,7 @@ bool check_is_in_eval_whitelist(const char* const function_name) { | |||
| 366 | /* yes, we could use a HashTable instead, but since the list is pretty | 399 | /* yes, we could use a HashTable instead, but since the list is pretty |
| 367 | * small, it doesn't maka a difference in practise. */ | 400 | * small, it doesn't maka a difference in practise. */ |
| 368 | while (it && it->data) { | 401 | while (it && it->data) { |
| 369 | if (0 == strcmp(function_name, (char*)(it->data))) { | 402 | if (sp_zend_string_equals(function_name, (const zend_string*)(it->data))) { |
| 370 | /* We've got a match, the function is whiteslited. */ | 403 | /* We've got a match, the function is whiteslited. */ |
| 371 | return true; | 404 | return true; |
| 372 | } | 405 | } |
