]> granicus.if.org Git - php/commitdiff
- Fixed bug #60455: stream_get_line misbehaves if EOF is not detected together
authorGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 11 Dec 2011 21:08:15 +0000 (21:08 +0000)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 11 Dec 2011 21:08:15 +0000 (21:08 +0000)
  with the last read.

ext/standard/tests/streams/bug60455_01.phpt [new file with mode: 0644]
ext/standard/tests/streams/bug60455_02.phpt [new file with mode: 0644]
ext/standard/tests/streams/bug60455_03.phpt [new file with mode: 0644]
main/streams/streams.c

diff --git a/ext/standard/tests/streams/bug60455_01.phpt b/ext/standard/tests/streams/bug60455_01.phpt
new file mode 100644 (file)
index 0000000..4669982
--- /dev/null
@@ -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 (file)
index 0000000..6e06e9f
--- /dev/null
@@ -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 (file)
index 0000000..5d7ba1f
--- /dev/null
@@ -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) ""
index 4679a97aa691cfa4917ebad2e1d65077a056edeb..d396de30d286f078626c06024e37a0230668eddd 100755 (executable)
@@ -989,9 +989,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;
                }
        }