stream_get_contents offset max is 1165

Bug #53006 stream_get_contents offset max is 1165
Submitted: 2010-10-07 01:09 UTC Modified: 2010-10-16 01:50 UTC
From: poulpillusion at free dot fr Assigned: cataphract (profile)
Status: Closed Package: Streams related
PHP Version: 5.3.3 OS: Linux Aptosid
Private report: No CVE-ID: None

 [2010-10-07 01:09 UTC] poulpillusion at free dot fr

Description:
------------
In the stream_get_contents function, the offset parameter's max value is 1165. Any upper value will block the script.

Test script:
---------------
// This will work...
$handle = fopen($url, 'rb');
echo stream_get_contents($handle, 8192, 1165);

// This will not work... the script will wait forever.
$handle = fopen($url, 'rb');
echo stream_get_contents($handle, 8192, 1166);


Expected result:
----------------
I expect this function not to wait if $offset + 8192 < $filesize


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports

 [2010-10-07 14:05 UTC] cataphract@php.net

You need to give more details:

* The actual url you're using.
* If it's a remote file, a wireshark dump of the conversation would also be useful (please trim it to only the relevant parts!).

 [2010-10-08 00:31 UTC] poulpillusion at free dot fr

-Status: Feedback +Status: Open

 [2010-10-08 00:31 UTC] poulpillusion at free dot fr

Here is a sample code you can paste into a PHP file :

<?php
// this does not work : 1166 seems to big... try with 1165 and it will work !
$url = 'http://www.nocturne-jdr.fr/toto.txt';
$handle = fopen($url, 'rb');
echo stream_get_contents($handle, 8, 1166);
?>

I dumped the conversation with wireshark but I don't know which parts are the "relevant" ones... Here it is : http://www.nocturne-jdr.fr/capture.log

 [2010-10-08 02:29 UTC] cataphract@php.net

Your script works here. Outputs:

«9
320
32»

As to the wireshark log, what I need is not the data of the conversation, it's the packets that came and their size. Only that can shed light on this problem.

 [2010-10-09 01:33 UTC] poulpillusion at free dot fr

-Status: Feedback +Status: Open

 [2010-10-09 01:33 UTC] poulpillusion at free dot fr

Well in fact I realized something strange... 

It sometimes works here. But most of the time it does not. I hit Ctrl+F5 to refresh and in about 10% cases I get the data... but in 90% cases it simply outputs nothing.

It seems to depend on the file I am trying to get : 
- the limit is 1165 for http://www.nocturne-jdr.fr/toto.txt
- the limit is 1189 for http://peach.themazzone.com/durian/movies/sintel-1024-surround.mp4

Maybe these limits are not the ones you experience... maybe you should try raising them ?

Concerning wireshark, it's not a tool I am really used to... Did my dump help you anyway ? You can open it with wireshark to examine it... But if it does not help, maybe you coult send me a link to some tutorial/documentation ?

Thank you.

 [2010-10-11 17:15 UTC] cataphract@php.net

Ah, I didn't realize it was a full wireshark log. Thanks, I'll look into it.

 [2010-10-11 18:44 UTC] cataphract@php.net

There's definitely a bug here.

However:

* I couldn't reproduce any long blocking. The erroneous behavior was simply the (timely) return of an empty string from stream_get_contents.
* In the network traffic dump, I couldn't find a FIN packet. PHP sent a RST right away.

I tried with Debian Lenny, PHP 5.3.3 (CLI).

 [2010-10-13 23:59 UTC] poulpillusion at free dot fr

Ok so... is there anything else I can do to help you fix this bug ? I mean : more testing, more feedback ?

 [2010-10-14 04:03 UTC] cataphract@php.net

Automatic comment from SVN on behalf of cataphract
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=304380
Log: - [DOC] Changed stream_get_contents() so that the offset is relative to the
  current position (seek with SEEK_CUR, not SEEK_SET). Only positive values are
  allowed. This breaking change is necessary to fix the erratic behavior in
  streams without a seek handlder. Addresses bug #53006.
#Note that the example on the doc page for stream_get_contents() may fail
#without this change.
#This change is also in the spirit of stream_get_contents(), whose description
#is &quot;Reads all remaining bytes (or up to maxlen bytes) from a stream...&quot;.
#Previous behavior allowed setting the file pointer to positions before the
#current one, so they wouldn't be &quot;remaining bytes&quot;. The previous behavior was
#also inconsistent in that it allowed an moving to offset 1, 2, ..., but not 0.

 [2010-10-14 05:15 UTC] cataphract@php.net

Automatic comment from SVN on behalf of cataphract
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=304384
Log: - [DOC] Reverted rev #304382 and rev #304380, as I figured out a way to
  fix the erratic behavior without breaking backwards compatibility. Namely,
  $offset retains SEEK_SET behavior but actually SEEK_CUR is passed to
  _php_stream_seek, if possible, by moving the offset stream-&gt;position bytes.
- Addresses bug #53006.

 [2010-10-15 01:11 UTC] poulpillusion at free dot fr

-Status: Feedback +Status: Assigned