From 07db64156e180c30daa5ab5d41ed72f9bba77e6d Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Thu, 25 Jun 2020 09:44:12 -0400 Subject: [PATCH] [RFC] Make string length for getTraceAsString() configurable Add a `zend.exception_string_param_max_len` ini setting. (same suffix as `log_errors_max_len`) Allow values between 0 and 1000000 bytes. For example, with zend.exception_string_param_max_len=0, "" would represent the empty string, and "..." would represent something longer than the empty string. Previously, this was hardcoded as exactly 15 bytes. Discussion: https://externals.io/message/110717 Closes GH-5769 --- Zend/tests/exception_024.phpt | 19 ++++++++++++++++ Zend/tests/exception_025.phpt | 41 +++++++++++++++++++++++++++++++++++ Zend/zend.c | 15 +++++++++++++ Zend/zend_exceptions.c | 4 ++-- Zend/zend_globals.h | 1 + main/main.c | 1 - php.ini-development | 13 +++++++++++ php.ini-production | 17 ++++++++++++++- run-tests.php | 1 + 9 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 Zend/tests/exception_024.phpt create mode 100644 Zend/tests/exception_025.phpt diff --git a/Zend/tests/exception_024.phpt b/Zend/tests/exception_024.phpt new file mode 100644 index 0000000000000..67a2b875329ea --- /dev/null +++ b/Zend/tests/exception_024.phpt @@ -0,0 +1,19 @@ +--TEST-- +zend.exception_string_param_max_len ini setting +--INI-- +zend.exception_string_param_max_len = 23 +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): main('12345678901234567890123...') +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/exception_025.phpt b/Zend/tests/exception_025.phpt new file mode 100644 index 0000000000000..b81c5406d6462 --- /dev/null +++ b/Zend/tests/exception_025.phpt @@ -0,0 +1,41 @@ +--TEST-- +zend.exception_string_param_max_len ini setting +--FILE-- + +--EXPECTF-- +bool(false) +bool(false) +string(2) "15" +string(7) "1000000" +Exception in %s:%d +Stack trace: +#0 %s(10): main('short') +#1 {main} +Exception in %s:%d +Stack trace: +#0 %s(11): main('12345678901234567890...') +#1 {main} +string(2) "20" +Exception in %s:%d +Stack trace: +#0 %s(13): main('...') +#1 {main} +Exception in %s:%d +Stack trace: +#0 %s(14): main('') +#1 {main} diff --git a/Zend/zend.c b/Zend/zend.c index aef5a398b1b6e..4b001c522cca8 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -160,6 +160,20 @@ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */ } /* }}} */ +static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */ +{ + zend_long i; + + ZEND_ATOL(i, ZSTR_VAL(new_value)); + if (i >= 0 && i <= 1000000) { + EG(exception_string_param_max_len) = i; + return SUCCESS; + } else { + return FAILURE; + } +} +/* }}} */ + #if ZEND_DEBUG # define SIGNAL_CHECK_DEFAULT "1" #else @@ -177,6 +191,7 @@ ZEND_INI_BEGIN() STD_ZEND_INI_BOOLEAN("zend.signal_check", SIGNAL_CHECK_DEFAULT, ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals) #endif STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals) + STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen, exception_string_param_max_len, zend_executor_globals, executor_globals) ZEND_INI_END() ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */ diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index be0eb1c33eb8f..8c96bb60981a3 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -482,8 +482,8 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ break; case IS_STRING: smart_str_appendc(str, '\''); - smart_str_append_escaped(str, Z_STRVAL_P(arg), MIN(Z_STRLEN_P(arg), 15)); - if (Z_STRLEN_P(arg) > 15) { + smart_str_append_escaped(str, Z_STRVAL_P(arg), MIN(Z_STRLEN_P(arg), EG(exception_string_param_max_len))); + if (Z_STRLEN_P(arg) > EG(exception_string_param_max_len)) { smart_str_appends(str, "...', "); } else { smart_str_appends(str, "', "); diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index be17a446545ae..652e0ef1e1329 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -241,6 +241,7 @@ struct _zend_executor_globals { HashTable weakrefs; zend_bool exception_ignore_args; + zend_long exception_string_param_max_len; zend_get_gc_buffer get_gc_buffer; diff --git a/main/main.c b/main/main.c index cc0e764561871..4e7a4f44414c1 100644 --- a/main/main.c +++ b/main/main.c @@ -260,7 +260,6 @@ static PHP_INI_MH(OnSetSerializePrecision) } /* }}} */ - /* {{{ PHP_INI_MH */ static PHP_INI_MH(OnChangeMemoryLimit) { diff --git a/php.ini-development b/php.ini-development index 490b214d29de0..ba30258fd0e6a 100644 --- a/php.ini-development +++ b/php.ini-development @@ -159,6 +159,11 @@ ; Development Value: Off ; Production Value: On +; zend.exception_string_param_max_len +; Default Value: 15 +; Development Value: 15 +; Production Value: 0 + ;;;;;;;;;;;;;;;;;;;; ; php.ini Options ; ;;;;;;;;;;;;;;;;;;;; @@ -371,6 +376,14 @@ zend.enable_gc = On ; Production Value: On zend.exception_ignore_args = Off +; Allows setting the maximum string length in an argument of a stringified stack trace +; to a value between 0 and 1000000. +; This has no effect when zend.exception_ignore_args is enabled. +; Default Value: 15 +; Development Value: 15 +; Production Value: 0 +zend.exception_string_param_max_len = 15 + ;;;;;;;;;;;;;;;;; ; Miscellaneous ; ;;;;;;;;;;;;;;;;; diff --git a/php.ini-production b/php.ini-production index c6e83d5f09841..a2a22506a404a 100644 --- a/php.ini-production +++ b/php.ini-production @@ -159,6 +159,11 @@ ; Development Value: Off ; Production Value: On +; zend.exception_string_param_max_len +; Default Value: 15 +; Development Value: 15 +; Production Value: 0 + ;;;;;;;;;;;;;;;;;;;; ; php.ini Options ; ;;;;;;;;;;;;;;;;;;;; @@ -366,13 +371,23 @@ zend.enable_gc = On ;zend.script_encoding = ; Allows to include or exclude arguments from stack traces generated for exceptions -; In production, it is recommended to turn this setting on to prohibit the output +; In production, it is recommended to turn this setting on to prohibit the output ; of sensitive information in stack traces ; Default Value: Off ; Development Value: Off ; Production Value: On zend.exception_ignore_args = On +; Allows setting the maximum string length in an argument of a stringified stack trace +; to a value between 0 and 1000000. +; This has no effect when zend.exception_ignore_args is enabled. +; Default Value: 15 +; Development Value: 15 +; Production Value: 0 +; In production, it is recommended to set this to 0 to reduce the output +; of sensitive information in stack traces. +zend.exception_string_param_max_len = 0 + ;;;;;;;;;;;;;;;;; ; Miscellaneous ; ;;;;;;;;;;;;;;;;; diff --git a/run-tests.php b/run-tests.php index 696e949974e3e..092009b50011c 100755 --- a/run-tests.php +++ b/run-tests.php @@ -343,6 +343,7 @@ function main() 'opcache.jit_hot_side_exit=1', 'zend.assertions=1', 'zend.exception_ignore_args=0', + 'zend.exception_string_param_max_len=15', 'short_open_tag=0', );