Dmitry Stogov wrote:
> Hi Greg,
>
> I've fixed your patch to work with all functions (fopen,
> file_get_contente).
> Please verify it with ext/phar and then I'll commit it.
>
> Thanks. Dmitry.
>
> Gregory Beaver wrote:
>> Hi,
>>
>> Please look at the stream wrappers in include_path patch I posted
>> last week.
>>
>> Thanks,
>> Greg
>>
Hi Dmitry,

the patch has a few major problems and a few minor ones.  First off,
there are spaces instead of tabs, which is not a huge deal, I've
corrected that in the attached patch.

It is, however, logically void to do stream wrapper operations in
plain_wrapper.c.  I removed that code entirely.  Instead, the path
resolve is now done in php_stream_open_wrapper_ex where it belongs,
before determining which stream wrapper to open.  This will result in a
double call to the function when calling include, but because the 2nd
call will simply return after determining it has received a full path.

I've attached 2 patches (apparently, Zend is not included in cvs diff -u
of php5), 1 for adding path resolution to include/require (this is a
significant performance improvement over the existing code).  The second
patch adds stream wrapper support to both php_resolve_path and
_php_stream_open_wrapper_ex, which automatically gives stream wrapper in
include_path support to all current and future functions that use
include_path.

Greg
Index: main/fopen_wrappers.c
===================================================================
RCS file: /repository/php-src/main/fopen_wrappers.c,v
retrieving revision 1.175.2.3.2.13.2.8
diff -u -r1.175.2.3.2.13.2.8 fopen_wrappers.c
--- main/fopen_wrappers.c       13 Mar 2008 14:09:54 -0000      
1.175.2.3.2.13.2.8
+++ main/fopen_wrappers.c       21 Mar 2008 16:50:45 -0000
@@ -452,11 +452,11 @@
                return NULL;
        }
 
-       /* Don't resolve patches which contain protocol */
+       /* Don't resolve paths which contain protocol */
        for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == 
'.'; p++);
-    if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) {
-       return NULL;
-    }
+       if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == 
'/')) {
+               return NULL;
+       }
 
        if ((*filename == '.' && 
             (IS_SLASH(filename[1]) || 
@@ -473,7 +473,15 @@
 
        ptr = path;
        while (ptr && *ptr) {
-               end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
+               /* Check for stream wrapper */
+               int is_stream_wrapper = 0;
+
+               for (p = ptr; isalnum((int)*p) || *p == '+' || *p == '-' || *p 
== '.'; p++);
+               if ((*p == ':') && (p - ptr > 1) && (p[1] == '/') && (p[2] == 
'/')) {
+                       p += 2;
+                       is_stream_wrapper = 1;
+               }
+               end = strchr(p, DEFAULT_DIR_SEPARATOR);
                if (end) {
                        if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) {
                                ptr = end + 1;
@@ -494,6 +502,25 @@
                        memcpy(trypath+len+1, filename, filename_length+1);
                        ptr = NULL;
                }
+               if (is_stream_wrapper) {
+                       char *actual;
+                       php_stream_wrapper *wrapper = 
php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE 
TSRMLS_CC);
+                       
+                       if (!wrapper) {
+                               continue;
+                       } else if (wrapper == &php_plain_files_wrapper) {
+                               strncpy(trypath, actual, MAXPATHLEN);
+                       } else {
+                               if (wrapper->wops->url_stat) {
+                                       php_stream_statbuf ssb;
+
+                                       if (SUCCESS == 
wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) {
+                                               return estrdup(trypath);
+                                       }
+                               }
+                               continue;
+                       }
+               }
                if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) {
                        return estrdup(resolved_path);
                }
@@ -511,6 +538,29 @@
                    exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) {
                        memcpy(trypath, exec_fname, exec_fname_length + 1);
                        memcpy(trypath+exec_fname_length + 1, filename, 
filename_length+1);
+
+                       /* Check for stream wrapper */
+                       for (p = trypath; isalnum((int)*p) || *p == '+' || *p 
== '-' || *p == '.'; p++);
+                   if ((*p == ':') && (p - trypath > 1) && (p[1] == '/') && 
(p[2] == '/')) {
+                               char *actual;
+                               php_stream_wrapper *wrapper = 
php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE 
TSRMLS_CC);
+                       
+                               if (!wrapper) {
+                                       return NULL;
+                               } else if (wrapper == &php_plain_files_wrapper) 
{
+                                       strncpy(trypath, actual, MAXPATHLEN);
+                               } else {
+                                       if (wrapper->wops->url_stat) {
+                                               php_stream_statbuf ssb;
+
+                                               if (SUCCESS == 
wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) {
+                                                       return estrdup(trypath);
+                                               }
+                                       }
+                                       return NULL;
+                               }
+                       }
+
                        if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) {
                                return estrdup(resolved_path);
                        }
Index: main/streams/streams.c
===================================================================
RCS file: /repository/php-src/main/streams/streams.c,v
retrieving revision 1.82.2.6.2.18.2.5
diff -u -r1.82.2.6.2.18.2.5 streams.c
--- main/streams/streams.c      12 Jan 2008 15:50:57 -0000      
1.82.2.6.2.18.2.5
+++ main/streams/streams.c      21 Mar 2008 16:50:46 -0000
@@ -1773,7 +1773,7 @@
        php_stream *stream = NULL;
        php_stream_wrapper *wrapper = NULL;
        char *path_to_open;
-       int persistent = options & STREAM_OPEN_PERSISTENT;
+       int persistent = options & STREAM_OPEN_PERSISTENT, free_path = 0;
        char *copy_of_path = NULL;
 
        
@@ -1787,9 +1787,22 @@
 
        path_to_open = path;
 
+       if (options & USE_PATH) {
+               path_to_open = zend_resolve_path(path, strlen(path) TSRMLS_CC);
+               if (path_to_open) {
+                       path = path_to_open;
+                       free_path = 1;
+               } else {
+                       path_to_open = path;
+               }
+       }
+
        wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options 
TSRMLS_CC);
        if (options & STREAM_USE_URL && (!wrapper || !wrapper->is_url)) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "This function may 
only be used against URLs");
+               if (free_path) {
+                       efree(path);
+               }
                return NULL;
        }
 
@@ -1809,6 +1822,9 @@
                        php_stream_wrapper_log_error(wrapper, options ^ 
REPORT_ERRORS TSRMLS_CC,
                                        "wrapper does not support persistent 
streams");
                        php_stream_close(stream);
+                       if (free_path) {
+                               efree(path);
+                       }
                        stream = NULL;
                }
                
@@ -1836,12 +1852,18 @@
                                        (options & STREAM_WILL_CAST)
                                                ? PHP_STREAM_PREFER_STDIO : 
PHP_STREAM_NO_PREFERENCE)) {
                        case PHP_STREAM_UNCHANGED:
+                               if (free_path) {
+                                       efree(path);
+                               }
                                return stream;
                        case PHP_STREAM_RELEASED:
                                if (newstream->orig_path) {
                                        pefree(newstream->orig_path, 
persistent);
                                }
                                newstream->orig_path = pestrdup(path, 
persistent);
+                               if (free_path) {
+                                       efree(path);
+                               }
                                return newstream;
                        default:
                                php_stream_close(stream);
@@ -1880,6 +1902,9 @@
                pefree(copy_of_path, persistent);
        }
 #endif
+       if (free_path) {
+               efree(path);
+       }
        return stream;
 }
 /* }}} */
Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.48.2.45
diff -u -r1.59.2.29.2.48.2.45 zend_vm_def.h
--- Zend/zend_vm_def.h  18 Mar 2008 14:10:43 -0000      1.59.2.29.2.48.2.45
+++ Zend/zend_vm_def.h  21 Mar 2008 16:50:55 -0000
@@ -3073,9 +3073,19 @@
                        }
                        break;
                case ZEND_INCLUDE:
-               case ZEND_REQUIRE:
-                       new_op_array = 
compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
-                       break;
+               case ZEND_REQUIRE: {
+                               char *resolved_path;
+               
+                               resolved_path = 
zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC);
+                               if (resolved_path) {
+                                       zval rz;
+                                       ZVAL_STRINGL(&rz, resolved_path, 
strlen(resolved_path), 0);
+                                       new_op_array = 
compile_filename(Z_LVAL(opline->op2.u.constant), &rz TSRMLS_CC);
+                                       efree(resolved_path);
+                               } else {
+                                       new_op_array = 
compile_filename(Z_LVAL(opline->op2.u.constant), inc_filename TSRMLS_CC);
+                               }
+                       }
                case ZEND_EVAL: {
                                char *eval_desc = 
zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to