@@ -41,6 +41,8 @@ typedef struct {
4141 size_t path_len ;
4242 char * pattern ;
4343 size_t pattern_len ;
44+ size_t * open_basedir_indexmap ;
45+ size_t open_basedir_indexmap_size ;
4446} glob_s_t ;
4547
4648PHPAPI char * _php_glob_stream_get_path (php_stream * stream , size_t * plen STREAMS_DC ) /* {{{ */
@@ -79,6 +81,9 @@ PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, size_t *plen STREA
7981}
8082/* }}} */
8183
84+ #define _php_glob_stream_get_result_count (pglob ) \
85+ pglob->open_basedir_indexmap ? (int) pglob->open_basedir_indexmap_size : pglob->glob.gl_pathc
86+
8287PHPAPI int _php_glob_stream_get_count (php_stream * stream , int * pflags STREAMS_DC ) /* {{{ */
8388{
8489 glob_s_t * pglob = (glob_s_t * )stream -> abstract ;
@@ -87,7 +92,7 @@ PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC
8792 if (pflags ) {
8893 * pflags = pglob -> flags ;
8994 }
90- return pglob -> glob . gl_pathc ;
95+ return _php_glob_stream_get_result_count ( pglob ) ;
9196 } else {
9297 if (pflags ) {
9398 * pflags = 0 ;
@@ -130,15 +135,20 @@ static ssize_t php_glob_stream_read(php_stream *stream, char *buf, size_t count)
130135 glob_s_t * pglob = (glob_s_t * )stream -> abstract ;
131136 php_stream_dirent * ent = (php_stream_dirent * )buf ;
132137 const char * path ;
138+ int glob_result_count ;
139+ size_t index ;
133140
134141 /* avoid problems if someone mis-uses the stream */
135142 if (count == sizeof (php_stream_dirent ) && pglob ) {
136- if (pglob -> index < (size_t )pglob -> glob .gl_pathc ) {
137- php_glob_stream_path_split (pglob , pglob -> glob .gl_pathv [pglob -> index ++ ], pglob -> flags & GLOB_APPEND , & path );
143+ glob_result_count = _php_glob_stream_get_result_count (pglob );
144+ if (pglob -> index < (size_t ) glob_result_count ) {
145+ index = pglob -> open_basedir_indexmap ? pglob -> open_basedir_indexmap [pglob -> index ] : pglob -> index ;
146+ php_glob_stream_path_split (pglob , pglob -> glob .gl_pathv [index ], pglob -> flags & GLOB_APPEND , & path );
147+ ++ pglob -> index ;
138148 PHP_STRLCPY (ent -> d_name , path , sizeof (ent -> d_name ), strlen (path ));
139149 return sizeof (php_stream_dirent );
140150 }
141- pglob -> index = pglob -> glob . gl_pathc ;
151+ pglob -> index = glob_result_count ;
142152 if (pglob -> path ) {
143153 efree (pglob -> path );
144154 pglob -> path = NULL ;
@@ -162,6 +172,9 @@ static int php_glob_stream_close(php_stream *stream, int close_handle) /* {{{ *
162172 if (pglob -> pattern ) {
163173 efree (pglob -> pattern );
164174 }
175+ if (pglob -> open_basedir_indexmap ) {
176+ efree (pglob -> open_basedir_indexmap );
177+ }
165178 }
166179 efree (stream -> abstract );
167180 return 0 ;
@@ -198,7 +211,7 @@ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, const cha
198211 int options , zend_string * * opened_path , php_stream_context * context STREAMS_DC )
199212{
200213 glob_s_t * pglob ;
201- int ret ;
214+ int ret , i ;
202215 const char * tmp , * pos ;
203216
204217 if (!strncmp (path , "glob://" , sizeof ("glob://" )- 1 )) {
@@ -208,10 +221,6 @@ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, const cha
208221 }
209222 }
210223
211- if (((options & STREAM_DISABLE_OPEN_BASEDIR ) == 0 ) && php_check_open_basedir (path )) {
212- return NULL ;
213- }
214-
215224 pglob = ecalloc (sizeof (* pglob ), 1 );
216225
217226 if (0 != (ret = glob (path , pglob -> flags & GLOB_FLAGMASK , NULL , & pglob -> glob ))) {
@@ -224,6 +233,18 @@ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, const cha
224233 }
225234 }
226235
236+ /* if open_basedir in use, check and filter restricted paths */
237+ if ((options & STREAM_DISABLE_OPEN_BASEDIR ) == 0 ) {
238+ for (i = 0 ; i < pglob -> glob .gl_pathc ; i ++ ) {
239+ if (!php_check_open_basedir_ex (pglob -> glob .gl_pathv [i ], 0 )) {
240+ if (!pglob -> open_basedir_indexmap ) {
241+ pglob -> open_basedir_indexmap = (size_t * ) emalloc (sizeof (size_t ) * pglob -> glob .gl_pathc );
242+ }
243+ pglob -> open_basedir_indexmap [pglob -> open_basedir_indexmap_size ++ ] = i ;
244+ }
245+ }
246+ }
247+
227248 pos = path ;
228249 if ((tmp = strrchr (pos , '/' )) != NULL ) {
229250 pos = tmp + 1 ;
0 commit comments