Skip to content

Commit ed2a242

Browse files
committed
Fix signed shift UB
1 parent 82a34e7 commit ed2a242

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

Zend/zend_operators.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,8 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op
17571757
zval_ptr_dtor(result);
17581758
}
17591759

1760-
ZVAL_LONG(result, op1_lval << op2_lval);
1760+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
1761+
ZVAL_LONG(result, (zend_long) ((zend_ulong) op1_lval << op2_lval));
17611762
return SUCCESS;
17621763
}
17631764
/* }}} */

Zend/zend_vm_def.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,9 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(6, ZEND_SL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
227227
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
228228
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
229229
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
230-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
230+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
231+
ZVAL_LONG(EX_VAR(opline->result.var),
232+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
231233
ZEND_VM_NEXT_OPCODE();
232234
}
233235

Zend/zend_vm_execute.h

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4507,7 +4507,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CON
45074507
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
45084508
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
45094509
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
4510-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
4510+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
4511+
ZVAL_LONG(EX_VAR(opline->result.var),
4512+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
45114513
ZEND_VM_NEXT_OPCODE();
45124514
}
45134515

@@ -6821,7 +6823,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMPVAR_HANDLER(Z
68216823
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
68226824
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
68236825
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
6824-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
6826+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
6827+
ZVAL_LONG(EX_VAR(opline->result.var),
6828+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
68256829
ZEND_VM_NEXT_OPCODE();
68266830
}
68276831

@@ -9471,7 +9475,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_
94719475
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
94729476
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
94739477
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
9474-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
9478+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
9479+
ZVAL_LONG(EX_VAR(opline->result.var),
9480+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
94759481
ZEND_VM_NEXT_OPCODE();
94769482
}
94779483

@@ -12926,7 +12932,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CONST_HANDLER(Z
1292612932
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
1292712933
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
1292812934
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
12929-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
12935+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
12936+
ZVAL_LONG(EX_VAR(opline->result.var),
12937+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
1293012938
ZEND_VM_NEXT_OPCODE();
1293112939
}
1293212940

@@ -14510,7 +14518,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_TMPVAR_HANDLER(
1451014518
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
1451114519
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
1451214520
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
14513-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
14521+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
14522+
ZVAL_LONG(EX_VAR(opline->result.var),
14523+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
1451414524
ZEND_VM_NEXT_OPCODE();
1451514525
}
1451614526

@@ -16214,7 +16224,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_TMPVAR_CV_HANDLER(ZEND
1621416224
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
1621516225
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
1621616226
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
16217-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
16227+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
16228+
ZVAL_LONG(EX_VAR(opline->result.var),
16229+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
1621816230
ZEND_VM_NEXT_OPCODE();
1621916231
}
1622016232

@@ -38589,7 +38601,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_
3858938601
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
3859038602
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
3859138603
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
38592-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
38604+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
38605+
ZVAL_LONG(EX_VAR(opline->result.var),
38606+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
3859338607
ZEND_VM_NEXT_OPCODE();
3859438608
}
3859538609

@@ -42459,7 +42473,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_TMPVAR_HANDLER(ZEND
4245942473
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
4246042474
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
4246142475
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
42462-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
42476+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
42477+
ZVAL_LONG(EX_VAR(opline->result.var),
42478+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
4246342479
ZEND_VM_NEXT_OPCODE();
4246442480
}
4246542481

@@ -47894,7 +47910,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPC
4789447910
if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)
4789547911
&& EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)
4789647912
&& EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) {
47897-
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) << Z_LVAL_P(op2));
47913+
/* Perform shift on unsigned numbers to get well-defined wrap behavior. */
47914+
ZVAL_LONG(EX_VAR(opline->result.var),
47915+
(zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2)));
4789847916
ZEND_VM_NEXT_OPCODE();
4789947917
}
4790047918

0 commit comments

Comments
 (0)