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

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 -p -d -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 09:09:03 -0000
@@ -473,7 +473,15 @@ PHPAPI char *php_resolve_path(const char
 
        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 @@ PHPAPI char *php_resolve_path(const char
                        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 @@ PHPAPI char *php_resolve_path(const char
                    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/plain_wrapper.c
===================================================================
RCS file: /repository/php-src/main/streams/plain_wrapper.c,v
retrieving revision 1.52.2.6.2.23.2.5
diff -u -p -d -r1.52.2.6.2.23.2.5 plain_wrapper.c
--- main/streams/plain_wrapper.c        31 Dec 2007 07:17:17 -0000      
1.52.2.6.2.23.2.5
+++ main/streams/plain_wrapper.c        21 Mar 2008 09:09:03 -0000
@@ -1254,7 +1254,7 @@ php_stream_wrapper php_plain_files_wrapp
 PHPAPI php_stream *_php_stream_fopen_with_path(char *filename, char *mode, 
char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC)
 {
        /* code ripped off from fopen_wrappers.c */
-       char *pathbuf, *ptr, *end;
+       char *pathbuf, *ptr, *end, *p;
        char *exec_fname;
        char trypath[MAXPATHLEN];
        struct stat sb;
@@ -1380,7 +1380,16 @@ not_relative_path:
        ptr = pathbuf;
 
        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 != NULL) {
                        *end = '\0';
                        end++;
@@ -1390,6 +1399,27 @@ not_relative_path:
                }
                snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename);
 
+               if (is_stream_wrapper) {
+                       char *actual;
+                       php_stream_wrapper *wrapper = 
php_stream_locate_url_wrapper(trypath, &actual, options TSRMLS_CC);
+
+                       if (!wrapper) {
+                               continue;
+                       } else if (wrapper == &php_plain_files_wrapper) {
+                               strncpy(trypath, actual, MAXPATHLEN);
+                       } else {
+                               stream = php_stream_open_wrapper(trypath, mode, 
options & ~REPORT_ERRORS, opened_path);
+                               if (stream) {
+                                       if (opened_path && !*opened_path) {
+                                               *opened_path = estrdup(trypath);
+                                       }
+                                       efree(pathbuf);
+                                       return stream;
+                               }
+                               continue;
+                       }
+               }
+
                if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && 
php_check_open_basedir_ex(trypath, 0 TSRMLS_CC)) {
                        goto stream_skip;
                }
--TEST--
Stream wrappers in include_path
--FILE--
<?php
$data1 = $data2 = $data3 = $data4 = $data5 = $data6 = <<<'EOD'
<?php echo __FILE__ . "\n";?>

EOD;

class mystream 
{
        public $path;
        public $mode;
        public $options;

        public $position;
        public $varname;

        function url_stat($path, $flags) {
                return array();
        }
        
        function stream_stat() {
                return array();
        }

        function stream_open($path, $mode, $options, &$opened_path)
        {
                $this->path = $path;
                $this->mode = $mode;
                $this->options = $options;

                $split = parse_url($path);
                if ($split["host"] !== "GLOBALS" || 
                    empty($split["path"]) ||
                    empty($GLOBALS[substr($split["path"],1)])) {
                    return false;
                }
                $this->varname = substr($split["path"],1);

                if (strchr($mode, 'a'))
                        $this->position = strlen($GLOBALS[$this->varname]);
                else
                        $this->position = 0;
                
                return true;
        }

        function stream_read($count)
        {
                $ret = substr($GLOBALS[$this->varname], $this->position, 
$count);
                $this->position += strlen($ret);
                return $ret;
        }

        function stream_tell()
        {
                return $this->position;
        }

        function stream_eof()
        {
                return $this->position >= strlen($GLOBALS[$this->varname]);
        }

        function stream_seek($offset, $whence)
        {
                switch($whence) {
                        case SEEK_SET:
                                if ($offset < strlen($GLOBALS[$this->varname]) 
&& $offset >= 0) {
                                        $this->position = $offset;
                                        return true;
                                } else {
                                        return false;
                                }
                                break;
                        case SEEK_CUR:
                                if ($offset >= 0) {
                                        $this->position += $offset;
                                        return true;
                                } else {
                                        return false;
                                }
                                break;
                        case SEEK_END:
                                if (strlen($GLOBALS[$this->varname]) + $offset 
>= 0) {
                                        $this->position = 
strlen($GLOBALS[$this->varname]) + $offset;
                                        return true;
                                } else {
                                        return false;
                                }
                                break;
                        default:
                                return false;
                }
        }

}

if (!stream_wrapper_register("test", "mystream")) {
        die("test wrapper registration failed");
}

echo file_get_contents("test://GLOBALS/data1");
include("test://GLOBALS/data1");
include_once("test://GLOBALS/data2");
include_once("test://GLOBALS/data2");
$include_path = get_include_path();
set_include_path($include_path . PATH_SEPARATOR . "test://GLOBALS");
echo file_get_contents("data3", true);
include("data3");
include_once("data4");
include_once("data4");
set_include_path("test://GLOBALS"  . PATH_SEPARATOR .  $include_path);
echo file_get_contents("data5", true);
include("data5");
include_once("data6");
include_once("data6");
?>
--EXPECTF--
<?php echo __FILE__ . "\n";?>
test://GLOBALS/data1
test://GLOBALS/data2
<?php echo __FILE__ . "\n";?>
test://GLOBALS/data3
test://GLOBALS/data4
<?php echo __FILE__ . "\n";?>
test://GLOBALS/data5
test://GLOBALS/data6


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

Reply via email to