dmitry Mon Jul 9 17:27:24 2007 UTC Added files: (Branch: PHP_5_2) /php-src/ext/standard/tests/file include_userstream_001.phpt include_userstream_002.phpt
Modified files: /php-src/main main.c php_globals.h php_streams.h /php-src/main/streams streams.c userspace.c /php-src/ext/standard basic_functions.c streamsfuncs.c streamsfuncs.h Log: Added ability to create local or remote (URL) user streams Local user streams must not be able to open(), URLs if allow_url_include is off Implemented new function stream_is_local() [ - stream_wrapper_register() extended with additional optional argument "flags" of type long. This time only one flag is implemented - STREAM_IS_URL, that means that userstream wrapper is remote (URL). By default stream is local. - stream_is_local() is a new function that accepts stream and tell if this stream is local or remote (URL) ]
http://cvs.php.net/viewvc.cgi/php-src/main/main.c?r1=1.640.2.23.2.38&r2=1.640.2.23.2.39&diff_format=u Index: php-src/main/main.c diff -u php-src/main/main.c:1.640.2.23.2.38 php-src/main/main.c:1.640.2.23.2.39 --- php-src/main/main.c:1.640.2.23.2.38 Fri Jun 15 09:20:27 2007 +++ php-src/main/main.c Mon Jul 9 17:27:23 2007 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: main.c,v 1.640.2.23.2.38 2007/06/15 09:20:27 dmitry Exp $ */ +/* $Id: main.c,v 1.640.2.23.2.39 2007/07/09 17:27:23 dmitry Exp $ */ /* {{{ includes */ @@ -1121,6 +1121,7 @@ PG(modules_activated) = 0; PG(header_is_being_sent) = 0; PG(connection_status) = PHP_CONNECTION_NORMAL; + PG(in_user_include) = 0; zend_activate(TSRMLS_C); sapi_activate(TSRMLS_C); http://cvs.php.net/viewvc.cgi/php-src/main/php_globals.h?r1=1.98.2.1.2.5&r2=1.98.2.1.2.6&diff_format=u Index: php-src/main/php_globals.h diff -u php-src/main/php_globals.h:1.98.2.1.2.5 php-src/main/php_globals.h:1.98.2.1.2.6 --- php-src/main/php_globals.h:1.98.2.1.2.5 Fri Mar 2 21:58:05 2007 +++ php-src/main/php_globals.h Mon Jul 9 17:27:23 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_globals.h,v 1.98.2.1.2.5 2007/03/02 21:58:05 stas Exp $ */ +/* $Id: php_globals.h,v 1.98.2.1.2.6 2007/07/09 17:27:23 dmitry Exp $ */ #ifndef PHP_GLOBALS_H #define PHP_GLOBALS_H @@ -156,6 +156,7 @@ zend_bool com_initialized; #endif long max_input_nesting_level; + zend_bool in_user_include; }; http://cvs.php.net/viewvc.cgi/php-src/main/php_streams.h?r1=1.103.2.1.2.2&r2=1.103.2.1.2.3&diff_format=u Index: php-src/main/php_streams.h diff -u php-src/main/php_streams.h:1.103.2.1.2.2 php-src/main/php_streams.h:1.103.2.1.2.3 --- php-src/main/php_streams.h:1.103.2.1.2.2 Wed Feb 21 21:57:21 2007 +++ php-src/main/php_streams.h Mon Jul 9 17:27:23 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_streams.h,v 1.103.2.1.2.2 2007/02/21 21:57:21 tony2001 Exp $ */ +/* $Id: php_streams.h,v 1.103.2.1.2.3 2007/07/09 17:27:23 dmitry Exp $ */ #ifndef PHP_STREAMS_H #define PHP_STREAMS_H @@ -499,6 +499,9 @@ /* get (or create) a persistent version of the stream */ #define STREAM_OPEN_PERSISTENT 2048 +/* don't check allow_url_fopen and allow_url_include */ +#define STREAM_DISABLE_URL_PROTECTION 0x00002000 + /* Antique - no longer has meaning */ #define IGNORE_URL_WIN 0 @@ -550,6 +553,9 @@ END_EXTERN_C() #endif +/* Definitions for user streams */ +#define PHP_STREAM_IS_URL 1 + /* * Local variables: * tab-width: 4 http://cvs.php.net/viewvc.cgi/php-src/main/streams/streams.c?r1=1.82.2.6.2.13&r2=1.82.2.6.2.14&diff_format=u Index: php-src/main/streams/streams.c diff -u php-src/main/streams/streams.c:1.82.2.6.2.13 php-src/main/streams/streams.c:1.82.2.6.2.14 --- php-src/main/streams/streams.c:1.82.2.6.2.13 Tue May 8 12:08:17 2007 +++ php-src/main/streams/streams.c Mon Jul 9 17:27:23 2007 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.82.2.6.2.13 2007/05/08 12:08:17 dmitry Exp $ */ +/* $Id: streams.c,v 1.82.2.6.2.14 2007/07/09 17:27:23 dmitry Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -1606,7 +1606,11 @@ return &php_plain_files_wrapper; } - if ((wrapperpp && (*wrapperpp)->is_url) && (!PG(allow_url_fopen) || ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include))) ) { + if (wrapperpp && (*wrapperpp)->is_url && + (options & STREAM_DISABLE_URL_PROTECTION) == 0 && + (!PG(allow_url_fopen) || + ((options & STREAM_OPEN_FOR_INCLUDE) || + PG(in_user_include)) && !PG(allow_url_include))) { if (options & REPORT_ERRORS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "URL file-access is disabled in the server configuration"); } http://cvs.php.net/viewvc.cgi/php-src/main/streams/userspace.c?r1=1.31.2.3.2.5&r2=1.31.2.3.2.6&diff_format=u Index: php-src/main/streams/userspace.c diff -u php-src/main/streams/userspace.c:1.31.2.3.2.5 php-src/main/streams/userspace.c:1.31.2.3.2.6 --- php-src/main/streams/userspace.c:1.31.2.3.2.5 Tue May 15 13:04:43 2007 +++ php-src/main/streams/userspace.c Mon Jul 9 17:27:24 2007 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: userspace.c,v 1.31.2.3.2.5 2007/05/15 13:04:43 scottmac Exp $ */ +/* $Id: userspace.c,v 1.31.2.3.2.6 2007/07/09 17:27:24 dmitry Exp $ */ #include "php.h" #include "php_globals.h" @@ -81,6 +81,7 @@ REGISTER_LONG_CONSTANT("STREAM_URL_STAT_QUIET", PHP_STREAM_URL_STAT_QUIET, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_MKDIR_RECURSIVE", PHP_STREAM_MKDIR_RECURSIVE, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_IS_URL", PHP_STREAM_IS_URL, CONST_CS|CONST_PERSISTENT); return SUCCESS; } @@ -215,6 +216,7 @@ int call_result; php_stream *stream = NULL; zval *zcontext = NULL; + zend_bool old_in_user_include; /* Try to catch bad usage without preventing flexibility */ if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) { @@ -223,6 +225,17 @@ } FG(user_stream_current_filename) = filename; + /* if the user stream was registered as local and we are in include context, + we add allow_url_include restrictions to allow_url_fopen ones */ + /* we need only is_url == 0 here since if is_url == 1 and remote wrappers + were restricted we wouldn't get here */ + old_in_user_include = PG(in_user_include); + if(uwrap->wrapper.is_url == 0 && + (options & STREAM_OPEN_FOR_INCLUDE) && + !PG(allow_url_include)) { + PG(in_user_include) = 1; + } + us = emalloc(sizeof(*us)); us->wrapper = uwrap; @@ -258,6 +271,7 @@ FREE_ZVAL(us->object); efree(us); FG(user_stream_current_filename) = NULL; + PG(in_user_include) = old_in_user_include; return NULL; } else { if (retval_ptr) { @@ -339,6 +353,7 @@ FG(user_stream_current_filename) = NULL; + PG(in_user_include) = old_in_user_include; return stream; } @@ -436,8 +451,9 @@ int protocol_len, classname_len; struct php_user_stream_wrapper * uwrap; int rsrc_id; + long flags = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &protocol, &protocol_len, &classname, &classname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &protocol, &protocol_len, &classname, &classname_len, &flags) == FAILURE) { RETURN_FALSE; } @@ -446,6 +462,7 @@ uwrap->classname = estrndup(classname, classname_len); uwrap->wrapper.wops = &user_stream_wops; uwrap->wrapper.abstract = uwrap; + uwrap->wrapper.is_url = ((flags & PHP_STREAM_IS_URL) != 0); rsrc_id = ZEND_REGISTER_RESOURCE(NULL, uwrap, le_protocols); http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.725.2.31.2.56&r2=1.725.2.31.2.57&diff_format=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.725.2.31.2.56 php-src/ext/standard/basic_functions.c:1.725.2.31.2.57 --- php-src/ext/standard/basic_functions.c:1.725.2.31.2.56 Tue Jun 26 12:10:08 2007 +++ php-src/ext/standard/basic_functions.c Mon Jul 9 17:27:24 2007 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.725.2.31.2.56 2007/06/26 12:10:08 tony2001 Exp $ */ +/* $Id: basic_functions.c,v 1.725.2.31.2.57 2007/07/09 17:27:24 dmitry Exp $ */ #include "php.h" #include "php_streams.h" @@ -207,9 +207,10 @@ /* }}} */ /* {{{ main/streams/userspace.c */ static -ZEND_BEGIN_ARG_INFO(arginfo_stream_wrapper_register, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_wrapper_register, 0, 0, 2) ZEND_ARG_INFO(0, protocol) ZEND_ARG_INFO(0, classname) + ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() static @@ -221,6 +222,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_stream_wrapper_restore, 0) ZEND_ARG_INFO(0, protocol) ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO(arginfo_stream_is_local, 0) + ZEND_ARG_INFO(0, stream) +ZEND_END_ARG_INFO() /* }}} */ /* {{{ array.c */ static @@ -3555,6 +3561,7 @@ PHP_FE(stream_wrapper_restore, arginfo_stream_wrapper_restore) PHP_FE(stream_get_wrappers, arginfo_stream_get_wrappers) PHP_FE(stream_get_transports, arginfo_stream_get_transports) + PHP_FE(stream_is_local, arginfo_stream_is_local) PHP_FE(get_headers, arginfo_get_headers) #if HAVE_SYS_TIME_H || defined(PHP_WIN32) http://cvs.php.net/viewvc.cgi/php-src/ext/standard/streamsfuncs.c?r1=1.58.2.6.2.14&r2=1.58.2.6.2.15&diff_format=u Index: php-src/ext/standard/streamsfuncs.c diff -u php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.14 php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.15 --- php-src/ext/standard/streamsfuncs.c:1.58.2.6.2.14 Mon Apr 9 15:38:58 2007 +++ php-src/ext/standard/streamsfuncs.c Mon Jul 9 17:27:24 2007 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.c,v 1.58.2.6.2.14 2007/04/09 15:38:58 dmitry Exp $ */ +/* $Id: streamsfuncs.c,v 1.58.2.6.2.15 2007/07/09 17:27:24 dmitry Exp $ */ #include "php.h" #include "php_globals.h" @@ -1341,6 +1341,37 @@ } /* }}} */ +/* {{{ proto bool stream_is_local(resource stream|string url) U +*/ +PHP_FUNCTION(stream_is_local) +{ + zval *zstream; + php_stream *stream = NULL; + php_stream_wrapper *wrapper = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zstream) == FAILURE) { + RETURN_FALSE; + } + + if(Z_TYPE_P(zstream) == IS_RESOURCE) { + php_stream_from_zval(stream, &zstream); + if(stream == NULL) { + RETURN_FALSE; + } + wrapper = stream->wrapper; + } else { + convert_to_string_ex(&zstream); + wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(zstream), NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC); + } + + if(!wrapper) { + RETURN_FALSE; + } + + RETURN_BOOL(wrapper->is_url==0); +} +/* }}} */ + #ifdef HAVE_SHUTDOWN /* {{{ proto int stream_socket_shutdown(resource stream, int how) causes all or part of a full-duplex connection on the socket associated http://cvs.php.net/viewvc.cgi/php-src/ext/standard/streamsfuncs.h?r1=1.13.2.1.2.3&r2=1.13.2.1.2.4&diff_format=u Index: php-src/ext/standard/streamsfuncs.h diff -u php-src/ext/standard/streamsfuncs.h:1.13.2.1.2.3 php-src/ext/standard/streamsfuncs.h:1.13.2.1.2.4 --- php-src/ext/standard/streamsfuncs.h:1.13.2.1.2.3 Mon Jan 1 09:36:09 2007 +++ php-src/ext/standard/streamsfuncs.h Mon Jul 9 17:27:24 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.h,v 1.13.2.1.2.3 2007/01/01 09:36:09 sebastian Exp $ */ +/* $Id: streamsfuncs.h,v 1.13.2.1.2.4 2007/07/09 17:27:24 dmitry Exp $ */ /* Flags for stream_socket_client */ #define PHP_STREAM_CLIENT_PERSISTENT 1 @@ -55,6 +55,7 @@ PHP_FUNCTION(stream_socket_enable_crypto); PHP_FUNCTION(stream_socket_shutdown); PHP_FUNCTION(stream_socket_pair); +PHP_FUNCTION(stream_is_local); /* * Local variables: http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/include_userstream_001.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/file/include_userstream_001.phpt +++ php-src/ext/standard/tests/file/include_userstream_001.phpt --TEST-- User streams and include() --INI-- allow_url_fopen=1 allow_url_include=0 --FILE-- <?php class test { private $data = '<?php echo "Hello World\n";?>'; private $pos; function stream_open($path, $mode, $options, &$opened_path) { if (strchr($mode, 'a')) $this->pos = strlen($this->data); else $this->po = 0; return true; } function stream_read($count) { $ret = substr($this->data, $this->pos, $count); $this->pos += strlen($ret); return $ret; } function stream_tell() { return $this->pos; } function stream_eof() { return $this->pos >= strlen($this->data); } function stream_seek($offset, $whence) { switch($whence) { case SEEK_SET: if ($offset < $this->data && $offset >= 0) { $this->pos = $offset; return true; } else { return false; } break; case SEEK_CUR: if ($offset >= 0) { $this->pos += $offset; return true; } else { return false; } break; case SEEK_END: if (strlen($this->data) + $offset >= 0) { $this->pos = strlen($this->data) + $offset; return true; } else { return false; } break; default: return false; } } } stream_register_wrapper("test1", "test", STREAM_IS_URL); stream_register_wrapper("test2", "test"); echo @file_get_contents("test1://hello"),"\n"; @include "test1://hello"; echo @file_get_contents("test2://hello"),"\n"; @include "test2://hello"; --EXPECT-- <?php echo "Hello World\n";?> <?php echo "Hello World\n";?> Hello World http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/include_userstream_002.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/file/include_userstream_002.phpt +++ php-src/ext/standard/tests/file/include_userstream_002.phpt --TEST-- local user streams must not be able to open() url's --INI-- allow_url_fopen=1 allow_url_include=0 --FILE-- <?php class test { private $data = '<?php echo "Hello World\n";?>'; private $pos; private $stream = null; function stream_open($path, $mode, $options, &$opened_path) { if (strpos($path, "test2://") === 0) { $this->stream = fopen("test1://".substr($path, 8), $mode); return !empty($this->stream); } if (strchr($mode, 'a')) $this->pos = strlen($this->data); else $this->po = 0; return true; } function stream_read($count) { if (!empty($this->stream)) { return fread($this->stream, $count); } $ret = substr($this->data, $this->pos, $count); $this->pos += strlen($ret); return $ret; } function stream_tell() { if (!empty($this->stream)) { return ftell($this->stream); } return $this->pos; } function stream_eof() { if (!empty($this->stream)) { return feof($this->stream); } return $this->pos >= strlen($this->data); } function stream_seek($offset, $whence) { if (!empty($this->stream)) { return fseek($this->stream, $offset, $whence); } switch($whence) { case SEEK_SET: if ($offset < $this->data && $offset >= 0) { $this->pos = $offset; return true; } else { return false; } break; case SEEK_CUR: if ($offset >= 0) { $this->pos += $offset; return true; } else { return false; } break; case SEEK_END: if (strlen($this->data) + $offset >= 0) { $this->pos = strlen($this->data) + $offset; return true; } else { return false; } break; default: return false; } } } stream_register_wrapper("test1", "test", STREAM_IS_URL); stream_register_wrapper("test2", "test"); echo @file_get_contents("test1://hello"),"\n"; @include "test1://hello"; echo @file_get_contents("test2://hello"),"\n"; include "test2://hello"; --EXPECTF-- <?php echo "Hello World\n";?> <?php echo "Hello World\n";?> Warning: fopen(): test1:// wrapper is disabled in the server configuration in %sinclude_userstream_002.php on line 10 Warning: fopen(test1://hello): failed to open stream: no suitable wrapper could be found in %sinclude_userstream_002.php on line 10 Warning: include(test2://hello): failed to open stream: "test::stream_open" call failed in %sinclude_userstream_002.php on line 89 Warning: include(): Failed opening 'test2://hello' for inclusion (include_path='%s') in %sinclude_userstream_002.php on line 89
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php