RE: [PATCH] adding stream wrappers to include_path
| From: | Dmitry Stogov | Date: | Thu, 13 Mar 2008 10:55:43 +0000 |
| Subject: | RE: [PATCH] adding stream wrappers to include_path | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-36117@lists.php.net to get a copy of this message | ||
Hi Greg,
In general include_path cannot contain pathes with ':' character,
because it is the POSIX path separator.
So I don't see a way to use stream wrappers in include_path. :(
Thanks. Dmitry.
> -----Original Message-----
> From: Gregory Beaver [mailto:greg@chiaraquartet.net]
> Sent: Friday, March 07, 2008 8:06 AM
> To: Dmitry Stogov; internals Mailing List
> Subject: [PATCH] adding stream wrappers to include_path
>
>
> Hi,
>
> I found some time to whip up a quick patch against 5.3.
>
> This patch allows adding stream wrappers to include_path on
> both windows and unix. This means one can set an
> include_path to
> ".:/usr/local/lib/php:phar:///path/to/ZF.phar/lib" or the
> windows equivalent ".;C:\php5;phar://C:/php5/ZF.phar/lib"
> Any stream wrapper, userspace or built-in, will work as long
> as it satisfies security constraints and implements
> url_stat(), stream_open(), stat(), and read() or the C equivalents.
>
> In other words, this test I already had created for pecl/phar works:
>
> <?php
> $fname = dirname(__FILE__) . '/tempmanifest1.phar.php';
> $a = new Phar($fname);
> $a['file1.php'] = 'file1.php
> ';
> $a['test/file1.php'] = 'test/file1.php
> ';
> unset($a);
> set_include_path('.' . PATH_SEPARATOR . 'phar://' . $fname);
> include 'file1.php'; set_include_path('.' . PATH_SEPARATOR .
> 'phar://' . $fname . '/test'); include 'file1.php'; include
> 'file2.php'; ?> ===DONE===
>
> with output:
>
> --EXPECTF--
> file1.php
> test/file1.php
>
> Warning: include(file2.php): failed to open stream: No such
> file or directory in %sinclude_path.php on line %d
>
> Warning: include(): Failed opening 'file2.php' for inclusion
> (include_path='.:phar:///home/cellog/workspace/php5/ext/phar/t
> ests/tempmanifest1.phar.php/test')
> in %sinclude_path.php on line %d
> ===DONE===
>
> The internals of the patch borrows logic from
> php_stream_locate_url_wrapper to quickly detect a stream
> wrapper. It excludes the data stream wrapper out of hand as
> this has no business in include_path for obvious reasons. It
> also fully supports disabled
> allow_url_fopen/allow_url_include by passing
> STREAM_OPEN_FOR_INCLUDE to the eventual
> php_stream_locate_url_wrapper call. The most important part
> of the patch is the way it finds a stream wrapper on unix.
> Because PATH_SEPARATOR is ":" on unix, the include_path
> scanner will stop after "phar" in the sample include_paths
> above. The new scanner checks for a valid stream wrapper (a
> sequence of alpha-numeric, +, -, or . characters followed by
> ://) and seeks to the next : if found.
>
> My primary concern with the patch is performance. I'm
> certain it can be tweaked. I extracted the call to url_stat
> from php_stream_stat(), which removes the possibility of
> hitting stat cache but eliminates the redundant call to
> php_stream_locate_url_wrapper. If it is indeed faster to use
> php_stream_stat(), that's one easy optimization.
>
> In any case, it adds an additional scan of each include_path
> component to detect stream wrappers, which is called on each
> include. This may be the biggest candidate for optimization,
> as a simple cache of paths with stream wrapper/not could be
> created whenever include_path is set and used instead of
> scanning the string every time.
>
> By the way, there may be some unsafe scans in
> php_stream_locate_url_wrapper, specifically line 1531 in PHP_5_3:
>
> if ((*p == ':') && (n > 1) && (!strncmp("//", p+1,
> 2) ||
> !memcmp("data", path, 4))) {
>
> It doesn't seem to verify that path is at least 4 or there is
> at least 2 extra characters after p before checking for "//" or "data"
>
> Thanks,
> Greg
>