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_pathHi,
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.phpWarning: include(file2.php): failed to open stream: No such
file or directory in %sinclude_path.php on line %dWarning: 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.
BecausePATH_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
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,
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