summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2017-07-04 16:09:28 +0300
committerDmitry Stogov <dmitry@zend.com>2017-07-04 16:09:28 +0300
commit0965a4ef9ffe37e7224f52a6902c3805582945ed (patch)
tree915e0f38e8b0907b19f486f7ad841e1829ee64f3
parent6276268b77791884e63bfd1404ebbf64ff5b8385 (diff)
downloadphp-git-0965a4ef9ffe37e7224f52a6902c3805582945ed.tar.gz
Check for exceptional cases before actual constant evaluation.
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index bf7eb4ba62..2179cf267c 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -58,19 +58,47 @@ int zend_optimizer_eval_binary_op(zval *result, zend_uchar opcode, zval *op1, zv
binary_op_type binary_op = get_binary_op(opcode);
int er, ret;
- if ((opcode == ZEND_DIV || opcode == ZEND_MOD) &&
- zval_get_long(op2) == 0) {
- /* div by 0 */
- return FAILURE;
- } else if ((opcode == ZEND_SL || opcode == ZEND_SR) &&
- zval_get_long(op2) < 0) {
- /* shift by negative number */
- return FAILURE;
- } else if (zend_binary_op_produces_numeric_string_error(opcode, op1, op2)) {
+ if (zend_binary_op_produces_numeric_string_error(opcode, op1, op2)) {
/* produces numeric string E_NOTICE/E_WARNING */
return FAILURE;
}
+ switch (opcode) {
+ case ZEND_ADD:
+ if ((Z_TYPE_P(op1) == IS_ARRAY
+ || Z_TYPE_P(op2) == IS_ARRAY)
+ && Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
+ /* produces "Unsupported operand types" exception */
+ return FAILURE;
+ }
+ break;
+ case ZEND_DIV:
+ case ZEND_MOD:
+ if (zval_get_long(op2) == 0) {
+ /* division by 0 */
+ return FAILURE;
+ }
+ /* break missing intentionally */
+ case ZEND_SUB:
+ case ZEND_MUL:
+ case ZEND_POW:
+ case ZEND_CONCAT:
+ case ZEND_FAST_CONCAT:
+ if (Z_TYPE_P(op1) == IS_ARRAY
+ || Z_TYPE_P(op2) == IS_ARRAY) {
+ /* produces "Unsupported operand types" exception */
+ return FAILURE;
+ }
+ break;
+ case ZEND_SL:
+ case ZEND_SR:
+ if (zval_get_long(op2) < 0) {
+ /* shift by negative number */
+ return FAILURE;
+ }
+ break;
+ }
+
er = EG(error_reporting);
EG(error_reporting) = 0;
ret = binary_op(result, op1, op2);
@@ -85,6 +113,13 @@ int zend_optimizer_eval_unary_op(zval *result, zend_uchar opcode, zval *op1) /*
unary_op_type unary_op = get_unary_op(opcode);
if (unary_op) {
+ if (opcode == ZEND_BW_NOT
+ && Z_TYPE_P(op1) != IS_LONG
+ && Z_TYPE_P(op1) != IS_DOUBLE
+ && Z_TYPE_P(op1) != IS_STRING) {
+ /* produces "Unsupported operand types" exception */
+ return FAILURE;
+ }
return unary_op(result, op1);
} else { /* ZEND_BOOL */
ZVAL_BOOL(result, zend_is_true(op1));