Bug #68948 [Com]: feof() on temporary streams broken

From: Date: Mon, 09 Feb 2015 20:35:34 +0000
Subject: Bug #68948 [Com]: feof() on temporary streams broken
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-190551@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68948&edit=1

 ID:                 68948
 Comment by:         slusarz at horde dot org
 Reported by:        yunosh@php.net
 Summary:            feof() on temporary streams broken
 Status:             Open
 Type:               Bug
 Package:            Streams related
 Operating System:   Linux
 PHP Version:        5.6.5
 Block user comment: N
 Private report:     N

 New Comment:

The previous way of handling EOFs in memory streams was entirely compatible with the fread()
documentation -- http://php.net/manual/en/function.fread.php
-- which clearly states (emphasis mine):

"When reading from **anything that is not a regular local file** ... reading will stop after a
packet is available. This means that you should collect the data together in chunks.... (Example
loops through fread() to build a string; it doesn't rely on feof() to return true immediately
when the end of string is reached.)"

In other words, this can be stated as: "When reading from a memory stream, which is NOT a
regular local file, it cannot be guaranteed that at the end of any fread() operation that EOF has
been reached."

Any code that requires feof() to return true in a in-memory stream immediately after a non-empty
fread() return is broken, since this is non-guaranteed behavior.  Thus, this fix must be reverted as
it is a backward incompatible change.  the base64 filter (or filter code in general) is the
problematic code and is what needs to be fixed.


Previous Comments:
------------------------------------------------------------------------
[2015-02-09 19:53:39] yunosh@php.net

Changing version because this is a major regression in the latest stable 5.5 and 5.6 releases too.

------------------------------------------------------------------------
[2015-02-07 13:08:53] sjaillet at gmail dot com

It's definitely a bug introduced recently.

Indeed with:

$stream = fopen("php://temp", "r+");
fwrite($stream, "0123456789");
rewind($stream);
var_dump(fread($stream, 1024), ftell($stream), feof($stream));

The output for 5.5.20, 5.6.4, php7@20141201, HHVM 3.5.0 is:

string(10) "0123456789"
int(10)
bool(true)

And now with 5.5.21, 5.6.5, php7@20150101 the output was:

string(10) "0123456789"
int(10)
bool(false)

------------------------------------------------------------------------
[2015-01-29 20:02:47] yunosh@php.net

It still happens if reading 11 bytes. And even with 10 bytes, this would be BC break against PHP 5.

------------------------------------------------------------------------
[2015-01-29 19:15:29] php at mcq8 dot be

This is due to https://github.com/php/php-src/pull/936
You only get an EOF when you tried to read more than there is data.
This is the same behaviour as reading from a file.

------------------------------------------------------------------------
[2015-01-29 17:42:00] yunosh@php.net

Description:
------------
feof() doesn't work properly on temporary streams.

Test script:
---------------
$stream = fopen("php://temp", "r+");
fwrite($stream, "0123456789");
rewind($stream);
var_dump(fread($stream, 10), ftell($stream), feof($stream));

Expected result:
----------------
string(10) "0123456789"
int(10)
bool(true)


Actual result:
--------------
string(10) "0123456789"
int(10)
bool(false)



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=68948&edit=1


Thread (10 messages)

« previous php.bugs (#190551) next »