diff options
Diffstat (limited to 'ex_imp.c')
| -rw-r--r-- | ex_imp.c | 357 |
1 files changed, 327 insertions, 30 deletions
| @@ -41,21 +41,33 @@ | |||
| 41 | #define EXTR_REFS 0x100 | 41 | #define EXTR_REFS 0x100 |
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | static int php_valid_var_name(char *var_name) | 44 | static int php_valid_var_name(char *var_name, int len) /* {{{ */ |
| 45 | { | 45 | { |
| 46 | int len, i; | 46 | int i, ch; |
| 47 | 47 | ||
| 48 | if (!var_name) | 48 | if (!var_name) |
| 49 | return 0; | 49 | return 0; |
| 50 | 50 | ||
| 51 | len = strlen(var_name); | 51 | /* These are allowed as first char: [a-zA-Z_\x7f-\xff] */ |
| 52 | 52 | ch = (int)((unsigned char *)var_name)[0]; | |
| 53 | if (!isalpha((int)((unsigned char *)var_name)[0]) && var_name[0] != '_') | 53 | if (var_name[0] != '_' && |
| 54 | (ch < 65 /* A */ || /* Z */ ch > 90) && | ||
| 55 | (ch < 97 /* a */ || /* z */ ch > 122) && | ||
| 56 | (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255) | ||
| 57 | ) { | ||
| 54 | return 0; | 58 | return 0; |
| 55 | 59 | } | |
| 60 | |||
| 61 | /* And these as the rest: [a-zA-Z0-9_\x7f-\xff] */ | ||
| 56 | if (len > 1) { | 62 | if (len > 1) { |
| 57 | for (i=1; i<len; i++) { | 63 | for (i = 1; i < len; i++) { |
| 58 | if (!isalnum((int)((unsigned char *)var_name)[i]) && var_name[i] != '_') { | 64 | ch = (int)((unsigned char *)var_name)[i]; |
| 65 | if (var_name[i] != '_' && | ||
| 66 | (ch < 48 /* 0 */ || /* 9 */ ch > 57) && | ||
| 67 | (ch < 65 /* A */ || /* Z */ ch > 90) && | ||
| 68 | (ch < 97 /* a */ || /* z */ ch > 122) && | ||
| 69 | (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255) | ||
| 70 | ) { | ||
| 59 | return 0; | 71 | return 0; |
| 60 | } | 72 | } |
| 61 | } | 73 | } |
| @@ -95,7 +107,162 @@ static int php_valid_var_name(char *var_name) | |||
| 95 | Imports variables into symbol table from an array */ | 107 | Imports variables into symbol table from an array */ |
| 96 | PHP_FUNCTION(suhosin_extract) | 108 | PHP_FUNCTION(suhosin_extract) |
| 97 | { | 109 | { |
| 98 | zval **var_array, **z_extract_type, **prefix; | 110 | #if PHP_VERSION_ID >= 50300 |
| 111 | zval *var_array, *prefix = NULL; | ||
| 112 | long extract_type = EXTR_OVERWRITE; | ||
| 113 | zval **entry, *data; | ||
| 114 | char *var_name; | ||
| 115 | ulong num_key; | ||
| 116 | uint var_name_len; | ||
| 117 | int var_exists, key_type, count = 0; | ||
| 118 | int extract_refs = 0; | ||
| 119 | HashPosition pos; | ||
| 120 | |||
| 121 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|lz/", &var_array, &extract_type, &prefix) == FAILURE) { | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | |||
| 125 | extract_refs = (extract_type & EXTR_REFS); | ||
| 126 | extract_type &= 0xff; | ||
| 127 | |||
| 128 | if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { | ||
| 129 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid extract type"); | ||
| 130 | return; | ||
| 131 | } | ||
| 132 | |||
| 133 | if (extract_type > EXTR_SKIP && extract_type <= EXTR_PREFIX_IF_EXISTS && ZEND_NUM_ARGS() < 3) { | ||
| 134 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "specified extract type requires the prefix parameter"); | ||
| 135 | return; | ||
| 136 | } | ||
| 137 | |||
| 138 | if (prefix) { | ||
| 139 | convert_to_string(prefix); | ||
| 140 | if (Z_STRLEN_P(prefix) && !php_valid_var_name(Z_STRVAL_P(prefix), Z_STRLEN_P(prefix))) { | ||
| 141 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "prefix is not a valid identifier"); | ||
| 142 | return; | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | if (!EG(active_symbol_table)) { | ||
| 147 | zend_rebuild_symbol_table(TSRMLS_C); | ||
| 148 | } | ||
| 149 | |||
| 150 | /* var_array is passed by ref for the needs of EXTR_REFS (needs to | ||
| 151 | * work on the original array to create refs to its members) | ||
| 152 | * simulate pass_by_value if EXTR_REFS is not used */ | ||
| 153 | if (!extract_refs) { | ||
| 154 | SEPARATE_ARG_IF_REF(var_array); | ||
| 155 | } | ||
| 156 | |||
| 157 | zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos); | ||
| 158 | while (zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), (void **)&entry, &pos) == SUCCESS) { | ||
| 159 | zval final_name; | ||
| 160 | |||
| 161 | ZVAL_NULL(&final_name); | ||
| 162 | |||
| 163 | key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &var_name_len, &num_key, 0, &pos); | ||
| 164 | var_exists = 0; | ||
| 165 | |||
| 166 | if (key_type == HASH_KEY_IS_STRING) { | ||
| 167 | var_name_len--; | ||
| 168 | var_exists = zend_hash_exists(EG(active_symbol_table), var_name, var_name_len + 1); | ||
| 169 | } else if (key_type == HASH_KEY_IS_LONG && (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID)) { | ||
| 170 | zval num; | ||
| 171 | |||
| 172 | ZVAL_LONG(&num, num_key); | ||
| 173 | convert_to_string(&num); | ||
| 174 | php_prefix_varname(&final_name, prefix, Z_STRVAL(num), Z_STRLEN(num), 1 TSRMLS_CC); | ||
| 175 | zval_dtor(&num); | ||
| 176 | } else { | ||
| 177 | zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); | ||
| 178 | continue; | ||
| 179 | } | ||
| 180 | |||
| 181 | switch (extract_type) { | ||
| 182 | case EXTR_IF_EXISTS: | ||
| 183 | if (!var_exists) break; | ||
| 184 | /* break omitted intentionally */ | ||
| 185 | |||
| 186 | case EXTR_OVERWRITE: | ||
| 187 | /* GLOBALS protection */ | ||
| 188 | if (var_exists && var_name_len == sizeof("GLOBALS") && !strcmp(var_name, "GLOBALS")) { | ||
| 189 | break; | ||
| 190 | } | ||
| 191 | if (var_exists && var_name_len == sizeof("this") && !strcmp(var_name, "this") && EG(scope) && EG(scope)->name_length != 0) { | ||
| 192 | break; | ||
| 193 | } | ||
| 194 | ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); | ||
| 195 | break; | ||
| 196 | |||
| 197 | case EXTR_PREFIX_IF_EXISTS: | ||
| 198 | if (var_exists) { | ||
| 199 | php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); | ||
| 200 | } | ||
| 201 | break; | ||
| 202 | |||
| 203 | case EXTR_PREFIX_SAME: | ||
| 204 | if (!var_exists && var_name_len != 0) { | ||
| 205 | ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); | ||
| 206 | } | ||
| 207 | /* break omitted intentionally */ | ||
| 208 | |||
| 209 | case EXTR_PREFIX_ALL: | ||
| 210 | if (Z_TYPE(final_name) == IS_NULL && var_name_len != 0) { | ||
| 211 | php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); | ||
| 212 | } | ||
| 213 | break; | ||
| 214 | |||
| 215 | case EXTR_PREFIX_INVALID: | ||
| 216 | if (Z_TYPE(final_name) == IS_NULL) { | ||
| 217 | if (!php_valid_var_name(var_name, var_name_len)) { | ||
| 218 | php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC); | ||
| 219 | } else { | ||
| 220 | ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | break; | ||
| 224 | |||
| 225 | default: | ||
| 226 | if (!var_exists) { | ||
| 227 | ZVAL_STRINGL(&final_name, var_name, var_name_len, 1); | ||
| 228 | } | ||
| 229 | break; | ||
| 230 | } | ||
| 231 | |||
| 232 | if (Z_TYPE(final_name) != IS_NULL && php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) { | ||
| 233 | if (extract_refs) { | ||
| 234 | zval **orig_var; | ||
| 235 | |||
| 236 | SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); | ||
| 237 | zval_add_ref(entry); | ||
| 238 | |||
| 239 | if (zend_hash_find(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, (void **) &orig_var) == SUCCESS) { | ||
| 240 | zval_ptr_dtor(orig_var); | ||
| 241 | *orig_var = *entry; | ||
| 242 | } else { | ||
| 243 | zend_hash_update(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, (void **) entry, sizeof(zval *), NULL); | ||
| 244 | } | ||
| 245 | } else { | ||
| 246 | MAKE_STD_ZVAL(data); | ||
| 247 | *data = **entry; | ||
| 248 | zval_copy_ctor(data); | ||
| 249 | |||
| 250 | ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, data, 1, 0); | ||
| 251 | } | ||
| 252 | count++; | ||
| 253 | } | ||
| 254 | zval_dtor(&final_name); | ||
| 255 | |||
| 256 | zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); | ||
| 257 | } | ||
| 258 | |||
| 259 | if (!extract_refs) { | ||
| 260 | zval_ptr_dtor(&var_array); | ||
| 261 | } | ||
| 262 | |||
| 263 | RETURN_LONG(count); | ||
| 264 | #else | ||
| 265 | zval **var_array, *orig_var_array, **z_extract_type, **prefix; | ||
| 99 | zval **entry, *data; | 266 | zval **entry, *data; |
| 100 | char *var_name; | 267 | char *var_name; |
| 101 | smart_str final_name = {0}; | 268 | smart_str final_name = {0}; |
| @@ -143,12 +310,6 @@ PHP_FUNCTION(suhosin_extract) | |||
| 143 | break; | 310 | break; |
| 144 | } | 311 | } |
| 145 | 312 | ||
| 146 | #if PHP_VERSION_ID >= 50300 | ||
| 147 | if (!EG(active_symbol_table)) { | ||
| 148 | zend_rebuild_symbol_table(TSRMLS_C); | ||
| 149 | } | ||
| 150 | #endif | ||
| 151 | |||
| 152 | if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { | 313 | if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { |
| 153 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown extract type"); | 314 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown extract type"); |
| 154 | return; | 315 | return; |
| @@ -158,7 +319,15 @@ PHP_FUNCTION(suhosin_extract) | |||
| 158 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument should be an array"); | 319 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument should be an array"); |
| 159 | return; | 320 | return; |
| 160 | } | 321 | } |
| 161 | 322 | ||
| 323 | /* var_array is passed by ref for the needs of EXTR_REFS (needs to | ||
| 324 | * work on the original array to create refs to its members) | ||
| 325 | * simulate pass_by_value if EXTR_REFS is not used */ | ||
| 326 | if (!extract_refs) { | ||
| 327 | orig_var_array = *var_array; | ||
| 328 | SEPARATE_ARG_IF_REF((*var_array)); | ||
| 329 | } | ||
| 330 | |||
| 162 | zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(var_array), &pos); | 331 | zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(var_array), &pos); |
| 163 | while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, &pos) == SUCCESS) { | 332 | while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, &pos) == SUCCESS) { |
| 164 | key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), &var_name, &var_name_len, &num_key, 0, &pos); | 333 | key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), &var_name, &var_name_len, &num_key, 0, &pos); |
| @@ -183,7 +352,10 @@ PHP_FUNCTION(suhosin_extract) | |||
| 183 | 352 | ||
| 184 | case EXTR_OVERWRITE: | 353 | case EXTR_OVERWRITE: |
| 185 | /* GLOBALS protection */ | 354 | /* GLOBALS protection */ |
| 186 | if (var_exists && !strcmp(var_name, "GLOBALS")) { | 355 | if (var_exists && var_name_len == sizeof("GLOBALS") && !strcmp(var_name, "GLOBALS")) { |
| 356 | break; | ||
| 357 | } | ||
| 358 | if (var_exists && var_name_len == sizeof("this") && !strcmp(var_name, "this") && EG(scope) && EG(scope)->name_length != 0) { | ||
| 187 | break; | 359 | break; |
| 188 | } | 360 | } |
| 189 | smart_str_appendl(&final_name, var_name, var_name_len); | 361 | smart_str_appendl(&final_name, var_name, var_name_len); |
| @@ -212,7 +384,7 @@ PHP_FUNCTION(suhosin_extract) | |||
| 212 | 384 | ||
| 213 | case EXTR_PREFIX_INVALID: | 385 | case EXTR_PREFIX_INVALID: |
| 214 | if (final_name.len == 0) { | 386 | if (final_name.len == 0) { |
| 215 | if (!php_valid_var_name(var_name)) { | 387 | if (!php_valid_var_name(var_name, var_name_len)) { |
| 216 | smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); | 388 | smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); |
| 217 | smart_str_appendc(&final_name, '_'); | 389 | smart_str_appendc(&final_name, '_'); |
| 218 | smart_str_appendl(&final_name, var_name, var_name_len); | 390 | smart_str_appendl(&final_name, var_name, var_name_len); |
| @@ -229,24 +401,17 @@ PHP_FUNCTION(suhosin_extract) | |||
| 229 | 401 | ||
| 230 | if (final_name.len) { | 402 | if (final_name.len) { |
| 231 | smart_str_0(&final_name); | 403 | smart_str_0(&final_name); |
| 232 | if (php_valid_var_name(final_name.c)) { | 404 | if (php_valid_var_name(final_name.c, final_name.len)) { |
| 233 | if (extract_refs) { | 405 | if (extract_refs) { |
| 234 | zval **orig_var; | 406 | zval **orig_var; |
| 235 | 407 | ||
| 408 | SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); | ||
| 409 | zval_add_ref(entry); | ||
| 410 | |||
| 236 | if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS) { | 411 | if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS) { |
| 237 | SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); | ||
| 238 | zval_add_ref(entry); | ||
| 239 | |||
| 240 | zval_ptr_dtor(orig_var); | 412 | zval_ptr_dtor(orig_var); |
| 241 | |||
| 242 | *orig_var = *entry; | 413 | *orig_var = *entry; |
| 243 | } else { | 414 | } else { |
| 244 | if (Z_REFCOUNT_PP(var_array) > 1) { | ||
| 245 | SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); | ||
| 246 | } else { | ||
| 247 | Z_SET_ISREF_PP(entry); | ||
| 248 | } | ||
| 249 | zval_add_ref(entry); | ||
| 250 | zend_hash_update(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) entry, sizeof(zval *), NULL); | 415 | zend_hash_update(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) entry, sizeof(zval *), NULL); |
| 251 | } | 416 | } |
| 252 | } else { | 417 | } else { |
| @@ -265,15 +430,88 @@ PHP_FUNCTION(suhosin_extract) | |||
| 265 | zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos); | 430 | zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos); |
| 266 | } | 431 | } |
| 267 | 432 | ||
| 433 | if (!extract_refs) { | ||
| 434 | zval_ptr_dtor(var_array); | ||
| 435 | *var_array = orig_var_array; | ||
| 436 | } | ||
| 268 | smart_str_free(&final_name); | 437 | smart_str_free(&final_name); |
| 269 | 438 | ||
| 270 | RETURN_LONG(count); | 439 | RETURN_LONG(count); |
| 440 | #endif | ||
| 271 | } | 441 | } |
| 272 | /* }}} */ | 442 | /* }}} */ |
| 273 | 443 | ||
| 274 | 444 | ||
| 275 | static int copy_request_variable(void *pDest, int num_args, va_list args, zend_hash_key *hash_key) | 445 | static int copy_request_variable(void *pDest, int num_args, va_list args, zend_hash_key *hash_key) |
| 276 | { | 446 | { |
| 447 | #if PHP_VERSION_ID >= 50300 | ||
| 448 | zval *prefix, new_key; | ||
| 449 | int prefix_len; | ||
| 450 | zval **var = (zval **) pDest; | ||
| 451 | |||
| 452 | if (num_args != 1) { | ||
| 453 | return 0; | ||
| 454 | } | ||
| 455 | |||
| 456 | prefix = va_arg(args, zval *); | ||
| 457 | prefix_len = Z_STRLEN_P(prefix); | ||
| 458 | |||
| 459 | if (!prefix_len && !hash_key->nKeyLength) { | ||
| 460 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric key detected - possible security hazard"); | ||
| 461 | return 0; | ||
| 462 | } | ||
| 463 | |||
| 464 | if (hash_key->nKeyLength) { | ||
| 465 | php_prefix_varname(&new_key, prefix, hash_key->arKey, hash_key->nKeyLength - 1, 0 TSRMLS_CC); | ||
| 466 | } else { | ||
| 467 | zval num; | ||
| 468 | |||
| 469 | ZVAL_LONG(&num, hash_key->h); | ||
| 470 | convert_to_string(&num); | ||
| 471 | php_prefix_varname(&new_key, prefix, Z_STRVAL(num), Z_STRLEN(num), 0 TSRMLS_CC); | ||
| 472 | zval_dtor(&num); | ||
| 473 | } | ||
| 474 | |||
| 475 | if (php_varname_check(Z_STRVAL(new_key), Z_STRLEN(new_key), 0 TSRMLS_CC) == FAILURE) { | ||
| 476 | zval_dtor(&new_key); | ||
| 477 | return 0; | ||
| 478 | } | ||
| 479 | |||
| 480 | if (Z_STRVAL(new_key)[0] == 'H') { | ||
| 481 | if ((strcmp(Z_STRVAL(new_key), "HTTP_GET_VARS")==0)|| | ||
| 482 | (strcmp(Z_STRVAL(new_key), "HTTP_POST_VARS")==0)|| | ||
| 483 | (strcmp(Z_STRVAL(new_key), "HTTP_POST_FILES")==0)|| | ||
| 484 | (strcmp(Z_STRVAL(new_key), "HTTP_ENV_VARS")==0)|| | ||
| 485 | (strcmp(Z_STRVAL(new_key), "HTTP_SERVER_VARS")==0)|| | ||
| 486 | (strcmp(Z_STRVAL(new_key), "HTTP_SESSION_VARS")==0)|| | ||
| 487 | (strcmp(Z_STRVAL(new_key), "HTTP_COOKIE_VARS")==0)|| | ||
| 488 | (strcmp(Z_STRVAL(new_key), "HTTP_RAW_POST_DATA")==0)) { | ||
| 489 | zval_dtor(&new_key); | ||
| 490 | return 0; | ||
| 491 | } | ||
| 492 | } else if (new_key[0] == '_') { | ||
| 493 | if ((strcmp(Z_STRVAL(new_key), "_COOKIE")==0)|| | ||
| 494 | (strcmp(Z_STRVAL(new_key), "_ENV")==0)|| | ||
| 495 | (strcmp(Z_STRVAL(new_key), "_FILES")==0)|| | ||
| 496 | (strcmp(Z_STRVAL(new_key), "_GET")==0)|| | ||
| 497 | (strcmp(Z_STRVAL(new_key), "_POST")==0)|| | ||
| 498 | (strcmp(Z_STRVAL(new_key), "_REQUEST")==0)|| | ||
| 499 | (strcmp(Z_STRVAL(new_key), "_SESSION")==0)|| | ||
| 500 | (strcmp(Z_STRVAL(new_key), "_SERVER")==0)) { | ||
| 501 | zval_dtor(&new_key); | ||
| 502 | return 0; | ||
| 503 | } | ||
| 504 | } else if (strcmp(Z_STRVAL(new_key), "GLOBALS")==0) { | ||
| 505 | zval_dtor(&new_key); | ||
| 506 | return 0; | ||
| 507 | } | ||
| 508 | |||
| 509 | zend_delete_global_variable(Z_STRVAL(new_key), Z_STRLEN(new_key) TSRMLS_CC); | ||
| 510 | ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), Z_STRVAL(new_key), Z_STRLEN(new_key) + 1, *var, Z_REFCOUNT_PP(var) + 1, 0); | ||
| 511 | |||
| 512 | zval_dtor(&new_key); | ||
| 513 | return 0; | ||
| 514 | #else | ||
| 277 | char *prefix, *new_key; | 515 | char *prefix, *new_key; |
| 278 | uint prefix_len, new_key_len; | 516 | uint prefix_len, new_key_len; |
| 279 | zval **var = (zval **) pDest; | 517 | zval **var = (zval **) pDest; |
| @@ -304,6 +542,7 @@ static int copy_request_variable(void *pDest, int num_args, va_list args, zend_h | |||
| 304 | memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength); | 542 | memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength); |
| 305 | } else { | 543 | } else { |
| 306 | new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); | 544 | new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); |
| 545 | new_key_len++; | ||
| 307 | } | 546 | } |
| 308 | 547 | ||
| 309 | if (new_key[0] == 'H') { | 548 | if (new_key[0] == 'H') { |
| @@ -344,16 +583,69 @@ static int copy_request_variable(void *pDest, int num_args, va_list args, zend_h | |||
| 344 | 583 | ||
| 345 | efree(new_key); | 584 | efree(new_key); |
| 346 | return 0; | 585 | return 0; |
| 586 | #endif | ||
| 347 | } | 587 | } |
| 348 | 588 | ||
| 349 | /* {{{ proto bool import_request_variables(string types [, string prefix]) | 589 | /* {{{ proto bool import_request_variables(string types [, string prefix]) |
| 350 | Import GET/POST/Cookie variables into the global scope */ | 590 | Import GET/POST/Cookie variables into the global scope */ |
| 351 | PHP_FUNCTION(suhosin_import_request_variables) | 591 | PHP_FUNCTION(suhosin_import_request_variables) |
| 352 | { | 592 | { |
| 593 | #if PHP_VERSION_ID >= 50300 | ||
| 594 | char *types; | ||
| 595 | int types_len; | ||
| 596 | zval *prefix = NULL; | ||
| 597 | char *p; | ||
| 598 | zend_bool ok = 0; | ||
| 599 | |||
| 600 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &types, &types_len, &prefix) == FAILURE) { | ||
| 601 | return; | ||
| 602 | } | ||
| 603 | |||
| 604 | if (ZEND_NUM_ARGS() > 1) { | ||
| 605 | convert_to_string(prefix); | ||
| 606 | |||
| 607 | if (Z_STRLEN_P(prefix) == 0) { | ||
| 608 | php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No prefix specified - possible security hazard"); | ||
| 609 | } | ||
| 610 | } else { | ||
| 611 | MAKE_STD_ZVAL(prefix); | ||
| 612 | ZVAL_EMPTY_STRING(prefix); | ||
| 613 | } | ||
| 614 | |||
| 615 | for (p = types; p && *p; p++) { | ||
| 616 | switch (*p) { | ||
| 617 | |||
| 618 | case 'g': | ||
| 619 | case 'G': | ||
| 620 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]) TSRMLS_CC, (apply_func_args_t) copy_request_variable, 1, prefix); | ||
| 621 | ok = 1; | ||
| 622 | break; | ||
| 623 | |||
| 624 | case 'p': | ||
| 625 | case 'P': | ||
| 626 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]) TSRMLS_CC, (apply_func_args_t) copy_request_variable, 1, prefix); | ||
| 627 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_FILES]) TSRMLS_CC, (apply_func_args_t) copy_request_variable, 1, prefix); | ||
| 628 | ok = 1; | ||
| 629 | break; | ||
| 630 | |||
| 631 | case 'c': | ||
| 632 | case 'C': | ||
| 633 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) TSRMLS_CC, (apply_func_args_t) copy_request_variable, 1, prefix); | ||
| 634 | ok = 1; | ||
| 635 | break; | ||
| 636 | } | ||
| 637 | } | ||
| 638 | |||
| 639 | if (ZEND_NUM_ARGS() < 2) { | ||
| 640 | zval_ptr_dtor(&prefix); | ||
| 641 | } | ||
| 642 | RETURN_BOOL(ok); | ||
| 643 | #else | ||
| 353 | zval **z_types, **z_prefix; | 644 | zval **z_types, **z_prefix; |
| 354 | char *types, *prefix; | 645 | char *types, *prefix; |
| 355 | uint prefix_len; | 646 | uint prefix_len; |
| 356 | char *p; | 647 | char *p; |
| 648 | zend_bool ok = 0; | ||
| 357 | 649 | ||
| 358 | switch (ZEND_NUM_ARGS()) { | 650 | switch (ZEND_NUM_ARGS()) { |
| 359 | 651 | ||
| @@ -391,20 +683,25 @@ PHP_FUNCTION(suhosin_import_request_variables) | |||
| 391 | case 'g': | 683 | case 'g': |
| 392 | case 'G': | 684 | case 'G': |
| 393 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len); | 685 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len); |
| 686 | ok = 1; | ||
| 394 | break; | 687 | break; |
| 395 | 688 | ||
| 396 | case 'p': | 689 | case 'p': |
| 397 | case 'P': | 690 | case 'P': |
| 398 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len); | 691 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len); |
| 399 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_FILES]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len); | 692 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_FILES]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len); |
| 693 | ok = 1; | ||
| 400 | break; | 694 | break; |
| 401 | 695 | ||
| 402 | case 'c': | 696 | case 'c': |
| 403 | case 'C': | 697 | case 'C': |
| 404 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len); | 698 | zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]), (apply_func_args_t) copy_request_variable, 2, prefix, prefix_len); |
| 699 | ok = 1; | ||
| 405 | break; | 700 | break; |
| 406 | } | 701 | } |
| 407 | } | 702 | } |
| 703 | RETURN_BOOL(ok); | ||
| 704 | #endif | ||
| 408 | } | 705 | } |
| 409 | /* }}} */ | 706 | /* }}} */ |
| 410 | 707 | ||
