From: Antony Dovgal Date: Thu, 24 Aug 2006 08:42:16 +0000 (+0000) Subject: fix #38450 (constructor is not called for classes used in userspace stream wrappers) X-Git-Tag: php-4.4.5RC1~80 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=58091606265acea282937cfe1d118b9992f96055;p=php fix #38450 (constructor is not called for classes used in userspace stream wrappers) --- diff --git a/NEWS b/NEWS index 68a3209c51..dfe1027bdf 100644 --- 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 index 0000000000..cae11bc53a --- /dev/null +++ b/ext/standard/tests/file/bug38450.phpt @@ -0,0 +1,114 @@ +--TEST-- +Bug #38450 (constructor is not called for classes used in userspace stream wrappers) +--FILE-- +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 diff --git a/main/user_streams.c b/main/user_streams.c index 10f4edc745..80079b8d0e 100644 --- a/main/user_streams.c +++ b/main/user_streams.c @@ -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);