# [PATCH] adding stream wrappers to include_path

- Thread: https://externals.io/message/36117
- Original archive: https://news-web.php.net/php.internals/36117
- Started by Dmitry Stogov on 2008-03-13T10:55:43+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #36117 — Dmitry Stogov — 2008-03-13T10:55:43+00:00

URL: https://externals.io/message/36117#36117

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

---

## #36118 — Pierre Joye — 2008-03-13T11:12:01+00:00

URL: https://externals.io/message/36117#36118 · In reply to: #36117

> 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. :(

What's about quotes or escape? Quotes are somehow more readable and
are already used in many places (generally not specifically in PHP). I
can imagine a:

set_include_path('"foo://something/bar"' . `PATH_SEPARATOR` . get_incude_path());

It may add some complexity in the parser but it can be really useful
(well, for phar-like applications at least as I would not recommend
too use that in normal apps :).

Cheers,
-- 
Pierre
http://blog.thepimp.net | http://www.libgd.org

---

## #36131 — Greg Beaver — 2008-03-14T02:35:20+00:00

URL: https://externals.io/message/36117#36131 · In reply to: #36117

Dmitry Stogov wrote:
> 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. :(

Hi Dmitry,

I strongly encourage you to take a few more seconds actually looking at 
the message you quoted (and perhaps the patch included) before jumping 
to hasty conclusions.  The patch was developed on ubuntu linux which 
indeed uses ":" as the path separator and yet strangely enough, the test 
scripts (which you kindly quoted in your reply) actually work with my 
patch!  In other words, this include_path:

".:/usr/local/lib/php:phar://whatever.phar/internal/path"

works just fine on unix, and this one:

".;C:\php5;phar://whatever.phar/internal/path"

works just fine on windows.

Greg
