Skip to content

Commit fd4f2a3

Browse files
committed
Reject write-only streams
1 parent 98cde49 commit fd4f2a3

4 files changed

Lines changed: 26 additions & 3 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,8 @@ $stream->on('end', function () {
714714

715715
See also [`ReadableStreamInterface`](#readablestreaminterface) for more details.
716716

717-
The first parameter given to the constructor MUST be a valid stream resource.
717+
The first parameter given to the constructor MUST be a valid stream resource
718+
that is opened in reading mode (e.g. `fopen()` mode `r`).
718719
Otherwise, it will throw an `InvalidArgumentException`:
719720

720721
```php

src/ReadableResourceStream.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ public function __construct($stream, LoopInterface $loop)
4242
throw new InvalidArgumentException('First parameter must be a valid stream resource');
4343
}
4444

45+
// ensure resource is opened for reading (fopen mode must contain "r" or "+")
46+
$meta = stream_get_meta_data($stream);
47+
if (isset($meta['mode']) && strpos($meta['mode'], 'r') === strpos($meta['mode'], '+')) {
48+
throw new InvalidArgumentException('Given stream resource is not opened in read mode');
49+
}
50+
4551
// this class relies on non-blocking I/O in order to not interrupt the event loop
4652
// e.g. pipes on Windows do not support this: https://bugs.php.net/bug.php?id=47918
4753
if (stream_set_blocking($stream, 0) !== true) {

tests/EnforceBlockingWrapper.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public function stream_cast($cast_as)
1919
return false;
2020
}
2121

22+
public function stream_eof()
23+
{
24+
return false;
25+
}
26+
2227
public function stream_set_option($option, $arg1, $arg2)
2328
{
2429
if ($option === STREAM_OPTION_BLOCKING) {

tests/ReadableResourceStreamTest.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public function testConstructor()
1515
$stream = fopen('php://temp', 'r+');
1616
$loop = $this->createLoopMock();
1717

18-
$conn = new ReadableResourceStream($stream, $loop);
18+
new ReadableResourceStream($stream, $loop);
1919
}
2020

2121
/**
@@ -26,7 +26,18 @@ public function testConstructorThrowsExceptionOnInvalidStream()
2626
$loop = $this->createLoopMock();
2727

2828
$this->setExpectedException('InvalidArgumentException');
29-
new ReadableResourceStream('breakme', $loop);
29+
new ReadableResourceStream(false, $loop);
30+
}
31+
32+
/**
33+
* @covers React\Stream\ReadableResourceStream::__construct
34+
*/
35+
public function testConstructorThrowsExceptionOnWriteOnlyStream()
36+
{
37+
$loop = $this->createLoopMock();
38+
39+
$this->setExpectedException('InvalidArgumentException');
40+
new ReadableResourceStream(STDOUT, $loop);
3041
}
3142

3243
/**

0 commit comments

Comments
 (0)