summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2007-07-09 17:27:24 +0000
committerDmitry Stogov <dmitry@php.net>2007-07-09 17:27:24 +0000
commit539f67ed8fc4af3084a0f7a0aea64f14a6b4d799 (patch)
treeb82b94354887b9e7152400ee32e7ac15027f79bb /ext
parentfe9a8266053de5e04468d2e276fbd277978dc1ef (diff)
downloadphp-git-539f67ed8fc4af3084a0f7a0aea64f14a6b4d799.tar.gz
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) ]
Diffstat (limited to 'ext')
-rw-r--r--ext/standard/basic_functions.c9
-rw-r--r--ext/standard/streamsfuncs.c31
-rw-r--r--ext/standard/streamsfuncs.h1
-rwxr-xr-xext/standard/tests/file/include_userstream_001.phpt82
-rwxr-xr-xext/standard/tests/file/include_userstream_002.phpt106
5 files changed, 228 insertions, 1 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 4ca820ddf0..e93b3a9ed6 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -207,9 +207,10 @@ ZEND_END_ARG_INFO()
/* }}} */
/* {{{ 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 @@ static
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 @@ zend_function_entry basic_functions[] = {
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)
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index a964dd6882..5d3abca2ce 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -1341,6 +1341,37 @@ PHP_FUNCTION(stream_socket_enable_crypto)
}
/* }}} */
+/* {{{ 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
diff --git a/ext/standard/streamsfuncs.h b/ext/standard/streamsfuncs.h
index 4d86645485..16b4a7eca8 100644
--- a/ext/standard/streamsfuncs.h
+++ b/ext/standard/streamsfuncs.h
@@ -55,6 +55,7 @@ PHP_FUNCTION(stream_filter_remove);
PHP_FUNCTION(stream_socket_enable_crypto);
PHP_FUNCTION(stream_socket_shutdown);
PHP_FUNCTION(stream_socket_pair);
+PHP_FUNCTION(stream_is_local);
/*
* Local variables:
diff --git a/ext/standard/tests/file/include_userstream_001.phpt b/ext/standard/tests/file/include_userstream_001.phpt
new file mode 100755
index 0000000000..d805afd204
--- /dev/null
+++ b/ext/standard/tests/file/include_userstream_001.phpt
@@ -0,0 +1,82 @@
+--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
diff --git a/ext/standard/tests/file/include_userstream_002.phpt b/ext/standard/tests/file/include_userstream_002.phpt
new file mode 100755
index 0000000000..80690a9b19
--- /dev/null
+++ b/ext/standard/tests/file/include_userstream_002.phpt
@@ -0,0 +1,106 @@
+--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(): URL file-access 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