diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | ext/standard/tests/streams/bug60455_01.phpt | 21 | ||||
-rw-r--r-- | ext/standard/tests/streams/bug60455_02.phpt | 30 | ||||
-rw-r--r-- | ext/standard/tests/streams/bug60455_03.phpt | 53 | ||||
-rwxr-xr-x | main/streams/streams.c | 5 |
5 files changed, 110 insertions, 3 deletions
@@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2011, PHP 5.3.9 +- Streams: + . Fixed bug #60455 (stream_get_line misbehaves if EOF is not detected together + with the last read). (Gustavo) + 08 Dec 2011, PHP 5.3.9RC3 - Filter: diff --git a/ext/standard/tests/streams/bug60455_01.phpt b/ext/standard/tests/streams/bug60455_01.phpt new file mode 100644 index 0000000000..466998201a --- /dev/null +++ b/ext/standard/tests/streams/bug60455_01.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #60455: stream_get_line and 1-line noeol input +--FILE-- +<?php + +//It's critical the read on the stream returns the input but doesn't set EOF +//flag the first time. This is why we need to use sockets. + +$domain = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? STREAM_PF_INET : STREAM_PF_UNIX); +$sockets = stream_socket_pair($domain, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP) + or die("stream_socket_pair"); +fwrite($sockets[0], "a"); +stream_socket_shutdown($sockets[0], STREAM_SHUT_RDWR); + +$f = $sockets[1]; +while (!feof($f)) { + $line = stream_get_line($f, 99, "\n"); + var_dump($line); +} +--EXPECT-- +string(1) "a" diff --git a/ext/standard/tests/streams/bug60455_02.phpt b/ext/standard/tests/streams/bug60455_02.phpt new file mode 100644 index 0000000000..6e06e9fa3f --- /dev/null +++ b/ext/standard/tests/streams/bug60455_02.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #60455: stream_get_line and 1-line followed by eol input +--FILE-- +<?php +class TestStream { + private $s = 0; + function stream_open($path, $mode, $options, &$opened_path) { + return true; + } + function stream_read($count) { + if ($this->s++ == 0) + return "a\n"; + + return ""; + } + function stream_eof() { + return $this->s >= 2; + } + +} + +stream_wrapper_register("test", "TestStream"); + +$f = fopen("test://", "r"); +while (!feof($f)) { + $line = stream_get_line($f, 99, "\n"); + var_dump($line); +} +--EXPECT-- +string(1) "a" diff --git a/ext/standard/tests/streams/bug60455_03.phpt b/ext/standard/tests/streams/bug60455_03.phpt new file mode 100644 index 0000000000..5d7ba1f248 --- /dev/null +++ b/ext/standard/tests/streams/bug60455_03.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #60455: stream_get_line and 2 lines, one possibly empty +--FILE-- +<?php +class TestStream { + private $lines = array(); + private $s = 0; + private $eofth = 3; + function stream_open($path, $mode, $options, &$opened_path) { + $this->lines[] = "a\n"; + $this->lines[] = ($path == "test://nonempty2nd" ? "b\n" : "\n"); + if ($path == "test://eofafter2nd") + $this->eofth = 2; + return true; + } + function stream_read($count) { + if (key_exists($this->s++, $this->lines)) + return $this->lines[$this->s - 1]; + + return ""; + } + function stream_eof() { + return $this->s >= $this->eofth; + } + +} + +stream_wrapper_register("test", "TestStream"); + +$f = fopen("test://nonempty2nd", "r"); +while (!feof($f)) { + $line = stream_get_line($f, 99, "\n"); + var_dump($line); +} +$f = fopen("test://", "r"); +while (!feof($f)) { + $line = stream_get_line($f, 99, "\n"); + var_dump($line); +} +$f = fopen("test://eofafter2nd", "r"); +while (!feof($f)) { + $line = stream_get_line($f, 99, "\n"); + var_dump($line); +} + + +--EXPECT-- +string(1) "a" +string(1) "b" +string(1) "a" +string(0) "" +string(1) "a" +string(0) "" diff --git a/main/streams/streams.c b/main/streams/streams.c index 81adff8137..294b3e41a6 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -918,9 +918,8 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re just_read = (stream->writepos - stream->readpos) - len; len += just_read; - /* read operation have less data than request; assume the stream is - * temporarily or permanently out of data */ - if (just_read < toread) { + /* Assume the stream is temporarily or permanently out of data */ + if (just_read == 0) { break; } } |