@@ -1432,6 +1432,29 @@ static void shadow_is_writable(INTERNAL_FUNCTION_PARAMETERS)
14321432}
14331433/* }}} */
14341434
1435+ /* Helper function to add glob results to merge hash table */
1436+ static void shadow_glob_add_to_hash (HashTable * mergedata , zval * glob_results , const char * path , int pathlen , void * dummy , int add_new )
1437+ {
1438+ zval * src_entry ;
1439+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (glob_results ), src_entry ) {
1440+ zend_string * mergepath_zs ;
1441+ char * relpath ;
1442+ if (Z_TYPE_P (src_entry ) != IS_STRING ) continue ;
1443+ relpath = Z_STRVAL_P (src_entry ) + pathlen + 1 ;
1444+ if (path && path [0 ] != '\0' ) {
1445+ mergepath_zs = strpprintf (MAXPATHLEN , "%s/%s" , path , relpath );
1446+ } else {
1447+ mergepath_zs = zend_string_init (relpath , strlen (relpath ), 0 );
1448+ }
1449+ if (add_new ) {
1450+ zend_hash_str_add_new_ptr (mergedata , ZSTR_VAL (mergepath_zs ), ZSTR_LEN (mergepath_zs ), dummy );
1451+ } else {
1452+ zend_hash_str_add_ptr (mergedata , ZSTR_VAL (mergepath_zs ), ZSTR_LEN (mergepath_zs ), dummy );
1453+ }
1454+ zend_string_release (mergepath_zs );
1455+ } ZEND_HASH_FOREACH_END ();
1456+ }
1457+
14351458/* {{{ proto array glob(string pattern [, int flags])
14361459 Find pathnames matching a pattern */
14371460static void shadow_glob (INTERNAL_FUNCTION_PARAMETERS )
@@ -1441,11 +1464,11 @@ static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS)
14411464 zend_long flags ;
14421465 char * instname = NULL , * templname = NULL , * mask = NULL , * path = NULL ;
14431466 zval instdata , templdata ;
1444- zval * src_entry ;
14451467 HashTable * mergedata ;
14461468 void * dummy = (void * )1 ;
14471469 int instlen , templen ;
14481470 int skip_template = 0 ;
1471+ zval * original_return_value = return_value ; /* Save the original pointer */
14491472
14501473 if (!SHADOW_ENABLED ()) {
14511474 orig_glob (INTERNAL_FUNCTION_PARAM_PASSTHRU );
@@ -1531,13 +1554,7 @@ static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS)
15311554 /* call with template */
15321555 if (shadow_call_replace_name (0 , templname , orig_glob , INTERNAL_FUNCTION_PARAM_PASSTHRU ) == SUCCESS && Z_TYPE_P (return_value ) == IS_ARRAY ) {
15331556 /* cut off instname and put path part there */
1534- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (return_value ), src_entry ) {
1535- char * mergepath ;
1536- if (Z_TYPE_P (src_entry ) != IS_STRING ) continue ; /* weird, glob shouldn't do that to us */
1537- spprintf (& mergepath , MAXPATHLEN , "%s/%s" , path , Z_STRVAL_P (src_entry )+ templen + 1 );
1538- zend_hash_str_add_new_ptr (mergedata , mergepath , strlen (mergepath ), dummy );
1539- efree (mergepath );
1540- } ZEND_HASH_FOREACH_END ();
1557+ shadow_glob_add_to_hash (mergedata , return_value , path , templen , dummy , 1 );
15411558 } else {
15421559 /* ignore problems here - other one may pick it up */
15431560 array_init (return_value );
@@ -1553,22 +1570,27 @@ static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS)
15531570 /* call with instance */
15541571 if (shadow_call_replace_name (0 , instname , orig_glob , INTERNAL_FUNCTION_PARAM_PASSTHRU ) == SUCCESS && Z_TYPE_P (return_value ) == IS_ARRAY ) {
15551572 /* merge data */
1556- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (return_value ), src_entry ) {
1557- char * mergepath ;
1558- if (Z_TYPE_P (src_entry ) != IS_STRING ) continue ; /* weird, glob shouldn't do that to us */
1559- spprintf (& mergepath , MAXPATHLEN , "%s/%s" , path , Z_STRVAL_P (src_entry )+ instlen + 1 );
1560- zend_hash_str_add_ptr (mergedata , mergepath , strlen (mergepath ), dummy );
1561- efree (mergepath );
1562- } ZEND_HASH_FOREACH_END ();
1573+ shadow_glob_add_to_hash (mergedata , return_value , path , instlen , dummy , 0 );
15631574 }
15641575 zval_dtor (return_value );
15651576 return_value = & templdata ;
15661577 /* convert mergedata to return */
1567- zend_hash_clean (Z_ARRVAL_P (return_value ));
1568- zend_string * filename_zs ;
1569- ZEND_HASH_FOREACH_STR_KEY (mergedata , filename_zs ) {
1570- add_next_index_str (return_value , zend_string_copy (filename_zs ));
1571- } ZEND_HASH_FOREACH_END ();
1578+ if (Z_TYPE_P (return_value ) == IS_ARRAY && Z_ARR_P (return_value ) != & zend_empty_array ) {
1579+ zend_hash_clean (Z_ARRVAL_P (return_value ));
1580+ } else {
1581+ array_init (return_value );
1582+ }
1583+ zend_string * name = NULL ;
1584+ zend_ulong num ;
1585+ zend_hash_internal_pointer_reset (mergedata );
1586+ while (zend_hash_get_current_key (mergedata , & name , & num ) == HASH_KEY_IS_STRING ) {
1587+ if (name && ZSTR_VAL (name ) && ZSTR_LEN (name )) {
1588+ add_next_index_str (return_value , zend_string_copy (name ));
1589+ }
1590+ zend_hash_move_forward (mergedata );
1591+ }
1592+ /* CRITICAL: Copy templdata back to the ORIGINAL return_value pointer */
1593+ ZVAL_COPY_VALUE (original_return_value , & templdata );
15721594 /* cleanup */
15731595 zend_hash_clean (mergedata );
15741596 zend_hash_destroy (mergedata );
0 commit comments