summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo André dos Santos Lopes <cataphract@php.net>2012-03-17 19:37:30 +0000
committerGustavo André dos Santos Lopes <cataphract@php.net>2012-03-17 19:37:30 +0000
commitef19fba2d59bc0e7875342d01cd513ae7f4c5d5e (patch)
tree058d63e2ffa0852058cc8a0ee2348e752f58d026
parenta07759a01354b88a5807a023127da81dc1bc5ac9 (diff)
downloadphp-git-ef19fba2d59bc0e7875342d01cd513ae7f4c5d5e.tar.gz
- Fixed bug #61371 (resource leak). This bug had two parts, a long standing leak
already fixed in trunk/5.3 and now merged onto 5.4 and a leak introduced in fixing bug #61115. This better fix for #61115 fixes the leak (the inhibition for deleting the context was too broad) and so prevents segfaults in new circumstances (where the inhibition was not broad enough).
-rw-r--r--NEWS2
-rw-r--r--ext/standard/tests/streams/bug61115-1.phpt11
-rw-r--r--ext/standard/tests/streams/bug61115-2.phpt10
-rw-r--r--ext/standard/tests/streams/bug61371.phpt40
-rwxr-xr-xmain/streams/streams.c2
5 files changed, 64 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 355a651120..04bcd32def 100644
--- a/NEWS
+++ b/NEWS
@@ -98,6 +98,8 @@ PHP NEWS
SessionHandler::write()). (Ilia)
- Streams:
+ . Fixed bug #61371 (stream_context_create() causes memory leaks on use
+ streams_socket_create). (Gustavo)
. Fixed bug #61253 (Wrappers opened with errors concurrency problem on ZTS).
(Gustavo)
. Fixed bug #61115 (stream related segfault on fatal error in
diff --git a/ext/standard/tests/streams/bug61115-1.phpt b/ext/standard/tests/streams/bug61115-1.phpt
new file mode 100644
index 0000000000..43c54b4974
--- /dev/null
+++ b/ext/standard/tests/streams/bug61115-1.phpt
@@ -0,0 +1,11 @@
+--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
diff --git a/ext/standard/tests/streams/bug61115-2.phpt b/ext/standard/tests/streams/bug61115-2.phpt
new file mode 100644
index 0000000000..260b8369df
--- /dev/null
+++ b/ext/standard/tests/streams/bug61115-2.phpt
@@ -0,0 +1,10 @@
+--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==
diff --git a/ext/standard/tests/streams/bug61371.phpt b/ext/standard/tests/streams/bug61371.phpt
new file mode 100644
index 0000000000..7fbfa56ba2
--- /dev/null
+++ b/ext/standard/tests/streams/bug61371.phpt
@@ -0,0 +1,40 @@
+--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
diff --git a/main/streams/streams.c b/main/streams/streams.c
index edcf0fb025..639ea075a0 100755
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -344,7 +344,7 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /*
/* 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 (!(close_options & PHP_STREAM_FREE_RSRC_DTOR)) {
+ if (EG(active)) {
context = stream->context;
}