fix(std/node): Buffer.copy doesn't work as expected (#8125)

This commit is contained in:
Steven Guerrero 2020-10-26 09:42:36 -05:00 committed by GitHub
parent 6a8d0d81c1
commit d52fb903cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 104 additions and 20 deletions

View file

@ -163,10 +163,16 @@ export default class Buffer extends Uint8Array {
}
}
const buffer = new Buffer(totalLength);
const buffer = Buffer.allocUnsafe(totalLength);
let pos = 0;
for (const buf of list) {
buffer.set(buf, pos);
for (const item of list) {
let buf: Buffer;
if (!(item instanceof Buffer)) {
buf = Buffer.from(item);
} else {
buf = item;
}
buf.copy(buffer, pos);
pos += buf.length;
}
@ -247,7 +253,12 @@ export default class Buffer extends Uint8Array {
sourceStart = 0,
sourceEnd = this.length,
): number {
const sourceBuffer = this.subarray(sourceStart, sourceEnd);
const sourceBuffer = this
.subarray(sourceStart, sourceEnd)
.subarray(0, Math.max(0, targetBuffer.length - targetStart));
if (sourceBuffer.length === 0) return 0;
targetBuffer.set(sourceBuffer, targetStart);
return sourceBuffer.length;
}

View file

@ -260,10 +260,15 @@ Deno.test({
Deno.test({
name: "Two Buffers are concatenated",
fn() {
const buffer1 = Buffer.alloc(1);
const buffer2 = Buffer.alloc(2);
const data1 = [1, 2, 3];
const data2 = [4, 5, 6];
const buffer1 = Buffer.from(data1);
const buffer2 = Buffer.from(data2);
const resultBuffer = Buffer.concat([buffer1, buffer2]);
assertEquals(resultBuffer.length, 3, "Buffer length should be 3");
const expectedBuffer = Buffer.from([...data1, ...data2]);
assertEquals(resultBuffer, expectedBuffer);
},
});
@ -285,27 +290,95 @@ Deno.test({
});
Deno.test({
name: "concat respects totalLenght parameter",
name: "Buffer concat respects totalLenght parameter",
fn() {
const maxLength1 = 10;
const buffer1 = Buffer.alloc(2);
const buffer2 = Buffer.alloc(2);
const resultBuffer = Buffer.concat([buffer1, buffer2], 10);
assertEquals(resultBuffer.length, 10, "Buffer length should be 10");
assertEquals(
Buffer.concat([buffer1, buffer2], maxLength1).length,
maxLength1,
);
const maxLength2 = 3;
const buffer3 = Buffer.alloc(2);
const buffer4 = Buffer.alloc(2);
assertEquals(
Buffer.concat([buffer3, buffer4], maxLength2).length,
maxLength2,
);
},
});
Deno.test({
name: "concat totalLenght throws if is lower than the size of the buffers",
name: "Buffer copy works as expected",
fn() {
const buffer1 = Buffer.alloc(2);
const buffer2 = Buffer.alloc(2);
assertThrows(
() => {
Buffer.concat([buffer1, buffer2], 3);
},
RangeError,
"offset is out of bounds",
"should throw on negative numbers",
const data1 = new Uint8Array([1, 2, 3]);
const data2 = new Uint8Array([4, 5, 6]);
const buffer1 = Buffer.from(data1);
const buffer2 = Buffer.from(data2);
//Mutates data_1
data1.set(data2);
//Mutates buffer_1
buffer2.copy(buffer1);
assertEquals(
data1,
buffer1,
);
},
});
Deno.test({
name: "Buffer copy respects the starting point for copy",
fn() {
const buffer1 = Buffer.from([1, 2, 3]);
const buffer2 = Buffer.alloc(8);
buffer1.copy(buffer2, 5);
const expected = Buffer.from([0, 0, 0, 0, 0, 1, 2, 3]);
assertEquals(
buffer2,
expected,
);
},
});
Deno.test({
name: "Buffer copy doesn't throw on offset but copies until offset reached",
fn() {
const buffer1 = Buffer.from([1, 2, 3]);
const buffer2 = Buffer.alloc(8);
const writtenBytes1 = buffer1.copy(buffer2, 6);
assertEquals(
writtenBytes1,
2,
);
assertEquals(
buffer2,
Buffer.from([0, 0, 0, 0, 0, 0, 1, 2]),
);
const buffer3 = Buffer.from([1, 2, 3]);
const buffer4 = Buffer.alloc(8);
const writtenBytes2 = buffer3.copy(buffer4, 8);
assertEquals(
writtenBytes2,
0,
);
assertEquals(
buffer4,
Buffer.from([0, 0, 0, 0, 0, 0, 0, 0]),
);
},
});