@@ -777,11 +777,13 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
777777 * have read the values of op1 and op2.
778778 */
779779
780+ zend_long sum = (zend_long ) ((zend_ulong ) Z_LVAL_P (op1 ) + (zend_ulong ) Z_LVAL_P (op2 ));
781+
780782 if (UNEXPECTED ((Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) == (Z_LVAL_P (op2 ) & LONG_SIGN_MASK )
781- && (Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (( Z_LVAL_P ( op1 ) + Z_LVAL_P ( op2 )) & LONG_SIGN_MASK ))) {
783+ && (Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (sum & LONG_SIGN_MASK ))) {
782784 ZVAL_DOUBLE (result , (double ) Z_LVAL_P (op1 ) + (double ) Z_LVAL_P (op2 ));
783785 } else {
784- ZVAL_LONG (result , Z_LVAL_P ( op1 ) + Z_LVAL_P ( op2 ) );
786+ ZVAL_LONG (result , sum );
785787 }
786788#endif
787789}
@@ -873,11 +875,19 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
873875 ZVAL_LONG (result , llresult );
874876 }
875877#else
876- ZVAL_LONG (result , Z_LVAL_P (op1 ) - Z_LVAL_P (op2 ));
878+ /*
879+ * 'result' may alias with op1 or op2, so we need to
880+ * ensure that 'result' is not updated until after we
881+ * have read the values of op1 and op2.
882+ */
883+
884+ zend_long sub = (zend_long ) ((zend_ulong ) Z_LVAL_P (op1 ) - (zend_ulong ) Z_LVAL_P (op2 ));
877885
878886 if (UNEXPECTED ((Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (Z_LVAL_P (op2 ) & LONG_SIGN_MASK )
879- && (Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (Z_LVAL_P ( result ) & LONG_SIGN_MASK ))) {
887+ && (Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (sub & LONG_SIGN_MASK ))) {
880888 ZVAL_DOUBLE (result , (double ) Z_LVAL_P (op1 ) - (double ) Z_LVAL_P (op2 ));
889+ } else {
890+ ZVAL_LONG (result , sub );
881891 }
882892#endif
883893}
0 commit comments