@@ -41,6 +41,8 @@ typedef struct {
41
41
size_t path_len ;
42
42
char * pattern ;
43
43
size_t pattern_len ;
44
+ size_t * open_basedir_indexmap ;
45
+ size_t open_basedir_indexmap_size ;
44
46
} glob_s_t ;
45
47
46
48
PHPAPI 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
79
81
}
80
82
/* }}} */
81
83
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
+
82
87
PHPAPI int _php_glob_stream_get_count (php_stream * stream , int * pflags STREAMS_DC ) /* {{{ */
83
88
{
84
89
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
87
92
if (pflags ) {
88
93
* pflags = pglob -> flags ;
89
94
}
90
- return pglob -> glob . gl_pathc ;
95
+ return _php_glob_stream_get_result_count ( pglob ) ;
91
96
} else {
92
97
if (pflags ) {
93
98
* pflags = 0 ;
@@ -130,15 +135,20 @@ static ssize_t php_glob_stream_read(php_stream *stream, char *buf, size_t count)
130
135
glob_s_t * pglob = (glob_s_t * )stream -> abstract ;
131
136
php_stream_dirent * ent = (php_stream_dirent * )buf ;
132
137
const char * path ;
138
+ int glob_result_count ;
139
+ size_t index ;
133
140
134
141
/* avoid problems if someone mis-uses the stream */
135
142
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 ;
138
148
PHP_STRLCPY (ent -> d_name , path , sizeof (ent -> d_name ), strlen (path ));
139
149
return sizeof (php_stream_dirent );
140
150
}
141
- pglob -> index = pglob -> glob . gl_pathc ;
151
+ pglob -> index = glob_result_count ;
142
152
if (pglob -> path ) {
143
153
efree (pglob -> path );
144
154
pglob -> path = NULL ;
@@ -162,6 +172,9 @@ static int php_glob_stream_close(php_stream *stream, int close_handle) /* {{{ *
162
172
if (pglob -> pattern ) {
163
173
efree (pglob -> pattern );
164
174
}
175
+ if (pglob -> open_basedir_indexmap ) {
176
+ efree (pglob -> open_basedir_indexmap );
177
+ }
165
178
}
166
179
efree (stream -> abstract );
167
180
return 0 ;
@@ -198,7 +211,7 @@ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, const cha
198
211
int options , zend_string * * opened_path , php_stream_context * context STREAMS_DC )
199
212
{
200
213
glob_s_t * pglob ;
201
- int ret ;
214
+ int ret , i ;
202
215
const char * tmp , * pos ;
203
216
204
217
if (!strncmp (path , "glob://" , sizeof ("glob://" )- 1 )) {
@@ -208,10 +221,6 @@ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, const cha
208
221
}
209
222
}
210
223
211
- if (((options & STREAM_DISABLE_OPEN_BASEDIR ) == 0 ) && php_check_open_basedir (path )) {
212
- return NULL ;
213
- }
214
-
215
224
pglob = ecalloc (sizeof (* pglob ), 1 );
216
225
217
226
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
224
233
}
225
234
}
226
235
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
+
227
248
pos = path ;
228
249
if ((tmp = strrchr (pos , '/' )) != NULL ) {
229
250
pos = tmp + 1 ;
0 commit comments