@@ -212,10 +212,16 @@ static zend_object *spl_filesystem_object_new(zend_class_entry *class_type)
212
212
}
213
213
/* }}} */
214
214
215
+ static inline bool spl_intern_is_glob (const spl_filesystem_object * intern )
216
+ {
217
+ /* NULL check on `dirp` is necessary as destructors may interfere. */
218
+ return intern -> u .dir .dirp && php_stream_is (intern -> u .dir .dirp , & php_glob_stream_ops );
219
+ }
220
+
215
221
PHPAPI zend_string * spl_filesystem_object_get_path (spl_filesystem_object * intern ) /* {{{ */
216
222
{
217
223
#ifdef HAVE_GLOB
218
- if (intern -> type == SPL_FS_DIR && php_stream_is (intern -> u . dir . dirp , & php_glob_stream_ops )) {
224
+ if (intern -> type == SPL_FS_DIR && spl_intern_is_glob (intern )) {
219
225
size_t len = 0 ;
220
226
char * tmp = php_glob_stream_get_path (intern -> u .dir .dirp , & len );
221
227
if (len == 0 ) {
@@ -658,7 +664,7 @@ static inline HashTable *spl_filesystem_object_get_debug_info(zend_object *objec
658
664
if (intern -> type == SPL_FS_DIR ) {
659
665
#ifdef HAVE_GLOB
660
666
pnstr = spl_gen_private_prop_name (spl_ce_DirectoryIterator , "glob" , sizeof ("glob" )- 1 );
661
- if (intern -> u . dir . dirp && php_stream_is (intern -> u . dir . dirp , & php_glob_stream_ops )) {
667
+ if (spl_intern_is_glob (intern )) {
662
668
ZVAL_STR_COPY (& tmp , intern -> path );
663
669
} else {
664
670
ZVAL_FALSE (& tmp );
@@ -1614,11 +1620,11 @@ PHP_METHOD(GlobIterator, count)
1614
1620
RETURN_THROWS ();
1615
1621
}
1616
1622
1617
- if (intern -> u . dir . dirp && php_stream_is (intern -> u . dir . dirp , & php_glob_stream_ops )) {
1623
+ if (spl_intern_is_glob (intern )) {
1618
1624
RETURN_LONG (php_glob_stream_get_count (intern -> u .dir .dirp , NULL ));
1619
1625
} else {
1620
- /* should not happen */
1621
- // TODO ZEND_ASSERT ?
1626
+ /* This can happen by abusing destructors. */
1627
+ /* TODO: relax this from E_ERROR to an exception */
1622
1628
php_error_docref (NULL , E_ERROR , "GlobIterator lost glob state" );
1623
1629
}
1624
1630
}
0 commit comments