mirror of
https://github.com/php/php-src.git
synced 2024-11-28 12:26:37 +08:00
- 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).
This commit is contained in:
parent
9bfe8010a0
commit
d974e44248
@ -106,10 +106,6 @@ PHP_FUNCTION(stream_socket_client)
|
||||
|
||||
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);
|
||||
}
|
||||
|
11
ext/standard/tests/streams/bug61115-1.phpt
Normal file
11
ext/standard/tests/streams/bug61115-1.phpt
Normal file
@ -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
|
10
ext/standard/tests/streams/bug61115-2.phpt
Normal file
10
ext/standard/tests/streams/bug61115-2.phpt
Normal file
@ -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==
|
13
ext/standard/tests/streams/bug61115.phpt
Normal file
13
ext/standard/tests/streams/bug61115.phpt
Normal file
@ -0,0 +1,13 @@
|
||||
--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
|
40
ext/standard/tests/streams/bug61371.phpt
Normal file
40
ext/standard/tests/streams/bug61371.phpt
Normal file
@ -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
|
@ -385,7 +385,14 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /*
|
||||
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;
|
||||
@ -464,8 +471,8 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
|
Loading…
Reference in New Issue
Block a user