Fix for 49148 (combination of stream_get_line and fseek does not work correctly)
| From: | Garrett Serack | Date: | Wed, 02 Sep 2009 21:02:23 +0000 |
| Subject: | Fix for 49148 (combination of stream_get_line and fseek does not work correctly) | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-45450@lists.php.net to get a copy of this message | ||
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