1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
From 2e6d70787c93413daecbea529bf0f74fa901d1db Mon Sep 17 00:00:00 2001
From: Xinchen Hui <laruence@gmail.com>
Date: Tue, 29 Mar 2016 17:14:36 +0800
Subject: [PATCH] Fixed bug #71914 (Reference is lost in "switch")
---
NEWS | 1 +
Zend/tests/bug71914.phpt | 25 +++++++++++++++++++++++++
Zend/zend_vm_def.h | 2 +-
Zend/zend_vm_execute.h | 18 +++++++++---------
4 files changed, 36 insertions(+), 10 deletions(-)
create mode 100644 Zend/tests/bug71914.phpt
diff --git a/Zend/tests/bug71914.phpt b/Zend/tests/bug71914.phpt
new file mode 100644
index 0000000..8f825f8
--- /dev/null
+++ b/Zend/tests/bug71914.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #71914 (Reference is lost in "switch")
+--FILE--
+<?php
+
+function bug(&$value) {
+ switch ($value) {
+ case "xxxx":
+ $value = true;
+ break;
+ }
+}
+
+
+function test($arr, &$dummy) {
+ bug($arr["str"]);
+ var_dump($arr["str"]);
+}
+
+
+$array = array("str" => "xxxx");
+test($array, $array["str"]);
+?>
+--EXPECT--
+bool(true)
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 2c721c3..8e658f5 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -4903,7 +4903,7 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
SAVE_OPLINE();
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if ((OP1_TYPE & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c719aa2..bdc1bd7 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -5858,7 +5858,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(
SAVE_OPLINE();
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if ((IS_CONST & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
@@ -9654,7 +9654,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN
SAVE_OPLINE();
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if ((IS_CONST & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
@@ -11428,7 +11428,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER
SAVE_OPLINE();
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if ((IS_CONST & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
@@ -32184,7 +32184,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN
SAVE_OPLINE();
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if ((IS_CV & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
@@ -37280,7 +37280,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O
SAVE_OPLINE();
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if ((IS_CV & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
@@ -39873,7 +39873,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE
SAVE_OPLINE();
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if ((IS_CV & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
@@ -42108,7 +42108,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER
SAVE_OPLINE();
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if (((IS_TMP_VAR|IS_VAR) & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
@@ -44256,7 +44256,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE
SAVE_OPLINE();
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if (((IS_TMP_VAR|IS_VAR) & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
@@ -45403,7 +45403,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLE
SAVE_OPLINE();
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
- } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+ } else if (((IS_TMP_VAR|IS_VAR) & IS_VAR) && UNEXPECTED(Z_ISREF_P(op1))) {
/* Don't keep lock on reference, lock the value instead */
if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
ZVAL_UNREF(op1);
--
2.1.4
From 256593abcf0452d2a95cc1869baeeaea0d72d2a7 Mon Sep 17 00:00:00 2001
From: Xinchen Hui <laruence@gmail.com>
Date: Tue, 29 Mar 2016 17:52:58 +0800
Subject: [PATCH] Update tests
---
Zend/tests/bug71914.phpt | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Zend/tests/bug71914.phpt b/Zend/tests/bug71914.phpt
index 8f825f8..a43eb56 100644
--- a/Zend/tests/bug71914.phpt
+++ b/Zend/tests/bug71914.phpt
@@ -11,15 +11,30 @@ function bug(&$value) {
}
}
+function returnArray() {
+ $array = array();
+ $array["str"] = "xxxx";
+ return $array;
+}
+
+class Foo {
+ public $array = array("str" => "xxxx");
+}
function test($arr, &$dummy) {
bug($arr["str"]);
var_dump($arr["str"]);
}
+$foo = new Foo();
+$arr = returnArray();
$array = array("str" => "xxxx");
test($array, $array["str"]);
+test($arr, $arr["str"]);
+test($foo->array, $foo->array["str"]);
?>
--EXPECT--
bool(true)
+bool(true)
+bool(true)
--
2.1.4
|