@@ -731,11 +731,13 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
731
731
* have read the values of op1 and op2.
732
732
*/
733
733
734
+ zend_long sum = (zend_long ) ((zend_ulong ) Z_LVAL_P (op1 ) + (zend_ulong ) Z_LVAL_P (op2 ));
735
+
734
736
if (UNEXPECTED ((Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) == (Z_LVAL_P (op2 ) & LONG_SIGN_MASK )
735
- && (Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (( Z_LVAL_P ( op1 ) + Z_LVAL_P ( op2 )) & LONG_SIGN_MASK ))) {
737
+ && (Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (sum & LONG_SIGN_MASK ))) {
736
738
ZVAL_DOUBLE (result , (double ) Z_LVAL_P (op1 ) + (double ) Z_LVAL_P (op2 ));
737
739
} else {
738
- ZVAL_LONG (result , Z_LVAL_P ( op1 ) + Z_LVAL_P ( op2 ) );
740
+ ZVAL_LONG (result , sum );
739
741
}
740
742
#endif
741
743
}
@@ -813,11 +815,19 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
813
815
ZVAL_LONG (result , llresult );
814
816
}
815
817
#else
816
- ZVAL_LONG (result , Z_LVAL_P (op1 ) - Z_LVAL_P (op2 ));
818
+ /*
819
+ * 'result' may alias with op1 or op2, so we need to
820
+ * ensure that 'result' is not updated until after we
821
+ * have read the values of op1 and op2.
822
+ */
823
+
824
+ zend_long sub = (zend_long ) ((zend_ulong ) Z_LVAL_P (op1 ) - (zend_ulong ) Z_LVAL_P (op2 ));
817
825
818
826
if (UNEXPECTED ((Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (Z_LVAL_P (op2 ) & LONG_SIGN_MASK )
819
- && (Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (Z_LVAL_P ( result ) & LONG_SIGN_MASK ))) {
827
+ && (Z_LVAL_P (op1 ) & LONG_SIGN_MASK ) != (sub & LONG_SIGN_MASK ))) {
820
828
ZVAL_DOUBLE (result , (double ) Z_LVAL_P (op1 ) - (double ) Z_LVAL_P (op2 ));
829
+ } else {
830
+ ZVAL_LONG (result , sub );
821
831
}
822
832
#endif
823
833
}
0 commit comments