summaryrefslogtreecommitdiff
path: root/ex_imp.c
diff options
context:
space:
mode:
Diffstat (limited to 'ex_imp.c')
-rw-r--r--ex_imp.c412
1 files changed, 0 insertions, 412 deletions
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