Skip to content

Commit 2936f8b

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
1 parent 8664ff7 commit 2936f8b

File tree

8 files changed

+101
-3
lines changed

8 files changed

+101
-3
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_exceptions.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "zend_dtrace.h"
2929
#include "zend_smart_str.h"
3030
#include "zend_exceptions_arginfo.h"
31+
#include "php_globals.h"
3132

3233
ZEND_API zend_class_entry *zend_ce_throwable;
3334
ZEND_API zend_class_entry *zend_ce_exception;
@@ -482,8 +483,8 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */
482483
break;
483484
case IS_STRING:
484485
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) {
486+
smart_str_append_escaped(str, Z_STRVAL_P(arg), MIN(Z_STRLEN_P(arg), PG(exception_string_param_max_len)));
487+
if (Z_STRLEN_P(arg) > PG(exception_string_param_max_len)) {
487488
smart_str_appends(str, "...', ");
488489
} else {
489490
smart_str_appends(str, "', ");

main/main.c

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

263+
/* {{{ PHP_INI_MH
264+
*/
265+
static PHP_INI_MH(OnSetThrowableStringParamMaxLen)
266+
{
267+
zend_long i;
268+
269+
ZEND_ATOL(i, ZSTR_VAL(new_value));
270+
if (i >= 0 && i <= 1000000) {
271+
PG(exception_string_param_max_len) = i;
272+
return SUCCESS;
273+
} else {
274+
return FAILURE;
275+
}
276+
}
277+
/* }}} */
263278

264279
/* {{{ PHP_INI_MH */
265280
static PHP_INI_MH(OnChangeMemoryLimit)
@@ -704,6 +719,7 @@ PHP_INI_BEGIN()
704719
STD_PHP_INI_BOOLEAN("register_argc_argv", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, register_argc_argv, php_core_globals, core_globals)
705720
STD_PHP_INI_BOOLEAN("auto_globals_jit", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, auto_globals_jit, php_core_globals, core_globals)
706721
STD_PHP_INI_BOOLEAN("short_open_tag", DEFAULT_SHORT_OPEN_TAG, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, short_tags, zend_compiler_globals, compiler_globals)
722+
STD_PHP_INI_ENTRY("zend.exception_string_param_max_len", "15", PHP_INI_ALL, OnSetThrowableStringParamMaxLen, exception_string_param_max_len, php_core_globals, core_globals)
707723

708724
STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateString, unserialize_callback_func, php_core_globals, core_globals)
709725
STD_PHP_INI_ENTRY("serialize_precision", "-1", PHP_INI_ALL, OnSetSerializePrecision, serialize_precision, php_core_globals, core_globals)

main/php_globals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ struct _php_core_globals {
167167
char *syslog_ident;
168168
zend_bool have_called_openlog;
169169
zend_long syslog_filter;
170+
171+
zend_long exception_string_param_max_len;
170172
};
171173

172174

php.ini-development

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,14 @@ zend.enable_gc = On
371371
; Production Value: On
372372
zend.exception_ignore_args = Off
373373

374+
; Allows setting the maximum string length in an argument of a stringified stack trace
375+
; to a value between 0 and 1000000.
376+
; This has no effect when zend.exception_ignore_args is enabled.
377+
; Default Value: 15
378+
; Development Value: 15
379+
; Production Value: 0
380+
zend.exception_string_param_max_len = 15
381+
374382
;;;;;;;;;;;;;;;;;
375383
; Miscellaneous ;
376384
;;;;;;;;;;;;;;;;;

php.ini-production

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,23 @@ zend.enable_gc = On
366366
;zend.script_encoding =
367367

368368
; 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
369+
; In production, it is recommended to turn this setting on to prohibit the output
370370
; of sensitive information in stack traces
371371
; Default Value: Off
372372
; Development Value: Off
373373
; Production Value: On
374374
zend.exception_ignore_args = On
375375

376+
; Allows setting the maximum string length in an argument of a stringified stack trace
377+
; to a value between 0 and 1000000.
378+
; This has no effect when zend.exception_ignore_args is enabled.
379+
; Default Value: 15
380+
; Development Value: 15
381+
; Production Value: 0
382+
; In production, it is recommended to set this to 0 to reduce the output
383+
; of sensitive information in stack traces.
384+
zend.exception_string_param_max_len = 0
385+
376386
;;;;;;;;;;;;;;;;;
377387
; Miscellaneous ;
378388
;;;;;;;;;;;;;;;;;

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)