-
Notifications
You must be signed in to change notification settings - Fork 150
Raise exception on write() if stream is not writeable #15
Conversation
return is_writable($meta['uri']); | ||
$mode = $meta['mode']; | ||
|
||
return (strstr($mode, 'w') || strstr($mode, '+')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are all the possible valid $mode
strings? Can w
be before +
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Answer is complex, depending on your definition of "valid". If by "valid" you mean everything that PHP accepts, then:
- for TEMP and MEMORY streams,
mode
is normalized, you always getrb
orw+b
- for files PHP will accept even things like this:
$f2 = fopen('/tmp/test', 'ah()+');
, and report them undermode
So, apparently in order to satisfy fopen
docs, we have to check if any of characters +, a, c, w, x
is present in mode
. If you agree, I can post fix in a moment.
Yes, w
can be before +
. Not sure why you ask though.
d9ea433
to
8a6427a
Compare
@@ -60,7 +60,7 @@ public function __construct($stream, $mode = 'r') | |||
public function __toString() | |||
{ | |||
if (! $this->isReadable()) { | |||
return ''; | |||
throw new RuntimeException('Stream is not readable'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, we cannot throw exceptions here; see the PHP manual. The correct behavior here is to return an empty string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uhm, that's what I asked about in #16 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know; it was seeing it in the context of the method that made me remember why I wasn't throwing an exception previously here. Since the exception is non-recoverable, we must cast to an empty string instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, now I remember the horror of debugging ZF1's view helper throwing exception...
71f512f
to
9088e59
Compare
Updated! |
strstr($mode, 'x') | ||
|| strstr($mode, 'w') | ||
|| strstr($mode, 'c') | ||
|| strstr($mode, 'a') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these modes need to be checked in the tests - consider using a data-provider
Added tests for all modes that make sense; did the same for |
Thanks @mtymek |
1f79766
to
206778b
Compare
private function findNonExistentTempName() | ||
{ | ||
while (true) { | ||
$tmpnam = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'diac' . uniqid(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is tempnam
for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See docs - tempnam
creates new file. If you open it with x
mode, you get a warning:
PHP Warning: fopen(/tmp/zrazAZD39N): failed to open stream: File exists in phar:///home/mat/bin/boris.phar/lib/Boris/EvalWorker.php(133) : eval()'d code on line 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, didn't know :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me neither, I realized this when my tests started to fail :-)
Fixes #13.
I had to change how
isWritable
does the check, asis_writable($meta['uri'])
is unreliable for TEMP and MEMORY streams.