diff --git a/std/io/bufio.ts b/std/io/bufio.ts index 954fc5eee1..df3ecb0029 100644 --- a/std/io/bufio.ts +++ b/std/io/bufio.ts @@ -706,5 +706,13 @@ export async function* readStringDelim( export async function* readLines( reader: Reader, ): AsyncIterableIterator { - yield* readStringDelim(reader, "\n"); + for await (let chunk of readStringDelim(reader, "\n")) { + // Finding a CR at the end of the line is evidence of a + // "\r\n" at the end of the line. The "\r" part should be + // removed too. + if (chunk.endsWith("\r")) { + chunk = chunk.slice(0, -1); + } + yield chunk; + } } diff --git a/std/io/bufio_test.ts b/std/io/bufio_test.ts index 03f699d507..804d59e99f 100644 --- a/std/io/bufio_test.ts +++ b/std/io/bufio_test.ts @@ -436,6 +436,10 @@ Deno.test("readStringDelimAndLines", async function (): Promise { assertEquals(chunks_, ["Hello World", "Hello World 2", "Hello World 3"]); const linesData = new Deno.Buffer(enc.encode("0\n1\n2\n3\n4\n5\n6\n7\n8\n9")); + // consider data with windows newlines too + const linesDataWindows = new Deno.Buffer( + enc.encode("0\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9"), + ); const lines_ = []; for await (const l of readLines(linesData)) { @@ -444,6 +448,14 @@ Deno.test("readStringDelimAndLines", async function (): Promise { assertEquals(lines_.length, 10); assertEquals(lines_, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]); + + // Now test for "windows" lines + lines_.length = 0; + for await (const l of readLines(linesDataWindows)) { + lines_.push(l); + } + assertEquals(lines_.length, 10); + assertEquals(lines_, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]); }); Deno.test(