diff options
| author | Ben Fuhrmannek | 2015-01-15 17:09:32 +0100 |
|---|---|---|
| committer | Ben Fuhrmannek | 2015-01-15 17:09:32 +0100 |
| commit | 5335470004c0e97fd5f4d4a2d0371693cb26fccc (patch) | |
| tree | b058967648f7069b5f43a1c23a7c7b8f56460959 | |
| parent | 68960966324f4701a1f402e97f17ca7870a317a4 (diff) | |
removed <5.4 compatibility code
| -rw-r--r-- | config.m4 | 2 | ||||
| -rw-r--r-- | config.w32 | 2 | ||||
| -rw-r--r-- | ex_imp.c | 412 | ||||
| -rw-r--r-- | execute.c | 44 | ||||
| -rw-r--r-- | header.c | 16 | ||||
| -rw-r--r-- | log.c | 13 | ||||
| -rw-r--r-- | php_suhosin.h | 121 | ||||
| -rw-r--r-- | post_handler.c | 11 | ||||
| -rw-r--r-- | rfc1867.c | 1397 | ||||
| -rw-r--r-- | rfc1867_new.c | 2 | ||||
| -rw-r--r-- | session.c | 61 | ||||
| -rw-r--r-- | sha256.c | 6 | ||||
| -rw-r--r-- | suhosin.c | 5 | ||||
| -rw-r--r-- | treat_data.c | 8 |
14 files changed, 7 insertions, 2093 deletions
| @@ -5,7 +5,7 @@ PHP_ARG_ENABLE(suhosin, whether to enable suhosin support, | |||
| 5 | [ --enable-suhosin Enable suhosin support]) | 5 | [ --enable-suhosin Enable suhosin support]) |
| 6 | 6 | ||
| 7 | if test "$PHP_SUHOSIN" != "no"; then | 7 | if test "$PHP_SUHOSIN" != "no"; then |
| 8 | PHP_NEW_EXTENSION(suhosin, suhosin.c sha256.c memory_limit.c treat_data.c ifilter.c post_handler.c ufilter.c rfc1867.c rfc1867_new.c log.c header.c execute.c ex_imp.c session.c aes.c crypt.c, $ext_shared) | 8 | PHP_NEW_EXTENSION(suhosin, suhosin.c sha256.c memory_limit.c treat_data.c ifilter.c post_handler.c ufilter.c rfc1867_new.c log.c header.c execute.c ex_imp.c session.c aes.c crypt.c, $ext_shared) |
| 9 | fi | 9 | fi |
| 10 | 10 | ||
| 11 | PHP_ARG_ENABLE(suhosin-experimental, whether to enable experimental suhosin features, | 11 | PHP_ARG_ENABLE(suhosin-experimental, whether to enable experimental suhosin features, |
| @@ -4,7 +4,7 @@ | |||
| 4 | ARG_ENABLE("suhosin", "whether to enable suhosin support", "yes"); | 4 | ARG_ENABLE("suhosin", "whether to enable suhosin support", "yes"); |
| 5 | 5 | ||
| 6 | if (PHP_SUHOSIN == "yes") { | 6 | if (PHP_SUHOSIN == "yes") { |
| 7 | EXTENSION("suhosin", "suhosin.c sha256.c memory_limit.c treat_data.c ifilter.c post_handler.c ufilter.c rfc1867.c rfc1867_new.c log.c header.c execute.c ex_imp.c session.c aes.c crypt.c"); | 7 | EXTENSION("suhosin", "suhosin.c sha256.c memory_limit.c treat_data.c ifilter.c post_handler.c ufilter.c rfc1867_new.c log.c header.c execute.c ex_imp.c session.c aes.c crypt.c"); |
| 8 | ARG_ENABLE("suhosin-experimental", "Enable experimental suhosin features", "no"); | 8 | ARG_ENABLE("suhosin-experimental", "Enable experimental suhosin features", "no"); |
| 9 | 9 | ||
| 10 | if (PHP_SUHOSIN_EXPERIMENTAL != "no") { | 10 | if (PHP_SUHOSIN_EXPERIMENTAL != "no") { |
| @@ -86,7 +86,6 @@ static int php_valid_var_name(char *var_name, int len) /* {{{ */ | |||
| 86 | Imports variables into symbol table from an array */ | 86 | Imports variables into symbol table from an array */ |
| 87 | PHP_FUNCTION(suhosin_extract) | 87 | PHP_FUNCTION(suhosin_extract) |
| 88 | { | 88 | { |
| 89 | #if 1 //PHP_VERSION_ID >= 50300 | ||
| 90 | zval *var_array, *prefix = NULL; | 89 | zval *var_array, *prefix = NULL; |
| 91 | long extract_type = EXTR_OVERWRITE; | 90 | long extract_type = EXTR_OVERWRITE; |
| 92 | zval **entry, *data; | 91 | zval **entry, *data; |
| @@ -240,430 +239,22 @@ PHP_FUNCTION(suhosin_extract) | |||
| 240 | } | 239 | } |
| 241 | 240 | ||
| 242 | RETURN_LONG(count); | 241 | RETURN_LONG(count); |
| 243 | #else | ||
| 244 | zval **var_array, *orig_var_array, **z_extract_type, **prefix; | ||
| 245 | zval **entry, *data; | ||
| 246 | char *var_name; | ||
| 247 | smart_str final_name = {0}; | ||
| 248 | ulong num_key; | ||
| 249 | uint var_name_len; | ||
| 250 | int var_exists, extract_type, key_type, count = 0; | ||
| 251 | int extract_refs = 0; | ||
| 252 | HashPosition pos; | ||
| 253 | |||
| 254 | switch (ZEND_NUM_ARGS()) { | ||
| 255 | case 1: | ||
| 256 | if (zend_get_parameters_ex(1, &var_array) == FAILURE) { | ||
| 257 | WRONG_PARAM_COUNT; | ||
| 258 | } | ||
| 259 | extract_type = EXTR_OVERWRITE; | ||
| 260 | break; | ||
| 261 | |||
| 262 | case 2: | ||
| 263 | if (zend_get_parameters_ex(2, &var_array, &z_extract_type) == FAILURE) { | ||
| 264 | WRONG_PARAM_COUNT; | ||
| 265 | } | ||
| 266 | convert_to_long_ex(z_extract_type); | ||
| 267 | extract_type = Z_LVAL_PP(z_extract_type); | ||
| 268 | extract_refs = (extract_type & EXTR_REFS); | ||
| 269 | extract_type &= 0xff; | ||
| 270 | if (extract_type > EXTR_SKIP && extract_type <= EXTR_PREFIX_IF_EXISTS) { | ||
| 271 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Prefix expected to be specified"); | ||
| 272 | return; | ||
| 273 | } | ||
| 274 | break; | ||
| 275 | |||
| 276 | case 3: | ||
| 277 | if (zend_get_parameters_ex(3, &var_array, &z_extract_type, &prefix) == FAILURE) { | ||
| 278 | WRONG_PARAM_COUNT; | ||
| 279 | } | ||
| 280 | convert_to_long_ex(z_extract_type); | ||
| 281 | extract_type = Z_LVAL_PP(z_extract_type); | ||
| 282 | extract_refs = (extract_type & EXTR_REFS); | ||
| 283 | extract_type &= 0xff; | ||
| 284 | convert_to_string_ex(prefix); | ||
| 285 | break; | ||
| 286 | |||
| 287 | default: | ||
| 288 | WRONG_PARAM_COUNT; | ||
| 289 | break; | ||
| 290 | } | ||
| 291 | |||
| 292 | if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { | ||
| 293 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown extract type"); | ||
| 294 | return; | ||
| 295 | } | ||
| 296 | |||
| 297 | if (Z_TYPE_PP(var_array) != IS_ARRAY) { | ||
| 298 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument should be an array"); | ||
| 299 | return; | ||
| 300 | } | ||
| 301 | |||
| 302 | /* var_array is passed by ref for the needs of EXTR_REFS (needs to | ||
| 303 | * work on the original array to create refs to its members) | ||
| 304 | * simulate pass_by_value if EXTR_REFS is not used */ | ||
| 305 | if (!extract_refs) { | ||
| 306 | orig_var_array = *var_array; | ||
| 307 | SEPARATE_ARG_IF_REF((*var_array)); | ||
| 308 | } | ||
| 309 | |||
| 310 | zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(var_array), &pos); | ||
| 311 | while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, &pos) == SUCCESS) { | ||
| 312 | key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), &var_name, &var_name_len, &num_key, 0, &pos); | ||
| 313 | var_exists = 0; | ||
| 314 | |||
| 315 | if (key_type == HASH_KEY_IS_STRING) { | ||
| 316 | var_name_len--; | ||
| 317 | var_exists = zend_hash_exists(EG(active_symbol_table), var_name, var_name_len + 1); | ||
| 318 | } else if (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID) { | ||
| 319 | smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); | ||
| 320 | smart_str_appendc(&final_name, '_'); | ||
| 321 | smart_str_append_long(&final_name, num_key); | ||
| 322 | } else { | ||
| 323 | zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos); | ||
| 324 | continue; | ||
| 325 | } | ||
| 326 | |||
| 327 | switch (extract_type) { | ||
| 328 | case EXTR_IF_EXISTS: | ||
| 329 | if (!var_exists) break; | ||
| 330 | /* break omitted intentionally */ | ||
| 331 | |||
| 332 | case EXTR_OVERWRITE: | ||
| 333 | /* GLOBALS protection */ | ||
| 334 | if (var_exists && var_name_len == sizeof("GLOBALS") && !strcmp(var_name, "GLOBALS")) { | ||
| 335 | break; | ||
| 336 | } | ||
| 337 | if (var_exists && var_name_len == sizeof("this") && !strcmp(var_name, "this") && EG(scope) && EG(scope)->name_length != 0) { | ||
| 338 | break; | ||
| 339 | } | ||
| 340 | smart_str_appendl(&final_name, var_name, var_name_len); | ||
| 341 | break; | ||
| 342 | |||
| 343 | case EXTR_PREFIX_IF_EXISTS: | ||
| 344 | if (var_exists) { | ||
| 345 | smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); | ||
| 346 | smart_str_appendc(&final_name, '_'); | ||
| 347 | smart_str_appendl(&final_name, var_name, var_name_len); | ||
| 348 | } | ||
| 349 | break; | ||
| 350 | |||
| 351 | case EXTR_PREFIX_SAME: | ||
| 352 | if (!var_exists) | ||
| 353 | smart_str_appendl(&final_name, var_name, var_name_len); | ||
| 354 | /* break omitted intentionally */ | ||
| 355 | |||
| 356 | case EXTR_PREFIX_ALL: | ||
| 357 | if (final_name.len == 0 && var_name_len != 0) { | ||
| 358 | smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); | ||
| 359 | smart_str_appendc(&final_name, '_'); | ||
| 360 | smart_str_appendl(&final_name, var_name, var_name_len); | ||
| 361 | } | ||
| 362 | break; | ||
| 363 | |||
| 364 | case EXTR_PREFIX_INVALID: | ||
| 365 | if (final_name.len == 0) { | ||
| 366 | if (!php_valid_var_name(var_name, var_name_len)) { | ||
| 367 | smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); | ||
| 368 | smart_str_appendc(&final_name, '_'); | ||
| 369 | smart_str_appendl(&final_name, var_name, var_name_len); | ||
| 370 | } else | ||
| 371 | smart_str_appendl(&final_name, var_name, var_name_len); | ||
| 372 | } | ||
| 373 | break; | ||
| 374 | |||
| 375 | default: | ||
| 376 | if (!var_exists) | ||
| 377 | smart_str_appendl(&final_name, var_name, var_name_len); | ||
| 378 | break; | ||
| 379 | } | ||
| 380 | |||
| 381 | if (final_name.len) { | ||
| 382 | smart_str_0(&final_name); | ||
| 383 | if (php_valid_var_name(final_name.c, final_name.len)) { | ||
| 384 | if (extract_refs) { | ||
| 385 | zval **orig_var; | ||
| 386 | |||
| 387 | SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); | ||
| 388 | zval_add_ref(entry); | ||
| 389 | |||
| 390 | if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS) { | ||
| 391 | zval_ptr_dtor(orig_var); | ||
| 392 | *orig_var = *entry; | ||
| 393 | } else { | ||
| 394 | zend_hash_update(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) entry, sizeof(zval *), NULL); | ||
| 395 | } | ||
| 396 | } else { | ||
| 397 | MAKE_STD_ZVAL(data); | ||
| 398 | *data = **entry; | ||
| 399 | zval_copy_ctor(data); | ||
| 400 | |||
| 401 | ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), final_name.c, final_name.len+1, data, 1, 0); | ||
| 402 | } | ||
| 403 | |||
| 404 | count++; | ||
| 405 | } | ||
| 406 | final_name.len = 0; | ||
| 407 | } | ||
| 408 | |||
| 409 | zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos); | ||
| 410 | } | ||
| 411 | |||
| 412 | if (!extract_refs) { | ||
| 413 | zval_ptr_dtor(var_array); | ||
| 414 | *var_array = orig_var_array; | ||
| 415 | } | ||
| 416 | smart_str_free(&final_name); | ||
| 417 | |||
| 418 | RETURN_LONG(count); | ||
| 419 | #endif | ||
| 420 | } | 242 | } |
| 421 | /* }}} */ | 243 | /* }}} */ |
| 422 | 244 | ||
| 423 | 245 | ||
| 424 | 246 | ||
| 425 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 426 | /* import_request_variables() has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0. */ | ||
| 427 | #define SUHOSIN_HAVE_IRV 1 | ||
| 428 | #endif | ||
| 429 | |||
| 430 | #ifdef SUHOSIN_HAVE_IRV | ||
| 431 | |||
| 432 | #if 1 //PHP_VERSION_ID >= 50300 | ||
| 433 | static int copy_request_variable(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) | ||
| 434 | { | ||
| 435 | zval *prefix, new_key; | ||
| 436 | int prefix_len; | ||
| 437 | zval **var = (zval **) pDest; | ||
| 438 | |||
| 439 | if (num_args != 1) { | ||
| 440 | return 0; | ||
| 441 | } | ||
| 442 | |||
| 443 | prefix = va_arg(args, zval *); | ||
| 444 | prefix_len = Z_STRLEN_P(prefix); | ||
| 445 | |||
| 446 | if (!prefix_len && !hash_key->nKeyLength) { | ||
| 447 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric key detected - possible security hazard"); | ||
| 448 | return 0; | ||
| 449 | } | ||
| 450 | |||
| 451 | if (hash_key->nKeyLength) { | ||
| 452 | php_prefix_varname(&new_key, prefix, (char *)hash_key->arKey, hash_key->nKeyLength - 1, 0 TSRMLS_CC); | ||
| 453 | } else { | ||
| 454 | zval num; | ||
| 455 | |||
| 456 | ZVAL_LONG(&num, hash_key->h); | ||
| 457 | convert_to_string(&num); | ||
| 458 | php_prefix_varname(&new_key, prefix, Z_STRVAL(num), Z_STRLEN(num), 0 TSRMLS_CC); | ||
| 459 | zval_dtor(&num); | ||
| 460 | } | ||
| 461 | |||
| 462 | if (php_varname_check(Z_STRVAL(new_key), Z_STRLEN(new_key), 1 TSRMLS_CC) == FAILURE || suhosin_is_protected_varname(Z_STRVAL(new_key), Z_STRLEN(new_key))) { | ||
| 463 | zval_dtor(&new_key); | ||
| 464 | return 0; | ||
| 465 | } | ||
| 466 | |||
| 467 | zend_delete_global_variable(Z_STRVAL(new_key), Z_STRLEN(new_key) TSRMLS_CC); | ||
| 468 | ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), Z_STRVAL(new_key), Z_STRLEN(new_key) + 1, *var, Z_REFCOUNT_PP(var) + 1, 0); | ||
| 469 | |||
| 470 | zval_dtor(&new_key); | ||
| 471 | return 0; | ||
| 472 | } | ||
| 473 | #else | ||
| 474 | static int copy_request_variable(void *pDest, int num_args, va_list args, zend_hash_key *hash_key) | ||
| 475 | { | ||
| 476 | char *prefix, *new_key; | ||
| 477 | uint prefix_len, new_key_len; | ||
| 478 | zval **var = (zval **) pDest; | ||
| 479 | TSRMLS_FETCH(); | ||
| 480 | |||
| 481 | if (num_args != 2) { | ||
| 482 | return 0; | ||
| 483 | } | ||
| 484 | |||
| 485 | prefix = va_arg(args, char *); | ||
| 486 | prefix_len = va_arg(args, uint); | ||
| 487 | |||
| 488 | if (!prefix_len) { | ||
| 489 | if (!hash_key->nKeyLength) { | ||
| 490 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric key detected - possible security hazard."); | ||
| 491 | return 0; | ||
| 492 | } else if (!strcmp(hash_key->arKey, "GLOBALS")) { | ||
| 493 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite."); | ||
| 494 | return 0; | ||
| 495 | } | ||
| 496 | } | ||
| 497 | |||
| 498 | if (hash_key->nKeyLength) { | ||
| 499 | new_key_len = prefix_len + hash_key->nKeyLength; | ||
| 500 | new_key = (char *) emalloc(new_key_len); | ||
| 501 | |||
| 502 | memcpy(new_key, prefix, prefix_len); | ||
| 503 | memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength); | ||
| 504 | } else { | ||
| 505 | new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h); | ||
| 506 | new_key_len++; | ||
| 507 | } | ||
| 508 | |||
| 509 | if (php_varname_check(new_key, new_key_len-1, 1 TSRMLS_CC) == FAILURE || suhosin_is_protected_varname(new_key, new_key_len-1)) { | ||
| 510 | efree(new_key); | ||
| 511 | return 0; | ||
| 512 | } | ||
| 513 | |||
| 514 | #if PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) | ||
| 515 | zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC); | ||
| 516 | #else | ||
| 517 | zend_hash_del(&EG(symbol_table), new_key, new_key_len-1); | ||
| 518 | #endif | ||
| 519 | ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, Z_REFCOUNT_PP(var)+1, 0); | ||
| 520 | |||
| 521 | efree(new_key); | ||
| 522 | return 0; | ||
| 523 | } | ||
| 524 | #endif | ||
| 525 | |||
| 526 | /* {{{ proto bool import_request_variables(string types [, string prefix]) | ||
| 527 | Import GET/POST/Cookie variables into the global scope */ | ||
| 528 | PHP_FUNCTION(suhosin_import_request_variables) | ||
| 529 | { | ||
| 530 | #if 1 //PHP_VERSION_ID >= 50300 | ||
| 531 | char *types; | ||
| 532 | int types_len; | ||
| 533 | zval *prefix = NULL; | ||
| 534 | char *p; | ||
| 535 | zend_bool ok = 0; | ||
| 536 | |||
| 537 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &types, &types_len, &prefix) == FAILURE) { | ||
| 538 | return; | ||
| 539 | } | ||
| 540 | |||
| 541 | if (ZEND_NUM_ARGS() > 1) { | ||
| 542 | convert_to_string(prefix); | ||
| 543 | |||
| 544 | if (Z_STRLEN_P(prefix) == 0) { | ||
| 545 | php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No prefix specified - possible security hazard"); | ||
| 546 | } | ||
| 547 | } else { | ||
| 548 | MAKE_STD_ZVAL(prefix); | ||
| 549 | ZVAL_EMPTY_STRING(prefix); | ||
| 550 | } | ||
| 551 | |||
| 552 | for (p = types; p && *p; p++) { | ||
| 553 | switch (*p) { | ||
| 554 | |||
| 555 | case 'g': | ||
| 556 | case 'G': | ||
| 557 | 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); | ||
| 558 | ok = 1; | ||
| 559 | break; | ||
| 560 | |||
| 561 | case 'p': | ||
| 562 | case 'P': | ||
| 563 | 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); | ||
| 564 | 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); | ||
| 565 | ok = 1; | ||
| 566 | break; | ||
| 567 | |||
| 568 | case 'c': | ||
| 569 | case 'C': | ||
| 570 | 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); | ||
| 571 | ok = 1; | ||
| 572 | break; | ||
| 573 | } | ||
| 574 | } | ||
| 575 | |||
| 576 | if (ZEND_NUM_ARGS() < 2) { | ||
| 577 | zval_ptr_dtor(&prefix); | ||
| 578 | } | ||
| 579 | RETURN_BOOL(ok); | ||
| 580 | #else | ||
| 581 | zval **z_types, **z_prefix; | ||
| 582 | char *types, *prefix; | ||
| 583 | uint prefix_len; | ||
| 584 | char *p; | ||
| 585 | zend_bool ok = 0; | ||
| 586 | |||
| 587 | switch (ZEND_NUM_ARGS()) { | ||
| 588 | |||
| 589 | case 1: | ||
| 590 | if (zend_get_parameters_ex(1, &z_types) == FAILURE) { | ||
| 591 | RETURN_FALSE; | ||
| 592 | } | ||
| 593 | prefix = ""; | ||
| 594 | prefix_len = 0; | ||
| 595 | break; | ||
| 596 | |||
| 597 | case 2: | ||
| 598 | if (zend_get_parameters_ex(2, &z_types, &z_prefix) == FAILURE) { | ||
| 599 | RETURN_FALSE; | ||
| 600 | } | ||
| 601 | convert_to_string_ex(z_prefix); | ||
| 602 | prefix = Z_STRVAL_PP(z_prefix); | ||
| 603 | prefix_len = Z_STRLEN_PP(z_prefix); | ||
| 604 | break; | ||
| 605 | |||
| 606 | default: | ||
| 607 | ZEND_WRONG_PARAM_COUNT(); | ||
| 608 | } | ||
| 609 | |||
| 610 | if (prefix_len == 0) { | ||
| 611 | php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No prefix specified - possible security hazard"); | ||
| 612 | } | ||
| 613 | |||
| 614 | convert_to_string_ex(z_types); | ||
| 615 | types = Z_STRVAL_PP(z_types); | ||
| 616 | |||
| 617 | for (p = types; p && *p; p++) { | ||
| 618 | switch (*p) { | ||
| 619 | |||
| 620 | case 'g': | ||
| 621 | case 'G': | ||
| 622 | 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); | ||
| 623 | ok = 1; | ||
| 624 | break; | ||
| 625 | |||
| 626 | case 'p': | ||
| 627 | case 'P': | ||
| 628 | 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); | ||
| 629 | 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); | ||
| 630 | ok = 1; | ||
| 631 | break; | ||
| 632 | |||
| 633 | case 'c': | ||
| 634 | case 'C': | ||
| 635 | 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); | ||
| 636 | ok = 1; | ||
| 637 | break; | ||
| 638 | } | ||
| 639 | } | ||
| 640 | RETURN_BOOL(ok); | ||
| 641 | #endif | ||
| 642 | } | ||
| 643 | /* }}} */ | ||
| 644 | |||
| 645 | #endif /* SUHOSIN_HAVE_IRV */ | ||
| 646 | |||
| 647 | ZEND_BEGIN_ARG_INFO_EX(suhosin_arginfo_extract, 0, 0, 1) | 247 | ZEND_BEGIN_ARG_INFO_EX(suhosin_arginfo_extract, 0, 0, 1) |
| 648 | ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) /* ARRAY_INFO(0, arg, 0) */ | 248 | ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) /* ARRAY_INFO(0, arg, 0) */ |
| 649 | ZEND_ARG_INFO(0, extract_type) | 249 | ZEND_ARG_INFO(0, extract_type) |
| 650 | ZEND_ARG_INFO(0, prefix) | 250 | ZEND_ARG_INFO(0, prefix) |
| 651 | ZEND_END_ARG_INFO() | 251 | ZEND_END_ARG_INFO() |
| 652 | 252 | ||
| 653 | #ifdef SUHOSIN_HAVE_IRV | ||
| 654 | ZEND_BEGIN_ARG_INFO_EX(suhosin_arginfo_import_request_variables, 0, 0, 1) | ||
| 655 | ZEND_ARG_INFO(0, types) | ||
| 656 | ZEND_ARG_INFO(0, prefix) | ||
| 657 | ZEND_END_ARG_INFO() | ||
| 658 | #endif | ||
| 659 | 253 | ||
| 660 | /* {{{ suhosin_ex_imp_functions[] | 254 | /* {{{ suhosin_ex_imp_functions[] |
| 661 | */ | 255 | */ |
| 662 | zend_function_entry suhosin_ex_imp_functions[] = { | 256 | zend_function_entry suhosin_ex_imp_functions[] = { |
| 663 | PHP_NAMED_FE(extract, PHP_FN(suhosin_extract), suhosin_arginfo_extract) | 257 | PHP_NAMED_FE(extract, PHP_FN(suhosin_extract), suhosin_arginfo_extract) |
| 664 | #ifdef SUHOSIN_HAVE_IRV | ||
| 665 | PHP_NAMED_FE(import_request_variables, PHP_FN(suhosin_import_request_variables), suhosin_arginfo_import_request_variables) | ||
| 666 | #endif | ||
| 667 | {NULL, NULL, NULL} | 258 | {NULL, NULL, NULL} |
| 668 | }; | 259 | }; |
| 669 | /* }}} */ | 260 | /* }}} */ |
| @@ -672,9 +263,6 @@ void suhosin_hook_ex_imp(TSRMLS_D) | |||
| 672 | { | 263 | { |
| 673 | /* replace the extract and import_request_variables functions */ | 264 | /* replace the extract and import_request_variables functions */ |
| 674 | zend_hash_del(CG(function_table), "extract", sizeof("extract")); | 265 | zend_hash_del(CG(function_table), "extract", sizeof("extract")); |
| 675 | #ifdef SUHOSIN_HAVE_IRV | ||
| 676 | zend_hash_del(CG(function_table), "import_request_variables", sizeof("import_request_variables")); | ||
| 677 | #endif | ||
| 678 | #ifndef ZEND_ENGINE_2 | 266 | #ifndef ZEND_ENGINE_2 |
| 679 | zend_register_functions(suhosin_ex_imp_functions, NULL, MODULE_PERSISTENT TSRMLS_CC); | 267 | zend_register_functions(suhosin_ex_imp_functions, NULL, MODULE_PERSISTENT TSRMLS_CC); |
| 680 | #else | 268 | #else |
| @@ -859,12 +859,7 @@ int ih_mail(IH_HANDLER_PARAMS) | |||
| 859 | 859 | ||
| 860 | int ih_querycheck(IH_HANDLER_PARAMS) | 860 | int ih_querycheck(IH_HANDLER_PARAMS) |
| 861 | { | 861 | { |
| 862 | // #ifdef PHP_ATLEAST_5_3 | 862 | void **p = zend_vm_stack_top(TSRMLS_C) - 1; |
| 863 | #if 1 | ||
| 864 | void **p = zend_vm_stack_top(TSRMLS_C) - 1; | ||
| 865 | #else | ||
| 866 | void **p = EG(argument_stack).top_element-2; | ||
| 867 | #endif | ||
| 868 | unsigned long arg_count; | 863 | unsigned long arg_count; |
| 869 | zval **arg; | 864 | zval **arg; |
| 870 | char *query, *s, *e; | 865 | char *query, *s, *e; |
| @@ -1021,12 +1016,7 @@ int ih_querycheck(IH_HANDLER_PARAMS) | |||
| 1021 | 1016 | ||
| 1022 | int ih_fixusername(IH_HANDLER_PARAMS) | 1017 | int ih_fixusername(IH_HANDLER_PARAMS) |
| 1023 | { | 1018 | { |
| 1024 | // #ifdef PHP_ATLEAST_5_3 | 1019 | void **p = zend_vm_stack_top(TSRMLS_C) - 1; |
| 1025 | #if 1 | ||
| 1026 | void **p = zend_vm_stack_top(TSRMLS_C) - 1; | ||
| 1027 | #else | ||
| 1028 | void **p = EG(argument_stack).top_element-2; | ||
| 1029 | #endif | ||
| 1030 | unsigned long arg_count; | 1020 | unsigned long arg_count; |
| 1031 | zval **arg; | 1021 | zval **arg; |
| 1032 | char *prefix, *postfix, *user, *user_match, *cp; | 1022 | char *prefix, *postfix, *user, *user_match, *cp; |
| @@ -1117,17 +1107,12 @@ int ih_fixusername(IH_HANDLER_PARAMS) | |||
| 1117 | 1107 | ||
| 1118 | static int ih_function_exists(IH_HANDLER_PARAMS) | 1108 | static int ih_function_exists(IH_HANDLER_PARAMS) |
| 1119 | { | 1109 | { |
| 1120 | // #ifndef PHP_ATLEAST_5_3 | ||
| 1121 | #if 1 | ||
| 1122 | zval **function_name; | 1110 | zval **function_name; |
| 1123 | #endif | ||
| 1124 | zend_function *func; | 1111 | zend_function *func; |
| 1125 | char *lcname; | 1112 | char *lcname; |
| 1126 | zend_bool retval; | 1113 | zend_bool retval; |
| 1127 | int func_name_len; | 1114 | int func_name_len; |
| 1128 | 1115 | ||
| 1129 | // #ifndef PHP_ATLEAST_5_3 | ||
| 1130 | #if 1 | ||
| 1131 | if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) { | 1116 | if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) { |
| 1132 | ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(1); | 1117 | ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(1); |
| 1133 | } | 1118 | } |
| @@ -1135,18 +1120,6 @@ static int ih_function_exists(IH_HANDLER_PARAMS) | |||
| 1135 | func_name_len = Z_STRLEN_PP(function_name); | 1120 | func_name_len = Z_STRLEN_PP(function_name); |
| 1136 | lcname = estrndup(Z_STRVAL_PP(function_name), func_name_len); | 1121 | lcname = estrndup(Z_STRVAL_PP(function_name), func_name_len); |
| 1137 | zend_str_tolower(lcname, func_name_len); | 1122 | zend_str_tolower(lcname, func_name_len); |
| 1138 | #else | ||
| 1139 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &lcname, &func_name_len) == FAILURE) { | ||
| 1140 | return (1); | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | /* Ignore leading "\" */ | ||
| 1144 | if (func_name_len > 0 && lcname[0] == '\\') { | ||
| 1145 | lcname = &lcname[1]; | ||
| 1146 | func_name_len--; | ||
| 1147 | } | ||
| 1148 | lcname = zend_str_tolower_dup(lcname, func_name_len); | ||
| 1149 | #endif | ||
| 1150 | 1123 | ||
| 1151 | retval = (zend_hash_find(EG(function_table), lcname, func_name_len+1, (void **)&func) == SUCCESS); | 1124 | retval = (zend_hash_find(EG(function_table), lcname, func_name_len+1, (void **)&func) == SUCCESS); |
| 1152 | 1125 | ||
| @@ -1563,18 +1536,9 @@ static int ih_rand(IH_HANDLER_PARAMS) | |||
| 1563 | 1536 | ||
| 1564 | static int ih_getrandmax(IH_HANDLER_PARAMS) | 1537 | static int ih_getrandmax(IH_HANDLER_PARAMS) |
| 1565 | { | 1538 | { |
| 1566 | // #ifdef PHP_ATLEAST_5_3 | ||
| 1567 | #if 1 | ||
| 1568 | if (zend_parse_parameters_none() == FAILURE) { | 1539 | if (zend_parse_parameters_none() == FAILURE) { |
| 1569 | return(0); | 1540 | return(0); |
| 1570 | } | 1541 | } |
| 1571 | #else | ||
| 1572 | int argc = ZEND_NUM_ARGS(); | ||
| 1573 | |||
| 1574 | if (argc != 0) { | ||
| 1575 | ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(1); | ||
| 1576 | } | ||
| 1577 | #endif | ||
| 1578 | RETVAL_LONG(PHP_MT_RAND_MAX); | 1542 | RETVAL_LONG(PHP_MT_RAND_MAX); |
| 1579 | return (1); | 1543 | return (1); |
| 1580 | } | 1544 | } |
| @@ -1742,11 +1706,7 @@ static void suhosin_execute_internal(zend_execute_data *execute_data_ptr, int re | |||
| 1742 | 1706 | ||
| 1743 | #if PHP_VERSION_ID < 50500 | 1707 | #if PHP_VERSION_ID < 50500 |
| 1744 | #ifdef ZEND_ENGINE_2 | 1708 | #ifdef ZEND_ENGINE_2 |
| 1745 | # if 0 // PHP_VERSION_ID < 50400 | ||
| 1746 | return_value = (*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr; | ||
| 1747 | # else | ||
| 1748 | return_value = (*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; | 1709 | return_value = (*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; |
| 1749 | # endif | ||
| 1750 | #else | 1710 | #else |
| 1751 | return_value = execute_data_ptr->Ts[execute_data_ptr->opline->result.u.var].var.ptr; | 1711 | return_value = execute_data_ptr->Ts[execute_data_ptr->opline->result.u.var].var.ptr; |
| 1752 | #endif | 1712 | #endif |
| @@ -32,11 +32,7 @@ | |||
| 32 | #include "SAPI.h" | 32 | #include "SAPI.h" |
| 33 | #include "php_variables.h" | 33 | #include "php_variables.h" |
| 34 | 34 | ||
| 35 | #if 1 //PHP_VERSION_ID >= 50300 | ||
| 36 | static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; | 35 | static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; |
| 37 | #else | ||
| 38 | static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; | ||
| 39 | #endif | ||
| 40 | 36 | ||
| 41 | char *suhosin_encrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key TSRMLS_DC) | 37 | char *suhosin_encrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key TSRMLS_DC) |
| 42 | { | 38 | { |
| @@ -190,20 +186,14 @@ char *suhosin_cookie_decryptor(TSRMLS_D) | |||
| 190 | 186 | ||
| 191 | /* {{{ suhosin_header_handler | 187 | /* {{{ suhosin_header_handler |
| 192 | */ | 188 | */ |
| 193 | #if 1 //PHP_VERSION_ID >= 50300 | ||
| 194 | int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) | 189 | int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) |
| 195 | #else | ||
| 196 | int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) | ||
| 197 | #endif | ||
| 198 | { | 190 | { |
| 199 | int retval = SAPI_HEADER_ADD, i; | 191 | int retval = SAPI_HEADER_ADD, i; |
| 200 | char *tmp; | 192 | char *tmp; |
| 201 | 193 | ||
| 202 | #if 1 //PHP_VERSION_ID >= 50300 | ||
| 203 | if (op != SAPI_HEADER_ADD && op != SAPI_HEADER_REPLACE) { | 194 | if (op != SAPI_HEADER_ADD && op != SAPI_HEADER_REPLACE) { |
| 204 | goto suhosin_skip_header_handling; | 195 | goto suhosin_skip_header_handling; |
| 205 | } | 196 | } |
| 206 | #endif | ||
| 207 | 197 | ||
| 208 | if (sapi_header && sapi_header->header) { | 198 | if (sapi_header && sapi_header->header) { |
| 209 | 199 | ||
| @@ -294,11 +284,7 @@ int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct | |||
| 294 | suhosin_skip_header_handling: | 284 | suhosin_skip_header_handling: |
| 295 | /* If existing call the sapi header handler */ | 285 | /* If existing call the sapi header handler */ |
| 296 | if (orig_header_handler) { | 286 | if (orig_header_handler) { |
| 297 | #if 1 //PHP_VERSION_ID >= 50300 | ||
| 298 | retval = orig_header_handler(sapi_header, op, sapi_headers TSRMLS_CC); | 287 | retval = orig_header_handler(sapi_header, op, sapi_headers TSRMLS_CC); |
| 299 | #else | ||
| 300 | retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC); | ||
| 301 | #endif | ||
| 302 | } | 288 | } |
| 303 | 289 | ||
| 304 | return retval; | 290 | return retval; |
| @@ -287,11 +287,7 @@ log_sapi: | |||
| 287 | /* SAPI Logging activated? */ | 287 | /* SAPI Logging activated? */ |
| 288 | SDEBUG("(suhosin_log) log_syslog: %ld - log_sapi: %ld - log_script: %ld - log_phpscript: %ld", SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script), SUHOSIN_G(log_phpscript)); | 288 | SDEBUG("(suhosin_log) log_syslog: %ld - log_sapi: %ld - log_script: %ld - log_phpscript: %ld", SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script), SUHOSIN_G(log_phpscript)); |
| 289 | if (((SUHOSIN_G(log_sapi)|S_INTERNAL) & loglevel)!=0) { | 289 | if (((SUHOSIN_G(log_sapi)|S_INTERNAL) & loglevel)!=0) { |
| 290 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 291 | sapi_module.log_message(buf); | ||
| 292 | #else | ||
| 293 | sapi_module.log_message(buf TSRMLS_CC); | 290 | sapi_module.log_message(buf TSRMLS_CC); |
| 294 | #endif | ||
| 295 | } | 291 | } |
| 296 | if ((SUHOSIN_G(log_stdout) & loglevel)!=0) { | 292 | if ((SUHOSIN_G(log_stdout) & loglevel)!=0) { |
| 297 | fprintf(stdout, "%s\n", buf); | 293 | fprintf(stdout, "%s\n", buf); |
| @@ -372,9 +368,6 @@ log_phpscript: | |||
| 372 | zval *result = NULL; | 368 | zval *result = NULL; |
| 373 | 369 | ||
| 374 | long orig_execution_depth = SUHOSIN_G(execution_depth); | 370 | long orig_execution_depth = SUHOSIN_G(execution_depth); |
| 375 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 376 | zend_bool orig_safe_mode = PG(safe_mode); | ||
| 377 | #endif | ||
| 378 | char *orig_basedir = PG(open_basedir); | 371 | char *orig_basedir = PG(open_basedir); |
| 379 | 372 | ||
| 380 | char *phpscript = SUHOSIN_G(log_phpscriptname); | 373 | char *phpscript = SUHOSIN_G(log_phpscriptname); |
| @@ -411,18 +404,12 @@ SDEBUG("scriptname %s", SUHOSIN_G(log_phpscriptname)); | |||
| 411 | 404 | ||
| 412 | SUHOSIN_G(execution_depth) = 0; | 405 | SUHOSIN_G(execution_depth) = 0; |
| 413 | if (SUHOSIN_G(log_phpscript_is_safe)) { | 406 | if (SUHOSIN_G(log_phpscript_is_safe)) { |
| 414 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 415 | PG(safe_mode) = 0; | ||
| 416 | #endif | ||
| 417 | PG(open_basedir) = NULL; | 407 | PG(open_basedir) = NULL; |
| 418 | } | 408 | } |
| 419 | 409 | ||
| 420 | zend_execute(new_op_array TSRMLS_CC); | 410 | zend_execute(new_op_array TSRMLS_CC); |
| 421 | 411 | ||
| 422 | SUHOSIN_G(execution_depth) = orig_execution_depth; | 412 | SUHOSIN_G(execution_depth) = orig_execution_depth; |
| 423 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 424 | PG(safe_mode) = orig_safe_mode; | ||
| 425 | #endif | ||
| 426 | PG(open_basedir) = orig_basedir; | 413 | PG(open_basedir) = orig_basedir; |
| 427 | 414 | ||
| 428 | #ifdef ZEND_ENGINE_2 | 415 | #ifdef ZEND_ENGINE_2 |
diff --git a/php_suhosin.h b/php_suhosin.h index ccf1a91..d5a20ab 100644 --- a/php_suhosin.h +++ b/php_suhosin.h | |||
| @@ -120,51 +120,6 @@ protected_varname: | |||
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | 122 | ||
| 123 | #if 0 //PHP_VERSION_ID < 50203 | ||
| 124 | static inline int php_varname_check(char *name, int name_len, zend_bool silent TSRMLS_DC) /* {{{ */ | ||
| 125 | { | ||
| 126 | if (name_len == sizeof("GLOBALS") - 1 && !memcmp(name, "GLOBALS", sizeof("GLOBALS") - 1)) { | ||
| 127 | if (!silent) { | ||
| 128 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite"); | ||
| 129 | } | ||
| 130 | return FAILURE; | ||
| 131 | } else if (name[0] == '_' && | ||
| 132 | ( | ||
| 133 | (name_len == sizeof("_GET") - 1 && !memcmp(name, "_GET", sizeof("_GET") - 1)) || | ||
| 134 | (name_len == sizeof("_POST") - 1 && !memcmp(name, "_POST", sizeof("_POST") - 1)) || | ||
| 135 | (name_len == sizeof("_COOKIE") - 1 && !memcmp(name, "_COOKIE", sizeof("_COOKIE") - 1)) || | ||
| 136 | (name_len == sizeof("_ENV") - 1 && !memcmp(name, "_ENV", sizeof("_ENV") - 1)) || | ||
| 137 | (name_len == sizeof("_SERVER") - 1 && !memcmp(name, "_SERVER", sizeof("_SERVER") - 1)) || | ||
| 138 | (name_len == sizeof("_SESSION") - 1 && !memcmp(name, "_SESSION", sizeof("_SESSION") - 1)) || | ||
| 139 | (name_len == sizeof("_FILES") - 1 && !memcmp(name, "_FILES", sizeof("_FILES") - 1)) || | ||
| 140 | (name_len == sizeof("_REQUEST") -1 && !memcmp(name, "_REQUEST", sizeof("_REQUEST") - 1)) | ||
| 141 | ) | ||
| 142 | ) { | ||
| 143 | if (!silent) { | ||
| 144 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted super-global (%s) variable overwrite", name); | ||
| 145 | } | ||
| 146 | return FAILURE; | ||
| 147 | } else if (name[0] == 'H' && | ||
| 148 | ( | ||
| 149 | (name_len == sizeof("HTTP_POST_VARS") - 1 && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS") - 1)) || | ||
| 150 | (name_len == sizeof("HTTP_GET_VARS") - 1 && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS") - 1)) || | ||
| 151 | (name_len == sizeof("HTTP_COOKIE_VARS") - 1 && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS") - 1)) || | ||
| 152 | (name_len == sizeof("HTTP_ENV_VARS") - 1 && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS") - 1)) || | ||
| 153 | (name_len == sizeof("HTTP_SERVER_VARS") - 1 && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS") - 1)) || | ||
| 154 | (name_len == sizeof("HTTP_SESSION_VARS") - 1 && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS") - 1)) || | ||
| 155 | (name_len == sizeof("HTTP_RAW_POST_DATA") - 1 && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA") - 1)) || | ||
| 156 | (name_len == sizeof("HTTP_POST_FILES") - 1 && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES") - 1)) | ||
| 157 | ) | ||
| 158 | ) { | ||
| 159 | if (!silent) { | ||
| 160 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted long input array (%s) overwrite", name); | ||
| 161 | } | ||
| 162 | return FAILURE; | ||
| 163 | } | ||
| 164 | return SUCCESS; | ||
| 165 | } | ||
| 166 | #endif | ||
| 167 | |||
| 168 | ZEND_BEGIN_MODULE_GLOBALS(suhosin) | 123 | ZEND_BEGIN_MODULE_GLOBALS(suhosin) |
| 169 | zend_uint in_code_type; | 124 | zend_uint in_code_type; |
| 170 | long execution_depth; | 125 | long execution_depth; |
| @@ -452,82 +407,6 @@ void suhosin_bailout(TSRMLS_D); | |||
| 452 | size_t suhosin_strnspn(const char *input, size_t n, const char *accept); | 407 | size_t suhosin_strnspn(const char *input, size_t n, const char *accept); |
| 453 | size_t suhosin_strncspn(const char *input, size_t n, const char *reject); | 408 | size_t suhosin_strncspn(const char *input, size_t n, const char *reject); |
| 454 | 409 | ||
| 455 | /* Add pseudo refcount macros for PHP version < 5.3 */ | ||
| 456 | // #ifndef Z_REFCOUNT_PP | ||
| 457 | #if 0 | ||
| 458 | #define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz)) | ||
| 459 | #define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc) | ||
| 460 | #define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz)) | ||
| 461 | #define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz)) | ||
| 462 | #define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz)) | ||
| 463 | #define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz)) | ||
| 464 | #define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz)) | ||
| 465 | #define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref) | ||
| 466 | |||
| 467 | #define Z_REFCOUNT_P(pz) zval_refcount_p(pz) | ||
| 468 | #define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc) | ||
| 469 | #define Z_ADDREF_P(pz) zval_addref_p(pz) | ||
| 470 | #define Z_DELREF_P(pz) zval_delref_p(pz) | ||
| 471 | #define Z_ISREF_P(pz) zval_isref_p(pz) | ||
| 472 | #define Z_SET_ISREF_P(pz) zval_set_isref_p(pz) | ||
| 473 | #define Z_UNSET_ISREF_P(pz) zval_unset_isref_p(pz) | ||
| 474 | #define Z_SET_ISREF_TO_P(pz, isref) zval_set_isref_to_p(pz, isref) | ||
| 475 | |||
| 476 | #define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z)) | ||
| 477 | #define Z_SET_REFCOUNT(z, rc) Z_SET_REFCOUNT_P(&(z), rc) | ||
| 478 | #define Z_ADDREF(z) Z_ADDREF_P(&(z)) | ||
| 479 | #define Z_DELREF(z) Z_DELREF_P(&(z)) | ||
| 480 | #define Z_ISREF(z) Z_ISREF_P(&(z)) | ||
| 481 | #define Z_SET_ISREF(z) Z_SET_ISREF_P(&(z)) | ||
| 482 | #define Z_UNSET_ISREF(z) Z_UNSET_ISREF_P(&(z)) | ||
| 483 | #define Z_SET_ISREF_TO(z, isref) Z_SET_ISREF_TO_P(&(z), isref) | ||
| 484 | |||
| 485 | #if defined(__GNUC__) | ||
| 486 | #define zend_always_inline inline __attribute__((always_inline)) | ||
| 487 | #elif defined(_MSC_VER) | ||
| 488 | #define zend_always_inline __forceinline | ||
| 489 | #else | ||
| 490 | #define zend_always_inline inline | ||
| 491 | #endif | ||
| 492 | |||
| 493 | static zend_always_inline zend_uint zval_refcount_p(zval* pz) { | ||
| 494 | return pz->refcount; | ||
| 495 | } | ||
| 496 | |||
| 497 | static zend_always_inline zend_uint zval_set_refcount_p(zval* pz, zend_uint rc) { | ||
| 498 | return pz->refcount = rc; | ||
| 499 | } | ||
| 500 | |||
| 501 | static zend_always_inline zend_uint zval_addref_p(zval* pz) { | ||
| 502 | return ++pz->refcount; | ||
| 503 | } | ||
| 504 | |||
| 505 | static zend_always_inline zend_uint zval_delref_p(zval* pz) { | ||
| 506 | return --pz->refcount; | ||
| 507 | } | ||
| 508 | |||
| 509 | static zend_always_inline zend_bool zval_isref_p(zval* pz) { | ||
| 510 | return pz->is_ref; | ||
| 511 | } | ||
| 512 | |||
| 513 | static zend_always_inline zend_bool zval_set_isref_p(zval* pz) { | ||
| 514 | return pz->is_ref = 1; | ||
| 515 | } | ||
| 516 | |||
| 517 | static zend_always_inline zend_bool zval_unset_isref_p(zval* pz) { | ||
| 518 | return pz->is_ref = 0; | ||
| 519 | } | ||
| 520 | |||
| 521 | static zend_always_inline zend_bool zval_set_isref_to_p(zval* pz, zend_bool isref) { | ||
| 522 | return pz->is_ref = isref; | ||
| 523 | } | ||
| 524 | |||
| 525 | // #else | ||
| 526 | |||
| 527 | // #define PHP_ATLEAST_5_3 true | ||
| 528 | |||
| 529 | #endif | ||
| 530 | |||
| 531 | 410 | ||
| 532 | #endif /* PHP_SUHOSIN_H */ | 411 | #endif /* PHP_SUHOSIN_H */ |
| 533 | 412 | ||
diff --git a/post_handler.c b/post_handler.c index 388a096..ec40387 100644 --- a/post_handler.c +++ b/post_handler.c | |||
| @@ -46,9 +46,8 @@ SAPI_POST_HANDLER_FUNC(suhosin_std_post_handler) | |||
| 46 | { | 46 | { |
| 47 | char *var, *val, *e, *s, *p; | 47 | char *var, *val, *e, *s, *p; |
| 48 | zval *array_ptr = (zval *) arg; | 48 | zval *array_ptr = (zval *) arg; |
| 49 | #if 1 //PHP_VERSION_ID >= 50311 | ||
| 50 | long count = 0; | 49 | long count = 0; |
| 51 | #endif | 50 | |
| 52 | if (SG(request_info).post_data == NULL) { | 51 | if (SG(request_info).post_data == NULL) { |
| 53 | return; | 52 | return; |
| 54 | } | 53 | } |
| @@ -61,12 +60,10 @@ last_value: | |||
| 61 | if ((val = memchr(s, '=', (p - s)))) { /* have a value */ | 60 | if ((val = memchr(s, '=', (p - s)))) { /* have a value */ |
| 62 | unsigned int val_len, new_val_len; | 61 | unsigned int val_len, new_val_len; |
| 63 | 62 | ||
| 64 | #if 1 //PHP_VERSION_ID >= 50311 | ||
| 65 | if (++count > PG(max_input_vars)) { | 63 | if (++count > PG(max_input_vars)) { |
| 66 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); | 64 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); |
| 67 | return; | 65 | return; |
| 68 | } | 66 | } |
| 69 | #endif | ||
| 70 | var = s; | 67 | var = s; |
| 71 | 68 | ||
| 72 | php_url_decode(var, (val - s)); | 69 | php_url_decode(var, (val - s)); |
| @@ -266,15 +263,9 @@ void suhosin_hook_post_handlers(TSRMLS_D) | |||
| 266 | HashTable tempht; | 263 | HashTable tempht; |
| 267 | zend_ini_entry *ini_entry; | 264 | zend_ini_entry *ini_entry; |
| 268 | 265 | ||
| 269 | #if 1 //PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 0) | ||
| 270 | sapi_unregister_post_entry(&suhosin_post_entries[0] TSRMLS_CC); | 266 | sapi_unregister_post_entry(&suhosin_post_entries[0] TSRMLS_CC); |
| 271 | sapi_unregister_post_entry(&suhosin_post_entries[1] TSRMLS_CC); | 267 | sapi_unregister_post_entry(&suhosin_post_entries[1] TSRMLS_CC); |
| 272 | sapi_register_post_entries(suhosin_post_entries TSRMLS_CC); | 268 | sapi_register_post_entries(suhosin_post_entries TSRMLS_CC); |
| 273 | #else | ||
| 274 | sapi_unregister_post_entry(&suhosin_post_entries[0]); | ||
| 275 | sapi_unregister_post_entry(&suhosin_post_entries[1]); | ||
| 276 | sapi_register_post_entries(suhosin_post_entries); | ||
| 277 | #endif | ||
| 278 | 269 | ||
| 279 | /* we want to get notified if another extension deregisters the suhosin post handlers */ | 270 | /* we want to get notified if another extension deregisters the suhosin post handlers */ |
| 280 | 271 | ||
diff --git a/rfc1867.c b/rfc1867.c deleted file mode 100644 index e1e13f0..0000000 --- a/rfc1867.c +++ /dev/null | |||
| @@ -1,1397 +0,0 @@ | |||
| 1 | /* | ||
| 2 | +----------------------------------------------------------------------+ | ||
| 3 | | PHP Version 5 | | ||
| 4 | +----------------------------------------------------------------------+ | ||
| 5 | | Copyright (c) 1997-2006 The PHP Group | | ||
| 6 | +----------------------------------------------------------------------+ | ||
| 7 | | This source file is subject to version 3.01 of the PHP license, | | ||
| 8 | | that is bundled with this package in the file LICENSE, and is | | ||
| 9 | | available through the world-wide-web at the following url: | | ||
| 10 | | http://www.php.net/license/3_01.txt | | ||
| 11 | | If you did not receive a copy of the PHP license and are unable to | | ||
| 12 | | obtain it through the world-wide-web, please send a note to | | ||
| 13 | | license@php.net so we can mail you a copy immediately. | | ||
| 14 | +----------------------------------------------------------------------+ | ||
| 15 | | Authors: Rasmus Lerdorf <rasmus@php.net> | | ||
| 16 | | Jani Taskinen <sniper@php.net> | | ||
| 17 | +----------------------------------------------------------------------+ | ||
| 18 | */ | ||
| 19 | |||
| 20 | /* $Id: rfc1867.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */ | ||
| 21 | |||
| 22 | /* | ||
| 23 | * This product includes software developed by the Apache Group | ||
| 24 | * for use in the Apache HTTP server project (http://www.apache.org/). | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <stdio.h> | ||
| 29 | #include "php.h" | ||
| 30 | #include "php_open_temporary_file.h" | ||
| 31 | #include "zend_globals.h" | ||
| 32 | #include "php_globals.h" | ||
| 33 | #include "php_variables.h" | ||
| 34 | #include "php_suhosin.h" | ||
| 35 | #include "suhosin_rfc1867.h" | ||
| 36 | #include "php_ini.h" | ||
| 37 | #include "ext/standard/php_string.h" | ||
| 38 | |||
| 39 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 40 | |||
| 41 | #define DEBUG_FILE_UPLOAD ZEND_DEBUG | ||
| 42 | |||
| 43 | #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) | ||
| 44 | #include "ext/mbstring/mbstring.h" | ||
| 45 | |||
| 46 | static void safe_php_register_variable(char *var, char *strval, zval *track_vars_array, zend_bool override_protection TSRMLS_DC); | ||
| 47 | |||
| 48 | #define SAFE_RETURN { \ | ||
| 49 | php_mb_flush_gpc_variables(num_vars, val_list, len_list, array_ptr TSRMLS_CC); \ | ||
| 50 | if (lbuf) efree(lbuf); \ | ||
| 51 | if (abuf) efree(abuf); \ | ||
| 52 | if (array_index) efree(array_index); \ | ||
| 53 | zend_hash_destroy(&PG(rfc1867_protected_variables)); \ | ||
| 54 | zend_llist_destroy(&header); \ | ||
| 55 | if (mbuff->boundary_next) efree(mbuff->boundary_next); \ | ||
| 56 | if (mbuff->boundary) efree(mbuff->boundary); \ | ||
| 57 | if (mbuff->buffer) efree(mbuff->buffer); \ | ||
| 58 | if (mbuff) efree(mbuff); \ | ||
| 59 | return; } | ||
| 60 | |||
| 61 | static void php_mb_flush_gpc_variables(int num_vars, char **val_list, int *len_list, zval *array_ptr TSRMLS_DC) | ||
| 62 | { | ||
| 63 | int i; | ||
| 64 | if (php_mb_encoding_translation(TSRMLS_C)) { | ||
| 65 | if (num_vars > 0 && | ||
| 66 | php_mb_gpc_encoding_detector(val_list, len_list, num_vars, NULL TSRMLS_CC) == SUCCESS) { | ||
| 67 | php_mb_gpc_encoding_converter(val_list, len_list, num_vars, NULL, NULL TSRMLS_CC); | ||
| 68 | } | ||
| 69 | for (i=0; i<num_vars; i+=2){ | ||
| 70 | safe_php_register_variable(val_list[i], val_list[i+1], array_ptr, 0 TSRMLS_CC); | ||
| 71 | efree(val_list[i]); | ||
| 72 | efree(val_list[i+1]); | ||
| 73 | } | ||
| 74 | efree(val_list); | ||
| 75 | efree(len_list); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | static void php_mb_gpc_realloc_buffer(char ***pval_list, int **plen_list, int *num_vars_max, int inc TSRMLS_DC) | ||
| 80 | { | ||
| 81 | /* allow only even increments */ | ||
| 82 | if (inc & 1) { | ||
| 83 | inc++; | ||
| 84 | } | ||
| 85 | (*num_vars_max) += inc; | ||
| 86 | *pval_list = (char **)erealloc(*pval_list, (*num_vars_max+2)*sizeof(char *)); | ||
| 87 | *plen_list = (int *)erealloc(*plen_list, (*num_vars_max+2)*sizeof(int)); | ||
| 88 | } | ||
| 89 | |||
| 90 | static void php_mb_gpc_stack_variable(char *param, char *value, char ***pval_list, int **plen_list, int *num_vars, int *num_vars_max TSRMLS_DC) | ||
| 91 | { | ||
| 92 | char **val_list=*pval_list; | ||
| 93 | int *len_list=*plen_list; | ||
| 94 | |||
| 95 | if (*num_vars>=*num_vars_max){ | ||
| 96 | php_mb_gpc_realloc_buffer(pval_list, plen_list, num_vars_max, | ||
| 97 | 16 TSRMLS_CC); | ||
| 98 | /* in case realloc relocated the buffer */ | ||
| 99 | val_list = *pval_list; | ||
| 100 | len_list = *plen_list; | ||
| 101 | } | ||
| 102 | |||
| 103 | val_list[*num_vars] = (char *)estrdup(param); | ||
| 104 | len_list[*num_vars] = strlen(param); | ||
| 105 | (*num_vars)++; | ||
| 106 | val_list[*num_vars] = (char *)estrdup(value); | ||
| 107 | len_list[*num_vars] = strlen(value); | ||
| 108 | (*num_vars)++; | ||
| 109 | } | ||
| 110 | |||
| 111 | #else | ||
| 112 | |||
| 113 | #define SAFE_RETURN { \ | ||
| 114 | if (lbuf) efree(lbuf); \ | ||
| 115 | if (abuf) efree(abuf); \ | ||
| 116 | if (array_index) efree(array_index); \ | ||
| 117 | zend_hash_destroy(&PG(rfc1867_protected_variables)); \ | ||
| 118 | zend_llist_destroy(&header); \ | ||
| 119 | if (mbuff->boundary_next) efree(mbuff->boundary_next); \ | ||
| 120 | if (mbuff->boundary) efree(mbuff->boundary); \ | ||
| 121 | if (mbuff->buffer) efree(mbuff->buffer); \ | ||
| 122 | if (mbuff) efree(mbuff); \ | ||
| 123 | return; } | ||
| 124 | #endif | ||
| 125 | |||
| 126 | /* The longest property name we use in an uploaded file array */ | ||
| 127 | #define MAX_SIZE_OF_INDEX sizeof("[tmp_name]") | ||
| 128 | |||
| 129 | /* The longest anonymous name */ | ||
| 130 | #define MAX_SIZE_ANONNAME 33 | ||
| 131 | |||
| 132 | /* Errors */ | ||
| 133 | #define UPLOAD_ERROR_OK 0 /* File upload succesful */ | ||
| 134 | #define UPLOAD_ERROR_A 1 /* Uploaded file exceeded upload_max_filesize */ | ||
| 135 | #define UPLOAD_ERROR_B 2 /* Uploaded file exceeded MAX_FILE_SIZE */ | ||
| 136 | #define UPLOAD_ERROR_C 3 /* Partially uploaded */ | ||
| 137 | #define UPLOAD_ERROR_D 4 /* No file uploaded */ | ||
| 138 | #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */ | ||
| 139 | #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ | ||
| 140 | #define UPLOAD_ERROR_X 8 /* File upload stopped by extension */ | ||
| 141 | |||
| 142 | /* | ||
| 143 | void php_rfc1867_register_constants(TSRMLS_D) | ||
| 144 | { | ||
| 145 | REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_OK", UPLOAD_ERROR_OK, CONST_CS | CONST_PERSISTENT); | ||
| 146 | REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_INI_SIZE", UPLOAD_ERROR_A, CONST_CS | CONST_PERSISTENT); | ||
| 147 | REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FORM_SIZE", UPLOAD_ERROR_B, CONST_CS | CONST_PERSISTENT); | ||
| 148 | REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_PARTIAL", UPLOAD_ERROR_C, CONST_CS | CONST_PERSISTENT); | ||
| 149 | REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT); | ||
| 150 | REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT); | ||
| 151 | REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT); | ||
| 152 | REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_EXTENSION", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT); | ||
| 153 | } | ||
| 154 | */ | ||
| 155 | |||
| 156 | static void normalize_protected_variable(char *varname TSRMLS_DC) | ||
| 157 | { | ||
| 158 | char *s=varname, *index=NULL, *indexend=NULL, *p; | ||
| 159 | |||
| 160 | /* overjump leading space */ | ||
| 161 | while (*s == ' ') { | ||
| 162 | s++; | ||
| 163 | } | ||
| 164 | |||
| 165 | /* and remove it */ | ||
| 166 | if (s != varname) { | ||
| 167 | memmove(varname, s, strlen(s)+1); | ||
| 168 | } | ||
| 169 | |||
| 170 | for (p=varname; *p && *p != '['; p++) { | ||
| 171 | switch(*p) { | ||
| 172 | case ' ': | ||
| 173 | case '.': | ||
| 174 | *p='_'; | ||
| 175 | break; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | /* find index */ | ||
| 180 | index = strchr(varname, '['); | ||
| 181 | if (index) { | ||
| 182 | index++; | ||
| 183 | s=index; | ||
| 184 | } else { | ||
| 185 | return; | ||
| 186 | } | ||
| 187 | |||
| 188 | /* done? */ | ||
| 189 | while (index) { | ||
| 190 | |||
| 191 | while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') { | ||
| 192 | index++; | ||
| 193 | } | ||
| 194 | indexend = strchr(index, ']'); | ||
| 195 | indexend = indexend ? indexend + 1 : index + strlen(index); | ||
| 196 | |||
| 197 | if (s != index) { | ||
| 198 | memmove(s, index, strlen(index)+1); | ||
| 199 | s += indexend-index; | ||
| 200 | } else { | ||
| 201 | s = indexend; | ||
| 202 | } | ||
| 203 | |||
| 204 | if (*s == '[') { | ||
| 205 | s++; | ||
| 206 | index = s; | ||
| 207 | } else { | ||
| 208 | index = NULL; | ||
| 209 | } | ||
| 210 | } | ||
| 211 | *s++='\0'; | ||
| 212 | } | ||
| 213 | |||
| 214 | |||
| 215 | static void add_protected_variable(char *varname TSRMLS_DC) | ||
| 216 | { | ||
| 217 | int dummy=1; | ||
| 218 | |||
| 219 | normalize_protected_variable(varname TSRMLS_CC); | ||
| 220 | zend_hash_add(&PG(rfc1867_protected_variables), varname, strlen(varname)+1, &dummy, sizeof(int), NULL); | ||
| 221 | } | ||
| 222 | |||
| 223 | |||
| 224 | static zend_bool is_protected_variable(char *varname TSRMLS_DC) | ||
| 225 | { | ||
| 226 | normalize_protected_variable(varname TSRMLS_CC); | ||
| 227 | return zend_hash_exists(&PG(rfc1867_protected_variables), varname, strlen(varname)+1); | ||
| 228 | } | ||
| 229 | |||
| 230 | |||
| 231 | static void safe_php_register_variable(char *var, char *strval, zval *track_vars_array, zend_bool override_protection TSRMLS_DC) | ||
| 232 | { | ||
| 233 | if (override_protection || !is_protected_variable(var TSRMLS_CC)) { | ||
| 234 | php_register_variable(var, strval, track_vars_array TSRMLS_CC); | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | |||
| 239 | static void safe_php_register_variable_ex(char *var, zval *val, zval *track_vars_array, zend_bool override_protection TSRMLS_DC) | ||
| 240 | { | ||
| 241 | if (override_protection || !is_protected_variable(var TSRMLS_CC)) { | ||
| 242 | php_register_variable_ex(var, val, track_vars_array TSRMLS_CC); | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | |||
| 247 | static void register_http_post_files_variable(char *strvar, char *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC) | ||
| 248 | { | ||
| 249 | #if PHP_VERSION_ID < 50400 | ||
| 250 | int register_globals = PG(register_globals); | ||
| 251 | |||
| 252 | PG(register_globals) = 0; | ||
| 253 | #endif | ||
| 254 | safe_php_register_variable(strvar, val, http_post_files, override_protection TSRMLS_CC); | ||
| 255 | #if PHP_VERSION_ID < 50400 | ||
| 256 | PG(register_globals) = register_globals; | ||
| 257 | #endif | ||
| 258 | } | ||
| 259 | |||
| 260 | |||
| 261 | static void register_http_post_files_variable_ex(char *var, zval *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC) | ||
| 262 | { | ||
| 263 | #if PHP_VERSION_ID < 50400 | ||
| 264 | int register_globals = PG(register_globals); | ||
| 265 | |||
| 266 | PG(register_globals) = 0; | ||
| 267 | #endif | ||
| 268 | safe_php_register_variable_ex(var, val, http_post_files, override_protection TSRMLS_CC); | ||
| 269 | #if PHP_VERSION_ID < 50400 | ||
| 270 | PG(register_globals) = register_globals; | ||
| 271 | #endif | ||
| 272 | } | ||
| 273 | |||
| 274 | /* | ||
| 275 | * Following code is based on apache_multipart_buffer.c from libapreq-0.33 package. | ||
| 276 | * | ||
| 277 | */ | ||
| 278 | |||
| 279 | #define FILLUNIT (1024 * 5) | ||
| 280 | |||
| 281 | typedef struct { | ||
| 282 | |||
| 283 | /* read buffer */ | ||
| 284 | char *buffer; | ||
| 285 | char *buf_begin; | ||
| 286 | int bufsize; | ||
| 287 | int bytes_in_buffer; | ||
| 288 | |||
| 289 | /* boundary info */ | ||
| 290 | char *boundary; | ||
| 291 | char *boundary_next; | ||
| 292 | int boundary_next_len; | ||
| 293 | |||
| 294 | } multipart_buffer; | ||
| 295 | |||
| 296 | |||
| 297 | typedef struct { | ||
| 298 | char *key; | ||
| 299 | char *value; | ||
| 300 | } mime_header_entry; | ||
| 301 | |||
| 302 | |||
| 303 | /* | ||
| 304 | fill up the buffer with client data. | ||
| 305 | returns number of bytes added to buffer. | ||
| 306 | */ | ||
| 307 | static int fill_buffer(multipart_buffer *self TSRMLS_DC) | ||
| 308 | { | ||
| 309 | int bytes_to_read, total_read = 0, actual_read = 0; | ||
| 310 | |||
| 311 | /* shift the existing data if necessary */ | ||
| 312 | if (self->bytes_in_buffer > 0 && self->buf_begin != self->buffer) { | ||
| 313 | memmove(self->buffer, self->buf_begin, self->bytes_in_buffer); | ||
| 314 | } | ||
| 315 | |||
| 316 | self->buf_begin = self->buffer; | ||
| 317 | |||
| 318 | /* calculate the free space in the buffer */ | ||
| 319 | bytes_to_read = self->bufsize - self->bytes_in_buffer; | ||
| 320 | |||
| 321 | /* read the required number of bytes */ | ||
| 322 | while (bytes_to_read > 0) { | ||
| 323 | |||
| 324 | char *buf = self->buffer + self->bytes_in_buffer; | ||
| 325 | |||
| 326 | actual_read = sapi_module.read_post(buf, bytes_to_read TSRMLS_CC); | ||
| 327 | |||
| 328 | /* update the buffer length */ | ||
| 329 | if (actual_read > 0) { | ||
| 330 | self->bytes_in_buffer += actual_read; | ||
| 331 | SG(read_post_bytes) += actual_read; | ||
| 332 | total_read += actual_read; | ||
| 333 | bytes_to_read -= actual_read; | ||
| 334 | } else { | ||
| 335 | break; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | return total_read; | ||
| 340 | } | ||
| 341 | |||
| 342 | |||
| 343 | /* eof if we are out of bytes, or if we hit the final boundary */ | ||
| 344 | static int multipart_buffer_eof(multipart_buffer *self TSRMLS_DC) | ||
| 345 | { | ||
| 346 | if ( (self->bytes_in_buffer == 0 && fill_buffer(self TSRMLS_CC) < 1) ) { | ||
| 347 | return 1; | ||
| 348 | } else { | ||
| 349 | return 0; | ||
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | |||
| 354 | /* create new multipart_buffer structure */ | ||
| 355 | static multipart_buffer *multipart_buffer_new(char *boundary, int boundary_len) | ||
| 356 | { | ||
| 357 | multipart_buffer *self = (multipart_buffer *) ecalloc(1, sizeof(multipart_buffer)); | ||
| 358 | |||
| 359 | int minsize = boundary_len + 6; | ||
| 360 | if (minsize < FILLUNIT) minsize = FILLUNIT; | ||
| 361 | |||
| 362 | self->buffer = (char *) ecalloc(1, minsize + 1); | ||
| 363 | self->bufsize = minsize; | ||
| 364 | |||
| 365 | self->boundary = (char *) ecalloc(1, boundary_len + 3); | ||
| 366 | sprintf(self->boundary, "--%s", boundary); | ||
| 367 | |||
| 368 | self->boundary_next = (char *) ecalloc(1, boundary_len + 4); | ||
| 369 | sprintf(self->boundary_next, "\n--%s", boundary); | ||
| 370 | self->boundary_next_len = boundary_len + 3; | ||
| 371 | |||
| 372 | self->buf_begin = self->buffer; | ||
| 373 | self->bytes_in_buffer = 0; | ||
| 374 | |||
| 375 | return self; | ||
| 376 | } | ||
| 377 | |||
| 378 | |||
| 379 | /* | ||
| 380 | gets the next CRLF terminated line from the input buffer. | ||
| 381 | if it doesn't find a CRLF, and the buffer isn't completely full, returns | ||
| 382 | NULL; otherwise, returns the beginning of the null-terminated line, | ||
| 383 | minus the CRLF. | ||
| 384 | |||
| 385 | note that we really just look for LF terminated lines. this works | ||
| 386 | around a bug in internet explorer for the macintosh which sends mime | ||
| 387 | boundaries that are only LF terminated when you use an image submit | ||
| 388 | button in a multipart/form-data form. | ||
| 389 | */ | ||
| 390 | static char *next_line(multipart_buffer *self) | ||
| 391 | { | ||
| 392 | /* look for LF in the data */ | ||
| 393 | char* line = self->buf_begin; | ||
| 394 | char* ptr = memchr(self->buf_begin, '\n', self->bytes_in_buffer); | ||
| 395 | |||
| 396 | if (ptr) { /* LF found */ | ||
| 397 | |||
| 398 | /* terminate the string, remove CRLF */ | ||
| 399 | if ((ptr - line) > 0 && *(ptr-1) == '\r') { | ||
| 400 | *(ptr-1) = 0; | ||
| 401 | } else { | ||
| 402 | *ptr = 0; | ||
| 403 | } | ||
| 404 | |||
| 405 | /* bump the pointer */ | ||
| 406 | self->buf_begin = ptr + 1; | ||
| 407 | self->bytes_in_buffer -= (self->buf_begin - line); | ||
| 408 | |||
| 409 | } else { /* no LF found */ | ||
| 410 | |||
| 411 | /* buffer isn't completely full, fail */ | ||
| 412 | if (self->bytes_in_buffer < self->bufsize) { | ||
| 413 | return NULL; | ||
| 414 | } | ||
| 415 | /* return entire buffer as a partial line */ | ||
| 416 | line[self->bufsize] = 0; | ||
| 417 | self->buf_begin = ptr; | ||
| 418 | self->bytes_in_buffer = 0; | ||
| 419 | } | ||
| 420 | |||
| 421 | return line; | ||
| 422 | } | ||
| 423 | |||
| 424 | |||
| 425 | /* returns the next CRLF terminated line from the client */ | ||
| 426 | static char *get_line(multipart_buffer *self TSRMLS_DC) | ||
| 427 | { | ||
| 428 | char* ptr = next_line(self); | ||
| 429 | |||
| 430 | if (!ptr) { | ||
| 431 | fill_buffer(self TSRMLS_CC); | ||
| 432 | ptr = next_line(self); | ||
| 433 | } | ||
| 434 | |||
| 435 | return ptr; | ||
| 436 | } | ||
| 437 | |||
| 438 | |||
| 439 | /* Free header entry */ | ||
| 440 | static void php_free_hdr_entry(mime_header_entry *h) | ||
| 441 | { | ||
| 442 | if (h->key) { | ||
| 443 | efree(h->key); | ||
| 444 | } | ||
| 445 | if (h->value) { | ||
| 446 | efree(h->value); | ||
| 447 | } | ||
| 448 | } | ||
| 449 | |||
| 450 | |||
| 451 | /* finds a boundary */ | ||
| 452 | static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC) | ||
| 453 | { | ||
| 454 | char *line; | ||
| 455 | |||
| 456 | /* loop thru lines */ | ||
| 457 | while( (line = get_line(self TSRMLS_CC)) ) | ||
| 458 | { | ||
| 459 | /* finished if we found the boundary */ | ||
| 460 | if (!strcmp(line, boundary)) { | ||
| 461 | return 1; | ||
| 462 | } | ||
| 463 | } | ||
| 464 | |||
| 465 | /* didn't find the boundary */ | ||
| 466 | return 0; | ||
| 467 | } | ||
| 468 | |||
| 469 | |||
| 470 | /* parse headers */ | ||
| 471 | static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC) | ||
| 472 | { | ||
| 473 | char *line; | ||
| 474 | mime_header_entry prev_entry, entry; | ||
| 475 | int prev_len, cur_len; | ||
| 476 | |||
| 477 | /* didn't find boundary, abort */ | ||
| 478 | if (!find_boundary(self, self->boundary TSRMLS_CC)) { | ||
| 479 | return 0; | ||
| 480 | } | ||
| 481 | |||
| 482 | /* get lines of text, or CRLF_CRLF */ | ||
| 483 | |||
| 484 | while( (line = get_line(self TSRMLS_CC)) && strlen(line) > 0 ) | ||
| 485 | { | ||
| 486 | /* add header to table */ | ||
| 487 | |||
| 488 | char *key = line; | ||
| 489 | char *value = NULL; | ||
| 490 | |||
| 491 | /* space in the beginning means same header */ | ||
| 492 | if (!isspace(line[0])) { | ||
| 493 | value = strchr(line, ':'); | ||
| 494 | } | ||
| 495 | |||
| 496 | if (value) { | ||
| 497 | *value = 0; | ||
| 498 | do { value++; } while(isspace(*value)); | ||
| 499 | |||
| 500 | entry.value = estrdup(value); | ||
| 501 | entry.key = estrdup(key); | ||
| 502 | |||
| 503 | } else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */ | ||
| 504 | |||
| 505 | prev_len = strlen(prev_entry.value); | ||
| 506 | cur_len = strlen(line); | ||
| 507 | |||
| 508 | entry.value = emalloc(prev_len + cur_len + 1); | ||
| 509 | memcpy(entry.value, prev_entry.value, prev_len); | ||
| 510 | memcpy(entry.value + prev_len, line, cur_len); | ||
| 511 | entry.value[cur_len + prev_len] = '\0'; | ||
| 512 | |||
| 513 | entry.key = estrdup(prev_entry.key); | ||
| 514 | |||
| 515 | zend_llist_remove_tail(header); | ||
| 516 | } else { | ||
| 517 | continue; | ||
| 518 | } | ||
| 519 | |||
| 520 | zend_llist_add_element(header, &entry); | ||
| 521 | prev_entry = entry; | ||
| 522 | } | ||
| 523 | |||
| 524 | return 1; | ||
| 525 | } | ||
| 526 | |||
| 527 | |||
| 528 | static char *php_mime_get_hdr_value(zend_llist header, char *key) | ||
| 529 | { | ||
| 530 | mime_header_entry *entry; | ||
| 531 | |||
| 532 | if (key == NULL) { | ||
| 533 | return NULL; | ||
| 534 | } | ||
| 535 | |||
| 536 | entry = zend_llist_get_first(&header); | ||
| 537 | while (entry) { | ||
| 538 | if (!strcasecmp(entry->key, key)) { | ||
| 539 | return entry->value; | ||
| 540 | } | ||
| 541 | entry = zend_llist_get_next(&header); | ||
| 542 | } | ||
| 543 | |||
| 544 | return NULL; | ||
| 545 | } | ||
| 546 | |||
| 547 | |||
| 548 | static char *php_ap_getword(char **line, char stop) | ||
| 549 | { | ||
| 550 | char *pos = *line, quote; | ||
| 551 | char *res; | ||
| 552 | |||
| 553 | while (*pos && *pos != stop) { | ||
| 554 | |||
| 555 | if ((quote = *pos) == '"' || quote == '\'') { | ||
| 556 | ++pos; | ||
| 557 | while (*pos && *pos != quote) { | ||
| 558 | if (*pos == '\\' && pos[1] && pos[1] == quote) { | ||
| 559 | pos += 2; | ||
| 560 | } else { | ||
| 561 | ++pos; | ||
| 562 | } | ||
| 563 | } | ||
| 564 | if (*pos) { | ||
| 565 | ++pos; | ||
| 566 | } | ||
| 567 | } else ++pos; | ||
| 568 | |||
| 569 | } | ||
| 570 | if (*pos == '\0') { | ||
| 571 | res = estrdup(*line); | ||
| 572 | *line += strlen(*line); | ||
| 573 | return res; | ||
| 574 | } | ||
| 575 | |||
| 576 | res = estrndup(*line, pos - *line); | ||
| 577 | |||
| 578 | while (*pos == stop) { | ||
| 579 | ++pos; | ||
| 580 | } | ||
| 581 | |||
| 582 | *line = pos; | ||
| 583 | return res; | ||
| 584 | } | ||
| 585 | |||
| 586 | |||
| 587 | static char *substring_conf(char *start, int len, char quote TSRMLS_DC) | ||
| 588 | { | ||
| 589 | char *result = emalloc(len + 2); | ||
| 590 | char *resp = result; | ||
| 591 | int i; | ||
| 592 | |||
| 593 | for (i = 0; i < len; ++i) { | ||
| 594 | if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) { | ||
| 595 | *resp++ = start[++i]; | ||
| 596 | } else { | ||
| 597 | #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) | ||
| 598 | if (php_mb_encoding_translation(TSRMLS_C)) { | ||
| 599 | size_t j = php_mb_gpc_mbchar_bytes(start+i TSRMLS_CC); | ||
| 600 | while (j-- > 0 && i < len) { | ||
| 601 | *resp++ = start[i++]; | ||
| 602 | } | ||
| 603 | --i; | ||
| 604 | } else { | ||
| 605 | *resp++ = start[i]; | ||
| 606 | } | ||
| 607 | #else | ||
| 608 | *resp++ = start[i]; | ||
| 609 | #endif | ||
| 610 | } | ||
| 611 | } | ||
| 612 | |||
| 613 | *resp++ = '\0'; | ||
| 614 | return result; | ||
| 615 | } | ||
| 616 | |||
| 617 | |||
| 618 | static char *php_ap_getword_conf(char **line TSRMLS_DC) | ||
| 619 | { | ||
| 620 | char *str = *line, *strend, *res, quote; | ||
| 621 | |||
| 622 | #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) | ||
| 623 | if (php_mb_encoding_translation(TSRMLS_C)) { | ||
| 624 | int len=strlen(str); | ||
| 625 | php_mb_gpc_encoding_detector(&str, &len, 1, NULL TSRMLS_CC); | ||
| 626 | } | ||
| 627 | #endif | ||
| 628 | |||
| 629 | while (*str && isspace(*str)) { | ||
| 630 | ++str; | ||
| 631 | } | ||
| 632 | |||
| 633 | if (!*str) { | ||
| 634 | *line = str; | ||
| 635 | return estrdup(""); | ||
| 636 | } | ||
| 637 | |||
| 638 | if ((quote = *str) == '"' || quote == '\'') { | ||
| 639 | strend = str + 1; | ||
| 640 | look_for_quote: | ||
| 641 | while (*strend && *strend != quote) { | ||
| 642 | if (*strend == '\\' && strend[1] && strend[1] == quote) { | ||
| 643 | strend += 2; | ||
| 644 | } else { | ||
| 645 | ++strend; | ||
| 646 | } | ||
| 647 | } | ||
| 648 | if (*strend && *strend == quote) { | ||
| 649 | char p = *(strend + 1); | ||
| 650 | if (p != '\r' && p != '\n' && p != '\0') { | ||
| 651 | strend++; | ||
| 652 | goto look_for_quote; | ||
| 653 | } | ||
| 654 | } | ||
| 655 | |||
| 656 | res = substring_conf(str + 1, strend - str - 1, quote TSRMLS_CC); | ||
| 657 | |||
| 658 | if (*strend == quote) { | ||
| 659 | ++strend; | ||
| 660 | } | ||
| 661 | |||
| 662 | } else { | ||
| 663 | |||
| 664 | strend = str; | ||
| 665 | while (*strend && !isspace(*strend)) { | ||
| 666 | ++strend; | ||
| 667 | } | ||
| 668 | res = substring_conf(str, strend - str, 0 TSRMLS_CC); | ||
| 669 | } | ||
| 670 | |||
| 671 | while (*strend && isspace(*strend)) { | ||
| 672 | ++strend; | ||
| 673 | } | ||
| 674 | |||
| 675 | *line = strend; | ||
| 676 | return res; | ||
| 677 | } | ||
| 678 | |||
| 679 | |||
| 680 | /* | ||
| 681 | search for a string in a fixed-length byte string. | ||
| 682 | if partial is true, partial matches are allowed at the end of the buffer. | ||
| 683 | returns NULL if not found, or a pointer to the start of the first match. | ||
| 684 | */ | ||
| 685 | static void *php_ap_memstr(char *haystack, int haystacklen, char *needle, int needlen, int partial) | ||
| 686 | { | ||
| 687 | int len = haystacklen; | ||
| 688 | char *ptr = haystack; | ||
| 689 | |||
| 690 | /* iterate through first character matches */ | ||
| 691 | while( (ptr = memchr(ptr, needle[0], len)) ) { | ||
| 692 | |||
| 693 | /* calculate length after match */ | ||
| 694 | len = haystacklen - (ptr - (char *)haystack); | ||
| 695 | |||
| 696 | /* done if matches up to capacity of buffer */ | ||
| 697 | if (memcmp(needle, ptr, needlen < len ? needlen : len) == 0 && (partial || len >= needlen)) { | ||
| 698 | break; | ||
| 699 | } | ||
| 700 | |||
| 701 | /* next character */ | ||
| 702 | ptr++; len--; | ||
| 703 | } | ||
| 704 | |||
| 705 | return ptr; | ||
| 706 | } | ||
| 707 | |||
| 708 | |||
| 709 | /* read until a boundary condition */ | ||
| 710 | static int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes, int *end TSRMLS_DC) | ||
| 711 | { | ||
| 712 | int len, max; | ||
| 713 | char *bound; | ||
| 714 | |||
| 715 | /* fill buffer if needed */ | ||
| 716 | if (bytes > self->bytes_in_buffer) { | ||
| 717 | fill_buffer(self TSRMLS_CC); | ||
| 718 | } | ||
| 719 | |||
| 720 | /* look for a potential boundary match, only read data up to that point */ | ||
| 721 | if ((bound = php_ap_memstr(self->buf_begin, self->bytes_in_buffer, self->boundary_next, self->boundary_next_len, 1))) { | ||
| 722 | max = bound - self->buf_begin; | ||
| 723 | if (end && php_ap_memstr(self->buf_begin, self->bytes_in_buffer, self->boundary_next, self->boundary_next_len, 0)) { | ||
| 724 | *end = 1; | ||
| 725 | } | ||
| 726 | } else { | ||
| 727 | max = self->bytes_in_buffer; | ||
| 728 | } | ||
| 729 | |||
| 730 | /* maximum number of bytes we are reading */ | ||
| 731 | len = max < bytes-1 ? max : bytes-1; | ||
| 732 | |||
| 733 | /* if we read any data... */ | ||
| 734 | if (len > 0) { | ||
| 735 | |||
| 736 | /* copy the data */ | ||
| 737 | memcpy(buf, self->buf_begin, len); | ||
| 738 | buf[len] = 0; | ||
| 739 | |||
| 740 | if (bound && len > 0 && buf[len-1] == '\r') { | ||
| 741 | buf[--len] = 0; | ||
| 742 | } | ||
| 743 | |||
| 744 | /* update the buffer */ | ||
| 745 | self->bytes_in_buffer -= len; | ||
| 746 | self->buf_begin += len; | ||
| 747 | } | ||
| 748 | |||
| 749 | return len; | ||
| 750 | } | ||
| 751 | |||
| 752 | |||
| 753 | /* | ||
| 754 | XXX: this is horrible memory-usage-wise, but we only expect | ||
| 755 | to do this on small pieces of form data. | ||
| 756 | */ | ||
| 757 | static char *multipart_buffer_read_body(multipart_buffer *self, unsigned int *len TSRMLS_DC) | ||
| 758 | { | ||
| 759 | char buf[FILLUNIT], *out=NULL; | ||
| 760 | int total_bytes=0, read_bytes=0; | ||
| 761 | |||
| 762 | while((read_bytes = multipart_buffer_read(self, buf, sizeof(buf), NULL TSRMLS_CC))) { | ||
| 763 | out = erealloc(out, total_bytes + read_bytes + 1); | ||
| 764 | memcpy(out + total_bytes, buf, read_bytes); | ||
| 765 | total_bytes += read_bytes; | ||
| 766 | } | ||
| 767 | |||
| 768 | if (out) out[total_bytes] = '\0'; | ||
| 769 | *len = total_bytes; | ||
| 770 | |||
| 771 | return out; | ||
| 772 | } | ||
| 773 | |||
| 774 | |||
| 775 | /* | ||
| 776 | * The combined READER/HANDLER | ||
| 777 | * | ||
| 778 | */ | ||
| 779 | |||
| 780 | SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) | ||
| 781 | { | ||
| 782 | char *boundary, *s=NULL, *boundary_end = NULL, *start_arr=NULL, *array_index=NULL; | ||
| 783 | char *temp_filename=NULL, *lbuf=NULL, *abuf=NULL; | ||
| 784 | int boundary_len=0, total_bytes=0, cancel_upload=0, is_arr_upload=0, array_len=0; | ||
| 785 | int max_file_size=0, skip_upload=0, anonindex=0, is_anonymous; | ||
| 786 | zval *http_post_files=NULL; HashTable *uploaded_files=NULL; | ||
| 787 | #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) | ||
| 788 | int str_len = 0, num_vars = 0, num_vars_max = 2*10, *len_list = NULL; | ||
| 789 | char **val_list = NULL; | ||
| 790 | #endif | ||
| 791 | multipart_buffer *mbuff; | ||
| 792 | zval *array_ptr = (zval *) arg; | ||
| 793 | int fd=-1; | ||
| 794 | zend_llist header; | ||
| 795 | void *event_extra_data = NULL; | ||
| 796 | #if PHP_VERSION_ID >= 50302 || (PHP_VERSION_ID >= 50212 && PHP_VERSION_ID < 50300) | ||
| 797 | int upload_cnt = INI_INT("max_file_uploads"); | ||
| 798 | #endif | ||
| 799 | |||
| 800 | SDEBUG("suhosin_rfc1867_handler"); | ||
| 801 | |||
| 802 | if (SG(request_info).content_length > SG(post_max_size)) { | ||
| 803 | sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size)); | ||
| 804 | return; | ||
| 805 | } | ||
| 806 | |||
| 807 | /* Get the boundary */ | ||
| 808 | boundary = strstr(content_type_dup, "boundary"); | ||
| 809 | if (!boundary) { | ||
| 810 | int content_type_len = strlen(content_type_dup); | ||
| 811 | char *content_type_lcase = estrndup(content_type_dup, content_type_len); | ||
| 812 | |||
| 813 | php_strtolower(content_type_lcase, content_type_len); | ||
| 814 | boundary = strstr(content_type_lcase, "boundary"); | ||
| 815 | if (boundary) { | ||
| 816 | boundary = content_type_dup + (boundary - content_type_lcase); | ||
| 817 | } | ||
| 818 | efree(content_type_lcase); | ||
| 819 | } | ||
| 820 | |||
| 821 | if (!boundary || !(boundary=strchr(boundary, '='))) { | ||
| 822 | sapi_module.sapi_error(E_WARNING, "Missing boundary in multipart/form-data POST data"); | ||
| 823 | return; | ||
| 824 | } | ||
| 825 | |||
| 826 | boundary++; | ||
| 827 | boundary_len = strlen(boundary); | ||
| 828 | |||
| 829 | if (boundary[0] == '"') { | ||
| 830 | boundary++; | ||
| 831 | boundary_end = strchr(boundary, '"'); | ||
| 832 | if (!boundary_end) { | ||
| 833 | sapi_module.sapi_error(E_WARNING, "Invalid boundary in multipart/form-data POST data"); | ||
| 834 | return; | ||
| 835 | } | ||
| 836 | } else { | ||
| 837 | /* search for the end of the boundary */ | ||
| 838 | boundary_end = strchr(boundary, ','); | ||
| 839 | } | ||
| 840 | if (boundary_end) { | ||
| 841 | boundary_end[0] = '\0'; | ||
| 842 | boundary_len = boundary_end-boundary; | ||
| 843 | } | ||
| 844 | |||
| 845 | /* Initialize the buffer */ | ||
| 846 | if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) { | ||
| 847 | sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer"); | ||
| 848 | return; | ||
| 849 | } | ||
| 850 | |||
| 851 | /* Initialize $_FILES[] */ | ||
| 852 | zend_hash_init(&PG(rfc1867_protected_variables), 5, NULL, NULL, 0); | ||
| 853 | |||
| 854 | ALLOC_HASHTABLE(uploaded_files); | ||
| 855 | zend_hash_init(uploaded_files, 5, NULL, (dtor_func_t) free_estring, 0); | ||
| 856 | SG(rfc1867_uploaded_files) = uploaded_files; | ||
| 857 | |||
| 858 | ALLOC_ZVAL(http_post_files); | ||
| 859 | array_init(http_post_files); | ||
| 860 | INIT_PZVAL(http_post_files); | ||
| 861 | PG(http_globals)[TRACK_VARS_FILES] = http_post_files; | ||
| 862 | |||
| 863 | #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) | ||
| 864 | if (php_mb_encoding_translation(TSRMLS_C)) { | ||
| 865 | val_list = (char **)ecalloc(num_vars_max+2, sizeof(char *)); | ||
| 866 | len_list = (int *)ecalloc(num_vars_max+2, sizeof(int)); | ||
| 867 | } | ||
| 868 | #endif | ||
| 869 | zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0); | ||
| 870 | |||
| 871 | |||
| 872 | { | ||
| 873 | multipart_event_start event_start; | ||
| 874 | |||
| 875 | event_start.content_length = SG(request_info).content_length; | ||
| 876 | if (suhosin_rfc1867_filter(MULTIPART_EVENT_START, &event_start, &event_extra_data TSRMLS_CC) == FAILURE) { | ||
| 877 | goto fileupload_done; | ||
| 878 | } | ||
| 879 | } | ||
| 880 | |||
| 881 | while (!multipart_buffer_eof(mbuff TSRMLS_CC)) | ||
| 882 | { | ||
| 883 | char buff[FILLUNIT]; | ||
| 884 | char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL; | ||
| 885 | size_t blen=0, wlen=0; | ||
| 886 | off_t offset; | ||
| 887 | |||
| 888 | zend_llist_clean(&header); | ||
| 889 | |||
| 890 | if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) { | ||
| 891 | goto fileupload_done; | ||
| 892 | } | ||
| 893 | |||
| 894 | if ((cd = php_mime_get_hdr_value(header, "Content-Disposition"))) { | ||
| 895 | char *pair=NULL; | ||
| 896 | int end=0; | ||
| 897 | |||
| 898 | while (isspace(*cd)) { | ||
| 899 | ++cd; | ||
| 900 | } | ||
| 901 | |||
| 902 | while (*cd && (pair = php_ap_getword(&cd, ';'))) | ||
| 903 | { | ||
| 904 | char *key=NULL, *word = pair; | ||
| 905 | |||
| 906 | while (isspace(*cd)) { | ||
| 907 | ++cd; | ||
| 908 | } | ||
| 909 | |||
| 910 | if (strchr(pair, '=')) { | ||
| 911 | key = php_ap_getword(&pair, '='); | ||
| 912 | |||
| 913 | if (!strcasecmp(key, "name")) { | ||
| 914 | if (param) { | ||
| 915 | efree(param); | ||
| 916 | } | ||
| 917 | param = php_ap_getword_conf(&pair TSRMLS_CC); | ||
| 918 | } else if (!strcasecmp(key, "filename")) { | ||
| 919 | if (filename) { | ||
| 920 | efree(filename); | ||
| 921 | } | ||
| 922 | filename = php_ap_getword_conf(&pair TSRMLS_CC); | ||
| 923 | } | ||
| 924 | } | ||
| 925 | if (key) { | ||
| 926 | efree(key); | ||
| 927 | } | ||
| 928 | efree(word); | ||
| 929 | } | ||
| 930 | |||
| 931 | /* Normal form variable, safe to read all data into memory */ | ||
| 932 | if (!filename && param) { | ||
| 933 | |||
| 934 | unsigned int value_len; | ||
| 935 | char *value = multipart_buffer_read_body(mbuff, &value_len TSRMLS_CC); | ||
| 936 | unsigned int new_val_len; /* Dummy variable */ | ||
| 937 | |||
| 938 | if (!value) { | ||
| 939 | value = estrdup(""); | ||
| 940 | } | ||
| 941 | SDEBUG("calling inputfilter"); | ||
| 942 | if (suhosin_input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC) == 0) { | ||
| 943 | SUHOSIN_G(abort_request)=1; | ||
| 944 | efree(param); | ||
| 945 | efree(value); | ||
| 946 | continue; | ||
| 947 | } | ||
| 948 | |||
| 949 | #ifdef ZEND_ENGINE_2 | ||
| 950 | if (sapi_module.input_filter(PARSE_POST, param, &value, new_val_len, &new_val_len TSRMLS_CC)) { | ||
| 951 | #endif | ||
| 952 | { | ||
| 953 | multipart_event_formdata event_formdata; | ||
| 954 | size_t newlength = 0; | ||
| 955 | |||
| 956 | event_formdata.post_bytes_processed = SG(read_post_bytes); | ||
| 957 | event_formdata.name = param; | ||
| 958 | event_formdata.value = &value; | ||
| 959 | event_formdata.length = new_val_len; | ||
| 960 | event_formdata.newlength = &newlength; | ||
| 961 | if (suhosin_rfc1867_filter(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC) == FAILURE) { | ||
| 962 | efree(param); | ||
| 963 | efree(value); | ||
| 964 | continue; | ||
| 965 | } | ||
| 966 | new_val_len = newlength; | ||
| 967 | } | ||
| 968 | |||
| 969 | #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) | ||
| 970 | if (php_mb_encoding_translation(TSRMLS_C)) { | ||
| 971 | php_mb_gpc_stack_variable(param, value, &val_list, &len_list, | ||
| 972 | &num_vars, &num_vars_max TSRMLS_CC); | ||
| 973 | } else { | ||
| 974 | safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); | ||
| 975 | } | ||
| 976 | #else | ||
| 977 | safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); | ||
| 978 | #endif | ||
| 979 | #ifdef ZEND_ENGINE_2 | ||
| 980 | } else { | ||
| 981 | multipart_event_formdata event_formdata; | ||
| 982 | |||
| 983 | event_formdata.post_bytes_processed = SG(read_post_bytes); | ||
| 984 | event_formdata.name = param; | ||
| 985 | event_formdata.value = &value; | ||
| 986 | event_formdata.length = value_len; | ||
| 987 | event_formdata.newlength = NULL; | ||
| 988 | suhosin_rfc1867_filter(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC); | ||
| 989 | } | ||
| 990 | #endif | ||
| 991 | if (!strcasecmp(param, "MAX_FILE_SIZE")) { | ||
| 992 | max_file_size = atol(value); | ||
| 993 | } | ||
| 994 | |||
| 995 | efree(param); | ||
| 996 | efree(value); | ||
| 997 | continue; | ||
| 998 | } | ||
| 999 | |||
| 1000 | /* If file_uploads=off, skip the file part */ | ||
| 1001 | if (!PG(file_uploads)) { | ||
| 1002 | skip_upload = 1; | ||
| 1003 | } | ||
| 1004 | #if PHP_VERSION_ID >= 50302 || (PHP_VERSION_ID >= 50212 && PHP_VERSION_ID < 50300) | ||
| 1005 | else if (upload_cnt <= 0) { | ||
| 1006 | skip_upload = 1; | ||
| 1007 | sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); | ||
| 1008 | } | ||
| 1009 | #endif | ||
| 1010 | |||
| 1011 | /* Return with an error if the posted data is garbled */ | ||
| 1012 | if (!param && !filename) { | ||
| 1013 | sapi_module.sapi_error(E_WARNING, "File Upload Mime headers garbled"); | ||
| 1014 | goto fileupload_done; | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | if (!param) { | ||
| 1018 | is_anonymous = 1; | ||
| 1019 | param = emalloc(MAX_SIZE_ANONNAME); | ||
| 1020 | snprintf(param, MAX_SIZE_ANONNAME, "%u", anonindex++); | ||
| 1021 | } else { | ||
| 1022 | is_anonymous = 0; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | /* New Rule: never repair potential malicious user input */ | ||
| 1026 | if (!skip_upload) { | ||
| 1027 | char *tmp = param; | ||
| 1028 | long c = 0; | ||
| 1029 | |||
| 1030 | while (*tmp) { | ||
| 1031 | if (*tmp == '[') { | ||
| 1032 | c++; | ||
| 1033 | } else if (*tmp == ']') { | ||
| 1034 | c--; | ||
| 1035 | if (tmp[1] && tmp[1] != '[') { | ||
| 1036 | skip_upload = 1; | ||
| 1037 | break; | ||
| 1038 | } | ||
| 1039 | } | ||
| 1040 | if (c < 0) { | ||
| 1041 | skip_upload = 1; | ||
| 1042 | break; | ||
| 1043 | } | ||
| 1044 | tmp++; | ||
| 1045 | } | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | total_bytes = cancel_upload = 0; | ||
| 1049 | |||
| 1050 | if (!skip_upload) { | ||
| 1051 | multipart_event_file_start event_file_start; | ||
| 1052 | |||
| 1053 | /* Handle file */ | ||
| 1054 | fd = php_open_temporary_fd(PG(upload_tmp_dir), "php", &temp_filename TSRMLS_CC); | ||
| 1055 | #if PHP_VERSION_ID >= 50302 || (PHP_VERSION_ID >= 50212 && PHP_VERSION_ID < 50300) | ||
| 1056 | upload_cnt--; | ||
| 1057 | #endif | ||
| 1058 | if (fd==-1) { | ||
| 1059 | sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file"); | ||
| 1060 | cancel_upload = UPLOAD_ERROR_E; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | event_file_start.post_bytes_processed = SG(read_post_bytes); | ||
| 1064 | event_file_start.name = param; | ||
| 1065 | event_file_start.filename = &filename; | ||
| 1066 | if (suhosin_rfc1867_filter(MULTIPART_EVENT_FILE_START, &event_file_start, &event_extra_data TSRMLS_CC) == FAILURE) { | ||
| 1067 | if (temp_filename) { | ||
| 1068 | if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ | ||
| 1069 | close(fd); | ||
| 1070 | unlink(temp_filename); | ||
| 1071 | } | ||
| 1072 | efree(temp_filename); | ||
| 1073 | } | ||
| 1074 | temp_filename = NULL; | ||
| 1075 | efree(param); | ||
| 1076 | efree(filename); | ||
| 1077 | continue; | ||
| 1078 | } | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | |||
| 1082 | if (skip_upload) { | ||
| 1083 | efree(param); | ||
| 1084 | efree(filename); | ||
| 1085 | continue; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | if(strlen(filename) == 0) { | ||
| 1089 | #if DEBUG_FILE_UPLOAD | ||
| 1090 | sapi_module.sapi_error(E_NOTICE, "No file uploaded"); | ||
| 1091 | #endif | ||
| 1092 | cancel_upload = UPLOAD_ERROR_D; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | offset = 0; | ||
| 1096 | end = 0; | ||
| 1097 | while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC))) | ||
| 1098 | { | ||
| 1099 | { | ||
| 1100 | multipart_event_file_data event_file_data; | ||
| 1101 | |||
| 1102 | event_file_data.post_bytes_processed = SG(read_post_bytes); | ||
| 1103 | event_file_data.offset = offset; | ||
| 1104 | event_file_data.data = buff; | ||
| 1105 | event_file_data.length = blen; | ||
| 1106 | event_file_data.newlength = &blen; | ||
| 1107 | if (suhosin_rfc1867_filter(MULTIPART_EVENT_FILE_DATA, &event_file_data, &event_extra_data TSRMLS_CC) == FAILURE) { | ||
| 1108 | cancel_upload = UPLOAD_ERROR_X; | ||
| 1109 | continue; | ||
| 1110 | } | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | |||
| 1114 | if (PG(upload_max_filesize) > 0 && total_bytes+blen > PG(upload_max_filesize)) { | ||
| 1115 | #if DEBUG_FILE_UPLOAD | ||
| 1116 | sapi_module.sapi_error(E_NOTICE, "upload_max_filesize of %ld bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename); | ||
| 1117 | #endif | ||
| 1118 | cancel_upload = UPLOAD_ERROR_A; | ||
| 1119 | } else if (max_file_size && (total_bytes+blen > max_file_size)) { | ||
| 1120 | #if DEBUG_FILE_UPLOAD | ||
| 1121 | sapi_module.sapi_error(E_NOTICE, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); | ||
| 1122 | #endif | ||
| 1123 | cancel_upload = UPLOAD_ERROR_B; | ||
| 1124 | } else if (blen > 0) { | ||
| 1125 | |||
| 1126 | wlen = write(fd, buff, blen); | ||
| 1127 | |||
| 1128 | if (wlen < blen) { | ||
| 1129 | #if DEBUG_FILE_UPLOAD | ||
| 1130 | sapi_module.sapi_error(E_NOTICE, "Only %d bytes were written, expected to write %d", wlen, blen); | ||
| 1131 | #endif | ||
| 1132 | cancel_upload = UPLOAD_ERROR_F; | ||
| 1133 | } else { | ||
| 1134 | total_bytes += wlen; | ||
| 1135 | } | ||
| 1136 | |||
| 1137 | offset += wlen; | ||
| 1138 | } | ||
| 1139 | } | ||
| 1140 | if (fd!=-1) { /* may not be initialized if file could not be created */ | ||
| 1141 | close(fd); | ||
| 1142 | } | ||
| 1143 | if (!cancel_upload && !end) { | ||
| 1144 | #if DEBUG_FILE_UPLOAD | ||
| 1145 | sapi_module.sapi_error(E_NOTICE, "Missing mime boundary at the end of the data for file %s", strlen(filename) > 0 ? filename : ""); | ||
| 1146 | #endif | ||
| 1147 | cancel_upload = UPLOAD_ERROR_C; | ||
| 1148 | } | ||
| 1149 | #if DEBUG_FILE_UPLOAD | ||
| 1150 | if(strlen(filename) > 0 && total_bytes == 0 && !cancel_upload) { | ||
| 1151 | sapi_module.sapi_error(E_WARNING, "Uploaded file size 0 - file [%s=%s] not saved", param, filename); | ||
| 1152 | cancel_upload = 5; | ||
| 1153 | } | ||
| 1154 | #endif | ||
| 1155 | |||
| 1156 | { | ||
| 1157 | multipart_event_file_end event_file_end; | ||
| 1158 | |||
| 1159 | event_file_end.post_bytes_processed = SG(read_post_bytes); | ||
| 1160 | event_file_end.temp_filename = temp_filename; | ||
| 1161 | event_file_end.cancel_upload = cancel_upload; | ||
| 1162 | if (suhosin_rfc1867_filter(MULTIPART_EVENT_FILE_END, &event_file_end, &event_extra_data TSRMLS_CC) == FAILURE) { | ||
| 1163 | cancel_upload = UPLOAD_ERROR_X; | ||
| 1164 | } | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | if (cancel_upload) { | ||
| 1168 | if (temp_filename) { | ||
| 1169 | if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ | ||
| 1170 | unlink(temp_filename); | ||
| 1171 | } | ||
| 1172 | efree(temp_filename); | ||
| 1173 | } | ||
| 1174 | temp_filename=""; | ||
| 1175 | } else { | ||
| 1176 | zend_hash_add(SG(rfc1867_uploaded_files), temp_filename, strlen(temp_filename) + 1, &temp_filename, sizeof(char *), NULL); | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | /* is_arr_upload is true when name of file upload field | ||
| 1180 | * ends in [.*] | ||
| 1181 | * start_arr is set to point to 1st [ | ||
| 1182 | */ | ||
| 1183 | is_arr_upload = (start_arr = strchr(param,'[')) && (param[strlen(param)-1] == ']'); | ||
| 1184 | |||
| 1185 | if (is_arr_upload) { | ||
| 1186 | array_len = strlen(start_arr); | ||
| 1187 | if (array_index) { | ||
| 1188 | efree(array_index); | ||
| 1189 | } | ||
| 1190 | array_index = estrndup(start_arr+1, array_len-2); | ||
| 1191 | } | ||
| 1192 | |||
| 1193 | /* Add $foo_name */ | ||
| 1194 | if (lbuf) { | ||
| 1195 | efree(lbuf); | ||
| 1196 | } | ||
| 1197 | lbuf = (char *) emalloc(strlen(param) + MAX_SIZE_OF_INDEX + 1); | ||
| 1198 | |||
| 1199 | if (is_arr_upload) { | ||
| 1200 | if (abuf) efree(abuf); | ||
| 1201 | abuf = estrndup(param, strlen(param)-array_len); | ||
| 1202 | sprintf(lbuf, "%s_name[%s]", abuf, array_index); | ||
| 1203 | } else { | ||
| 1204 | sprintf(lbuf, "%s_name", param); | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) | ||
| 1208 | if (php_mb_encoding_translation(TSRMLS_C)) { | ||
| 1209 | if (num_vars>=num_vars_max){ | ||
| 1210 | php_mb_gpc_realloc_buffer(&val_list, &len_list, &num_vars_max, | ||
| 1211 | 1 TSRMLS_CC); | ||
| 1212 | } | ||
| 1213 | val_list[num_vars] = filename; | ||
| 1214 | len_list[num_vars] = strlen(filename); | ||
| 1215 | num_vars++; | ||
| 1216 | if(php_mb_gpc_encoding_detector(val_list, len_list, num_vars, NULL TSRMLS_CC) == SUCCESS) { | ||
| 1217 | str_len = strlen(filename); | ||
| 1218 | php_mb_gpc_encoding_converter(&filename, &str_len, 1, NULL, NULL TSRMLS_CC); | ||
| 1219 | } | ||
| 1220 | s = php_mb_strrchr(filename, '\\' TSRMLS_CC); | ||
| 1221 | if ((tmp = php_mb_strrchr(filename, '/' TSRMLS_CC)) > s) { | ||
| 1222 | s = tmp; | ||
| 1223 | } | ||
| 1224 | num_vars--; | ||
| 1225 | goto filedone; | ||
| 1226 | } | ||
| 1227 | #endif | ||
| 1228 | /* The \ check should technically be needed for win32 systems only where | ||
| 1229 | * it is a valid path separator. However, IE in all it's wisdom always sends | ||
| 1230 | * the full path of the file on the user's filesystem, which means that unless | ||
| 1231 | * the user does basename() they get a bogus file name. Until IE's user base drops | ||
| 1232 | * to nill or problem is fixed this code must remain enabled for all systems. | ||
| 1233 | */ | ||
| 1234 | s = strrchr(filename, '\\'); | ||
| 1235 | if ((tmp = strrchr(filename, '/')) > s) { | ||
| 1236 | s = tmp; | ||
| 1237 | } | ||
| 1238 | #ifdef PHP_WIN32 | ||
| 1239 | if (PG(magic_quotes_gpc)) { | ||
| 1240 | s = s ? s : filename; | ||
| 1241 | tmp = strrchr(s, '\''); | ||
| 1242 | s = tmp > s ? tmp : s; | ||
| 1243 | tmp = strrchr(s, '"'); | ||
| 1244 | s = tmp > s ? tmp : s; | ||
| 1245 | } | ||
| 1246 | #endif | ||
| 1247 | |||
| 1248 | #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) | ||
| 1249 | filedone: | ||
| 1250 | #endif | ||
| 1251 | |||
| 1252 | if (!is_anonymous) { | ||
| 1253 | if (s && s > filename) { | ||
| 1254 | safe_php_register_variable(lbuf, s+1, NULL, 0 TSRMLS_CC); | ||
| 1255 | } else { | ||
| 1256 | safe_php_register_variable(lbuf, filename, NULL, 0 TSRMLS_CC); | ||
| 1257 | } | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | /* Add $foo[name] */ | ||
| 1261 | if (is_arr_upload) { | ||
| 1262 | sprintf(lbuf, "%s[name][%s]", abuf, array_index); | ||
| 1263 | } else { | ||
| 1264 | sprintf(lbuf, "%s[name]", param); | ||
| 1265 | } | ||
| 1266 | if (s && s > filename) { | ||
| 1267 | register_http_post_files_variable(lbuf, s+1, http_post_files, 0 TSRMLS_CC); | ||
| 1268 | } else { | ||
| 1269 | register_http_post_files_variable(lbuf, filename, http_post_files, 0 TSRMLS_CC); | ||
| 1270 | } | ||
| 1271 | efree(filename); | ||
| 1272 | s = NULL; | ||
| 1273 | |||
| 1274 | /* Possible Content-Type: */ | ||
| 1275 | if (cancel_upload || !(cd = php_mime_get_hdr_value(header, "Content-Type"))) { | ||
| 1276 | cd = ""; | ||
| 1277 | } else { | ||
| 1278 | /* fix for Opera 6.01 */ | ||
| 1279 | s = strchr(cd, ';'); | ||
| 1280 | if (s != NULL) { | ||
| 1281 | *s = '\0'; | ||
| 1282 | } | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | /* Add $foo_type */ | ||
| 1286 | if (is_arr_upload) { | ||
| 1287 | sprintf(lbuf, "%s_type[%s]", abuf, array_index); | ||
| 1288 | } else { | ||
| 1289 | sprintf(lbuf, "%s_type", param); | ||
| 1290 | } | ||
| 1291 | if (!is_anonymous) { | ||
| 1292 | safe_php_register_variable(lbuf, cd, NULL, 0 TSRMLS_CC); | ||
| 1293 | } | ||
| 1294 | |||
| 1295 | /* Add $foo[type] */ | ||
| 1296 | if (is_arr_upload) { | ||
| 1297 | sprintf(lbuf, "%s[type][%s]", abuf, array_index); | ||
| 1298 | } else { | ||
| 1299 | sprintf(lbuf, "%s[type]", param); | ||
| 1300 | } | ||
| 1301 | register_http_post_files_variable(lbuf, cd, http_post_files, 0 TSRMLS_CC); | ||
| 1302 | |||
| 1303 | /* Restore Content-Type Header */ | ||
| 1304 | if (s != NULL) { | ||
| 1305 | *s = ';'; | ||
| 1306 | } | ||
| 1307 | s = ""; | ||
| 1308 | |||
| 1309 | { | ||
| 1310 | /* store temp_filename as-is (without magic_quotes_gpc-ing it, in case upload_tmp_dir | ||
| 1311 | * contains escapeable characters. escape only the variable name.) */ | ||
| 1312 | zval zfilename; | ||
| 1313 | |||
| 1314 | /* Initialize variables */ | ||
| 1315 | add_protected_variable(param TSRMLS_CC); | ||
| 1316 | |||
| 1317 | /* if param is of form xxx[.*] this will cut it to xxx */ | ||
| 1318 | if (!is_anonymous) { | ||
| 1319 | ZVAL_STRING(&zfilename, temp_filename, 1); | ||
| 1320 | safe_php_register_variable_ex(param, &zfilename, NULL, 1 TSRMLS_CC); | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | /* Add $foo[tmp_name] */ | ||
| 1324 | if (is_arr_upload) { | ||
| 1325 | sprintf(lbuf, "%s[tmp_name][%s]", abuf, array_index); | ||
| 1326 | } else { | ||
| 1327 | sprintf(lbuf, "%s[tmp_name]", param); | ||
| 1328 | } | ||
| 1329 | add_protected_variable(lbuf TSRMLS_CC); | ||
| 1330 | ZVAL_STRING(&zfilename, temp_filename, 1); | ||
| 1331 | register_http_post_files_variable_ex(lbuf, &zfilename, http_post_files, 1 TSRMLS_CC); | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | { | ||
| 1335 | zval file_size, error_type; | ||
| 1336 | |||
| 1337 | error_type.value.lval = cancel_upload; | ||
| 1338 | error_type.type = IS_LONG; | ||
| 1339 | |||
| 1340 | /* Add $foo[error] */ | ||
| 1341 | if (cancel_upload) { | ||
| 1342 | file_size.value.lval = 0; | ||
| 1343 | file_size.type = IS_LONG; | ||
| 1344 | } else { | ||
| 1345 | file_size.value.lval = total_bytes; | ||
| 1346 | file_size.type = IS_LONG; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | if (is_arr_upload) { | ||
| 1350 | sprintf(lbuf, "%s[error][%s]", abuf, array_index); | ||
| 1351 | } else { | ||
| 1352 | sprintf(lbuf, "%s[error]", param); | ||
| 1353 | } | ||
| 1354 | register_http_post_files_variable_ex(lbuf, &error_type, http_post_files, 0 TSRMLS_CC); | ||
| 1355 | |||
| 1356 | /* Add $foo_size */ | ||
| 1357 | if (is_arr_upload) { | ||
| 1358 | sprintf(lbuf, "%s_size[%s]", abuf, array_index); | ||
| 1359 | } else { | ||
| 1360 | sprintf(lbuf, "%s_size", param); | ||
| 1361 | } | ||
| 1362 | if (!is_anonymous) { | ||
| 1363 | safe_php_register_variable_ex(lbuf, &file_size, NULL, 0 TSRMLS_CC); | ||
| 1364 | } | ||
| 1365 | |||
| 1366 | /* Add $foo[size] */ | ||
| 1367 | if (is_arr_upload) { | ||
| 1368 | sprintf(lbuf, "%s[size][%s]", abuf, array_index); | ||
| 1369 | } else { | ||
| 1370 | sprintf(lbuf, "%s[size]", param); | ||
| 1371 | } | ||
| 1372 | register_http_post_files_variable_ex(lbuf, &file_size, http_post_files, 0 TSRMLS_CC); | ||
| 1373 | } | ||
| 1374 | efree(param); | ||
| 1375 | } | ||
| 1376 | } | ||
| 1377 | fileupload_done: | ||
| 1378 | { | ||
| 1379 | multipart_event_end event_end; | ||
| 1380 | |||
| 1381 | event_end.post_bytes_processed = SG(read_post_bytes); | ||
| 1382 | suhosin_rfc1867_filter(MULTIPART_EVENT_END, &event_end, &event_extra_data TSRMLS_CC); | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | SAFE_RETURN; | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | #endif | ||
| 1389 | |||
| 1390 | /* | ||
| 1391 | * Local variables: | ||
| 1392 | * tab-width: 4 | ||
| 1393 | * c-basic-offset: 4 | ||
| 1394 | * End: | ||
| 1395 | * vim600: sw=4 ts=4 fdm=marker | ||
| 1396 | * vim<600: sw=4 ts=4 | ||
| 1397 | */ | ||
diff --git a/rfc1867_new.c b/rfc1867_new.c index 9831e8a..2a8b3ab 100644 --- a/rfc1867_new.c +++ b/rfc1867_new.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #include "suhosin_rfc1867.h" | 35 | #include "suhosin_rfc1867.h" |
| 36 | #include "ext/standard/php_string.h" | 36 | #include "ext/standard/php_string.h" |
| 37 | 37 | ||
| 38 | #if 1 //PHP_VERSION_ID >= 50400 | ||
| 39 | 38 | ||
| 40 | #define DEBUG_FILE_UPLOAD ZEND_DEBUG | 39 | #define DEBUG_FILE_UPLOAD ZEND_DEBUG |
| 41 | 40 | ||
| @@ -1267,7 +1266,6 @@ fileupload_done: | |||
| 1267 | } | 1266 | } |
| 1268 | /* }}} */ | 1267 | /* }}} */ |
| 1269 | 1268 | ||
| 1270 | #endif | ||
| 1271 | 1269 | ||
| 1272 | /* | 1270 | /* |
| 1273 | * Local variables: | 1271 | * Local variables: |
| @@ -58,22 +58,6 @@ static int suhosin_get_session_var(char *name, size_t namelen, zval ***state_var | |||
| 58 | 58 | ||
| 59 | if (SESSION_G(http_session_vars) && SESSION_G(http_session_vars)->type == IS_ARRAY) { | 59 | if (SESSION_G(http_session_vars) && SESSION_G(http_session_vars)->type == IS_ARRAY) { |
| 60 | ret = zend_hash_find(Z_ARRVAL_P(SESSION_G(http_session_vars)), name, namelen + 1, (void **) state_var); | 60 | ret = zend_hash_find(Z_ARRVAL_P(SESSION_G(http_session_vars)), name, namelen + 1, (void **) state_var); |
| 61 | |||
| 62 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 63 | /* If register_globals is enabled, and | ||
| 64 | * if there is an entry for the slot in $_SESSION, and | ||
| 65 | * if that entry is still set to NULL, and | ||
| 66 | * if the global var exists, then | ||
| 67 | * we prefer the same key in the global sym table. */ | ||
| 68 | |||
| 69 | if (PG(register_globals) && ret == SUCCESS && Z_TYPE_PP(*state_var) == IS_NULL) { | ||
| 70 | zval **tmp; | ||
| 71 | |||
| 72 | if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) { | ||
| 73 | *state_var = tmp; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | #endif | ||
| 77 | } | 61 | } |
| 78 | return ret; | 62 | return ret; |
| 79 | } | 63 | } |
| @@ -123,7 +107,6 @@ static void suhosin_send_cookie(TSRMLS_D) | |||
| 123 | 107 | ||
| 124 | /* The following is requires to be 100% compatible to PHP | 108 | /* The following is requires to be 100% compatible to PHP |
| 125 | versions where the hash extension is not available by default */ | 109 | versions where the hash extension is not available by default */ |
| 126 | #if 1 //(PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 3) | ||
| 127 | if (zend_hash_find(EG(ini_directives), "session.hash_bits_per_character", sizeof("session.hash_bits_per_character"), (void **) &ini_entry) == SUCCESS) { | 110 | if (zend_hash_find(EG(ini_directives), "session.hash_bits_per_character", sizeof("session.hash_bits_per_character"), (void **) &ini_entry) == SUCCESS) { |
| 128 | #ifndef ZTS | 111 | #ifndef ZTS |
| 129 | base = (char *) ini_entry->mh_arg2; | 112 | base = (char *) ini_entry->mh_arg2; |
| @@ -132,7 +115,6 @@ static void suhosin_send_cookie(TSRMLS_D) | |||
| 132 | #endif | 115 | #endif |
| 133 | session_send_cookie = (int *) (base+(size_t) ini_entry->mh_arg1+sizeof(long)); | 116 | session_send_cookie = (int *) (base+(size_t) ini_entry->mh_arg1+sizeof(long)); |
| 134 | } | 117 | } |
| 135 | #endif | ||
| 136 | *session_send_cookie = 1; | 118 | *session_send_cookie = 1; |
| 137 | } | 119 | } |
| 138 | 120 | ||
| @@ -155,9 +137,7 @@ static int suhosin_hook_s_read(void **mod_data, const char *key, char **val, int | |||
| 155 | /* protect dumb session handlers */ | 137 | /* protect dumb session handlers */ |
| 156 | if (key == NULL || !key[0] || | 138 | if (key == NULL || !key[0] || |
| 157 | (*mod_data == NULL | 139 | (*mod_data == NULL |
| 158 | #if 1 //PHP_VERSION_ID >= 50400 | ||
| 159 | && !SESSION_G(mod_user_implemented) | 140 | && !SESSION_G(mod_user_implemented) |
| 160 | #endif | ||
| 161 | )) { | 141 | )) { |
| 162 | regenerate: | 142 | regenerate: |
| 163 | SDEBUG("regenerating key is %s", key); | 143 | SDEBUG("regenerating key is %s", key); |
| @@ -169,14 +149,6 @@ regenerate: | |||
| 169 | goto regenerate; | 149 | goto regenerate; |
| 170 | } | 150 | } |
| 171 | } | 151 | } |
| 172 | #if 0 //(PHP_MAJOR_VERSION < 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 2) | ||
| 173 | else if (strpbrk(KEY, "\r\n\t <>'\"\\")) { | ||
| 174 | suhosin_log(S_SESSION, "session id ('%s') contains invalid chars - regenerating", KEY); | ||
| 175 | if (!SUHOSIN_G(simulation)) { | ||
| 176 | goto regenerate; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | #endif | ||
| 180 | 152 | ||
| 181 | r = SUHOSIN_G(old_s_read)(mod_data, KEY, val, vallen TSRMLS_CC); | 153 | r = SUHOSIN_G(old_s_read)(mod_data, KEY, val, vallen TSRMLS_CC); |
| 182 | 154 | ||
| @@ -209,9 +181,7 @@ static int suhosin_hook_s_write(void **mod_data, const char *key, const char *va | |||
| 209 | /* protect dumb session handlers */ | 181 | /* protect dumb session handlers */ |
| 210 | if (key == NULL || !key[0] || val == NULL || strlen(key) > SUHOSIN_G(session_max_id_length) || | 182 | if (key == NULL || !key[0] || val == NULL || strlen(key) > SUHOSIN_G(session_max_id_length) || |
| 211 | (*mod_data == NULL | 183 | (*mod_data == NULL |
| 212 | #if 1 //PHP_VERSION_ID >= 50400 | ||
| 213 | && !SESSION_G(mod_user_implemented) | 184 | && !SESSION_G(mod_user_implemented) |
| 214 | #endif | ||
| 215 | )) { | 185 | )) { |
| 216 | r = FAILURE; | 186 | r = FAILURE; |
| 217 | goto return_write; | 187 | goto return_write; |
| @@ -257,9 +227,7 @@ static int suhosin_hook_s_destroy(void **mod_data, const char *key TSRMLS_DC) | |||
| 257 | /* protect dumb session handlers */ | 227 | /* protect dumb session handlers */ |
| 258 | if (key == NULL || !key[0] || strlen(key) > SUHOSIN_G(session_max_id_length) || | 228 | if (key == NULL || !key[0] || strlen(key) > SUHOSIN_G(session_max_id_length) || |
| 259 | (*mod_data == NULL | 229 | (*mod_data == NULL |
| 260 | #if 1 //PHP_VERSION_ID >= 50400 | ||
| 261 | && !SESSION_G(mod_user_implemented) | 230 | && !SESSION_G(mod_user_implemented) |
| 262 | #endif | ||
| 263 | )) { | 231 | )) { |
| 264 | return FAILURE; | 232 | return FAILURE; |
| 265 | } | 233 | } |
| @@ -343,7 +311,6 @@ void suhosin_hook_session(TSRMLS_D) | |||
| 343 | return; | 311 | return; |
| 344 | } | 312 | } |
| 345 | /* retrieve globals from module entry struct if possible */ | 313 | /* retrieve globals from module entry struct if possible */ |
| 346 | #if 1 //PHP_VERSION_ID >= 50200 | ||
| 347 | #ifdef ZTS | 314 | #ifdef ZTS |
| 348 | if (session_globals_id == 0) { | 315 | if (session_globals_id == 0) { |
| 349 | session_globals_id = *module->globals_id_ptr; | 316 | session_globals_id = *module->globals_id_ptr; |
| @@ -353,32 +320,6 @@ void suhosin_hook_session(TSRMLS_D) | |||
| 353 | session_globals = module->globals_ptr; | 320 | session_globals = module->globals_ptr; |
| 354 | } | 321 | } |
| 355 | #endif | 322 | #endif |
| 356 | #else | ||
| 357 | /* retrieve globals from symbols if PHP version is old */ | ||
| 358 | #ifdef ZTS | ||
| 359 | if (session_globals_id == 0) { | ||
| 360 | ps_globals_id_ptr = DL_FETCH_SYMBOL(module->handle, "ps_globals_id"); | ||
| 361 | if (ps_globals_id_ptr == NULL) { | ||
| 362 | ps_globals_id_ptr = DL_FETCH_SYMBOL(module->handle, "_ps_globals_id"); | ||
| 363 | } | ||
| 364 | if (ps_globals_id_ptr == NULL) { | ||
| 365 | return; | ||
| 366 | } | ||
| 367 | |||
| 368 | session_globals_id = *ps_globals_id_ptr; | ||
| 369 | } | ||
| 370 | #else | ||
| 371 | if (session_globals == NULL) { | ||
| 372 | session_globals = DL_FETCH_SYMBOL(module->handle, "ps_globals"); | ||
| 373 | if (session_globals == NULL) { | ||
| 374 | session_globals = DL_FETCH_SYMBOL(module->handle, "_ps_globals"); | ||
| 375 | } | ||
| 376 | if (session_globals == NULL) { | ||
| 377 | return; | ||
| 378 | } | ||
| 379 | } | ||
| 380 | #endif | ||
| 381 | #endif | ||
| 382 | 323 | ||
| 383 | if (old_OnUpdateSaveHandler != NULL) { | 324 | if (old_OnUpdateSaveHandler != NULL) { |
| 384 | return; | 325 | return; |
| @@ -401,12 +342,10 @@ void suhosin_hook_session(TSRMLS_D) | |||
| 401 | suhosin_hook_session_module(TSRMLS_C); | 342 | suhosin_hook_session_module(TSRMLS_C); |
| 402 | 343 | ||
| 403 | /* Protect the PHP serializer from ! attacks */ | 344 | /* Protect the PHP serializer from ! attacks */ |
| 404 | #if 1 //PHP_MAJOR_VERSION > 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 2) | ||
| 405 | serializer = (ps_serializer *) SESSION_G(serializer); | 345 | serializer = (ps_serializer *) SESSION_G(serializer); |
| 406 | if (serializer != NULL && strcmp(serializer->name, "php")==0) { | 346 | if (serializer != NULL && strcmp(serializer->name, "php")==0) { |
| 407 | serializer->encode = suhosin_session_encode; | 347 | serializer->encode = suhosin_session_encode; |
| 408 | } | 348 | } |
| 409 | #endif | ||
| 410 | 349 | ||
| 411 | /* increase session identifier entropy */ | 350 | /* increase session identifier entropy */ |
| 412 | if (SESSION_G(entropy_length) == 0 || SESSION_G(entropy_file) == NULL) { | 351 | if (SESSION_G(entropy_length) == 0 || SESSION_G(entropy_file) == NULL) { |
| @@ -86,12 +86,6 @@ static PHP_FUNCTION(suhosin_sha256_file) | |||
| 86 | return; | 86 | return; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 90 | if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { | ||
| 91 | RETURN_FALSE; | ||
| 92 | } | ||
| 93 | #endif | ||
| 94 | |||
| 95 | if (php_check_open_basedir(arg TSRMLS_CC)) { | 89 | if (php_check_open_basedir(arg TSRMLS_CC)) { |
| 96 | RETURN_FALSE; | 90 | RETURN_FALSE; |
| 97 | } | 91 | } |
| @@ -1058,12 +1058,9 @@ PHP_MINIT_FUNCTION(suhosin) | |||
| 1058 | php_register_info_logo(SUHOSIN_LOGO_GUID, "image/jpeg", suhosin_logo, sizeof(suhosin_logo)); | 1058 | php_register_info_logo(SUHOSIN_LOGO_GUID, "image/jpeg", suhosin_logo, sizeof(suhosin_logo)); |
| 1059 | #endif | 1059 | #endif |
| 1060 | 1060 | ||
| 1061 | #if PHP_VERSION_ID < 50400 //PHP_MAJOR_VERSION < 5 | 1061 | #if PHP_VERSION_ID < 50400 |
| 1062 | #error Suhosin Extension is not designed to run with PHP versions lower than 5.4. | 1062 | #error Suhosin Extension is not designed to run with PHP versions lower than 5.4. |
| 1063 | #endif | 1063 | #endif |
| 1064 | #if 0 //PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 2 && !SUHOSIN_DEBUG | ||
| 1065 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Suhosin Extension does not officially support PHP 5.2 and below anymore, because it is discontinued. Use it at your own risk."); | ||
| 1066 | #endif | ||
| 1067 | 1064 | ||
| 1068 | #if !defined(HAVE_PHP_SESSION) && !defined(SUHOSIN_NO_SESSION_WARNING) | 1065 | #if !defined(HAVE_PHP_SESSION) && !defined(SUHOSIN_NO_SESSION_WARNING) |
| 1069 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Suhosin was compiled without session support, which is probably not what you want. All session related features will not be available, e.g. session encryption. If session support is really not needed, recompile Suhosin with -DSUHOSIN_NO_SESSION_WARNING=1 to suppress this warning."); | 1066 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Suhosin was compiled without session support, which is probably not what you want. All session related features will not be available, e.g. session encryption. If session support is really not needed, recompile Suhosin with -DSUHOSIN_NO_SESSION_WARNING=1 to suppress this warning."); |
diff --git a/treat_data.c b/treat_data.c index 9dc86d1..10e8166 100644 --- a/treat_data.c +++ b/treat_data.c | |||
| @@ -39,9 +39,7 @@ SAPI_TREAT_DATA_FUNC(suhosin_treat_data) | |||
| 39 | int free_buffer = 0; | 39 | int free_buffer = 0; |
| 40 | char *strtok_buf = NULL; | 40 | char *strtok_buf = NULL; |
| 41 | 41 | ||
| 42 | #if 1 //PHP_VERSION_ID >= 50311 | ||
| 43 | long count = 0; | 42 | long count = 0; |
| 44 | #endif | ||
| 45 | 43 | ||
| 46 | /* Mark that we were not yet called */ | 44 | /* Mark that we were not yet called */ |
| 47 | SUHOSIN_G(already_scanned) = 0; | 45 | SUHOSIN_G(already_scanned) = 0; |
| @@ -148,12 +146,10 @@ SAPI_TREAT_DATA_FUNC(suhosin_treat_data) | |||
| 148 | } | 146 | } |
| 149 | val = strchr(var, '='); | 147 | val = strchr(var, '='); |
| 150 | 148 | ||
| 151 | #if 1 //PHP_VERSION_ID >= 50311 | ||
| 152 | if (++count > PG(max_input_vars)) { | 149 | if (++count > PG(max_input_vars)) { |
| 153 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); | 150 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); |
| 154 | break; | 151 | break; |
| 155 | } | 152 | } |
| 156 | #endif | ||
| 157 | 153 | ||
| 158 | if (val) { /* have a value */ | 154 | if (val) { /* have a value */ |
| 159 | int val_len; | 155 | int val_len; |
| @@ -210,13 +206,9 @@ SAPI_TREAT_DATA_FUNC(suhosin_treat_data) | |||
| 210 | 206 | ||
| 211 | void suhosin_hook_treat_data() | 207 | void suhosin_hook_treat_data() |
| 212 | { | 208 | { |
| 213 | #if 0 //PHP_VERSION_ID < 50400 | ||
| 214 | sapi_register_treat_data(suhosin_treat_data); | ||
| 215 | #else | ||
| 216 | TSRMLS_FETCH(); | 209 | TSRMLS_FETCH(); |
| 217 | 210 | ||
| 218 | sapi_register_treat_data(suhosin_treat_data TSRMLS_CC); | 211 | sapi_register_treat_data(suhosin_treat_data TSRMLS_CC); |
| 219 | #endif | ||
| 220 | #ifdef ZEND_ENGINE_2 | 212 | #ifdef ZEND_ENGINE_2 |
| 221 | if (old_input_filter == NULL) { | 213 | if (old_input_filter == NULL) { |
| 222 | old_input_filter = sapi_module.input_filter; | 214 | old_input_filter = sapi_module.input_filter; |
