]> granicus.if.org Git - php/commitdiff
fix #38450 (constructor is not called for classes used in userspace stream wrappers)
authorAntony Dovgal <tony2001@php.net>
Thu, 24 Aug 2006 08:42:16 +0000 (08:42 +0000)
committerAntony Dovgal <tony2001@php.net>
Thu, 24 Aug 2006 08:42:16 +0000 (08:42 +0000)
NEWS
ext/standard/tests/file/bug38450.phpt [new file with mode: 0644]
main/user_streams.c

diff --git a/NEWS b/NEWS
index 68a3209c51180885171321a7ba83f046a69a2db4..dfe1027bdfd843d25ce3cea676ac4f9c481f238e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 PHP 4                                                                      NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2006, Version 4.4.5
+- Fixed bug #38450 (constructor is not called for classes used in userspace
+  stream wrappers). (Tony)
 - Fixed bug #38378 (wddx_serialize_value() generates no wellformed xml). 
   (sj at sjaensch dot org, grzegorz dot nosek at netart dot pl, Tony).
        
diff --git a/ext/standard/tests/file/bug38450.phpt b/ext/standard/tests/file/bug38450.phpt
new file mode 100644 (file)
index 0000000..cae11bc
--- /dev/null
@@ -0,0 +1,114 @@
+--TEST--
+Bug #38450 (constructor is not called for classes used in userspace stream wrappers)
+--FILE--
+<?php
+
+class VariableStream {
+       var $position;
+       var $varname;
+
+       function VariableStream($var) {
+               var_dump("constructor!");
+       }
+
+       function stream_open($path, $mode, $options, &$opened_path)
+       {
+               $url = parse_url($path);
+               $this->varname = $url["host"];
+               $this->position = 0;
+
+               return true;
+       }
+
+       function stream_read($count)
+       {
+               $ret = substr($GLOBALS[$this->varname], $this->position, $count);
+               $this->position += strlen($ret);
+               return $ret;
+       }
+
+       function stream_write($data)
+       {
+               $left = substr($GLOBALS[$this->varname], 0, $this->position);
+               $right = substr($GLOBALS[$this->varname], $this->position + strlen($data));
+               $GLOBALS[$this->varname] = $left . $data . $right;
+               $this->position += strlen($data);
+               return strlen($data);
+       }
+
+       function stream_tell()
+       {
+               return $this->position;
+       }
+
+       function stream_eof()
+       {
+               return $this->position >= strlen($GLOBALS[$this->varname]);
+       }
+       function stream_seek($offset, $whence)
+       {
+               switch ($whence) {
+               case SEEK_SET:
+                       if ($offset < strlen($GLOBALS[$this->varname]) && $offset >= 0) {
+                               $this->position = $offset;
+                               return true;
+                       } else {
+                               return false;
+                       }
+                       break;
+
+               case SEEK_CUR:
+                       if ($offset >= 0) {
+                               $this->position += $offset;
+                               return true;
+                       } else {
+                               return false;
+                       }
+                       break;
+
+               case SEEK_END:
+                       if (strlen($GLOBALS[$this->varname]) + $offset >= 0) {
+                               $this->position = strlen($GLOBALS[$this->varname]) + $offset;
+                               return true;
+                       } else {
+                               return false;
+                       }
+                       break;
+
+               default:
+                       return false;
+               }
+       }
+}
+
+stream_wrapper_register("var", "VariableStream")
+       or die("Failed to register protocol");
+
+$myvar = "";
+
+$fp = fopen("var://myvar", "r+");
+
+fwrite($fp, "line1\n");
+fwrite($fp, "line2\n");
+fwrite($fp, "line3\n");
+
+rewind($fp);
+while (!feof($fp)) {
+       echo fgets($fp);
+}
+fclose($fp);
+var_dump($myvar);
+
+echo "Done\n";
+?>
+--EXPECTF--    
+Warning: Missing argument 1 for variablestream() in %s on line %d
+string(12) "constructor!"
+line1
+line2
+line3
+string(18) "line1
+line2
+line3
+"
+Done
index 10f4edc7452b8c81a32d4b21d855053af0e616d7..80079b8d0ea24d49352ee53ba7edea373a7e2a95 100644 (file)
@@ -193,7 +193,33 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena
        object_init_ex(us->object, uwrap->ce);
        ZVAL_REFCOUNT(us->object) = 1;
        PZVAL_IS_REF(us->object) = 1;
-       
+
+       if (zend_hash_exists(&uwrap->ce->function_table, uwrap->ce->name, uwrap->ce->name_length+1)) {
+               zval *retval_ptr;
+               zval *function_name;
+
+               MAKE_STD_ZVAL(function_name);
+               ZVAL_STRINGL(function_name, uwrap->ce->name, uwrap->ce->name_length, 1);
+
+               if (call_user_function_ex(EG(function_table), &us->object, function_name, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC) == FAILURE) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute %s::%s()", uwrap->ce->name, uwrap->ce->name);
+                       zval_dtor(function_name);
+                       FREE_ZVAL(function_name);
+                       zval_dtor(us->object);
+                       FREE_ZVAL(us->object);
+                       efree(us);
+                       FG(user_stream_current_filename) = NULL;
+                       return NULL;
+               } else {
+                       if (retval_ptr) {
+                               zval_ptr_dtor(&retval_ptr);
+                       }
+               }
+               zval_dtor(function_name);
+               FREE_ZVAL(function_name);
+       }
+
+
        /* call it's stream_open method - set up params first */
        MAKE_STD_ZVAL(zfilename);
        ZVAL_STRING(zfilename, filename, 1);