summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/tests/streams/bug63240.phpt17
-rw-r--r--main/streams/streams.c12
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 81bf59446f..40b18e9f5b 100644
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -1055,9 +1055,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;
}