|
49 | 49 | #include "zend_multiply.h"
|
50 | 50 | #include "zend_object_handlers.h"
|
51 | 51 |
|
52 |
| -#define LONG_SIGN_MASK ZEND_LONG_MIN |
| 52 | +#define LONG_SIGN_MASK (((zend_ulong)1) << (8*sizeof(zend_long)-1)) |
53 | 53 |
|
54 | 54 | BEGIN_EXTERN_C()
|
55 | 55 | ZEND_API zend_result ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2);
|
@@ -723,7 +723,7 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
|
723 | 723 | */
|
724 | 724 |
|
725 | 725 | if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
|
726 |
| - && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) { |
| 726 | + && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (((zend_ulong) Z_LVAL_P(op1) + (zend_ulong) Z_LVAL_P(op2)) & LONG_SIGN_MASK))) { |
727 | 727 | ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
|
728 | 728 | } else {
|
729 | 729 | ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
|
@@ -804,11 +804,17 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
|
804 | 804 | ZVAL_LONG(result, llresult);
|
805 | 805 | }
|
806 | 806 | #else
|
807 |
| - ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); |
| 807 | + /* |
| 808 | + * 'result' may alias with op1 or op2, so we need to |
| 809 | + * ensure that 'result' is not updated until after we |
| 810 | + * have read the values of op1 and op2. |
| 811 | + */ |
808 | 812 |
|
809 | 813 | if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
|
810 |
| - && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) { |
| 814 | + && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (((zend_ulong) Z_LVAL_P(op1) - (zend_ulong) Z_LVAL_P(op2)) & LONG_SIGN_MASK))) { |
811 | 815 | ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
|
| 816 | + } else { |
| 817 | + ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); |
812 | 818 | }
|
813 | 819 | #endif
|
814 | 820 | }
|
|
0 commit comments