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

Add a Patch

Pull Requests

Add a Pull Request

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-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 23 12:01:31 2024 UTC