From: Gustavo Lopes Date: Fri, 12 Oct 2012 18:00:37 +0000 (+0200) Subject: Fix bug #63240 on stream_get_line() X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76601c4fd1052bd46e8db4addb1bb9dd3b001f98;p=php 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 --- 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-- + +--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 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; }