From 642c3790925d6a692747d4a1a6ee02deef0b93b5 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 29 Jun 2015 12:58:07 +0300 Subject: [PATCH] Prevent attempts of compile-time evaluation of invalid operators (e.g. division/modulo by zero and shift by negative number) --- Zend/tests/bug69957.phpt | 84 ++++++++++++++++++++++++++++++++++++++++ Zend/zend_compile.c | 17 +++----- 2 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 Zend/tests/bug69957.phpt diff --git a/Zend/tests/bug69957.phpt b/Zend/tests/bug69957.phpt new file mode 100644 index 0000000000..3653df7d91 --- /dev/null +++ b/Zend/tests/bug69957.phpt @@ -0,0 +1,84 @@ +--TEST-- +Bug #69957 (Different ways of handling div/mod by zero) +--FILE-- +getMessage()); +} + +try { + $divisor = 0; + $result = 1 % $divisor; + var_dump($result); +} catch (Throwable $t){ + echo "\nVariable mod\n"; + printf("Type: %s\n", get_class($t)); + printf("Message: %s\n", $t->getMessage()); +} + +try { + $result = 1 / 0; + var_dump($result); +} catch (Throwable $t){ + echo "\nLiteral div\n"; + printf("Type: %s\n", get_class($t)); + printf("Message: %s\n", $t->getMessage()); +} + +try { + $result = 1 % 0; + var_dump($result); +} catch (Throwable $t){ + echo "\nLiteral mod\n"; + printf("Type: %s\n", get_class($t)); + printf("Message: %s\n", $t->getMessage()); +} + +try { + $result = 1 / 0.0; + var_dump($result); +} catch (Throwable $t){ + echo "\nDouble div\n"; + printf("Type: %s\n", get_class($t)); + printf("Message: %s\n", $t->getMessage()); +} + +try { + $result = 1 % 0.0; + var_dump($result); +} catch (Throwable $t){ + echo "\nDouble mod\n"; + printf("Type: %s\n", get_class($t)); + printf("Message: %s\n", $t->getMessage()); +} + +?> +--EXPECTF-- +Warning: Division by zero in %sbug69957.php on line %d +float(INF) + +Variable mod +Type: Exception +Message: Division by zero + +Warning: Division by zero in %sbug69957.php on line %d +float(INF) + +Literal mod +Type: Exception +Message: Division by zero + +Warning: Division by zero in %sbug69957.php on line %d +float(INF) + +Double mod +Type: Exception +Message: Division by zero + diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a42e63ec99..be70ff6643 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5625,17 +5625,12 @@ static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode binary_op_type fn = get_binary_op(opcode); /* don't evaluate division by zero at compile-time */ - if (opcode == ZEND_DIV) { - convert_scalar_to_number(op2); - if (Z_TYPE_P(op2) == IS_LONG) { - if (Z_LVAL_P(op2) == 0) { - return 0; - } - } else if (Z_TYPE_P(op2) == IS_DOUBLE) { - if (Z_DVAL_P(op2) == 0.0) { - return 0; - } - } + if ((opcode == ZEND_DIV || opcode == ZEND_MOD) && + zval_get_long(op2) == 0) { + return 0; + } else if ((opcode == ZEND_SL || opcode == ZEND_SR) && + zval_get_long(op2) < 0) { + return 0; } fn(result, op1, op2); -- 2.40.0