当Buffer.from()
与字符串一起使用时,它会读取变量边界之外的内容,这是一个已知的错误吗?
我在我的后端有 * 非常奇怪 * 的行为,当我连接2个缓冲区时,它会读取变量的内容和它后面的东西,就像其他变量的内容一样。
打字脚本MWE是:
import fs = require("fs");
function concatTypedArrays(a: Uint8Array, b: Uint8Array): Uint8Array {
const c = new Uint8Array(a.length + b.length);
c.set(a, 0);
c.set(b, a.length);
return c;
}
function concatBuffers(
a: Uint8Array | Uint16Array | Uint32Array,
b: Uint8Array | Uint16Array | Uint32Array
): Uint8Array {
return concatTypedArrays(
new Uint8Array(a.buffer || a),
new Uint8Array(b.buffer || b)
);
}
const test_var = "this is a long string: 6caD764D996ceB0B6217a01C3ec29DDEc760286C97c28FCBFFdF0dc41CD2AE5A0BdcF36a7Cd29cfc99E118Ef0Be71b4Ba4c1dfdE5CeEAaafee3b93ea4eb20ED5ab99bd0aABd2BFd9bdAc1FdA962813D7CD558c9a0AAD4dD81988eaF6c1481bA8AAa731A87AF7DC0B90cB303CBB16122f8778a1c62F38f19Ff599c147c133fC9a9ba0e272de1bA9eD8b6DcC3bD84Ea8d8d0033CdE1d56aa8bcfb4d7dBFd3cF7e354642c026f6EbFb0f1D28Bb6778Ba4CCaaB15eD66fF6Bd428a3cf6C8dD1dBAb3bAbbA3FF7B1ce784473daD21eF45f7a08Eff4FF1Beae9ce4F69DdB1351Bb1d348A7b4aE2F21c9dF3DeAaA2bECF646e34Dbc7F18C3c28fcccAafbA5ACA9C3d8D240adB5C18Df99DcefbEdE1b27C7bd867364abB983eEa7cDC25B401df91ba8A8E776AD0f3a8Faa06bc1ECaF5B0dA0f633f9bf85B24A33c6cAFfF0eEc4BD68B99eBdc8Af258F90ebB049Eb8e9daD3AcbdA47a5Cd2BFFD4d3cbd26BA";
console.log(`test_var: ${test_var}`);
let blob = new Uint8Array(0);
const test_str = "a string";
blob = concatBuffers(blob, new Uint8Array([0x41, 0x20]));
blob = concatBuffers(blob, Buffer.from(test_str));
// blob = concatBuffers(blob, Buffer.alloc(test_str.length, test_str));
fs.writeFileSync("./test_f.bin", blob);
(完成项目here)
将Buffer.from
更改为Buffer.alloc
解决了这个问题。否则,输出文件将包含作用域中其他变量的内容。从我的Angular 来看(我通常做嵌入式和系统编程),我没有看到这种行为的明确原因。
预期的输出文件内容为:
A a string
但我得到了:
A <around 200 bytes from the program's context> a string<around 200 bytes from the program's context>
这是一个已知的bug,还是我的实现有问题?(或完全不同)
1条答案
按热度按时间kadbb4591#
问题就在这里:
当你像在
blob = concatBuffers(blob, Buffer.from(test_str));
调用中那样传递一个Buffer
时,你直接使用该缓冲区的buffer
属性(它的底层数组),而不考虑它的byteOffset
或length
。但是缓冲区的内容不能从基础数组的开头开始,也不能完全填满它。byteOffset
文档:在
Buffer.from(ArrayBuffer, byteOffset, length)
中设置byteOffset
时,或者**有时在分配小于Buffer.poolSize
**的Buffer
时,缓冲区不会从底层ArrayBuffer
上的零偏移开始。**当直接使用
buf.buffer
访问底层ArrayBuffer
时,这可能会导致问题,因为ArrayBuffer
的其他部分可能与Buffer
对象本身无关。例如,在我的系统中,底层数组是8192字节,缓冲区数据从偏移量16开始。尽管
test_str
只有8个字符长。因此,您使用的是缓冲区底层数组中的垃圾数据。相反,您只需要使用
Buffer
实际使用的Buffer
底层数组的一部分,这是通过尊重byteOffset
和length
来实现的。