[PATCH] adding stream wrappers to include_path

From: Date: Fri, 07 Mar 2008 05:06:23 +0000
Subject: [PATCH] adding stream wrappers to include_path
Groups: php.internals 
Request: Send a blank email to internals+get-36031@lists.php.net to get a copy of this message
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/tests/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

« previous php.internals (#36031) next »