diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-08-04 13:56:27 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-08-04 13:56:27 +0400 |
commit | 7301994c28d548c5a4eda6a3a4ae0fab6af04636 (patch) | |
tree | 4058df108a4ea2499c850a23eb7cf3850dd2941d /ext/spl | |
parent | 863a603fada3ce107cb402683bc79dce1359c463 (diff) | |
parent | fe894c2154e6b013f0d0b29ca660ad719fd1affe (diff) | |
download | php-git-7301994c28d548c5a4eda6a3a4ae0fab6af04636.tar.gz |
Merge branch 'master' into phpng
* master: (46 commits)
PHP_INT_MIN and _MAX tests
NEWS and UPGRADING
Added PHP_INT_MIN
Fix wrong lenght size
Bug #51096 - Remove unnecessary ? for first/last day of
Moved streams related functions to xp_ssl.c
Remove duplicate NEWS
Update NEWS
Update NEWS
Update NEWS
BFN
BFN
Fixed bug #67715 (php-milter does not build and crashes randomly).
We need to turn off any strict mode here for this warning to show up
Disable restrictions regarding arrays in constants at run-time. For the discussion around it, see the thread on the mailing list: http://www.mail-archive.com/internals@lists.php.net/msg68245.html
Revert "Fix bug #67064 in a BC safe way"
Updated NEWS for #67693
Updated NEWS for #67693
Fixed bug #67693 - incorrect push to the empty array
add missing entry to NEWS
...
Conflicts:
Zend/tests/errmsg_040.phpt
Zend/tests/ns_059.phpt
Zend/zend_language_parser.y
Zend/zend_vm_def.h
ext/openssl/openssl.c
ext/reflection/php_reflection.c
ext/session/session.c
ext/spl/spl_directory.c
ext/spl/spl_iterators.c
ext/sqlite3/sqlite3.c
ext/standard/array.c
Diffstat (limited to 'ext/spl')
-rw-r--r-- | ext/spl/spl_directory.c | 95 | ||||
-rw-r--r-- | ext/spl/spl_iterators.c | 109 | ||||
-rw-r--r-- | ext/spl/tests/bug54281.phpt | 6 |
3 files changed, 188 insertions, 22 deletions
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 9405dafa0d..f9fe83e26d 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1596,7 +1596,7 @@ SPL_METHOD(GlobIterator, count) return; } - if (php_stream_is(intern->u.dir.dirp ,&php_glob_stream_ops)) { + if (intern->u.dir.dirp && php_stream_is(intern->u.dir.dirp ,&php_glob_stream_ops)) { RETURN_LONG(php_glob_stream_get_count(intern->u.dir.dirp, NULL)); } else { /* should not happen */ @@ -2083,6 +2083,8 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function zend_get_parameters_array_ex(pass_num_args, params + (arg2 ? 2 : 1)); + ZVAL_UNDEF(&retval); + fci.size = sizeof(fci); fci.function_table = EG(function_table); fci.object = NULL; @@ -2237,6 +2239,10 @@ static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object static void spl_filesystem_file_rewind(zval * this_ptr, spl_filesystem_object *intern TSRMLS_DC) /* {{{ */ { + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } if (-1 == php_stream_rewind(intern->u.file.stream)) { zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot rewind file %s", intern->file_name); } else { @@ -2368,6 +2374,11 @@ SPL_METHOD(SplFileObject, eof) return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + RETURN_BOOL(php_stream_eof(intern->u.file.stream)); } /* }}} */ @@ -2384,6 +2395,9 @@ SPL_METHOD(SplFileObject, valid) if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { RETURN_BOOL(intern->u.file.current_line || !Z_ISUNDEF(intern->u.file.current_zval)); } else { + if(!intern->u.file.stream) { + RETURN_FALSE; + } RETVAL_BOOL(!php_stream_eof(intern->u.file.stream)); } } /* }}} */ @@ -2398,6 +2412,11 @@ SPL_METHOD(SplFileObject, fgets) return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) { RETURN_FALSE; } @@ -2414,6 +2433,11 @@ SPL_METHOD(SplFileObject, current) return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) { spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); } @@ -2556,6 +2580,12 @@ SPL_METHOD(SplFileObject, fgetcsv) int d_len = 0, e_len = 0, esc_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { + + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + switch(ZEND_NUM_ARGS()) { case 3: @@ -2697,6 +2727,11 @@ SPL_METHOD(SplFileObject, fflush) { spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + RETURN_BOOL(!php_stream_flush(intern->u.file.stream)); } /* }}} */ @@ -2705,7 +2740,14 @@ SPL_METHOD(SplFileObject, fflush) SPL_METHOD(SplFileObject, ftell) { spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); - long ret = php_stream_tell(intern->u.file.stream); + long ret; + + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + + ret = php_stream_tell(intern->u.file.stream); if (ret == -1) { RETURN_FALSE; @@ -2725,6 +2767,11 @@ SPL_METHOD(SplFileObject, fseek) return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + spl_filesystem_file_free_line(intern TSRMLS_CC); RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, whence)); } /* }}} */ @@ -2737,6 +2784,11 @@ SPL_METHOD(SplFileObject, fgetc) char buf[2]; int result; + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + spl_filesystem_file_free_line(intern TSRMLS_CC); result = php_stream_getc(intern->u.file.stream); @@ -2761,6 +2813,11 @@ SPL_METHOD(SplFileObject, fgetss) spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); zval arg2; + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + if (intern->u.file.max_line_len > 0) { ZVAL_LONG(&arg2, intern->u.file.max_line_len); } else { @@ -2779,6 +2836,11 @@ SPL_METHOD(SplFileObject, fpassthru) { spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + RETURN_LONG(php_stream_passthru(intern->u.file.stream)); } /* }}} */ @@ -2788,6 +2850,11 @@ SPL_METHOD(SplFileObject, fscanf) { spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + spl_filesystem_file_free_line(intern TSRMLS_CC); intern->u.file.current_line_num++; @@ -2808,6 +2875,11 @@ SPL_METHOD(SplFileObject, fwrite) return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + if (ZEND_NUM_ARGS() > 1) { str_len = MAX(0, MIN(length, str_len)); } @@ -2827,6 +2899,11 @@ SPL_METHOD(SplFileObject, fread) return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + if (length <= 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0"); RETURN_FALSE; @@ -2855,6 +2932,11 @@ SPL_METHOD(SplFileObject, ftruncate) return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + if (!php_stream_truncate_supported(intern->u.file.stream)) { zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name); RETURN_FALSE; @@ -2869,15 +2951,20 @@ SPL_METHOD(SplFileObject, seek) { spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); long line_pos; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_pos) == FAILURE) { return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + if (line_pos < 0) { zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't seek file %s to negative line %ld", intern->file_name, line_pos); RETURN_FALSE; } - + spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC); while(intern->u.file.current_line_num < line_pos) { diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index ac9b9bef83..29c1c17e8a 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -145,6 +145,29 @@ static inline spl_recursive_it_object *spl_recursive_it_from_obj(zend_object *ob (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_ELEMENT_ADDR(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; @@ -166,8 +189,11 @@ static int spl_recursive_it_valid_ex(spl_recursive_it_object *object, zval *zthi { zend_object_iterator *sub_iter; int level = object->level; - - while (level >= 0) { + + if(!object->iterators) { + return FAILURE; + } + while (level >=0) { sub_iter = object->iterators[level].iterator; if (sub_iter->funcs->valid(sub_iter TSRMLS_CC) == SUCCESS) { return SUCCESS; @@ -215,6 +241,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 +403,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->val); - } + SPL_FETCH_SUB_ITERATOR(sub_iter, object); while (object->level) { sub_iter = object->iterators[object->level].iterator; @@ -598,7 +624,7 @@ SPL_METHOD(RecursiveIteratorIterator, rewind) SPL_METHOD(RecursiveIteratorIterator, valid) { spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -611,12 +637,14 @@ SPL_METHOD(RecursiveIteratorIterator, valid) SPL_METHOD(RecursiveIteratorIterator, key) { spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - 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 { @@ -629,13 +657,15 @@ SPL_METHOD(RecursiveIteratorIterator, key) SPL_METHOD(RecursiveIteratorIterator, current) { spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - 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); + data = iterator->funcs->get_current_data(iterator TSRMLS_CC); if (data) { RETURN_ZVAL(data, 1, 0); @@ -681,6 +711,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); } /* }}} */ @@ -689,13 +726,15 @@ SPL_METHOD(RecursiveIteratorIterator, getSubIterator) SPL_METHOD(RecursiveIteratorIterator, getInnerIterator) { spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - long level = object->level; + zval *zobject; if (zend_parse_parameters_none() == FAILURE) { return; } - - RETURN_ZVAL(&object->iterators[level].zobject, 1, 0); + + SPL_FETCH_SUB_ELEMENT_ADDR(zobject, object, zobject); + + RETURN_ZVAL(zobject, 1, 0); } /* }}} */ /* {{{ proto RecursiveIterator RecursiveIteratorIterator::beginIteration() @@ -723,13 +762,19 @@ SPL_METHOD(RecursiveIteratorIterator, endIteration) SPL_METHOD(RecursiveIteratorIterator, callHasChildren) { spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - zend_class_entry *ce = object->iterators[object->level].ce; + zend_class_entry *ce; zval *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 (Z_TYPE_P(zobject) == IS_UNDEF) { RETURN_FALSE; @@ -746,13 +791,15 @@ SPL_METHOD(RecursiveIteratorIterator, callHasChildren) SPL_METHOD(RecursiveIteratorIterator, callGetChildren) { spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - zend_class_entry *ce = object->iterators[object->level].ce; + zend_class_entry *ce; zval *zobject; if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_SUB_ELEMENT(ce, object, ce); + zobject = &object->iterators[object->level].zobject; if (Z_TYPE_P(zobject) == IS_UNDEF) { return; @@ -1068,7 +1115,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); } /* }}} */ @@ -1097,6 +1150,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); } /* }}} */ @@ -1110,6 +1169,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); } /* }}} */ @@ -1127,10 +1192,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; zval *data; + SPL_FETCH_SUB_ITERATOR(iterator, object); data = iterator->funcs->get_current_data(iterator TSRMLS_CC); if (data) { RETURN_ZVAL(data, 1, 0); @@ -1173,7 +1245,7 @@ SPL_METHOD(RecursiveTreeIterator, current) SPL_METHOD(RecursiveTreeIterator, key) { spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - zend_object_iterator *iterator = object->iterators[object->level].iterator; + zend_object_iterator *iterator; zval prefix, key, postfix, key_copy; char *ptr; zend_string *str; @@ -1182,6 +1254,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 { @@ -1884,7 +1958,8 @@ SPL_METHOD(RecursiveCallbackFilterIterator, getChildren) return; } - intern = Z_SPLDUAL_IT_P(getThis()); +//??? intern = Z_SPLDUAL_IT_P(getThis()); + 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) && Z_TYPE(retval) != IS_UNDEF) { diff --git a/ext/spl/tests/bug54281.phpt b/ext/spl/tests/bug54281.phpt index d42d9e585d..71792eaa20 100644 --- a/ext/spl/tests/bug54281.phpt +++ b/ext/spl/tests/bug54281.phpt @@ -12,4 +12,8 @@ foreach($it as $k=>$v) { } ?> --EXPECTF-- -Fatal error: RecursiveIteratorIterator::rewind(): The RecursiveArrayIteratorIterator instance wasn't initialized properly in %s on line %d +Fatal error: Uncaught exception 'LogicException' with message 'The object is in an invalid state as the parent constructor was not called' in %s:%d +Stack trace: +#0 %s/bug54281.php(8): RecursiveIteratorIterator->rewind() +#1 {main} + thrown in %s/bug54281.php on line 8 |