dmitry Tue Jul 3 10:22:56 2007 UTC
Added files:
/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.732&r2=1.733&diff_format=u
Index: php-src/main/main.c
diff -u php-src/main/main.c:1.732 php-src/main/main.c:1.733
--- php-src/main/main.c:1.732 Fri Jun 15 09:20:53 2007
+++ php-src/main/main.c Tue Jul 3 10:22:55 2007
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: main.c,v 1.732 2007/06/15 09:20:53 dmitry Exp $ */
+/* $Id: main.c,v 1.733 2007/07/03 10:22:55 dmitry Exp $ */
/* {{{ includes
*/
@@ -1232,6 +1232,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.111&r2=1.112&diff_format=u
Index: php-src/main/php_globals.h
diff -u php-src/main/php_globals.h:1.111 php-src/main/php_globals.h:1.112
--- php-src/main/php_globals.h:1.111 Fri Mar 2 22:04:46 2007
+++ php-src/main/php_globals.h Tue Jul 3 10:22:55 2007
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_globals.h,v 1.111 2007/03/02 22:04:46 stas Exp $ */
+/* $Id: php_globals.h,v 1.112 2007/07/03 10:22:55 dmitry Exp $ */
#ifndef PHP_GLOBALS_H
#define PHP_GLOBALS_H
@@ -142,6 +142,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.128&r2=1.129&diff_format=u
Index: php-src/main/php_streams.h
diff -u php-src/main/php_streams.h:1.128 php-src/main/php_streams.h:1.129
--- php-src/main/php_streams.h:1.128 Sat Mar 3 22:30:07 2007
+++ php-src/main/php_streams.h Tue Jul 3 10:22:55 2007
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_streams.h,v 1.128 2007/03/03 22:30:07 helly Exp $ */
+/* $Id: php_streams.h,v 1.129 2007/07/03 10:22:55 dmitry Exp $ */
#ifndef PHP_STREAMS_H
#define PHP_STREAMS_H
@@ -619,6 +619,9 @@
/* use glob stream for directory open in plain files stream */
#define STREAM_USE_GLOB_DIR_OPEN 0x00001000
+/* use glob stream for directory open in plain files stream */
+#define STREAM_DISABLE_URL_PROTECTION 0x00002000
+
/* Antique - no longer has meaning */
#define IGNORE_URL_WIN 0
@@ -669,7 +672,7 @@
PHP_INI_MH(OnUpdateAllowUrl);
PHPAPI int php_stream_wrapper_is_allowed(const char *wrapper, int wrapper_len,
const char *setting TSRMLS_DC);
-#define php_stream_allow_url_fopen(wrapper, wrapper_len)
php_stream_wrapper_is_allowed((wrapper), (wrapper_len),
PG(allow_url_fopen_list) TSRMLS_CC)
+#define php_stream_allow_url_fopen(wrapper, wrapper_len)
php_stream_wrapper_is_allowed((wrapper), (wrapper_len),
PG(in_user_include)?PG(allow_url_include_list):PG(allow_url_fopen_list)
TSRMLS_CC)
#define php_stream_allow_url_include(wrapper, wrapper_len)
php_stream_wrapper_is_allowed((wrapper), (wrapper_len),
PG(allow_url_include_list) TSRMLS_CC)
/* Give other modules access to the url_stream_wrappers_hash and
stream_filters_hash */
@@ -683,6 +686,8 @@
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.151&r2=1.152&diff_format=u
Index: php-src/main/streams/streams.c
diff -u php-src/main/streams/streams.c:1.151
php-src/main/streams/streams.c:1.152
--- php-src/main/streams/streams.c:1.151 Tue May 8 12:08:41 2007
+++ php-src/main/streams/streams.c Tue Jul 3 10:22:55 2007
@@ -19,7 +19,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: streams.c,v 1.151 2007/05/08 12:08:41 dmitry Exp $ */
+/* $Id: streams.c,v 1.152 2007/07/03 10:22:55 dmitry Exp $ */
#define _GNU_SOURCE
#include "php.h"
@@ -2163,8 +2163,9 @@
return plain_files_wrapper;
}
- if (!php_stream_allow_url_fopen(protocol, n) ||
- ((options & STREAM_OPEN_FOR_INCLUDE) &&
!php_stream_allow_url_include(protocol, n)) ) {
+ if (((options & STREAM_DISABLE_URL_PROTECTION) == 0) &&
+ (!php_stream_allow_url_fopen(protocol, n) ||
+ ((options & STREAM_OPEN_FOR_INCLUDE) &&
!php_stream_allow_url_include(protocol, n)))) {
if (options & REPORT_ERRORS) {
/* protocol[n] probably isn't '\0' */
char *protocol_dup = estrndup(protocol, n);
@@ -2797,7 +2798,7 @@
return FAILURE;
}
- wrapper = php_stream_locate_url_wrapper(scheme, NULL,
options TSRMLS_CC);
+ wrapper = php_stream_locate_url_wrapper(scheme, NULL,
options | STREAM_DISABLE_URL_PROTECTION TSRMLS_CC);
efree(scheme);
if (!wrapper) {
*pathenc = NULL;
http://cvs.php.net/viewvc.cgi/php-src/main/streams/userspace.c?r1=1.42&r2=1.43&diff_format=u
Index: php-src/main/streams/userspace.c
diff -u php-src/main/streams/userspace.c:1.42
php-src/main/streams/userspace.c:1.43
--- php-src/main/streams/userspace.c:1.42 Tue May 15 13:01:47 2007
+++ php-src/main/streams/userspace.c Tue Jul 3 10:22:55 2007
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: userspace.c,v 1.42 2007/05/15 13:01:47 scottmac Exp $ */
+/* $Id: userspace.c,v 1.43 2007/07/03 10:22:55 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_list) == NULL ||
strlen(PG(allow_url_include_list)) !=1 || PG(allow_url_include_list)[0] !=
'*')) {
+ 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) {
@@ -338,7 +352,8 @@
zval_ptr_dtor(&zfilename);
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.861&r2=1.862&diff_format=u
Index: php-src/ext/standard/basic_functions.c
diff -u php-src/ext/standard/basic_functions.c:1.861
php-src/ext/standard/basic_functions.c:1.862
--- php-src/ext/standard/basic_functions.c:1.861 Tue Jun 26 21:29:32 2007
+++ php-src/ext/standard/basic_functions.c Tue Jul 3 10:22:55 2007
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: basic_functions.c,v 1.861 2007/06/26 21:29:32 tony2001 Exp $ */
+/* $Id: basic_functions.c,v 1.862 2007/07/03 10:22:55 dmitry Exp $ */
#include "php.h"
#include "php_streams.h"
@@ -205,9 +205,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
@@ -2347,6 +2348,11 @@
ZEND_END_ARG_INFO()
static
+ZEND_BEGIN_ARG_INFO(arginfo_stream_is_local, 0)
+ ZEND_ARG_INFO(0, stream)
+ZEND_END_ARG_INFO()
+
+static
ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_select, 0, 0, 4)
ZEND_ARG_INFO(1, read_streams) /* ARRAY_INFO(1, read_streams, 1) */
ZEND_ARG_INFO(1, write_streams) /* ARRAY_INFO(1, write_streams, 1) */
@@ -3596,6 +3602,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.103&r2=1.104&diff_format=u
Index: php-src/ext/standard/streamsfuncs.c
diff -u php-src/ext/standard/streamsfuncs.c:1.103
php-src/ext/standard/streamsfuncs.c:1.104
--- php-src/ext/standard/streamsfuncs.c:1.103 Thu Apr 12 13:15:17 2007
+++ php-src/ext/standard/streamsfuncs.c Tue Jul 3 10:22:55 2007
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: streamsfuncs.c,v 1.103 2007/04/12 13:15:17 tony2001 Exp $ */
+/* $Id: streamsfuncs.c,v 1.104 2007/07/03 10:22:55 dmitry Exp $ */
#include "php.h"
#include "php_globals.h"
@@ -1647,6 +1647,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) U
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.19&r2=1.20&diff_format=u
Index: php-src/ext/standard/streamsfuncs.h
diff -u php-src/ext/standard/streamsfuncs.h:1.19
php-src/ext/standard/streamsfuncs.h:1.20
--- php-src/ext/standard/streamsfuncs.h:1.19 Mon Jan 1 09:29:32 2007
+++ php-src/ext/standard/streamsfuncs.h Tue Jul 3 10:22:55 2007
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: streamsfuncs.h,v 1.19 2007/01/01 09:29:32 sebastian Exp $ */
+/* $Id: streamsfuncs.h,v 1.20 2007/07/03 10:22:55 dmitry Exp $ */
/* Flags for stream_socket_client */
#define PHP_STREAM_CLIENT_PERSISTENT 1
@@ -57,6 +57,7 @@
PHP_FUNCTION(stream_socket_shutdown);
PHP_FUNCTION(stream_socket_pair);
PHP_FUNCTION(stream_resolve_include_path);
+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