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

Reply via email to