I finally got to the bottom of this bug. It was hiding nice and deep.

I thought I'd run this by folks first before committing, as it impacts streams, 
which are pretty important :D . It passes the current tests, and I wrote test 
for it too. (below).

Index: main/streams/streams.c
===================================================================
--- main/streams/streams.c      (revision 287973)
+++ main/streams/streams.c      (working copy)
@@ -901,10 +901,7 @@
                }

                if (!e) {
-                       if (seek_len < maxlen && !stream->eof) {
-                               return NULL;
-                       }
-                       toread = maxlen;
+                       toread = (seek_len < maxlen) ? seek_len : maxlen;
                } else {
                        toread = e - (char *) stream->readbuf - stream->readpos;
                        skip = 1;


=======/ext/standard/tests/streams/bug49148.phpt:=======

--TEST--
Bug #49148 (combination of stream_get_line and fseek does not work correctly)
--FILE--
<?php
// should give back "line 1" and ""
$tmp = tmpfile();
fwrite($tmp, "line1\r\n");
fseek($tmp, 0);

var_dump(stream_get_line($tmp, null, "\r\n"));
var_dump(stream_get_line($tmp, null, "\r\n"));
fclose($tmp);

// should give back "line 1" and ""
$tmp = tmpfile();
fwrite($tmp, "line1\r\n");
fseek($tmp, 0);

var_dump(stream_get_line($tmp, null, "\r\n"));
fseek($tmp, ftell($tmp)); // expected that this does not affect result.
var_dump(stream_get_line($tmp, null, "\r\n"));
fclose($tmp);

// should give back "line 1" and "line 2"
$tmp = tmpfile();
fwrite($tmp, "line1\r\n");
fwrite($tmp, "line2");
fseek($tmp, 0);
var_dump(stream_get_line($tmp, null, "\r\n"));
var_dump(stream_get_line($tmp, null, "\r\n"));
fclose($tmp);

// should give back "line 1" and "line 2"
$tmp = tmpfile();
fwrite($tmp, "line1\r\n");
fwrite($tmp, "line2");
fseek($tmp, 0);
var_dump(stream_get_line($tmp, null, "\r\n"));
fseek($tmp, ftell($tmp)); // expected that this does not affect result.
var_dump(stream_get_line($tmp, null, "\r\n"));
fclose($tmp);

// should give back "line 1" and "line 2"
$tmp = tmpfile();
fwrite($tmp, "line1\r\n");
fwrite($tmp, "line2\r\n");
fseek($tmp, 0);
var_dump(stream_get_line($tmp, null, "\r\n"));
var_dump(stream_get_line($tmp, null, "\r\n"));
fclose($tmp);

// should give back "line 1" and "line 2"
$tmp = tmpfile();
fwrite($tmp, "line1\r\n");
fwrite($tmp, "line2\r\n");
fseek($tmp, 0);
var_dump(stream_get_line($tmp, null, "\r\n"));
fseek($tmp, ftell($tmp)); // expected that this does not affect result.
var_dump(stream_get_line($tmp, null, "\r\n"));
fclose($tmp);

?>
--EXPECT--
string(5) "line1"
string(0) ""
string(5) "line1"
string(0) ""
string(5) "line1"
string(5) "line2"
string(5) "line1"
string(5) "line2"
string(5) "line1"
string(5) "line2"
string(5) "line1"
string(5) "line2"

Garrett

Reply via email to