summaryrefslogtreecommitdiff
path: root/std/io
diff options
context:
space:
mode:
Diffstat (limited to 'std/io')
-rw-r--r--std/io/bufio.ts6
-rw-r--r--std/io/bufio_test.ts20
2 files changed, 25 insertions, 1 deletions
diff --git a/std/io/bufio.ts b/std/io/bufio.ts
index aa74809fe..5c005672a 100644
--- a/std/io/bufio.ts
+++ b/std/io/bufio.ts
@@ -338,7 +338,11 @@ export class BufReader implements Reader {
// Buffer full?
if (this.buffered() >= this.buf.byteLength) {
this.r = this.w;
- throw new BufferFullError(this.buf);
+ // #4521 The internal buffer should not be reused across reads because it causes corruption of data.
+ const oldbuf = this.buf;
+ const newbuf = this.buf.slice(0);
+ this.buf = newbuf;
+ throw new BufferFullError(oldbuf);
}
s = this.w - this.r; // do not rescan area we scanned before
diff --git a/std/io/bufio_test.ts b/std/io/bufio_test.ts
index c49023814..d3e39bff6 100644
--- a/std/io/bufio_test.ts
+++ b/std/io/bufio_test.ts
@@ -12,6 +12,7 @@ import {
BufWriterSync,
BufferFullError,
PartialReadError,
+ ReadLineResult,
readStringDelim,
readLines,
} from "./bufio.ts";
@@ -445,3 +446,22 @@ Deno.test("readStringDelimAndLines", async function (): Promise<void> {
assertEquals(lines_.length, 10);
assertEquals(lines_, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
});
+
+Deno.test(async function bufReaderShouldNotShareArrayBufferAcrossReads() {
+ const decoder = new TextDecoder();
+ const data = "abcdefghijklmnopqrstuvwxyz";
+ const bufSize = 25;
+ const b = new BufReader(stringsReader(data), bufSize);
+
+ const r1 = (await b.readLine()) as ReadLineResult;
+ assertNotEOF(r1);
+ assertEquals(decoder.decode(r1.line), "abcdefghijklmnopqrstuvwxy");
+
+ const r2 = (await b.readLine()) as ReadLineResult;
+ assertNotEOF(r2);
+ assertEquals(decoder.decode(r2.line), "z");
+ assert(
+ r1.line.buffer !== r2.line.buffer,
+ "array buffer should not be shared across reads"
+ );
+});