From ae77c7b057c548cb352cd78d60734c273101ea16 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 2 Oct 2020 12:08:00 +0200 Subject: [PATCH] Return correct result code for division by zero Turns out we do need to return FAILURE here on div by zero exception. Use a three-way return value from div_function_base. Fixes oss-fuzz #25975. --- Zend/tests/div_by_zero_in_static.phpt | 11 +++++++++++ Zend/zend_operators.c | 23 ++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 Zend/tests/div_by_zero_in_static.phpt diff --git a/Zend/tests/div_by_zero_in_static.phpt b/Zend/tests/div_by_zero_in_static.phpt new file mode 100644 index 0000000000..2d7a908e73 --- /dev/null +++ b/Zend/tests/div_by_zero_in_static.phpt @@ -0,0 +1,11 @@ +--TEST-- +Division by zero in static +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught DivisionByZeroError: Division by zero in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 5f9dbe3d3c..e7fb82e04f 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1253,7 +1253,9 @@ ZEND_API zend_result ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *o } /* }}} */ -static zend_result ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval *op2) /* {{{ */ +/* Returns SUCCESS/FAILURE/TYPES_NOT_HANDLED */ +#define TYPES_NOT_HANDLED 1 +static int ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval *op2) /* {{{ */ { zend_uchar type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2)); @@ -1290,14 +1292,14 @@ static zend_result ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2)); return SUCCESS; } else { - return FAILURE; + return TYPES_NOT_HANDLED; } division_by_0: if (result != op1) { ZVAL_UNDEF(result); } zend_throw_error(zend_ce_division_by_zero_error, "Division by zero"); - return SUCCESS; + return FAILURE; } /* }}} */ @@ -1305,8 +1307,10 @@ ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *o { ZVAL_DEREF(op1); ZVAL_DEREF(op2); - if (div_function_base(result, op1, op2) == SUCCESS) { - return SUCCESS; + + int retval = div_function_base(result, op1, op2); + if (retval != TYPES_NOT_HANDLED) { + return retval; } ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV); @@ -1325,12 +1329,9 @@ ZEND_API zend_result ZEND_FASTCALL div_function(zval *result, zval *op1, zval *o zval_ptr_dtor(result); } - if (div_function_base(result, &op1_copy, &op2_copy) == SUCCESS) { - return SUCCESS; - } - - ZEND_ASSERT(0 && "Operation must succeed"); - return FAILURE; + retval = div_function_base(result, &op1_copy, &op2_copy); + ZEND_ASSERT(retval != TYPES_NOT_HANDLED && "Types should be handled"); + return retval; } /* }}} */ -- 2.50.1