diff options
author | Gustavo Lopes <glopes@nebm.ist.utl.pt> | 2012-10-12 20:00:37 +0200 |
---|---|---|
committer | Gustavo Lopes <glopes@nebm.ist.utl.pt> | 2012-10-12 20:23:43 +0200 |
commit | 76601c4fd1052bd46e8db4addb1bb9dd3b001f98 (patch) | |
tree | 05b4c962aa6b5538a4c068b9f156efe2e9808b6c | |
parent | 5020b51d72d3e7ee38f366ef3685ce2c8e9b13c1 (diff) | |
download | php-git-76601c4fd1052bd46e8db4addb1bb9dd3b001f98.tar.gz |
Fix bug #63240 on stream_get_line()
stream_get_line() could contain the delimiter string if that string
had more than one character. The bug manifested itself when a read on
the stream ended with part of the delimiter string and the read after
would start with the rest of the delimiter string; provided that
the data of first read did not complete the max length result of the
call to stream_get_line() with the partial delimiter used in that max
length return. In that case, the delimiter will still appear in
the result, divided in two subsequent return values. That is not a bug.
See <http://www.mail-archive.com/internals@lists.php.net/msg61325.html>
-rw-r--r-- | ext/standard/tests/streams/bug63240.phpt | 17 | ||||
-rw-r--r-- | main/streams/streams.c | 12 |
2 files changed, 27 insertions, 2 deletions
diff --git a/ext/standard/tests/streams/bug63240.phpt b/ext/standard/tests/streams/bug63240.phpt new file mode 100644 index 0000000000..7612c43745 --- /dev/null +++ b/ext/standard/tests/streams/bug63240.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #63240: stream_get_line() return contains delimiter string +--FILE-- +<?php +$fd = fopen('php://temp', 'r+'); +$delimiter = 'MM'; +$str = str_repeat('.', 8191) . $delimiter . "rest"; +fwrite($fd, $str); +rewind($fd); +$line = stream_get_line($fd, 9000, $delimiter); +var_dump(strlen($line)); +$line = stream_get_line($fd, 9000, $delimiter); +var_dump($line); +?> +--EXPECT-- +int(8191) +string(4) "rest" diff --git a/main/streams/streams.c b/main/streams/streams.c index dfd60940fc..eec9b70349 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -989,9 +989,17 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re if (has_delim) { /* search for delimiter, but skip buffered_len (the number of bytes * buffered before this loop iteration), as they have already been - * searched for the delimiter */ + * searched for the delimiter. + * The left part of the delimiter may still remain in the buffer, + * so subtract up to <delim_len - 1> from buffered_len, which is + * the ammount of data we skip on this search as an optimization + */ found_delim = _php_stream_search_delim( - stream, maxlen, buffered_len, delim, delim_len TSRMLS_CC); + stream, maxlen, + buffered_len >= (delim_len - 1) + ? buffered_len - (delim_len - 1) + : 0, + delim, delim_len TSRMLS_CC); if (found_delim) { break; } |