@@ -189,11 +189,18 @@ static pm_result match_array(zval *zv, zend_ast *pattern)
189
189
HashTable * ht = Z_ARRVAL_P (zv );
190
190
zend_ast_list * element_list = zend_ast_get_list (pattern -> child [0 ]);
191
191
192
- if (!(pattern -> attr & ZEND_ARRAY_PATTERN_NON_EXHAUSTIVE ) && element_list -> children != zend_hash_num_elements (ht )) {
193
- return PM_MISMATCH ;
192
+ if (pattern -> attr & ZEND_ARRAY_PATTERN_NON_EXHAUSTIVE ) {
193
+ if (element_list -> children > zend_hash_num_elements (ht )) {
194
+ return PM_MISMATCH ;
195
+ }
196
+ } else {
197
+ if (element_list -> children != zend_hash_num_elements (ht )) {
198
+ return PM_MISMATCH ;
199
+ }
194
200
}
195
201
196
- // FIXME: Deal with indexes properly
202
+ /* Explicit and implicit keys may not be mixed, so there's no need to
203
+ * replicate array key sequencing logic. */
197
204
zend_long index = 0 ;
198
205
199
206
for (uint32_t i = 0 ; i < element_list -> children ; i ++ ) {
@@ -213,7 +220,7 @@ static pm_result match_array(zval *zv, zend_ast *pattern)
213
220
element_zv = zend_hash_index_find (ht , index );
214
221
index ++ ;
215
222
}
216
- if (Z_TYPE_P (element_zv ) == IS_UNDEF || !zend_pattern_match_ex (element_zv , pattern_ast )) {
223
+ if (! element_zv || Z_TYPE_P (element_zv ) == IS_UNDEF || !zend_pattern_match_ex (element_zv , pattern_ast )) {
217
224
return PM_MISMATCH ;
218
225
}
219
226
}
@@ -235,12 +242,20 @@ pm_result zend_pattern_match_ex(zval *zv, zend_ast *pattern)
235
242
return match_object (zv , pattern );
236
243
case ZEND_AST_WILDCARD_PATTERN :
237
244
return PM_MATCH ;
238
- case ZEND_AST_OR_PATTERN :;
245
+ case ZEND_AST_OR_PATTERN : {
239
246
pm_result lhs = zend_pattern_match_ex (zv , pattern -> child [0 ]);
240
247
if (lhs != PM_MISMATCH ) {
241
248
return lhs ;
242
249
}
243
250
return zend_pattern_match_ex (zv , pattern -> child [1 ]);
251
+ }
252
+ case ZEND_AST_AND_PATTERN : {
253
+ pm_result lhs = zend_pattern_match_ex (zv , pattern -> child [0 ]);
254
+ if (lhs != PM_MATCH ) {
255
+ return lhs ;
256
+ }
257
+ return zend_pattern_match_ex (zv , pattern -> child [1 ]);
258
+ }
244
259
case ZEND_AST_RANGE_PATTERN :
245
260
return match_range (zv , pattern );
246
261
case ZEND_AST_BINDING_PATTERN :
0 commit comments