diff options
| author | xXx-caillou-xXx | 2018-07-13 10:36:50 +0200 |
|---|---|---|
| committer | jvoisin | 2018-07-13 08:36:50 +0000 |
| commit | 7963580d72a358975133f86f01de2d2eab08ba38 (patch) | |
| tree | 4bec345d70f687a2a6002b36e2f2fc79318959f6 /src/sp_config_keywords.c | |
| parent | 12b740bc7bb01ffe397cecc5b6fa25b136304911 (diff) | |
Massively optimize how rules are handled
This commit does a lot of things:
- Use hashtables instead of lists to store the rules
- Rules that can be applied at launch time won't be tried at runtime
- Improve feedback when writing nonsensical rules
- Make intensive use of `zend_string` instead of `char*`
Diffstat (limited to 'src/sp_config_keywords.c')
| -rw-r--r-- | src/sp_config_keywords.c | 199 |
1 files changed, 97 insertions, 102 deletions
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index 2a570cd..81f43f7 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c | |||
| @@ -1,39 +1,8 @@ | |||
| 1 | #include "php_snuffleupagus.h" | 1 | #include "php_snuffleupagus.h" |
| 2 | #include "zend_types.h" | ||
| 2 | 3 | ||
| 3 | ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus) | 4 | ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus) |
| 4 | 5 | ||
| 5 | static const struct { | ||
| 6 | unsigned int type; | ||
| 7 | char *keys[5]; // Update this value if necessary | ||
| 8 | } CONSTRUCTS_TYPES[] = { | ||
| 9 | {.type = ZEND_INCLUDE_OR_EVAL, | ||
| 10 | .keys = {"include", "include_once", "require", "require_once", NULL}}, | ||
| 11 | {.type = ZEND_ECHO, .keys = {"echo", NULL}}, | ||
| 12 | {.type = ZEND_NEW, .keys = {"new", NULL}}, | ||
| 13 | {.type = ZEND_EXIT, .keys = {"exit", NULL}}, | ||
| 14 | {.type = ZEND_STRLEN, .keys = {"strlen", NULL}}, | ||
| 15 | {.type = ZEND_EVAL_CODE, .keys = {"eval", NULL}}, | ||
| 16 | {.type = 0, .keys = {NULL}}}; | ||
| 17 | |||
| 18 | static int get_construct_type(sp_disabled_function const *const df) { | ||
| 19 | for (size_t i = 0; 0 != CONSTRUCTS_TYPES[i].type; i++) { | ||
| 20 | for (size_t j = 0; NULL != CONSTRUCTS_TYPES[i].keys[j]; j++) { | ||
| 21 | assert(df->function || df->r_function); | ||
| 22 | if (df->function) { | ||
| 23 | if (0 == strcmp(df->function, CONSTRUCTS_TYPES[i].keys[j])) { | ||
| 24 | return CONSTRUCTS_TYPES[i].type; | ||
| 25 | } | ||
| 26 | } else { | ||
| 27 | if (true == sp_is_regexp_matching(df->r_function, | ||
| 28 | CONSTRUCTS_TYPES[i].keys[j])) { | ||
| 29 | return CONSTRUCTS_TYPES[i].type; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | } | ||
| 34 | return -1; | ||
| 35 | } | ||
| 36 | |||
| 37 | static int parse_enable(char *line, bool *restrict retval, | 6 | static int parse_enable(char *line, bool *restrict retval, |
| 38 | bool *restrict simulation) { | 7 | bool *restrict simulation) { |
| 39 | bool enable = false, disable = false; | 8 | bool enable = false, disable = false; |
| @@ -137,7 +106,7 @@ int parse_unserialize(char *line) { | |||
| 137 | {parse_str, SP_TOKEN_DUMP, &(unserialize->dump)}, | 106 | {parse_str, SP_TOKEN_DUMP, &(unserialize->dump)}, |
| 138 | {0}}; | 107 | {0}}; |
| 139 | 108 | ||
| 140 | unserialize->textual_representation = estrdup(line); | 109 | unserialize->textual_representation = zend_string_init(line, strlen(line), 1); |
| 141 | 110 | ||
| 142 | int ret = parse_keywords(sp_config_funcs, line); | 111 | int ret = parse_keywords(sp_config_funcs, line); |
| 143 | if (0 != ret) { | 112 | if (0 != ret) { |
| @@ -167,7 +136,8 @@ int parse_readonly_exec(char *line) { | |||
| 167 | {parse_str, SP_TOKEN_DUMP, &(readonly_exec->dump)}, | 136 | {parse_str, SP_TOKEN_DUMP, &(readonly_exec->dump)}, |
| 168 | {0}}; | 137 | {0}}; |
| 169 | 138 | ||
| 170 | readonly_exec->textual_representation = estrdup(line); | 139 | readonly_exec->textual_representation = |
| 140 | zend_string_init(line, strlen(line), 1); | ||
| 171 | int ret = parse_keywords(sp_config_funcs, line); | 141 | int ret = parse_keywords(sp_config_funcs, line); |
| 172 | 142 | ||
| 173 | if (0 != ret) { | 143 | if (0 != ret) { |
| @@ -196,8 +166,8 @@ int parse_global(char *line) { | |||
| 196 | } | 166 | } |
| 197 | 167 | ||
| 198 | static int parse_eval_filter_conf(char *line, sp_list_node **list) { | 168 | static int parse_eval_filter_conf(char *line, sp_list_node **list) { |
| 199 | char *token; | 169 | char *token, *tmp; |
| 200 | char *rest; | 170 | zend_string *rest = NULL; |
| 201 | sp_config_eval *eval = SNUFFLEUPAGUS_G(config).config_eval; | 171 | sp_config_eval *eval = SNUFFLEUPAGUS_G(config).config_eval; |
| 202 | 172 | ||
| 203 | sp_config_functions sp_config_funcs[] = { | 173 | sp_config_functions sp_config_funcs[] = { |
| @@ -207,15 +177,19 @@ static int parse_eval_filter_conf(char *line, sp_list_node **list) { | |||
| 207 | {parse_str, SP_TOKEN_DUMP, &(SNUFFLEUPAGUS_G(config).config_eval->dump)}, | 177 | {parse_str, SP_TOKEN_DUMP, &(SNUFFLEUPAGUS_G(config).config_eval->dump)}, |
| 208 | {0}}; | 178 | {0}}; |
| 209 | 179 | ||
| 210 | eval->textual_representation = estrdup(line); | 180 | eval->textual_representation = zend_string_init(line, strlen(line), 1); |
| 211 | 181 | ||
| 212 | int ret = parse_keywords(sp_config_funcs, line); | 182 | int ret = parse_keywords(sp_config_funcs, line); |
| 213 | if (0 != ret) { | 183 | if (0 != ret) { |
| 214 | return ret; | 184 | return ret; |
| 215 | } | 185 | } |
| 216 | 186 | ||
| 217 | while ((token = strtok_r(rest, ",", &rest))) { | 187 | tmp = ZSTR_VAL(rest); |
| 218 | *list = sp_list_insert(*list, token); | 188 | while ((token = strtok_r(tmp, ",", &tmp))) { |
| 189 | *list = sp_list_insert(*list, zend_string_init(token, strlen(token), 1)); | ||
| 190 | } | ||
| 191 | if (rest != NULL) { | ||
| 192 | pefree(rest, 1); | ||
| 219 | } | 193 | } |
| 220 | return SUCCESS; | 194 | return SUCCESS; |
| 221 | } | 195 | } |
| @@ -232,7 +206,7 @@ int parse_eval_whitelist(char *line) { | |||
| 232 | 206 | ||
| 233 | int parse_cookie(char *line) { | 207 | int parse_cookie(char *line) { |
| 234 | int ret = 0; | 208 | int ret = 0; |
| 235 | char *samesite = NULL; | 209 | zend_string *samesite = NULL; |
| 236 | sp_cookie *cookie = pecalloc(sizeof(sp_cookie), 1, 1); | 210 | sp_cookie *cookie = pecalloc(sizeof(sp_cookie), 1, 1); |
| 237 | 211 | ||
| 238 | sp_config_functions sp_config_funcs_cookie_encryption[] = { | 212 | sp_config_functions sp_config_funcs_cookie_encryption[] = { |
| @@ -274,7 +248,7 @@ int parse_cookie(char *line) { | |||
| 274 | sp_line_no); | 248 | sp_line_no); |
| 275 | return -1; | 249 | return -1; |
| 276 | } | 250 | } |
| 277 | if ((!cookie->name || '\0' == cookie->name[0]) && !cookie->name_r) { | 251 | if ((!cookie->name || 0 == ZSTR_LEN(cookie->name)) && !cookie->name_r) { |
| 278 | sp_log_err("config", | 252 | sp_log_err("config", |
| 279 | "You must specify a cookie name/regexp on line " | 253 | "You must specify a cookie name/regexp on line " |
| 280 | "%zu.", | 254 | "%zu.", |
| @@ -289,16 +263,17 @@ int parse_cookie(char *line) { | |||
| 289 | return -1; | 263 | return -1; |
| 290 | } | 264 | } |
| 291 | if (samesite) { | 265 | if (samesite) { |
| 292 | if (0 == strcasecmp(samesite, SP_TOKEN_SAMESITE_LAX)) { | 266 | if (zend_string_equals_literal_ci(samesite, SP_TOKEN_SAMESITE_LAX)) { |
| 293 | cookie->samesite = lax; | 267 | cookie->samesite = lax; |
| 294 | } else if (0 == strcasecmp(samesite, SP_TOKEN_SAMESITE_STRICT)) { | 268 | } else if (zend_string_equals_literal_ci(samesite, |
| 269 | SP_TOKEN_SAMESITE_STRICT)) { | ||
| 295 | cookie->samesite = strict; | 270 | cookie->samesite = strict; |
| 296 | } else { | 271 | } else { |
| 297 | sp_log_err( | 272 | sp_log_err( |
| 298 | "config", | 273 | "config", |
| 299 | "%s is an invalid value to samesite (expected %s or %s) on line " | 274 | "%s is an invalid value to samesite (expected %s or %s) on line " |
| 300 | "%zu.", | 275 | "%zu.", |
| 301 | samesite, SP_TOKEN_SAMESITE_LAX, SP_TOKEN_SAMESITE_STRICT, | 276 | ZSTR_VAL(samesite), SP_TOKEN_SAMESITE_LAX, SP_TOKEN_SAMESITE_STRICT, |
| 302 | sp_line_no); | 277 | sp_line_no); |
| 303 | return -1; | 278 | return -1; |
| 304 | } | 279 | } |
| @@ -308,11 +283,22 @@ int parse_cookie(char *line) { | |||
| 308 | return SUCCESS; | 283 | return SUCCESS; |
| 309 | } | 284 | } |
| 310 | 285 | ||
| 286 | int add_df_to_hashtable(HashTable *ht, sp_disabled_function *df) { | ||
| 287 | zval *list = zend_hash_find(ht, df->function); | ||
| 288 | |||
| 289 | if (NULL == list) { | ||
| 290 | zend_hash_add_ptr(ht, df->function, sp_list_insert(NULL, df)); | ||
| 291 | } else { | ||
| 292 | Z_PTR_P(list) = sp_list_insert(Z_PTR_P(list), df); | ||
| 293 | } | ||
| 294 | return SUCCESS; | ||
| 295 | } | ||
| 296 | |||
| 311 | int parse_disabled_functions(char *line) { | 297 | int parse_disabled_functions(char *line) { |
| 312 | int ret = 0; | 298 | int ret = 0; |
| 313 | bool enable = true, disable = false, allow = false, drop = false; | 299 | bool enable = true, disable = false, allow = false, drop = false; |
| 314 | char *pos = NULL, *var = NULL, *param = NULL; | 300 | zend_string *pos = NULL, *var = NULL, *param = NULL; |
| 315 | char *line_number = NULL; | 301 | zend_string *line_number = NULL; |
| 316 | sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1); | 302 | sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1); |
| 317 | df->pos = -1; | 303 | df->pos = -1; |
| 318 | 304 | ||
| @@ -330,7 +316,7 @@ int parse_disabled_functions(char *line) { | |||
| 330 | {parse_empty, SP_TOKEN_DROP, &(drop)}, | 316 | {parse_empty, SP_TOKEN_DROP, &(drop)}, |
| 331 | {parse_str, SP_TOKEN_HASH, &(df->hash)}, | 317 | {parse_str, SP_TOKEN_HASH, &(df->hash)}, |
| 332 | {parse_str, SP_TOKEN_PARAM, &(param)}, | 318 | {parse_str, SP_TOKEN_PARAM, &(param)}, |
| 333 | {parse_regexp, SP_TOKEN_VALUE_REGEXP, &(df->value_r)}, | 319 | {parse_regexp, SP_TOKEN_VALUE_REGEXP, &(df->r_value)}, |
| 334 | {parse_str, SP_TOKEN_VALUE, &(df->value)}, | 320 | {parse_str, SP_TOKEN_VALUE, &(df->value)}, |
| 335 | {parse_str, SP_TOKEN_KEY, &(df->key)}, | 321 | {parse_str, SP_TOKEN_KEY, &(df->key)}, |
| 336 | {parse_regexp, SP_TOKEN_KEY_REGEXP, &(df->r_key)}, | 322 | {parse_regexp, SP_TOKEN_KEY_REGEXP, &(df->r_key)}, |
| @@ -360,7 +346,7 @@ int parse_disabled_functions(char *line) { | |||
| 360 | return 1; \ | 346 | return 1; \ |
| 361 | } | 347 | } |
| 362 | 348 | ||
| 363 | MUTUALLY_EXCLUSIVE(df->value, df->value_r, "value", "regexp"); | 349 | MUTUALLY_EXCLUSIVE(df->value, df->r_value, "value", "regexp"); |
| 364 | MUTUALLY_EXCLUSIVE(df->r_function, df->function, "r_function", "function"); | 350 | MUTUALLY_EXCLUSIVE(df->r_function, df->function, "r_function", "function"); |
| 365 | MUTUALLY_EXCLUSIVE(df->filename, df->r_filename, "r_filename", "filename"); | 351 | MUTUALLY_EXCLUSIVE(df->filename, df->r_filename, "r_filename", "filename"); |
| 366 | MUTUALLY_EXCLUSIVE(df->ret, df->r_ret, "r_ret", "ret"); | 352 | MUTUALLY_EXCLUSIVE(df->ret, df->r_ret, "r_ret", "ret"); |
| @@ -375,25 +361,38 @@ int parse_disabled_functions(char *line) { | |||
| 375 | "'.r_param', '.param' and '.pos' are mutually exclusive on line %zu.", | 361 | "'.r_param', '.param' and '.pos' are mutually exclusive on line %zu.", |
| 376 | line, sp_line_no); | 362 | line, sp_line_no); |
| 377 | return -1; | 363 | return -1; |
| 378 | } else if ((df->r_key || df->key) && (df->value_r || df->value)) { | 364 | } else if ((df->r_key || df->key) && (df->r_value || df->value)) { |
| 379 | sp_log_err("config", | 365 | sp_log_err("config", |
| 380 | "Invalid configuration line: 'sp.disabled_functions%s':" | 366 | "Invalid configuration line: 'sp.disabled_functions%s':" |
| 381 | "`key` and `value` are mutually exclusive on line %zu.", | 367 | "`key` and `value` are mutually exclusive on line %zu.", |
| 382 | line, sp_line_no); | 368 | line, sp_line_no); |
| 383 | return -1; | 369 | return -1; |
| 384 | } else if ((df->r_ret || df->ret) && (df->r_param || param)) { | 370 | } else if ((df->r_ret || df->ret || df->ret_type) && (df->r_param || param)) { |
| 385 | sp_log_err("config", | 371 | sp_log_err("config", |
| 386 | "Invalid configuration line: 'sp.disabled_functions%s':" | 372 | "Invalid configuration line: 'sp.disabled_functions%s':" |
| 387 | "`ret` and `param` are mutually exclusive on line %zu.", | 373 | "`ret` and `param` are mutually exclusive on line %zu.", |
| 388 | line, sp_line_no); | 374 | line, sp_line_no); |
| 389 | return -1; | 375 | return -1; |
| 376 | } else if ((df->r_ret || df->ret || df->ret_type) && (var)) { | ||
| 377 | sp_log_err("config", | ||
| 378 | "Invalid configuration line: 'sp.disabled_functions%s':" | ||
| 379 | "`ret` and `var` are mutually exclusive on line %zu.", | ||
| 380 | line, sp_line_no); | ||
| 381 | return -1; | ||
| 382 | } else if ((df->r_ret || df->ret || df->ret_type) && | ||
| 383 | (df->value || df->r_value)) { | ||
| 384 | sp_log_err("config", | ||
| 385 | "Invalid configuration line: 'sp.disabled_functions%s':" | ||
| 386 | "`ret` and `value` are mutually exclusive on line %zu.", | ||
| 387 | line, sp_line_no); | ||
| 388 | return -1; | ||
| 390 | } else if (!(df->r_function || df->function)) { | 389 | } else if (!(df->r_function || df->function)) { |
| 391 | sp_log_err("config", | 390 | sp_log_err("config", |
| 392 | "Invalid configuration line: 'sp.disabled_functions%s':" | 391 | "Invalid configuration line: 'sp.disabled_functions%s':" |
| 393 | " must take a function name on line %zu.", | 392 | " must take a function name on line %zu.", |
| 394 | line, sp_line_no); | 393 | line, sp_line_no); |
| 395 | return -1; | 394 | return -1; |
| 396 | } else if (df->filename && *df->filename != '/') { | 395 | } else if (df->filename && *ZSTR_VAL(df->filename) != '/') { |
| 397 | sp_log_err("config", | 396 | sp_log_err("config", |
| 398 | "Invalid configuration line: 'sp.disabled_functions%s':" | 397 | "Invalid configuration line: 'sp.disabled_functions%s':" |
| 399 | "'.filename' must be an absolute path on line %zu.", | 398 | "'.filename' must be an absolute path on line %zu.", |
| @@ -410,10 +409,10 @@ int parse_disabled_functions(char *line) { | |||
| 410 | if (pos) { | 409 | if (pos) { |
| 411 | errno = 0; | 410 | errno = 0; |
| 412 | char *endptr; | 411 | char *endptr; |
| 413 | df->pos = (int)strtol(pos, &endptr, 10); | 412 | df->pos = (int)strtol(ZSTR_VAL(pos), &endptr, 10); |
| 414 | if (errno != 0 || endptr == pos) { | 413 | if (errno != 0 || endptr == ZSTR_VAL(pos)) { |
| 415 | sp_log_err("config", "Failed to parse arg '%s' of `pos` on line %zu.", | 414 | sp_log_err("config", "Failed to parse arg '%s' of `pos` on line %zu.", |
| 416 | pos, sp_line_no); | 415 | ZSTR_VAL(pos), sp_line_no); |
| 417 | return -1; | 416 | return -1; |
| 418 | } | 417 | } |
| 419 | } | 418 | } |
| @@ -421,46 +420,46 @@ int parse_disabled_functions(char *line) { | |||
| 421 | if (line_number) { | 420 | if (line_number) { |
| 422 | errno = 0; | 421 | errno = 0; |
| 423 | char *endptr; | 422 | char *endptr; |
| 424 | df->line = (unsigned int)strtoul(line_number, &endptr, 10); | 423 | df->line = (unsigned int)strtoul(ZSTR_VAL(line_number), &endptr, 10); |
| 425 | if (errno != 0 || endptr == line_number) { | 424 | if (errno != 0 || endptr == ZSTR_VAL(line_number)) { |
| 426 | sp_log_err("config", "Failed to parse arg '%s' of `line` on line %zu.", | 425 | sp_log_err("config", "Failed to parse arg '%s' of `line` on line %zu.", |
| 427 | line_number, sp_line_no); | 426 | ZSTR_VAL(line_number), sp_line_no); |
| 428 | return -1; | 427 | return -1; |
| 429 | } | 428 | } |
| 430 | } | 429 | } |
| 431 | df->allow = allow; | 430 | df->allow = allow; |
| 432 | df->textual_representation = estrdup(line); | 431 | df->textual_representation = zend_string_init(line, strlen(line), 1); |
| 433 | 432 | ||
| 434 | if (df->function) { | 433 | if (df->function) { |
| 435 | df->functions_list = parse_functions_list(df->function); | 434 | df->functions_list = parse_functions_list(ZSTR_VAL(df->function)); |
| 436 | } | 435 | } |
| 437 | 436 | ||
| 438 | if (param) { | 437 | if (param) { |
| 439 | if (strlen(param) > 0 && param[0] != '$') { | 438 | if (ZSTR_LEN(param) > 0 && ZSTR_VAL(param)[0] != '$') { |
| 440 | /* This is an ugly hack. We're prefixing with a `$` because otherwise | 439 | /* This is an ugly hack. We're prefixing with a `$` because otherwise |
| 441 | * the parser treats this as a constant. | 440 | * the parser treats this as a constant. |
| 442 | * FIXME: Remove this, and improve our (weird) parser. */ | 441 | * FIXME: Remove this, and improve our (weird) parser. */ |
| 443 | char *new = pecalloc(strlen(param) + 2, 1, 1); | 442 | char *new = pecalloc(ZSTR_LEN(param) + 2, 1, 1); |
| 444 | new[0] = '$'; | 443 | new[0] = '$'; |
| 445 | memcpy(new + 1, param, strlen(param)); | 444 | memcpy(new + 1, ZSTR_VAL(param), ZSTR_LEN(param)); |
| 446 | df->param = sp_parse_var(new); | 445 | df->param = sp_parse_var(new); |
| 447 | free(new); | 446 | free(new); |
| 448 | } else { | 447 | } else { |
| 449 | df->param = sp_parse_var(param); | 448 | df->param = sp_parse_var(ZSTR_VAL(param)); |
| 450 | } | 449 | } |
| 451 | if (!df->param) { | 450 | if (!df->param) { |
| 452 | sp_log_err("config", "Invalid value '%s' for `param` on line %zu.", param, | 451 | sp_log_err("config", "Invalid value '%s' for `param` on line %zu.", |
| 453 | sp_line_no); | 452 | ZSTR_VAL(param), sp_line_no); |
| 454 | return -1; | 453 | return -1; |
| 455 | } | 454 | } |
| 456 | } | 455 | } |
| 457 | 456 | ||
| 458 | if (var) { | 457 | if (var) { |
| 459 | if (*var) { | 458 | if (ZSTR_LEN(var)) { |
| 460 | df->var = sp_parse_var(var); | 459 | df->var = sp_parse_var(ZSTR_VAL(var)); |
| 461 | if (!df->var) { | 460 | if (!df->var) { |
| 462 | sp_log_err("config", "Invalid value '%s' for `var` on line %zu.", var, | 461 | sp_log_err("config", "Invalid value '%s' for `var` on line %zu.", |
| 463 | sp_line_no); | 462 | ZSTR_VAL(var), sp_line_no); |
| 464 | return -1; | 463 | return -1; |
| 465 | } | 464 | } |
| 466 | } else { | 465 | } else { |
| @@ -469,38 +468,33 @@ int parse_disabled_functions(char *line) { | |||
| 469 | } | 468 | } |
| 470 | } | 469 | } |
| 471 | 470 | ||
| 472 | switch (get_construct_type(df)) { | ||
| 473 | case ZEND_INCLUDE_OR_EVAL: | ||
| 474 | SNUFFLEUPAGUS_G(config) | ||
| 475 | .config_disabled_constructs->construct_include = sp_list_insert( | ||
| 476 | SNUFFLEUPAGUS_G(config).config_disabled_constructs->construct_include, | ||
| 477 | df); | ||
| 478 | return ret; | ||
| 479 | case ZEND_EVAL_CODE: | ||
| 480 | SNUFFLEUPAGUS_G(config) | ||
| 481 | .config_disabled_constructs->construct_eval = sp_list_insert( | ||
| 482 | SNUFFLEUPAGUS_G(config).config_disabled_constructs->construct_eval, | ||
| 483 | df); | ||
| 484 | return ret; | ||
| 485 | case ZEND_ECHO: | ||
| 486 | default: | ||
| 487 | break; | ||
| 488 | } | ||
| 489 | |||
| 490 | if (true == disable) { | 471 | if (true == disable) { |
| 491 | return ret; | 472 | return ret; |
| 492 | } | 473 | } |
| 493 | 474 | ||
| 494 | if (df->ret || df->r_ret || df->ret_type) { | 475 | if (df->function && !df->functions_list) { |
| 495 | SNUFFLEUPAGUS_G(config).config_disabled_functions_ret->disabled_functions = | 476 | if (df->ret || df->r_ret || df->ret_type) { |
| 496 | sp_list_insert(SNUFFLEUPAGUS_G(config) | 477 | add_df_to_hashtable(SNUFFLEUPAGUS_G(config).config_disabled_functions_ret, |
| 497 | .config_disabled_functions_ret->disabled_functions, | 478 | df); |
| 498 | df); | 479 | } else { |
| 480 | add_df_to_hashtable(SNUFFLEUPAGUS_G(config).config_disabled_functions, | ||
| 481 | df); | ||
| 482 | } | ||
| 499 | } else { | 483 | } else { |
| 500 | SNUFFLEUPAGUS_G(config) | 484 | if (df->ret || df->r_ret || df->ret_type) { |
| 501 | .config_disabled_functions->disabled_functions = sp_list_insert( | 485 | SNUFFLEUPAGUS_G(config) |
| 502 | SNUFFLEUPAGUS_G(config).config_disabled_functions->disabled_functions, | 486 | .config_disabled_functions_reg_ret->disabled_functions = |
| 503 | df); | 487 | sp_list_insert( |
| 488 | SNUFFLEUPAGUS_G(config) | ||
| 489 | .config_disabled_functions_reg_ret->disabled_functions, | ||
| 490 | df); | ||
| 491 | } else { | ||
| 492 | SNUFFLEUPAGUS_G(config) | ||
| 493 | .config_disabled_functions_reg->disabled_functions = | ||
| 494 | sp_list_insert(SNUFFLEUPAGUS_G(config) | ||
| 495 | .config_disabled_functions_reg->disabled_functions, | ||
| 496 | df); | ||
| 497 | } | ||
| 504 | } | 498 | } |
| 505 | return ret; | 499 | return ret; |
| 506 | } | 500 | } |
| @@ -529,20 +523,21 @@ int parse_upload_validation(char *line) { | |||
| 529 | } | 523 | } |
| 530 | SNUFFLEUPAGUS_G(config).config_upload_validation->enable = enable; | 524 | SNUFFLEUPAGUS_G(config).config_upload_validation->enable = enable; |
| 531 | 525 | ||
| 532 | char const *script = SNUFFLEUPAGUS_G(config).config_upload_validation->script; | 526 | zend_string const *script = |
| 527 | SNUFFLEUPAGUS_G(config).config_upload_validation->script; | ||
| 533 | 528 | ||
| 534 | if (!script) { | 529 | if (!script) { |
| 535 | sp_log_err("config", | 530 | sp_log_err("config", |
| 536 | "The `script` directive is mandatory in '%s' on line %zu.", line, | 531 | "The `script` directive is mandatory in '%s' on line %zu.", line, |
| 537 | sp_line_no); | 532 | sp_line_no); |
| 538 | return -1; | 533 | return -1; |
| 539 | } else if (-1 == access(script, F_OK)) { | 534 | } else if (-1 == access(ZSTR_VAL(script), F_OK)) { |
| 540 | sp_log_err("config", "The `script` (%s) doesn't exist on line %zu.", script, | 535 | sp_log_err("config", "The `script` (%s) doesn't exist on line %zu.", |
| 541 | sp_line_no); | 536 | ZSTR_VAL(script), sp_line_no); |
| 542 | return -1; | 537 | return -1; |
| 543 | } else if (-1 == access(script, X_OK)) { | 538 | } else if (-1 == access(ZSTR_VAL(script), X_OK)) { |
| 544 | sp_log_err("config", "The `script` (%s) isn't executable on line %zu.", | 539 | sp_log_err("config", "The `script` (%s) isn't executable on line %zu.", |
| 545 | script, sp_line_no); | 540 | ZSTR_VAL(script), sp_line_no); |
| 546 | return -1; | 541 | return -1; |
| 547 | } | 542 | } |
| 548 | 543 | ||
