summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_operators.c3
-rw-r--r--Zend/zend_vm_def.h4
-rw-r--r--Zend/zend_vm_execute.h36
3 files changed, 32 insertions, 11 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 384884965d..14019a5afa 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1757,7 +1757,8 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op
zval_ptr_dtor(result);
}
- ZVAL_LONG(result, op1_lval << op2_lval);
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(result, (zend_long) ((zend_ulong) op1_lval << op2_lval));
return SUCCESS;
}
/* }}} */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 2cb9d038a4..ab0a6fbd1c 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -227,7 +227,9 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(6, ZEND_SL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index e6d8e88473..7b535d62bf 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4507,7 +4507,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CON
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
@@ -6821,7 +6823,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMPVAR_HANDLER(Z
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
@@ -9471,7 +9475,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
@@ -12926,7 +12932,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CONST_HANDLER(Z
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
@@ -14510,7 +14518,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER(
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
@@ -16214,7 +16224,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CV_HANDLER(ZEND
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
@@ -38589,7 +38601,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
@@ -42459,7 +42473,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_TMPVAR_HANDLER(ZEND
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}
@@ -47894,7 +47910,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPC
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
- ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
+ /* Perform shift on unsigned numbers to get well-defined wrap behavior. */
+ ZVAL_LONG(EX_VAR(opline->result.var),
+ (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
ZEND_VM_NEXT_OPCODE();
}