Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Raise exception on write() if stream is not writeable #15

Closed
wants to merge 4 commits into from

Conversation

mtymek
Copy link
Contributor

@mtymek mtymek commented May 24, 2015

Fixes #13.

I had to change how isWritable does the check, as is_writable($meta['uri']) is unreliable for TEMP and MEMORY streams.

return is_writable($meta['uri']);
$mode = $meta['mode'];

return (strstr($mode, 'w') || strstr($mode, '+'));
Copy link
Member

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 +?

Copy link
Contributor Author

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 get rb or w+b
  • for files PHP will accept even things like this: $f2 = fopen('/tmp/test', 'ah()+');, and report them under mode

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.

@Ocramius Ocramius added the bug label May 25, 2015
@Ocramius Ocramius added this to the 1.0.1 milestone May 25, 2015
@Ocramius Ocramius self-assigned this May 25, 2015
@mtymek mtymek force-pushed the throw_exception_write branch from d9ea433 to 8a6427a Compare May 25, 2015 11:22
@@ -60,7 +60,7 @@ public function __construct($stream, $mode = 'r')
public function __toString()
{
if (! $this->isReadable()) {
return '';
throw new RuntimeException('Stream is not readable');
Copy link
Member

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.

Copy link
Contributor Author

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 :)

Copy link
Member

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.

Copy link
Contributor Author

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...

@mtymek mtymek force-pushed the throw_exception_write branch from 71f512f to 9088e59 Compare May 25, 2015 20:48
@mtymek
Copy link
Contributor Author

mtymek commented May 25, 2015

Updated!

strstr($mode, 'x')
|| strstr($mode, 'w')
|| strstr($mode, 'c')
|| strstr($mode, 'a')
Copy link
Member

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

@mtymek
Copy link
Contributor Author

mtymek commented May 26, 2015

Added tests for all modes that make sense; did the same for isReadable.

@Ocramius
Copy link
Member

Thanks @mtymek

@mtymek mtymek force-pushed the throw_exception_write branch from 1f79766 to 206778b Compare May 26, 2015 11:42
private function findNonExistentTempName()
{
while (true) {
$tmpnam = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'diac' . uniqid();
Copy link
Member

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

Copy link
Contributor Author

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

Copy link
Member

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 :)

Copy link
Contributor Author

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 :-)

@Ocramius Ocramius closed this in d7d7751 May 26, 2015
Ocramius added a commit that referenced this pull request May 26, 2015
@Ocramius
Copy link
Member

@mtymek merged, thanks!

master: d7d7751
develop: 4718cf4

@mtymek mtymek deleted the throw_exception_write branch January 27, 2016 21:26
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Raise exception on write() if stream is not writeable
3 participants