summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.m42
-rw-r--r--config.w322
-rw-r--r--ex_imp.c412
-rw-r--r--execute.c44
-rw-r--r--header.c16
-rw-r--r--log.c13
-rw-r--r--php_suhosin.h121
-rw-r--r--post_handler.c11
-rw-r--r--rfc1867.c1397
-rw-r--r--rfc1867_new.c2
-rw-r--r--session.c61
-rw-r--r--sha256.c6
-rw-r--r--suhosin.c5
-rw-r--r--treat_data.c8
14 files changed, 7 insertions, 2093 deletions
diff --git a/config.m4 b/config.m4
index 9ddf5e9..c908de9 100644
--- a/config.m4
+++ b/config.m4
@@ -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
7if test "$PHP_SUHOSIN" != "no"; then 7if 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)
9fi 9fi
10 10
11PHP_ARG_ENABLE(suhosin-experimental, whether to enable experimental suhosin features, 11PHP_ARG_ENABLE(suhosin-experimental, whether to enable experimental suhosin features,
diff --git a/config.w32 b/config.w32
index 6f0993f..ecfe832 100644
--- a/config.w32
+++ b/config.w32
@@ -4,7 +4,7 @@
4ARG_ENABLE("suhosin", "whether to enable suhosin support", "yes"); 4ARG_ENABLE("suhosin", "whether to enable suhosin support", "yes");
5 5
6if (PHP_SUHOSIN == "yes") { 6if (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") {
diff --git a/ex_imp.c b/ex_imp.c
index 7122927..1c01191 100644
--- a/ex_imp.c
+++ b/ex_imp.c
@@ -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 */
87PHP_FUNCTION(suhosin_extract) 87PHP_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
433static 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
474static 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 */
528PHP_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
647ZEND_BEGIN_ARG_INFO_EX(suhosin_arginfo_extract, 0, 0, 1) 247ZEND_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)
651ZEND_END_ARG_INFO() 251ZEND_END_ARG_INFO()
652 252
653#ifdef SUHOSIN_HAVE_IRV
654ZEND_BEGIN_ARG_INFO_EX(suhosin_arginfo_import_request_variables, 0, 0, 1)
655 ZEND_ARG_INFO(0, types)
656 ZEND_ARG_INFO(0, prefix)
657ZEND_END_ARG_INFO()
658#endif
659 253
660/* {{{ suhosin_ex_imp_functions[] 254/* {{{ suhosin_ex_imp_functions[]
661 */ 255 */
662zend_function_entry suhosin_ex_imp_functions[] = { 256zend_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
diff --git a/execute.c b/execute.c
index 37abdfd..9c078f7 100644
--- a/execute.c
+++ b/execute.c
@@ -859,12 +859,7 @@ int ih_mail(IH_HANDLER_PARAMS)
859 859
860int ih_querycheck(IH_HANDLER_PARAMS) 860int 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
1022int ih_fixusername(IH_HANDLER_PARAMS) 1017int 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
1118static int ih_function_exists(IH_HANDLER_PARAMS) 1108static 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
1564static int ih_getrandmax(IH_HANDLER_PARAMS) 1537static 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
diff --git a/header.c b/header.c
index 1a85015..5229910 100644
--- a/header.c
+++ b/header.c
@@ -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
36static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL; 35static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
37#else
38static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
39#endif
40 36
41char *suhosin_encrypt_single_cookie(char *name, int name_len, char *value, int value_len, char *key TSRMLS_DC) 37char *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
194int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC) 189int suhosin_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC)
195#else
196int 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
294suhosin_skip_header_handling: 284suhosin_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;
diff --git a/log.c b/log.c
index ed83c24..f76737c 100644
--- a/log.c
+++ b/log.c
@@ -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
124static 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
168ZEND_BEGIN_MODULE_GLOBALS(suhosin) 123ZEND_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);
452size_t suhosin_strnspn(const char *input, size_t n, const char *accept); 407size_t suhosin_strnspn(const char *input, size_t n, const char *accept);
453size_t suhosin_strncspn(const char *input, size_t n, const char *reject); 408size_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
493static zend_always_inline zend_uint zval_refcount_p(zval* pz) {
494 return pz->refcount;
495}
496
497static zend_always_inline zend_uint zval_set_refcount_p(zval* pz, zend_uint rc) {
498 return pz->refcount = rc;
499}
500
501static zend_always_inline zend_uint zval_addref_p(zval* pz) {
502 return ++pz->refcount;
503}
504
505static zend_always_inline zend_uint zval_delref_p(zval* pz) {
506 return --pz->refcount;
507}
508
509static zend_always_inline zend_bool zval_isref_p(zval* pz) {
510 return pz->is_ref;
511}
512
513static zend_always_inline zend_bool zval_set_isref_p(zval* pz) {
514 return pz->is_ref = 1;
515}
516
517static zend_always_inline zend_bool zval_unset_isref_p(zval* pz) {
518 return pz->is_ref = 0;
519}
520
521static 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
46static 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
61static 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
79static 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
90static 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/*
143void 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
156static 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
215static 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
224static 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
231static 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
239static 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
247static 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
261static 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
281typedef 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
297typedef 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*/
307static 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 */
344static 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 */
355static 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 */
390static 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 */
426static 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 */
440static 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 */
452static 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 */
471static 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
528static 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
548static 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
587static 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
618static 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;
640look_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*/
685static 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 */
710static 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*/
757static 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
780SAPI_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 }
941SDEBUG("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)
1249filedone:
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 }
1377fileupload_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:
diff --git a/session.c b/session.c
index 1044977..0e16ce4 100644
--- a/session.c
+++ b/session.c
@@ -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 )) {
162regenerate: 142regenerate:
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) {
diff --git a/sha256.c b/sha256.c
index d91e575..64ee25f 100644
--- a/sha256.c
+++ b/sha256.c
@@ -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 }
diff --git a/suhosin.c b/suhosin.c
index b1bc47b..76cdac1 100644
--- a/suhosin.c
+++ b/suhosin.c
@@ -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
211void suhosin_hook_treat_data() 207void 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;