| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7de451f commit a22c56c
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,30 @@ | |||
| 1 | + --TEST-- | ||
| 2 | + Displaying function arguments in errors | ||
| 3 | + --INI-- | ||
| 4 | + error_include_args=On | ||
| 5 | + --FILE-- | ||
| 6 | + <?php | ||
| 7 | + | ||
| 8 | + // A function that sets its own parameters in docref call, to compare | ||
| 9 | + unlink('/'); | ||
| 10 | + | ||
| 11 | + // Something with sensitive parameters that exists in a minimal build, | ||
| 12 | + // and also doesn't set anything in the docref call. cost is set to 4 | ||
| 13 | + // to keep the test fast | ||
| 14 | + $flags = ["salt" => "123456789012345678901" . chr(0), "cost" => 4]; | ||
| 15 | + password_hash("test", PASSWORD_BCRYPT, $flags); | ||
| 16 | + | ||
| 17 | + ini_set("error_include_args", "Off"); | ||
| 18 | + | ||
| 19 | + unlink('/'); | ||
| 20 | + password_hash("test", PASSWORD_BCRYPT, $flags); | ||
| 21 | + | ||
| 22 | + ?> | ||
| 23 | + --EXPECTF-- | ||
| 24 | + Warning: unlink('/'): %s in %s on line %d | ||
| 25 | + | ||
| 26 | + Warning: password_hash(Object(SensitiveParameterValue), '2y', Array): The "salt" option has been ignored, since providing a custom salt is no longer supported in %s on line %d | ||
| 27 | + | ||
| 28 | + Warning: unlink(/): %s in %s on line %d | ||
| 29 | + | ||
| 30 | + Warning: password_hash(): The "salt" option has been ignored, since providing a custom salt is no longer supported in %s on line %d | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -506,7 +506,7 @@ ZEND_METHOD(ErrorException, getSeverity) | |||
| 506 | 506 | } \ | |
| 507 | 507 | } while (0) | |
| 508 | 508 | ||
| 509 | - static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ | ||
| 509 | + static void build_trace_args(zval *arg, smart_str *str) /* {{{ */ | ||
| 510 | 510 | { | |
| 511 | 511 | /* the trivial way would be to do | |
| 512 | 512 | * convert_to_string(arg); | |
@@ -516,24 +516,21 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ | |||
| 516 | 516 | ||
| 517 | 517 | ZVAL_DEREF(arg); | |
| 518 | 518 | ||
| 519 | - if (smart_str_append_zval(str, arg, EG(exception_string_param_max_len)) == SUCCESS) { | ||
| 520 | - smart_str_appends(str, ", "); | ||
| 521 | - } else { | ||
| 519 | + if (smart_str_append_zval(str, arg, EG(exception_string_param_max_len)) != SUCCESS) { | ||
| 522 | 520 | switch (Z_TYPE_P(arg)) { | |
| 523 | 521 | case IS_RESOURCE: | |
| 524 | 522 | smart_str_appends(str, "Resource id #"); | |
| 525 | 523 | smart_str_append_long(str, Z_RES_HANDLE_P(arg)); | |
| 526 | - smart_str_appends(str, ", "); | ||
| 527 | 524 | break; | |
| 528 | 525 | case IS_ARRAY: | |
| 529 | - smart_str_appends(str, "Array, "); | ||
| 526 | + smart_str_appends(str, "Array"); | ||
| 530 | 527 | break; | |
| 531 | 528 | case IS_OBJECT: { | |
| 532 | 529 | zend_string *class_name = Z_OBJ_HANDLER_P(arg, get_class_name)(Z_OBJ_P(arg)); | |
| 533 | 530 | smart_str_appends(str, "Object("); | |
| 534 | 531 | /* cut off on NULL byte ... class@anonymous */ | |
| 535 | 532 | smart_str_appends(str, ZSTR_VAL(class_name)); | |
| 536 | - smart_str_appends(str, "), "); | ||
| 533 | + smart_str_appends(str, ")"); | ||
| 537 | 534 | zend_string_release_ex(class_name, 0); | |
| 538 | 535 | break; | |
| 539 | 536 | } | |
@@ -542,7 +539,30 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ | |||
| 542 | 539 | } | |
| 543 | 540 | /* }}} */ | |
| 544 | 541 | ||
| 545 | - static void _build_trace_string(smart_str *str, const HashTable *ht, uint32_t num) /* {{{ */ | ||
| 542 | + static void build_trace_args_list(zval *tmp, smart_str *str) /* {{{ */ | ||
| 543 | + { | ||
| 544 | + if (UNEXPECTED(Z_TYPE_P(tmp) != IS_ARRAY)) { | ||
| 545 | + /* only happens w/ reflection abuse (Zend/tests/bug63762.phpt) */ | ||
| 546 | + zend_error(E_WARNING, "args element is not an array"); | ||
| 547 | + return; | ||
| 548 | + } | ||
| 549 | + | ||
| 550 | + bool first = true; | ||
| 551 | + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(tmp), zend_string *name, zval *arg) { | ||
| 552 | + if (!first) { | ||
| 553 | + smart_str_appends(str, ", "); | ||
| 554 | + } | ||
| 555 | + first = false; | ||
| 556 | + if (name) { | ||
| 557 | + smart_str_append(str, name); | ||
| 558 | + smart_str_appends(str, ": "); | ||
| 559 | + } | ||
| 560 | + build_trace_args(arg, str); | ||
| 561 | + } ZEND_HASH_FOREACH_END(); | ||
| 562 | + } | ||
| 563 | + /* }}} */ | ||
| 564 | + | ||
| 565 | + static void build_trace_string(smart_str *str, const HashTable *ht, uint32_t num) /* {{{ */ | ||
| 546 | 566 | { | |
| 547 | 567 | zval *file, *tmp; | |
| 548 | 568 | ||
@@ -588,27 +608,40 @@ static void _build_trace_string(smart_str *str, const HashTable *ht, uint32_t nu | |||
| 588 | 608 | smart_str_appendc(str, '('); | |
| 589 | 609 | tmp = zend_hash_find_known_hash(ht, ZSTR_KNOWN(ZEND_STR_ARGS)); | |
| 590 | 610 | if (tmp) { | |
| 591 | - if (EXPECTED(Z_TYPE_P(tmp) == IS_ARRAY)) { | ||
| 592 | - size_t last_len = ZSTR_LEN(str->s); | ||
| 593 | - zend_string *name; | ||
| 594 | - zval *arg; | ||
| 595 | - | ||
| 596 | - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(tmp), name, arg) { | ||
| 597 | - if (name) { | ||
| 598 | - smart_str_append(str, name); | ||
| 599 | - smart_str_appends(str, ": "); | ||
| 600 | - } | ||
| 601 | - _build_trace_args(arg, str); | ||
| 602 | - } ZEND_HASH_FOREACH_END(); | ||
| 611 | + build_trace_args_list(tmp, str); | ||
| 612 | + } | ||
| 613 | + smart_str_appends(str, ")\n"); | ||
| 614 | + } | ||
| 615 | + /* }}} */ | ||
| 603 | 616 | ||
| 604 | - if (last_len != ZSTR_LEN(str->s)) { | ||
| 605 | - ZSTR_LEN(str->s) -= 2; /* remove last ', ' */ | ||
| 606 | - } | ||
| 607 | - } else { | ||
| 608 | - zend_error(E_WARNING, "args element is not an array"); | ||
| 617 | + /* {{{ Gets the function arguments printed as a string from a backtrace frame. */ | ||
| 618 | + ZEND_API zend_string *zend_trace_function_args_to_string(const HashTable *frame) { | ||
| 619 | + smart_str str = {0}; | ||
| 620 | + | ||
| 621 | + zval *tmp = zend_hash_find_known_hash(frame, ZSTR_KNOWN(ZEND_STR_ARGS)); | ||
| 622 | + if (tmp) { | ||
| 623 | + build_trace_args_list(tmp, &str); | ||
| 624 | + } | ||
| 625 | + | ||
| 626 | + return smart_str_extract(&str); | ||
| 627 | + } | ||
| 628 | + /* }}} */ | ||
| 629 | + | ||
| 630 | + /* {{{ Gets the currently executing function's arguments as a string. Used by php_verror. */ | ||
| 631 | + ZEND_API zend_string *zend_trace_current_function_args_string(void) { | ||
| 632 | + zend_string *dynamic_params = NULL; | ||
| 633 | + /* get a backtrace to snarf function args */ | ||
| 634 | + zval backtrace; | ||
| 635 | + zend_fetch_debug_backtrace(&backtrace, /* skip_last */ 0, /* options */ 0, /* limit */ 1); | ||
| 636 | + /* can fail esp if low memory condition */ | ||
| 637 | + if (Z_TYPE(backtrace) == IS_ARRAY) { | ||
| 638 | + zval *first_frame = zend_hash_index_find(Z_ARRVAL(backtrace), 0); | ||
| 639 | + if (first_frame) { | ||
| 640 | + dynamic_params = zend_trace_function_args_to_string(Z_ARRVAL_P(first_frame)); | ||
| 609 | 641 | } | |
| 610 | 642 | } | |
| 611 | - smart_str_appends(str, ")\n"); | ||
| 643 | + zval_ptr_dtor(&backtrace); | ||
| 644 | + return dynamic_params; | ||
| 612 | 645 | } | |
| 613 | 646 | /* }}} */ | |
| 614 | 647 | ||
@@ -624,7 +657,7 @@ ZEND_API zend_string *zend_trace_to_string(const HashTable *trace, bool include_ | |||
| 624 | 657 | continue; | |
| 625 | 658 | } | |
| 626 | 659 | ||
| 627 | - _build_trace_string(&str, Z_ARRVAL_P(frame), num++); | ||
| 660 | + build_trace_string(&str, Z_ARRVAL_P(frame), num++); | ||
| 628 | 661 | } ZEND_HASH_FOREACH_END(); | |
| 629 | 662 | ||
| 630 | 663 | if (include_main) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -65,6 +65,8 @@ ZEND_API zend_result zend_update_exception_properties(zend_execute_data *execute | |||
| 65 | 65 | /* show an exception using zend_error(severity,...), severity should be E_ERROR */ | |
| 66 | 66 | ZEND_API ZEND_COLD zend_result zend_exception_error(zend_object *exception, int severity); | |
| 67 | 67 | ZEND_NORETURN void zend_exception_uncaught_error(const char *prefix, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2); | |
| 68 | + ZEND_API zend_string *zend_trace_function_args_to_string(const HashTable *frame); | ||
| 69 | + ZEND_API zend_string *zend_trace_current_function_args_string(void); | ||
| 68 | 70 | ZEND_API zend_string *zend_trace_to_string(const HashTable *trace, bool include_main); | |
| 69 | 71 | ||
| 70 | 72 | ZEND_API ZEND_COLD zend_object *zend_create_unwind_exit(void); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -100,7 +100,8 @@ class ServerClientTestCase | |||
| 100 | 100 | $ini = php_ini_loaded_file(); | |
| 101 | 101 | $cmd = sprintf( | |
| 102 | 102 | '%s %s "%s" %s', | |
| 103 | - PHP_BINARY, $ini ? "-n -c $ini" : "", | ||
| 103 | + // XXX: TEST_PHP_EXTRA_ARGS for run-test values won't work here? | ||
| 104 | + PHP_BINARY, $ini ? "-n -c $ini -d error_include_args=0" : "", | ||
| 104 | 105 | __FILE__, | |
| 105 | 106 | WORKER_ARGV_VALUE | |
| 106 | 107 | ); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -62,6 +62,7 @@ | |||
| 62 | 62 | #include "win32/php_registry.h" | |
| 63 | 63 | #include "ext/standard/flock_compat.h" | |
| 64 | 64 | #endif | |
| 65 | + #include "Zend/zend_builtin_functions.h" | ||
| 65 | 66 | #include "Zend/zend_exceptions.h" | |
| 66 | 67 | ||
| 67 | 68 | #if PHP_SIGCHILD | |
@@ -801,6 +802,7 @@ PHP_INI_BEGIN() | |||
| 801 | 802 | STD_PHP_INI_ENTRY_EX("display_errors", "1", PHP_INI_ALL, OnUpdateDisplayErrors, display_errors, php_core_globals, core_globals, display_errors_mode) | |
| 802 | 803 | STD_PHP_INI_BOOLEAN("display_startup_errors", "1", PHP_INI_ALL, OnUpdateBool, display_startup_errors, php_core_globals, core_globals) | |
| 803 | 804 | STD_PHP_INI_BOOLEAN("enable_dl", "1", PHP_INI_SYSTEM, OnUpdateBool, enable_dl, php_core_globals, core_globals) | |
| 805 | + STD_PHP_INI_BOOLEAN("error_include_args", "0", PHP_INI_ALL, OnUpdateBool, error_include_args, php_core_globals, core_globals) | ||
| 804 | 806 | STD_PHP_INI_BOOLEAN("expose_php", "1", PHP_INI_SYSTEM, OnUpdateBool, expose_php, php_core_globals, core_globals) | |
| 805 | 807 | STD_PHP_INI_ENTRY("docref_root", "", PHP_INI_ALL, OnUpdateString, docref_root, php_core_globals, core_globals) | |
| 806 | 808 | STD_PHP_INI_ENTRY("docref_ext", "", PHP_INI_ALL, OnUpdateString, docref_ext, php_core_globals, core_globals) | |
@@ -1132,7 +1134,14 @@ PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int typ | |||
| 1132 | 1134 | ||
| 1133 | 1135 | /* if we still have memory then format the origin */ | |
| 1134 | 1136 | if (is_function) { | |
| 1135 | - origin_len = spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params); | ||
| 1137 | + zend_string *dynamic_params = NULL; | ||
| 1138 | + if (PG(error_include_args)) { | ||
| 1139 | + dynamic_params = zend_trace_current_function_args_string(); | ||
| 1140 | + } | ||
| 1141 | + origin_len = spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, dynamic_params ? ZSTR_VAL(dynamic_params) : params); | ||
| 1142 | + if (dynamic_params) { | ||
| 1143 | + zend_string_release(dynamic_params); | ||
| 1144 | + } | ||
| 1136 | 1145 | } else { | |
| 1137 | 1146 | origin_len = strlen(function); | |
| 1138 | 1147 | origin = estrndup(function, origin_len); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -59,6 +59,7 @@ struct _php_core_globals { | |||
| 59 | 59 | ||
| 60 | 60 | uint8_t display_errors; | |
| 61 | 61 | bool display_startup_errors; | |
| 62 | + bool error_include_args; | ||
| 62 | 63 | bool log_errors; | |
| 63 | 64 | bool ignore_repeated_errors; | |
| 64 | 65 | bool ignore_repeated_source; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -611,6 +611,12 @@ ignore_repeated_source = Off | |||
| 611 | 611 | ; Production Value: On | |
| 612 | 612 | ;fatal_error_backtraces = On | |
| 613 | 613 | ||
| 614 | + ; This directive controls whether PHP will print the actual arguments of a | ||
| 615 | + ; function upon an error. If this is off (or there was an error fetching the | ||
| 616 | + ; arguments), the function providing the error may optionally provide some | ||
| 617 | + ; additional information after the problem function's name. | ||
| 618 | + ;error_include_args = Off | ||
| 619 | + | ||
| 614 | 620 | ;;;;;;;;;;;;;;;;; | |
| 615 | 621 | ; Data Handling ; | |
| 616 | 622 | ;;;;;;;;;;;;;;;;; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -613,6 +613,12 @@ ignore_repeated_source = Off | |||
| 613 | 613 | ; Production Value: On | |
| 614 | 614 | ;fatal_error_backtraces = On | |
| 615 | 615 | ||
| 616 | + ; This directive controls whether PHP will print the actual arguments of a | ||
| 617 | + ; function upon an error. If this is off (or there was an error fetching the | ||
| 618 | + ; arguments), the function providing the error may optionally provide some | ||
| 619 | + ; additional information after the problem function's name. | ||
| 620 | + ;error_include_args = Off | ||
| 621 | + | ||
| 616 | 622 | ;;;;;;;;;;;;;;;;; | |
| 617 | 623 | ; Data Handling ; | |
| 618 | 624 | ;;;;;;;;;;;;;;;;; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -273,6 +273,7 @@ function main(): void | |||
| 273 | 273 | 'fatal_error_backtraces=Off', | |
| 274 | 274 | 'display_errors=1', | |
| 275 | 275 | 'display_startup_errors=1', | |
| 276 | + 'error_include_args=0', | ||
| 276 | 277 | 'log_errors=0', | |
| 277 | 278 | 'html_errors=0', | |
| 278 | 279 | 'track_errors=0', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,8 @@ function php_cli_server_start( | |||
| 24 | 24 | file_put_contents($doc_root . '/' . ($router ?: 'index.php'), '<?php ' . $code . ' ?>'); | |
| 25 | 25 | } | |
| 26 | 26 | ||
| 27 | - $cmd = [$php_executable, '-t', $doc_root, '-n', ...$cmd_args, '-S', 'localhost:0']; | ||
| 27 | + // XXX: This should ideally use the same INI overrides as run-tests | ||
| 28 | + $cmd = [$php_executable, '-d', 'error_include_args=0', '-t', $doc_root, '-n', ...$cmd_args, '-S', 'localhost:0']; | ||
| 28 | 29 | if (!is_null($router)) { | |
| 29 | 30 | $cmd[] = $router; | |
| 30 | 31 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments