php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #31085 invalid feof() results due to Zend's caching of user stream wrappers
Submitted: 2004-12-14 11:41 UTC Modified: 2005-05-11 04:06 UTC
Votes:2
Avg. Score:3.0 ± 2.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: php at webdevelopers dot cz Assigned: wez (profile)
Status: Not a bug Package: Filesystem function related
PHP Version: 5.0.2 OS: Linux 2.6.6 (gcc 3.3.4)
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: php at webdevelopers dot cz
New email:
PHP Version: OS:

 

 [2004-12-14 11:41 UTC] php at webdevelopers dot cz
Description:
------------
PHP caches the userarea wrappers - it results for example
to WRAPPER::stream_read(8192) call by PHP even if the user issued fread($f, 10);
If the file is for example 20 bytes long then user gets EOF immediately after
first fread($f, 10) because PHP cached it by calling WRAPPER::stream_read(8192) instead!

Example:
(file size is 20 bytes)
user: $f=fopen(..., 'r');
zend: stream_open(...);
zend: stream_read(8192); // And we immediately get EOF in my example (8192 > 20)
user: fread($f, 10); // Reads first 10 bytes
user: feof($f);
zend: stream_eof(...); // Result is TRUE thus when feof() used in cyclus it does not iterate even if there are 10 bytes more in this example.


Reproduce code:
---------------
stream_wrapper_register('xyz', 'MyStream') or die('Failed to register X protocol.');
test('xyz://me.txt');
test('./test_me2.txt');
function test($fileName) {
  echo "TEST: $fileName\n";
  $f=fopen($fileName, 'w+'); fwrite($f, '123456789'); fclose($f);
  $f=fopen($fileName, 'r');
  while(!feof($f)) { echo "[".fread($f, 5)."]\n";}
  fclose($f);
}
class MyStream {
  private $f;
  function stream_open($path, $mode, $options, &$opened_path) {
    $path=str_replace('xyz://', './test_', $path);
    return (bool) $this->f=fopen($path, $mode);
  }
  function stream_read($count) {return fread($this->f, $count);}
  function stream_write($data) {return fwrite($this->f, $data);}
  function stream_tell() {return ftell($this->f);}
  function stream_eof() {return feof($this->f);}
  function stream_seek($offset, $whence) {return fseek($this->f, $offset, $whence);}
  function stream_close() {return fclose($this->f);}
}


Expected result:
----------------
TEST: xyz://me.txt
[12345]
[6789]
TEST: ./test_me2.txt
[12345]
[6789]


Actual result:
--------------
TEST: xyz://me.txt
TEST: ./test_me2.txt
[12345]
[6789]


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-01-24 02:26 UTC] hholzgra@php.net
Returning !feof() in stream_eof() seems to 'fix' this.

 looks like the LIVENESS test in main/streams/userspace.c:838 uses reverse logic?
 [2005-02-28 21:16 UTC] sniper@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5-win32-latest.zip


 [2005-03-08 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2005-05-11 04:06 UTC] wez@php.net
Duplicate of #27508; fixed in HEAD.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Jul 06 09:01:32 2025 UTC