Skip to content

Commit 07db641

Browse files
committed
[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
1 parent 8664ff7 commit 07db641

File tree

9 files changed

+108
-4
lines changed

9 files changed

+108
-4
lines changed

Zend/tests/exception_024.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
zend.exception_string_param_max_len ini setting
3+
--INI--
4+
zend.exception_string_param_max_len = 23
5+
--FILE--
6+
<?php
7+
8+
function main($arg) {
9+
throw new Exception();
10+
}
11+
main('123456789012345678901234567890');
12+
13+
?>
14+
--EXPECTF--
15+
Fatal error: Uncaught Exception in %s:%d
16+
Stack trace:
17+
#0 %s(%d): main('12345678901234567890123...')
18+
#1 {main}
19+
thrown in %s on line %d

Zend/tests/exception_025.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
zend.exception_string_param_max_len ini setting
3+
--FILE--
4+
<?php
5+
6+
function main($arg) {
7+
echo (new Exception()), "\n";
8+
}
9+
var_dump(ini_set('zend.exception_string_param_max_len', '-1'));
10+
var_dump(ini_set('zend.exception_string_param_max_len', '1000001'));
11+
var_dump(ini_set('zend.exception_string_param_max_len', '1000000'));
12+
var_dump(ini_set('zend.exception_string_param_max_len', '20'));
13+
main('short');
14+
main('123456789012345678901234567890');
15+
var_dump(ini_set('zend.exception_string_param_max_len', '0'));
16+
main('short');
17+
main('');
18+
19+
?>
20+
--EXPECTF--
21+
bool(false)
22+
bool(false)
23+
string(2) "15"
24+
string(7) "1000000"
25+
Exception in %s:%d
26+
Stack trace:
27+
#0 %s(10): main('short')
28+
#1 {main}
29+
Exception in %s:%d
30+
Stack trace:
31+
#0 %s(11): main('12345678901234567890...')
32+
#1 {main}
33+
string(2) "20"
34+
Exception in %s:%d
35+
Stack trace:
36+
#0 %s(13): main('...')
37+
#1 {main}
38+
Exception in %s:%d
39+
Stack trace:
40+
#0 %s(14): main('')
41+
#1 {main}

Zend/zend.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,20 @@ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
160160
}
161161
/* }}} */
162162

163+
static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */
164+
{
165+
zend_long i;
166+
167+
ZEND_ATOL(i, ZSTR_VAL(new_value));
168+
if (i >= 0 && i <= 1000000) {
169+
EG(exception_string_param_max_len) = i;
170+
return SUCCESS;
171+
} else {
172+
return FAILURE;
173+
}
174+
}
175+
/* }}} */
176+
163177
#if ZEND_DEBUG
164178
# define SIGNAL_CHECK_DEFAULT "1"
165179
#else
@@ -177,6 +191,7 @@ ZEND_INI_BEGIN()
177191
STD_ZEND_INI_BOOLEAN("zend.signal_check", SIGNAL_CHECK_DEFAULT, ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
178192
#endif
179193
STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals)
194+
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)
180195
ZEND_INI_END()
181196

182197
ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */

Zend/zend_exceptions.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,8 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */
482482
break;
483483
case IS_STRING:
484484
smart_str_appendc(str, '\'');
485-
smart_str_append_escaped(str, Z_STRVAL_P(arg), MIN(Z_STRLEN_P(arg), 15));
486-
if (Z_STRLEN_P(arg) > 15) {
485+
smart_str_append_escaped(str, Z_STRVAL_P(arg), MIN(Z_STRLEN_P(arg), EG(exception_string_param_max_len)));
486+
if (Z_STRLEN_P(arg) > EG(exception_string_param_max_len)) {
487487
smart_str_appends(str, "...', ");
488488
} else {
489489
smart_str_appends(str, "', ");

Zend/zend_globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ struct _zend_executor_globals {
241241
HashTable weakrefs;
242242

243243
zend_bool exception_ignore_args;
244+
zend_long exception_string_param_max_len;
244245

245246
zend_get_gc_buffer get_gc_buffer;
246247

main/main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@ static PHP_INI_MH(OnSetSerializePrecision)
260260
}
261261
/* }}} */
262262

263-
264263
/* {{{ PHP_INI_MH */
265264
static PHP_INI_MH(OnChangeMemoryLimit)
266265
{

php.ini-development

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@
159159
; Development Value: Off
160160
; Production Value: On
161161

162+
; zend.exception_string_param_max_len
163+
; Default Value: 15
164+
; Development Value: 15
165+
; Production Value: 0
166+
162167
;;;;;;;;;;;;;;;;;;;;
163168
; php.ini Options ;
164169
;;;;;;;;;;;;;;;;;;;;
@@ -371,6 +376,14 @@ zend.enable_gc = On
371376
; Production Value: On
372377
zend.exception_ignore_args = Off
373378

379+
; Allows setting the maximum string length in an argument of a stringified stack trace
380+
; to a value between 0 and 1000000.
381+
; This has no effect when zend.exception_ignore_args is enabled.
382+
; Default Value: 15
383+
; Development Value: 15
384+
; Production Value: 0
385+
zend.exception_string_param_max_len = 15
386+
374387
;;;;;;;;;;;;;;;;;
375388
; Miscellaneous ;
376389
;;;;;;;;;;;;;;;;;

php.ini-production

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@
159159
; Development Value: Off
160160
; Production Value: On
161161

162+
; zend.exception_string_param_max_len
163+
; Default Value: 15
164+
; Development Value: 15
165+
; Production Value: 0
166+
162167
;;;;;;;;;;;;;;;;;;;;
163168
; php.ini Options ;
164169
;;;;;;;;;;;;;;;;;;;;
@@ -366,13 +371,23 @@ zend.enable_gc = On
366371
;zend.script_encoding =
367372

368373
; Allows to include or exclude arguments from stack traces generated for exceptions
369-
; In production, it is recommended to turn this setting on to prohibit the output
374+
; In production, it is recommended to turn this setting on to prohibit the output
370375
; of sensitive information in stack traces
371376
; Default Value: Off
372377
; Development Value: Off
373378
; Production Value: On
374379
zend.exception_ignore_args = On
375380

381+
; Allows setting the maximum string length in an argument of a stringified stack trace
382+
; to a value between 0 and 1000000.
383+
; This has no effect when zend.exception_ignore_args is enabled.
384+
; Default Value: 15
385+
; Development Value: 15
386+
; Production Value: 0
387+
; In production, it is recommended to set this to 0 to reduce the output
388+
; of sensitive information in stack traces.
389+
zend.exception_string_param_max_len = 0
390+
376391
;;;;;;;;;;;;;;;;;
377392
; Miscellaneous ;
378393
;;;;;;;;;;;;;;;;;

run-tests.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ function main()
343343
'opcache.jit_hot_side_exit=1',
344344
'zend.assertions=1',
345345
'zend.exception_ignore_args=0',
346+
'zend.exception_string_param_max_len=15',
346347
'short_open_tag=0',
347348
);
348349

0 commit comments

Comments
 (0)