Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:36420 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 94464 invoked from network); 24 Mar 2008 11:39:19 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 24 Mar 2008 11:39:19 -0000 Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 212.25.124.162 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 212.25.124.162 mail.zend.com Linux 2.5 (sometimes 2.4) (4) Received: from [212.25.124.162] ([212.25.124.162:21132] helo=mail.zend.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 55/52-17613-5E297E74 for ; Mon, 24 Mar 2008 06:39:19 -0500 Received: (qmail 22151 invoked from network); 24 Mar 2008 11:39:13 -0000 Received: from unknown (HELO ?10.1.20.22?) (10.1.20.22) by mail.zend.net with SMTP; 24 Mar 2008 11:39:13 -0000 Message-ID: <47E792E1.9070803@zend.com> Date: Mon, 24 Mar 2008 14:39:13 +0300 User-Agent: Thunderbird 2.0.0.9 (Windows/20071031) MIME-Version: 1.0 To: Gregory Beaver CC: internals Mailing List , Stanislav Malyshev References: <47E2F8FA.20107@chiaraquartet.net> <47E37C42.10308@zend.com> <47E3E7F1.3060200@chiaraquartet.net> In-Reply-To: <47E3E7F1.3060200@chiaraquartet.net> Content-Type: multipart/mixed; boundary="------------030101060608010506030504" Subject: Re: [PHP-DEV] REMINDER - stream wrappers in include_path From: dmitry@zend.com (Dmitry Stogov) --------------030101060608010506030504 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi Greg, In your second patch you forgot "break", so it couldn't work. I don't see any reason in second patch at all, because you call php_resolve_patch() from _php_stream_open_wrapper_ex() anyway. The bad thing with the first part that it calls realpath() function twice for each include("relative_path.php") and it makes several file-system accesses (look into `strace ... 2>&1| grep lstat`). With your patch I see 6 syscalls more. So I would prefer my patch that is more efficient for regular files. The same patch with fixed white-spaces is attached. Thanks. Dmitry. Gregory Beaver wrote: > Dmitry Stogov wrote: >> 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 >>> > Hi Dmitry, > > the patch has a few major problems and a few minor ones. First off, > there are spaces instead of tabs, which is not a huge deal, I've > corrected that in the attached patch. > > It is, however, logically void to do stream wrapper operations in > plain_wrapper.c. I removed that code entirely. Instead, the path > resolve is now done in php_stream_open_wrapper_ex where it belongs, > before determining which stream wrapper to open. This will result in a > double call to the function when calling include, but because the 2nd > call will simply return after determining it has received a full path. > > I've attached 2 patches (apparently, Zend is not included in cvs diff -u > of php5), 1 for adding path resolution to include/require (this is a > significant performance improvement over the existing code). The second > patch adds stream wrapper support to both php_resolve_path and > _php_stream_open_wrapper_ex, which automatically gives stream wrapper in > include_path support to all current and future functions that use > include_path. > > Greg --------------030101060608010506030504 Content-Type: text/plain; name="wrappers_in_include_path-3.patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="wrappers_in_include_path-3.patch.txt" 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; } --------------030101060608010506030504--