diff options
author | Tjerk Meesters <datibbaw@php.net> | 2014-10-06 09:40:39 +0800 |
---|---|---|
committer | Tjerk Meesters <datibbaw@php.net> | 2014-10-14 22:49:01 +0800 |
commit | 71ba533640a33bf6d034637ad68c145dec3180ba (patch) | |
tree | 9a995c6b0bdd6f6b326a315fc8d7aaecf7f01d61 /ext/spl | |
parent | b73ef0ee4a8276734f6df180148dce2f445950ed (diff) | |
download | php-git-71ba533640a33bf6d034637ad68c145dec3180ba.tar.gz |
Fixed bug #68128
Three issues are addressed:
- RecursiveRegexIterator::accept() should accept non-empty arrays without
applying any regular expression and RegexIterator::accept() should not accept
an array.
- RegexIterator::accept() should not accept an atom that fails to match
anything, even when PREG_PATTERN_ORDER is used (which would return an array
of empty arrays).
- RecursiveRegexIterator::getChildren() should pass all constructor arguments
to its child iterator instead of just the regular expression.
Diffstat (limited to 'ext/spl')
-rw-r--r-- | ext/spl/spl_engine.h | 35 | ||||
-rw-r--r-- | ext/spl/spl_iterators.c | 57 | ||||
-rw-r--r-- | ext/spl/tests/bug68128.phpt | 91 | ||||
-rw-r--r-- | ext/spl/tests/iterator_048.phpt | 5 | ||||
-rw-r--r-- | ext/spl/tests/iterator_050.phpt | 4 | ||||
-rw-r--r-- | ext/spl/tests/iterator_052.phpt | 146 | ||||
-rw-r--r-- | ext/spl/tests/iterator_053.phpt | 125 | ||||
-rw-r--r-- | ext/spl/tests/iterator_054.phpt | 2 |
8 files changed, 182 insertions, 283 deletions
diff --git a/ext/spl/spl_engine.h b/ext/spl/spl_engine.h index a67e60c105..473438bb7a 100644 --- a/ext/spl/spl_engine.h +++ b/ext/spl/spl_engine.h @@ -49,6 +49,41 @@ static inline int spl_instantiate_arg_ex2(zend_class_entry *pce, zval **retval, } /* }}} */ +/* {{{ spl_instantiate_arg_n */ +static inline void spl_instantiate_arg_n(zend_class_entry *pce, zval **retval, int argc, zval ***argv TSRMLS_DC) +{ + zend_function *func = pce->constructor; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval *dummy; + zval z_name; + + spl_instantiate(pce, retval, 0 TSRMLS_CC); + + ZVAL_STRING(&z_name, func->common.function_name, 0); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = &pce->function_table; + fci.function_name = &z_name; + fci.object_ptr = *retval; + fci.symbol_table = NULL; + fci.retval_ptr_ptr = &dummy; + fci.param_count = argc; + fci.params = argv; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = func; + fcc.calling_scope = EG(scope); + fcc.called_scope = pce; + fcc.object_ptr = *retval; + + zend_call_function(&fci, &fcc TSRMLS_CC); + + zval_ptr_dtor(&dummy); +} +/* }}} */ + #endif /* SPL_ENGINE_H */ /* diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 87a448ca64..71e03b4514 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1979,8 +1979,10 @@ SPL_METHOD(RegexIterator, accept) if (intern->current.data == NULL) { RETURN_FALSE; + } else if (Z_TYPE_P(intern->current.data) == IS_ARRAY) { + RETURN_FALSE; } - + if (intern->u.regex.flags & REGIT_USE_KEY) { subject_ptr = intern->current.key; } else { @@ -2014,8 +2016,7 @@ SPL_METHOD(RegexIterator, accept) ALLOC_INIT_ZVAL(intern->current.data); php_pcre_match_impl(intern->u.regex.pce, subject, subject_len, &zcount, intern->current.data, intern->u.regex.mode == REGIT_MODE_ALL_MATCHES, intern->u.regex.use_flags, intern->u.regex.preg_flags, 0 TSRMLS_CC); - count = zend_hash_num_elements(Z_ARRVAL_P(intern->current.data)); - RETVAL_BOOL(count > 0); + RETVAL_BOOL(Z_LVAL(zcount) > 0); break; case REGIT_MODE_SPLIT: @@ -2193,7 +2194,7 @@ SPL_METHOD(RecursiveRegexIterator, __construct) SPL_METHOD(RecursiveRegexIterator, getChildren) { spl_dual_it_object *intern; - zval *retval, *regex; + zval *retval; if (zend_parse_parameters_none() == FAILURE) { return; @@ -2203,16 +2204,61 @@ SPL_METHOD(RecursiveRegexIterator, getChildren) zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); if (!EG(exception)) { + zval **args[5], *object, *regex, *mode, *flags, *preg_flags; + + MAKE_STD_ZVAL(object); MAKE_STD_ZVAL(regex); + MAKE_STD_ZVAL(mode); + MAKE_STD_ZVAL(flags); + MAKE_STD_ZVAL(preg_flags); + + MAKE_COPY_ZVAL(&retval, object); ZVAL_STRING(regex, intern->u.regex.regex, 1); - spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), &return_value, 0, retval, regex TSRMLS_CC); + ZVAL_LONG(mode, intern->u.regex.mode); + ZVAL_LONG(flags, intern->u.regex.flags); + ZVAL_LONG(preg_flags, intern->u.regex.preg_flags); + + args[0] = &object; + args[1] = ®ex; + args[2] = &mode; + args[3] = &flags; + args[4] = &preg_flags; + + spl_instantiate_arg_n(Z_OBJCE_P(getThis()), &return_value, 5, args TSRMLS_CC); + + zval_ptr_dtor(&object); zval_ptr_dtor(®ex); + zval_ptr_dtor(&mode); + zval_ptr_dtor(&flags); + zval_ptr_dtor(&preg_flags); } if (retval) { zval_ptr_dtor(&retval); } } /* }}} */ +SPL_METHOD(RecursiveRegexIterator, accept) +{ + spl_dual_it_object *intern; + zval *rv; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); + + if (intern->current.data == NULL) { + RETURN_FALSE; + } else if (Z_TYPE_P(intern->current.data) == IS_ARRAY) { + RETURN_BOOL(zend_hash_num_elements(Z_ARRVAL_P(intern->current.data)) > 0); + } + + zend_call_method_with_0_params(&(getThis()), spl_ce_RegexIterator, NULL, "accept", &rv); + + RETURN_ZVAL(rv, 1, 1); +} + #endif /* {{{ spl_dual_it_dtor */ @@ -2403,6 +2449,7 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_RecursiveRegexIterator[] = { SPL_ME(RecursiveRegexIterator, __construct, arginfo_rec_regex_it___construct, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveRegexIterator, accept, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(RecursiveFilterIterator, hasChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(RecursiveRegexIterator, getChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) PHP_FE_END diff --git a/ext/spl/tests/bug68128.phpt b/ext/spl/tests/bug68128.phpt new file mode 100644 index 0000000000..ff41dd4931 --- /dev/null +++ b/ext/spl/tests/bug68128.phpt @@ -0,0 +1,91 @@ +--TEST-- +Bug #68128 - RecursiveRegexIterator raises "Array to string conversion" notice +--FILE-- +<?php + +$array = new ArrayIterator(array('a', array('b', 'c'))); +$regex = new RegexIterator($array, '/Array/'); + +foreach ($regex as $match) { + var_dump($match); +} + +$rArrayIterator = new RecursiveArrayIterator(array('test1', array('tet3', 'test4', 'test5'))); +$rRegexIterator = new RecursiveRegexIterator($rArrayIterator, '/^(t)est(\d*)/', + RecursiveRegexIterator::ALL_MATCHES, 0, PREG_PATTERN_ORDER); + +foreach ($rRegexIterator as $key1 => $value1) { + + if ($rRegexIterator->hasChildren()) { + + // print all children + echo "Children: "; + foreach ($rRegexIterator->getChildren() as $key => $value) { + print_r($value); + } + echo "\n"; + } else { + echo "No children "; + print_r($value1); + echo "\n"; + } +} + +?> +--EXPECT-- +No children Array +( + [0] => Array + ( + [0] => test1 + ) + + [1] => Array + ( + [0] => t + ) + + [2] => Array + ( + [0] => 1 + ) + +) + +Children: Array +( + [0] => Array + ( + [0] => test4 + ) + + [1] => Array + ( + [0] => t + ) + + [2] => Array + ( + [0] => 4 + ) + +) +Array +( + [0] => Array + ( + [0] => test5 + ) + + [1] => Array + ( + [0] => t + ) + + [2] => Array + ( + [0] => 5 + ) + +) + diff --git a/ext/spl/tests/iterator_048.phpt b/ext/spl/tests/iterator_048.phpt index bad4e7888a..64ca97f4d6 100644 --- a/ext/spl/tests/iterator_048.phpt +++ b/ext/spl/tests/iterator_048.phpt @@ -13,11 +13,6 @@ class MyRecursiveRegexIterator extends RecursiveRegexIterator var_dump($v); } } - - function accept() - { - return $this->hasChildren() || parent::accept(); - } } $ar = new RecursiveArrayIterator(array('Foo', array('Bar'), 'FooBar', array('Baz'), 'Biz')); diff --git a/ext/spl/tests/iterator_050.phpt b/ext/spl/tests/iterator_050.phpt index fed4a3b2ee..63d8fbfa9a 100644 --- a/ext/spl/tests/iterator_050.phpt +++ b/ext/spl/tests/iterator_050.phpt @@ -46,8 +46,6 @@ array(3) { [2]=> %s(1) "2" } - -Notice: Array to string conversion in %siterator_050.php on line %d int(0) array(2) { [0]=> @@ -69,8 +67,6 @@ array(2) { [1]=> %s(1) "1" } - -Notice: Array to string conversion in %siterator_050.php on line %d object(ArrayIterator)#%d (1) { %s"storage"%s"ArrayIterator":private]=> array(9) { diff --git a/ext/spl/tests/iterator_052.phpt b/ext/spl/tests/iterator_052.phpt index c68bd5234d..84b3eb993c 100644 --- a/ext/spl/tests/iterator_052.phpt +++ b/ext/spl/tests/iterator_052.phpt @@ -46,18 +46,6 @@ var_dump($ar); <?php exit(0); ?> --EXPECTF-- bool(true) -int(0) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) int(1) array(3) { @@ -97,85 +85,11 @@ array(3) { } } bool(true) -int(3) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(4) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} - -Notice: Array to string conversion in %siterator_052.php on line %d +bool(false) bool(true) -int(5) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(6) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(7) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} -bool(true) -int(8) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) int(0) array(2) { @@ -231,67 +145,11 @@ array(2) { } } bool(true) -int(3) -array(2) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } -} -bool(true) -int(4) -array(2) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } -} - -Notice: Array to string conversion in %siterator_052.php on line %d bool(true) -int(5) -array(2) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } -} +bool(false) bool(true) -int(6) -array(2) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } -} bool(true) -int(7) -array(2) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } -} bool(true) -int(8) -array(2) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } -} object(ArrayIterator)#%d (1) { ["storage":"ArrayIterator":private]=> array(9) { diff --git a/ext/spl/tests/iterator_053.phpt b/ext/spl/tests/iterator_053.phpt index 5d9c740c31..b472523ab6 100644 --- a/ext/spl/tests/iterator_053.phpt +++ b/ext/spl/tests/iterator_053.phpt @@ -46,122 +46,14 @@ var_dump($ar); <?php exit(0); ?> --EXPECTF-- bool(true) -int(0) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(1) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(2) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} -bool(true) -int(3) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(4) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(5) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} +bool(false) bool(true) -int(6) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(7) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) -int(8) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} bool(true) int(0) array(2) { @@ -232,20 +124,7 @@ array(2) { string(1) "4" } } -bool(true) -int(5) -array(2) { - [0]=> - array(1) { - [0]=> - string(1) "5" - } - [1]=> - array(1) { - [0]=> - string(1) "5" - } -} +bool(false) bool(true) int(6) array(2) { diff --git a/ext/spl/tests/iterator_054.phpt b/ext/spl/tests/iterator_054.phpt index 1f1cd580c1..91266c9571 100644 --- a/ext/spl/tests/iterator_054.phpt +++ b/ext/spl/tests/iterator_054.phpt @@ -42,8 +42,6 @@ array(3) { [2]=> string(1) "3" } - -Notice: Array to string conversion in %siterator_054.php on line %d int(7) array(2) { [0]=> |