Skip to content

Commit 62288d7

Browse files
committed
Fix bug #73948
1 parent 38b1627 commit 62288d7

File tree

4 files changed

+79
-66
lines changed

4 files changed

+79
-66
lines changed

ext/pcre/php_pcre.c

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -942,24 +942,23 @@ static inline void add_offset_pair(zval *result, char *str, size_t len, PCRE2_SI
942942
{
943943
zval match_pair, tmp;
944944

945-
array_init_size(&match_pair, 2);
946-
947-
/* Add (match, offset) to the return value */
948-
if (PCRE2_UNSET == offset) {
949-
if (unmatched_as_null) {
950-
ZVAL_NULL(&tmp);
951-
} else {
945+
if (PCRE2_UNSET == offset && unmatched_as_null) {
946+
ZVAL_NULL(&match_pair);
947+
} else {
948+
/* Add (match, offset) to the return value */
949+
array_init_size(&match_pair, 2);
950+
if (PCRE2_UNSET == offset) {
952951
ZVAL_EMPTY_STRING(&tmp);
952+
} else {
953+
ZVAL_STRINGL(&tmp, str, len);
953954
}
954-
} else {
955-
ZVAL_STRINGL(&tmp, str, len);
955+
zend_hash_next_index_insert_new(Z_ARRVAL(match_pair), &tmp);
956+
ZVAL_LONG(&tmp, offset);
957+
zend_hash_next_index_insert_new(Z_ARRVAL(match_pair), &tmp);
956958
}
957-
zend_hash_next_index_insert_new(Z_ARRVAL(match_pair), &tmp);
958-
ZVAL_LONG(&tmp, offset);
959-
zend_hash_next_index_insert_new(Z_ARRVAL(match_pair), &tmp);
960959

961960
if (name) {
962-
Z_ADDREF(match_pair);
961+
Z_TRY_ADDREF(match_pair);
963962
zend_hash_update(Z_ARRVAL_P(result), name, &match_pair);
964963
}
965964
zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair);
@@ -982,7 +981,7 @@ static inline void populate_match_value(
982981

983982
static void populate_subpat_array(
984983
zval *subpats, char *subject, PCRE2_SIZE *offsets, zend_string **subpat_names,
985-
int count, const PCRE2_SPTR mark, zend_long flags) {
984+
uint32_t num_subpats, int count, const PCRE2_SPTR mark, zend_long flags) {
986985
zend_bool offset_capture = (flags & PREG_OFFSET_CAPTURE) != 0;
987986
zend_bool unmatched_as_null = (flags & PREG_UNMATCHED_AS_NULL) != 0;
988987
zval val;
@@ -1005,6 +1004,15 @@ static void populate_subpat_array(
10051004
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &val);
10061005
}
10071006
}
1007+
if (unmatched_as_null) {
1008+
for (i = count; i < num_subpats; i++) {
1009+
if (subpat_names[i]) {
1010+
ZVAL_NULL(&val);
1011+
zend_hash_update(Z_ARRVAL_P(subpats), subpat_names[i], &val);
1012+
}
1013+
add_next_index_null(subpats);
1014+
}
1015+
}
10081016
} else {
10091017
if (offset_capture) {
10101018
for (i = 0; i < count; i++) {
@@ -1019,6 +1027,11 @@ static void populate_subpat_array(
10191027
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &val);
10201028
}
10211029
}
1030+
if (unmatched_as_null) {
1031+
for (i = count; i < num_subpats; i++) {
1032+
add_next_index_null(subpats);
1033+
}
1034+
}
10221035
}
10231036
/* Add MARK, if available */
10241037
if (mark) {
@@ -1262,15 +1275,16 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str,
12621275
array_init_size(&result_set, count + (mark ? 1 : 0));
12631276
mark = pcre2_get_mark(match_data);
12641277
populate_subpat_array(
1265-
&result_set, subject, offsets, subpat_names, count, mark, flags);
1278+
&result_set, subject, offsets, subpat_names,
1279+
num_subpats, count, mark, flags);
12661280
/* And add it to the output array */
12671281
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &result_set);
12681282
}
12691283
} else { /* single pattern matching */
12701284
/* For each subpattern, insert it into the subpatterns array. */
12711285
mark = pcre2_get_mark(match_data);
12721286
populate_subpat_array(
1273-
subpats, subject, offsets, subpat_names, count, mark, flags);
1287+
subpats, subject, offsets, subpat_names, num_subpats, count, mark, flags);
12741288
break;
12751289
}
12761290
}
@@ -1429,14 +1443,14 @@ static int preg_get_backref(char **str, int *backref)
14291443

14301444
/* {{{ preg_do_repl_func
14311445
*/
1432-
static zend_string *preg_do_repl_func(zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *subject, PCRE2_SIZE *offsets, zend_string **subpat_names, int count, const PCRE2_SPTR mark, zend_long flags)
1446+
static zend_string *preg_do_repl_func(zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *subject, PCRE2_SIZE *offsets, zend_string **subpat_names, uint32_t num_subpats, int count, const PCRE2_SPTR mark, zend_long flags)
14331447
{
14341448
zend_string *result_str;
14351449
zval retval; /* Function return value */
14361450
zval arg; /* Argument to pass to function */
14371451

14381452
array_init_size(&arg, count + (mark ? 1 : 0));
1439-
populate_subpat_array(&arg, subject, offsets, subpat_names, count, mark, flags);
1453+
populate_subpat_array(&arg, subject, offsets, subpat_names, num_subpats, count, mark, flags);
14401454

14411455
fci->retval = &retval;
14421456
fci->param_count = 1;
@@ -1834,7 +1848,8 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
18341848
new_len = result_len + offsets[0] - start_offset; /* part before the match */
18351849

18361850
/* Use custom function to get replacement string and its length. */
1837-
eval_result = preg_do_repl_func(fci, fcc, subject, offsets, subpat_names, count,
1851+
eval_result = preg_do_repl_func(
1852+
fci, fcc, subject, offsets, subpat_names, num_subpats, count,
18381853
pcre2_get_mark(match_data), flags);
18391854

18401855
ZEND_ASSERT(eval_result);

ext/pcre/tests/bug61780_1.phpt

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ array (
3333
0 => '23',
3434
1 => 0,
3535
),
36-
1 =>
37-
array (
38-
0 => NULL,
39-
1 => -1,
40-
),
36+
1 => NULL,
4137
2 =>
4238
array (
4339
0 => '2',
@@ -96,11 +92,7 @@ array (
9692
1 =>
9793
array (
9894
0 => NULL,
99-
1 =>
100-
array (
101-
0 => NULL,
102-
1 => -1,
103-
),
95+
1 => NULL,
10496
2 =>
10597
array (
10698
0 => '4',
@@ -125,6 +117,8 @@ array (
125117
0 =>
126118
array (
127119
0 => '1',
120+
1 => NULL,
121+
2 => NULL,
128122
),
129123
1 =>
130124
array (
@@ -136,10 +130,13 @@ array (
136130
array (
137131
0 => '45',
138132
1 => '4',
133+
2 => NULL,
139134
),
140135
3 =>
141136
array (
142137
0 => '6',
138+
1 => NULL,
139+
2 => NULL,
143140
),
144141
)
145142

@@ -151,6 +148,8 @@ array (
151148
0 => '1',
152149
1 => 0,
153150
),
151+
1 => NULL,
152+
2 => NULL,
154153
),
155154
1 =>
156155
array (
@@ -159,11 +158,7 @@ array (
159158
0 => '23',
160159
1 => 1,
161160
),
162-
1 =>
163-
array (
164-
0 => NULL,
165-
1 => -1,
166-
),
161+
1 => NULL,
167162
2 =>
168163
array (
169164
0 => '2',
@@ -182,6 +177,7 @@ array (
182177
0 => '4',
183178
1 => 3,
184179
),
180+
2 => NULL,
185181
),
186182
3 =>
187183
array (
@@ -190,5 +186,7 @@ array (
190186
0 => '6',
191187
1 => 5,
192188
),
189+
1 => NULL,
190+
2 => NULL,
193191
),
194192
)

ext/pcre/tests/bug61780_2.phpt

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,8 @@ array (
3535
0 => '23',
3636
1 => 0,
3737
),
38-
'a' =>
39-
array (
40-
0 => NULL,
41-
1 => -1,
42-
),
43-
1 =>
44-
array (
45-
0 => NULL,
46-
1 => -1,
47-
),
38+
'a' => NULL,
39+
1 => NULL,
4840
'b' =>
4941
array (
5042
0 => '2',
@@ -122,11 +114,7 @@ array (
122114
'a' =>
123115
array (
124116
0 => NULL,
125-
1 =>
126-
array (
127-
0 => NULL,
128-
1 => -1,
129-
),
117+
1 => NULL,
130118
2 =>
131119
array (
132120
0 => '4',
@@ -137,11 +125,7 @@ array (
137125
1 =>
138126
array (
139127
0 => NULL,
140-
1 =>
141-
array (
142-
0 => NULL,
143-
1 => -1,
144-
),
128+
1 => NULL,
145129
2 =>
146130
array (
147131
0 => '4',
@@ -177,6 +161,10 @@ array (
177161
0 =>
178162
array (
179163
0 => '1',
164+
'a' => NULL,
165+
1 => NULL,
166+
'b' => NULL,
167+
2 => NULL,
180168
),
181169
1 =>
182170
array (
@@ -191,10 +179,16 @@ array (
191179
0 => '45',
192180
'a' => '4',
193181
1 => '4',
182+
'b' => NULL,
183+
2 => NULL,
194184
),
195185
3 =>
196186
array (
197187
0 => '6',
188+
'a' => NULL,
189+
1 => NULL,
190+
'b' => NULL,
191+
2 => NULL,
198192
),
199193
)
200194

@@ -206,6 +200,10 @@ array (
206200
0 => '1',
207201
1 => 0,
208202
),
203+
'a' => NULL,
204+
1 => NULL,
205+
'b' => NULL,
206+
2 => NULL,
209207
),
210208
1 =>
211209
array (
@@ -214,16 +212,8 @@ array (
214212
0 => '23',
215213
1 => 1,
216214
),
217-
'a' =>
218-
array (
219-
0 => NULL,
220-
1 => -1,
221-
),
222-
1 =>
223-
array (
224-
0 => NULL,
225-
1 => -1,
226-
),
215+
'a' => NULL,
216+
1 => NULL,
227217
'b' =>
228218
array (
229219
0 => '2',
@@ -252,6 +242,8 @@ array (
252242
0 => '4',
253243
1 => 3,
254244
),
245+
'b' => NULL,
246+
2 => NULL,
255247
),
256248
3 =>
257249
array (
@@ -260,5 +252,9 @@ array (
260252
0 => '6',
261253
1 => 5,
262254
),
255+
'a' => NULL,
256+
1 => NULL,
257+
'b' => NULL,
258+
2 => NULL,
263259
),
264260
)

ext/pcre/tests/preg_replace_callback_flags.phpt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,13 @@ array(1) {
9393
}
9494
string(3) "abc"
9595

96-
array(2) {
96+
array(3) {
9797
[0]=>
9898
string(1) "a"
9999
[1]=>
100100
string(1) "a"
101+
[2]=>
102+
NULL
101103
}
102104
array(3) {
103105
[0]=>
@@ -109,11 +111,13 @@ array(3) {
109111
}
110112
string(3) "abc"
111113

112-
array(2) {
114+
array(3) {
113115
[0]=>
114116
string(1) "a"
115117
[1]=>
116118
string(1) "a"
119+
[2]=>
120+
NULL
117121
}
118122
array(3) {
119123
[0]=>

0 commit comments

Comments
 (0)