Skip to content

Commit 7bb5c36

Browse files
committed
Merge branch 'v1.7'
* v1.7: PHPLIB-345: Fix PHP shutdown error with dangling writable streams (#779)
2 parents ad8b28f + a32f018 commit 7bb5c36

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/GridFS/StreamWrapper.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ class StreamWrapper
5757
/** @var ReadableStream|WritableStream|null */
5858
private $stream;
5959

60+
public function __destruct()
61+
{
62+
/* This destructor is a workaround for PHP trying to use the stream well
63+
* after all objects have been destructed. This can cause autoloading
64+
* issues and possibly segmentation faults during PHP shutdown. */
65+
$this->stream = null;
66+
}
67+
6068
/**
6169
* Return the stream's file document.
6270
*
@@ -88,6 +96,10 @@ public static function register($protocol = 'gridfs')
8896
*/
8997
public function stream_close()
9098
{
99+
if (! $this->stream) {
100+
return;
101+
}
102+
91103
$this->stream->close();
92104
}
93105

tests/GridFS/BucketFunctionalTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,23 @@
1919
use function array_merge;
2020
use function call_user_func;
2121
use function current;
22+
use function exec;
2223
use function fclose;
2324
use function fopen;
2425
use function fread;
2526
use function fwrite;
2627
use function hash_init;
28+
use function implode;
2729
use function is_callable;
2830
use function min;
2931
use function sprintf;
3032
use function str_repeat;
3133
use function stream_get_contents;
3234
use function strlen;
35+
use function strncasecmp;
3336
use function substr;
37+
use const PHP_EOL;
38+
use const PHP_OS;
3439
use const PHP_VERSION_ID;
3540

3641
/**
@@ -743,6 +748,29 @@ public function testUploadFromStreamFails()
743748
$this->bucket->uploadFromStream('filename', $source);
744749
}
745750

751+
public function testDanglingOpenWritableStream()
752+
{
753+
if (! strncasecmp(PHP_OS, 'WIN', 3)) {
754+
$this->markTestSkipped('Test does not apply to Windows');
755+
}
756+
757+
$path = __DIR__ . '/../../vendor/autoload.php';
758+
$command = <<<CMD
759+
php -r "require '$path'; \\\$stream = (new MongoDB\Client)->test->selectGridFSBucket()->openUploadStream('filename', ['disableMD5' => true]);" 2>&1
760+
CMD;
761+
762+
@exec(
763+
$command,
764+
$output,
765+
$return
766+
);
767+
768+
$this->assertSame(0, $return);
769+
$output = implode(PHP_EOL, $output);
770+
771+
$this->assertSame('', $output);
772+
}
773+
746774
/**
747775
* Asserts that a collection with the given name does not exist on the
748776
* server.

0 commit comments

Comments
 (0)