diff options
author | Dmitry Stogov <dmitry@php.net> | 2007-07-09 17:27:24 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2007-07-09 17:27:24 +0000 |
commit | 539f67ed8fc4af3084a0f7a0aea64f14a6b4d799 (patch) | |
tree | b82b94354887b9e7152400ee32e7ac15027f79bb /ext | |
parent | fe9a8266053de5e04468d2e276fbd277978dc1ef (diff) | |
download | php-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.c | 9 | ||||
-rw-r--r-- | ext/standard/streamsfuncs.c | 31 | ||||
-rw-r--r-- | ext/standard/streamsfuncs.h | 1 | ||||
-rwxr-xr-x | ext/standard/tests/file/include_userstream_001.phpt | 82 | ||||
-rwxr-xr-x | ext/standard/tests/file/include_userstream_002.phpt | 106 |
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 |