context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT);
- if (context) {
- zend_list_addref(context->rsrc_id);
- }
-
if (flags & PHP_STREAM_CLIENT_PERSISTENT) {
spprintf(&hashkey, 0, "stream_socket_client__%s", host);
}
--- /dev/null
+--TEST--
+Bug #61115: Stream related segfault on fatal error in php_stream_context_del_link - variation 1
+--FILE--
+<?php
+
+$fileResourceTemp = fopen('php://temp', 'wr');
+stream_context_get_options($fileResourceTemp);
+ftruncate($fileResourceTemp, PHP_INT_MAX);
+?>
+--EXPECTF--
+Fatal error: Allowed memory size of %d bytes exhausted at %s:%d (tried to allocate %d bytes) in %s on line %d
--- /dev/null
+--TEST--
+Bug #61115: Stream related segfault on fatal error in php_stream_context_del_link - variation 2
+--FILE--
+<?php
+stream_socket_client('abc', $var, $var, 0, STREAM_CLIENT_PERSISTENT);
+
+?>
+==DONE==
+--EXPECT--
+==DONE==
--- /dev/null
+--TEST--
+Bug #61115: Stream related segfault on fatal error in php_stream_context_del_link.
+--FILE--
+<?php
+
+$arrayLarge = array_fill(0, 113663, '*');
+
+$resourceFileTemp = fopen('php://temp', 'r+');
+stream_context_set_params($resourceFileTemp, array());
+preg_replace('', function() {}, $resourceFileTemp);
+?>
+--EXPECTF--
+Catchable fatal error: Object of class Closure could not be converted to string in %s on line %d
--- /dev/null
+--TEST--
+Bug #61371: stream_context_create() causes memory leaks on use streams_socket_create
+--FILE--
+<?php
+function test($doFclose) {
+$previous = null;
+$current = null;
+for($test=1;$test<=3;$test++) {
+ $current = memory_get_usage(true);
+ if (!is_null($previous)) {
+ var_dump($previous == $current);
+ }
+ $previous = $current;
+ echo 'memory: '.round($current / 1024, 0)."kb\n";
+ for($i=0;$i<=100;$i++) {
+ $context = stream_context_create(array());
+ $stream = stream_socket_client('udp://0.0.0.0:80', $errno, $errstr, 10, STREAM_CLIENT_CONNECT, $context);
+ if ($doFclose) fclose($stream);
+ unset($context);
+ unset($stream);
+ unset($errno);
+ unset($errstr);
+ }
+}
+}
+
+test(true);
+test(false);
+?>
+--EXPECTF--
+memory: %dkb
+bool(true)
+memory: %dkb
+bool(true)
+memory: %dkb
+memory: %dkb
+bool(true)
+memory: %dkb
+bool(true)
+memory: %dkb
int ret = 1;
int preserve_handle = close_options & PHP_STREAM_FREE_PRESERVE_HANDLE ? 1 : 0;
int release_cast = 1;
- php_stream_context *context = stream->context;
+ php_stream_context *context = NULL;
+
+ /* on an resource list destruction, the context, another resource, may have
+ * already been freed (if it was created after the stream resource), so
+ * don't reference it */
+ if (EG(active)) {
+ context = stream->context;
+ }
if (stream->flags & PHP_STREAM_FLAG_NO_CLOSE) {
preserve_handle = 1;
}
/* Remove stream from any context link list */
- if (stream->context && stream->context->links) {
- php_stream_context_del_link(stream->context, stream);
+ if (context && context->links) {
+ php_stream_context_del_link(context, stream);
}
if (close_options & PHP_STREAM_FREE_CALL_DTOR) {