diff --git a/core/shared/src/main/scala/fs2/text.scala b/core/shared/src/main/scala/fs2/text.scala index 93166de104..210ffde2ef 100644 --- a/core/shared/src/main/scala/fs2/text.scala +++ b/core/shared/src/main/scala/fs2/text.scala @@ -553,11 +553,25 @@ object text { } maxLineLength match { - case Some((max, raiseThrowable)) if stringBuilder.length > max => - Pull.raiseError[F]( - new LineTooLongException(stringBuilder.length, max) - )(using raiseThrowable) - case _ => + case Some((max, raiseThrowable)) => + val tooLongLength = + (linesBuffer.iterator.map(_.length) ++ Iterator(stringBuilder.length)) + .filter(_ > max) + .reduceOption(_ max _) + tooLongLength match { + case Some(length) => + Pull.raiseError[F]( + new LineTooLongException(length, max) + )(using raiseThrowable) + case None => + Pull.output(Chunk.from(linesBuffer)) >> go( + stream, + stringBuilder, + ignoreFirstCharNewLine, + first = false + ) + } + case None => Pull.output(Chunk.from(linesBuffer)) >> go( stream, stringBuilder, diff --git a/core/shared/src/test/scala/fs2/TextSuite.scala b/core/shared/src/test/scala/fs2/TextSuite.scala index 42248c62c1..90c0ca5288 100644 --- a/core/shared/src/test/scala/fs2/TextSuite.scala +++ b/core/shared/src/test/scala/fs2/TextSuite.scala @@ -324,6 +324,15 @@ class TextSuite extends Fs2Suite { ) } } + + test("linesLimited rejects long lines completed in a single chunk") { + val longLine = "x" * 1000 + "\n" + val singleChunk = Stream.emit(longLine).covary[Fallible] + assert(singleChunk.through(text.linesLimited(10)).toList.isLeft) + + val multiChunk = Stream.emits(longLine.toList.map(_.toString)).covary[Fallible] + assert(multiChunk.through(text.linesLimited(10)).toList.isLeft) + } } group("string2char / char2string") {