Skip to content

Commit 76601c4

Browse files
committed
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/[email protected]/msg61325.html>
1 parent 5020b51 commit 76601c4

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Bug #63240: stream_get_line() return contains delimiter string
3+
--FILE--
4+
<?php
5+
$fd = fopen('php://temp', 'r+');
6+
$delimiter = 'MM';
7+
$str = str_repeat('.', 8191) . $delimiter . "rest";
8+
fwrite($fd, $str);
9+
rewind($fd);
10+
$line = stream_get_line($fd, 9000, $delimiter);
11+
var_dump(strlen($line));
12+
$line = stream_get_line($fd, 9000, $delimiter);
13+
var_dump($line);
14+
?>
15+
--EXPECT--
16+
int(8191)
17+
string(4) "rest"

main/streams/streams.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -989,9 +989,17 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re
989989
if (has_delim) {
990990
/* search for delimiter, but skip buffered_len (the number of bytes
991991
* buffered before this loop iteration), as they have already been
992-
* searched for the delimiter */
992+
* searched for the delimiter.
993+
* The left part of the delimiter may still remain in the buffer,
994+
* so subtract up to <delim_len - 1> from buffered_len, which is
995+
* the ammount of data we skip on this search as an optimization
996+
*/
993997
found_delim = _php_stream_search_delim(
994-
stream, maxlen, buffered_len, delim, delim_len TSRMLS_CC);
998+
stream, maxlen,
999+
buffered_len >= (delim_len - 1)
1000+
? buffered_len - (delim_len - 1)
1001+
: 0,
1002+
delim, delim_len TSRMLS_CC);
9951003
if (found_delim) {
9961004
break;
9971005
}

0 commit comments

Comments
 (0)