From 76601c4fd1052bd46e8db4addb1bb9dd3b001f98 Mon Sep 17 00:00:00 2001 From: Gustavo Lopes Date: Fri, 12 Oct 2012 20:00:37 +0200 Subject: [PATCH] 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 --- ext/standard/tests/streams/bug63240.phpt | 17 +++++++++++++++++ main/streams/streams.c | 12 ++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 ext/standard/tests/streams/bug63240.phpt diff --git a/ext/standard/tests/streams/bug63240.phpt b/ext/standard/tests/streams/bug63240.phpt new file mode 100644 index 00000000000..7612c437454 --- /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 dfd60940fca..eec9b703499 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; }