Skip to content

Commit 9174984

Browse files
committed
Fix OSS-Fuzz #427814456
The first warning may trigger an error handler, destroying the operand and its string. So we need to protect the string in that case. Care was taken to avoid unnecessary refcounts and to avoid touching the hot code path. Closes GH-18951.
1 parent fc49d33 commit 9174984

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ PHP NEWS
88
- Core:
99
. Fixed bug GH-18833 (Use after free with weakmaps dependent on destruction
1010
order). (Daniil Gentili)
11+
. Fix OSS-Fuzz #427814456. (nielsdos)
1112

1213
- Curl:
1314
. Fix memory leaks when returning refcounted value from curl callback.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
OSS-Fuzz #427814456
3+
--FILE--
4+
<?php
5+
set_error_handler(function(){unset($GLOBALS['x']);});
6+
$x = str_repeat("3e33", random_int(2, 2));
7+
$x & true;
8+
echo "Done\n";
9+
?>
10+
--EXPECT--
11+
Done

Zend/zend_operators.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
401401
zend_long lval;
402402
double dval;
403403
bool trailing_data = false;
404+
zend_string *op_str = NULL; /* protect against error handlers */
404405

405406
/* For BC reasons we allow errors so that we can warn on leading numeric string */
406407
type = is_numeric_string_ex(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval,
@@ -410,6 +411,9 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
410411
return 0;
411412
}
412413
if (UNEXPECTED(trailing_data)) {
414+
if (type != IS_LONG) {
415+
op_str = zend_string_copy(Z_STR_P(op));
416+
}
413417
zend_error(E_WARNING, "A non-numeric value encountered");
414418
if (UNEXPECTED(EG(exception))) {
415419
*failed = 1;
@@ -425,11 +429,12 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(const zval *
425429
*/
426430
lval = zend_dval_to_lval_cap(dval);
427431
if (!zend_is_long_compatible(dval, lval)) {
428-
zend_incompatible_string_to_long_error(Z_STR_P(op));
432+
zend_incompatible_string_to_long_error(op_str ? op_str : Z_STR_P(op));
429433
if (UNEXPECTED(EG(exception))) {
430434
*failed = 1;
431435
}
432436
}
437+
zend_tmp_string_release(op_str);
433438
return lval;
434439
}
435440
}

0 commit comments

Comments
 (0)