]> granicus.if.org Git - php/commitdiff
Return correct result code for division by zero
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 2 Oct 2020 10:08:00 +0000 (12:08 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 2 Oct 2020 10:09:14 +0000 (12:09 +0200)
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 [new file with mode: 0644]
Zend/zend_operators.c

diff --git a/Zend/tests/div_by_zero_in_static.phpt b/Zend/tests/div_by_zero_in_static.phpt
new file mode 100644 (file)
index 0000000..2d7a908
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--
+Division by zero in static
+--FILE--
+<?php
+static $a = 1/0;
+?>
+--EXPECTF--
+Fatal error: Uncaught DivisionByZeroError: Division by zero in %s:%d
+Stack trace:
+#0 {main}
+  thrown in %s on line %d
index 5f9dbe3d3ce01ab2c89112c5cfc10b61a9d3f550..e7fb82e04fe46553662cd88f9c428d00d9620859 100644 (file)
@@ -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;
 }
 /* }}} */