diff options
Diffstat (limited to 'ext/spl/spl_iterators.c')
-rw-r--r-- | ext/spl/spl_iterators.c | 98 |
1 files changed, 82 insertions, 16 deletions
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index b590371f9c..e5c25975e7 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -139,6 +139,19 @@ static zend_object_handlers spl_handlers_dual_it; (var) = it; \ } while (0) +#define SPL_FETCH_SUB_ELEMENT(var, object, element) \ + do { \ + if(!(object)->iterators) { \ + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, \ + "The object is in an invalid state as the parent constructor was not called"); \ + return; \ + } \ + (var) = (object)->iterators[(object)->level].element; \ + } while (0) + +#define SPL_FETCH_SUB_ITERATOR(var, object) SPL_FETCH_SUB_ELEMENT(var, object, iterator) + + static void spl_recursive_it_dtor(zend_object_iterator *_iter TSRMLS_DC) { spl_recursive_it_iterator *iter = (spl_recursive_it_iterator*)_iter; @@ -161,7 +174,10 @@ static int spl_recursive_it_valid_ex(spl_recursive_it_object *object, zval *zthi { zend_object_iterator *sub_iter; int level = object->level; - + + if(!object->iterators) { + return FAILURE; + } while (level >=0) { sub_iter = object->iterators[level].iterator; if (sub_iter->funcs->valid(sub_iter TSRMLS_CC) == SUCCESS) { @@ -212,6 +228,8 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv zend_object_iterator *sub_iter; int has_children; + SPL_FETCH_SUB_ITERATOR(iterator, object); + while (!EG(exception)) { next_step: iterator = object->iterators[object->level].iterator; @@ -375,9 +393,7 @@ static void spl_recursive_it_rewind_ex(spl_recursive_it_object *object, zval *zt { zend_object_iterator *sub_iter; - if (!object->iterators) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "The %s instance wasn't initialized properly", Z_OBJCE_P(zthis)->name); - } + SPL_FETCH_SUB_ITERATOR(sub_iter, object); while (object->level) { sub_iter = object->iterators[object->level].iterator; @@ -597,7 +613,7 @@ SPL_METHOD(RecursiveIteratorIterator, rewind) SPL_METHOD(RecursiveIteratorIterator, valid) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -610,12 +626,14 @@ SPL_METHOD(RecursiveIteratorIterator, valid) SPL_METHOD(RecursiveIteratorIterator, key) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - zend_object_iterator *iterator = object->iterators[object->level].iterator; - + zend_object_iterator *iterator; + if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_SUB_ITERATOR(iterator, object); + if (iterator->funcs->get_current_key) { iterator->funcs->get_current_key(iterator, return_value TSRMLS_CC); } else { @@ -628,13 +646,15 @@ SPL_METHOD(RecursiveIteratorIterator, key) SPL_METHOD(RecursiveIteratorIterator, current) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - zend_object_iterator *iterator = object->iterators[object->level].iterator; + zend_object_iterator *iterator; zval **data; if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_SUB_ITERATOR(iterator, object); + iterator->funcs->get_current_data(iterator, &data TSRMLS_CC); if (data && *data) { RETURN_ZVAL(*data, 1, 0); @@ -673,6 +693,7 @@ SPL_METHOD(RecursiveIteratorIterator, getSubIterator) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); php_int_t level = object->level; + zval *zobject; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|i", &level) == FAILURE) { return; @@ -680,6 +701,13 @@ SPL_METHOD(RecursiveIteratorIterator, getSubIterator) if (level < 0 || level > object->level) { RETURN_NULL(); } + + if(!object->iterators) { + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, + "The object is in an invalid state as the parent constructor was not called"); + return; + } + RETURN_ZVAL(object->iterators[level].zobject, 1, 0); } /* }}} */ @@ -688,13 +716,15 @@ SPL_METHOD(RecursiveIteratorIterator, getSubIterator) SPL_METHOD(RecursiveIteratorIterator, getInnerIterator) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - php_int_t level = object->level; + zval *zobject; if (zend_parse_parameters_none() == FAILURE) { return; } - - RETURN_ZVAL(object->iterators[level].zobject, 1, 0); + + SPL_FETCH_SUB_ELEMENT(zobject, object, zobject); + + RETURN_ZVAL(zobject, 1, 0); } /* }}} */ /* {{{ proto RecursiveIterator RecursiveIteratorIterator::beginIteration() @@ -722,13 +752,19 @@ SPL_METHOD(RecursiveIteratorIterator, endIteration) SPL_METHOD(RecursiveIteratorIterator, callHasChildren) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - zend_class_entry *ce = object->iterators[object->level].ce; + zend_class_entry *ce; zval *retval, *zobject; if (zend_parse_parameters_none() == FAILURE) { return; } + if (!object->iterators) { + RETURN_NULL(); + } + + SPL_FETCH_SUB_ELEMENT(ce, object, ce); + zobject = object->iterators[object->level].zobject; if (!zobject) { RETURN_FALSE; @@ -747,13 +783,15 @@ SPL_METHOD(RecursiveIteratorIterator, callHasChildren) SPL_METHOD(RecursiveIteratorIterator, callGetChildren) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - zend_class_entry *ce = object->iterators[object->level].ce; + zend_class_entry *ce; zval *retval, *zobject; if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_SUB_ELEMENT(ce, object, ce); + zobject = object->iterators[object->level].zobject; if (!zobject) { return; @@ -1072,6 +1110,13 @@ SPL_METHOD(RecursiveTreeIterator, getPrefix) if (zend_parse_parameters_none() == FAILURE) { return; } + + if(!object->iterators) { + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, + "The object is in an invalid state as the parent constructor was not called"); + return; + } + spl_recursive_tree_iterator_get_prefix(object, return_value TSRMLS_CC); } /* }}} */ @@ -1100,6 +1145,12 @@ SPL_METHOD(RecursiveTreeIterator, getEntry) if (zend_parse_parameters_none() == FAILURE) { return; } + + if(!object->iterators) { + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, + "The object is in an invalid state as the parent constructor was not called"); + return; + } spl_recursive_tree_iterator_get_entry(object, return_value TSRMLS_CC); } /* }}} */ @@ -1113,6 +1164,12 @@ SPL_METHOD(RecursiveTreeIterator, getPostfix) if (zend_parse_parameters_none() == FAILURE) { return; } + + if(!object->iterators) { + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, + "The object is in an invalid state as the parent constructor was not called"); + return; + } spl_recursive_tree_iterator_get_postfix(object, return_value TSRMLS_CC); } /* }}} */ @@ -1130,10 +1187,17 @@ SPL_METHOD(RecursiveTreeIterator, current) return; } + if(!object->iterators) { + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, + "The object is in an invalid state as the parent constructor was not called"); + return; + } + if (object->flags & RTIT_BYPASS_CURRENT) { - zend_object_iterator *iterator = object->iterators[object->level].iterator; + zend_object_iterator *iterator; zval **data; + SPL_FETCH_SUB_ITERATOR(iterator, object); iterator->funcs->get_current_data(iterator, &data TSRMLS_CC); if (data && *data) { RETURN_ZVAL(*data, 1, 0); @@ -1177,7 +1241,7 @@ SPL_METHOD(RecursiveTreeIterator, current) SPL_METHOD(RecursiveTreeIterator, key) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - zend_object_iterator *iterator = object->iterators[object->level].iterator; + zend_object_iterator *iterator; zval prefix, key, postfix, key_copy; char *str, *ptr; size_t str_len; @@ -1186,6 +1250,8 @@ SPL_METHOD(RecursiveTreeIterator, key) return; } + SPL_FETCH_SUB_ITERATOR(iterator, object); + if (iterator->funcs->get_current_key) { iterator->funcs->get_current_key(iterator, &key TSRMLS_CC); } else { @@ -1899,7 +1965,7 @@ SPL_METHOD(RecursiveCallbackFilterIterator, getChildren) return; } - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); if (!EG(exception) && retval) { |