php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #30936 fread from userspace stream wrapper only reads 8192 bytes
Submitted: 2004-11-29 22:47 UTC Modified: 2004-12-01 17:45 UTC
From: jason at e7x dot com Assigned: wez
Status: Not a bug Package: Filesystem function related
PHP Version: 4.3.9 OS: Windows 2000/Linux
Private report: No CVE-ID:
 [2004-11-29 22:47 UTC] jason at e7x dot com
Description:
------------
Attempting to fread() more than 8192 bytes from a userspace stream wrapper will only read and return the first 8192 bytes, putting an echo statement in stream_read() shows that it is only being called once.

Reading <= 8192 bytes at a time works as expected, as does fgets($f, 15000) (reads 14999 bytes).

This bug is only present in 4.3.9 and 4.3.10RC1, 4.3.8 works fine. 

Reproduce code:
---------------
<?php

// using example class from the manual: 
// http://uk.php.net/stream_wrapper_register

$x = str_repeat('x', 15000);
$f = fopen('var://x', 'r');
$len = strlen(fread($f, 15000));
fclose($f);

echo "Read $len bytes";

?>

Expected result:
----------------
Read 15000 bytes

Actual result:
--------------
Read 8192 bytes

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-11-29 23:24 UTC] derick@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

http://php.net/fread says:

fread() reads up to length bytes from the file pointer referenced by handle

note the \"up to\".
 [2004-11-30 00:27 UTC] jason at e7x dot com
Length bytes have not been read and EOF was not reached, this is not a network stream.

In the example code there *are* 15000 bytes available to read. Regular file system functions, compress.zlib (didn't try other builtin streams) and PHP <= 4.3.8 have no problem reading more than 8192 bytes in one hit.

I can't find any reference to an 8192 limit anywhere in the manual.
 [2004-11-30 08:41 UTC] chregu@php.net
http://ch.php.net/manual/en/function.fread.php

First paragraph:

"fread() reads up to length bytes from the file pointer referenced by handle."


 [2004-11-30 22:37 UTC] jason at e7x dot com
I'm afraid I still don't see the relevance of that sentence.
Surely "up to" does not mean it may stop reading at any point for no apparent reason.

Maybe I'm not explaining this very well. Or maybe I've completely missed the point of streams.

Looking in the source (not that I really understand what I'm looking at) for 4.3.9 and comparing to 4.3.8, this looks suspicious:

main/streams.c line 656-658:
/* just break anyway, to avoid greedy read */
if (stream->wrapper != &php_plain_files_wrapper)
	break;

This is not in the source 4.3.8 (which worked as expected). If I understand correctly is what prevents reading more than what may already be in the buffer plus the next buffered chunk (so summary is wrong, fread($f,1); fread($f,20000) the second will return 16383 bytes (if available)).

I guess the issue is why a greedy read should be bad here and not anywhere else.

It's not worth arguing about. I can read in smaller chunks and stick them together as I go, but maybe the second warning on the fread manual page should be expanded to include stream wrappers.
 [2004-12-01 08:45 UTC] derick@php.net
Wez, might we have your comments on this one too?
 [2004-12-01 17:45 UTC] wez@php.net
This is the intended behaviour.

You should *always* be prepared to call fread() multiple times until you have read all the data.  The only exception to this rule is when reading from a local file, for historical reasons.

The 8192 magic number is the chunk size used internally by PHP.

If you don't want to write a loop to read the data, use stream_get_contents().

 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 10:03:03 2014 UTC