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