Buffer.from(), Buffer.alloc(), and Buffer.allocUnsafe()
由于历史原因,Buffer 实例通过 Buffer 构造函数创建,它基于提供的不同参数分配返回不同的 Buffer :
给
Buffer()的第一个参数传参(如,new Buffer(10)),通过指定的大小分配一个新的 Buffer 。给这样的 Buffer 分配的内存是没有初始化过的,并会包含敏感数据。这样的Buffer对象必须手动通过 buf.fill(0) 初始化或写满这个Buffer。虽然这种行为是为了提高性能而故意为之的,开发经验已经证明对于是创造一个更慢但很安全的Buffer还是创建一个快速但未初始化的Buffer之间需要更加明确的区分。通过给第一个参数传字符串、数组或 Buffer ,可以将所传对象的数据拷贝当前 Buffer 中。
传一个
ArrayBuffer返回一个与给定的ArrayBuffer共享分配的内存的Buffer。
因为 new Buffer() 行为会根据第一个参数所传值的类型不同而显著改变,所以应用程序如果没有适当地验证给 new Buffer() 传的输入参数,或未能适当地初始化新分配的 Buffer 的内容,会给他们的代码带来安全性和可靠性方面的问题。
为了使创建的 Buffer 对象更可靠,更不容易出错,新的 Buffer.from()、 Buffer.alloc() 和 Buffer.allocUnsafe() 方法作为创建 Buffer 实例的替代手段而相继出台。
开发者应当把所有正在使用的 new Buffer() 构造函数迁移到这些新的API之一:
Buffer.from(array) 返回一个包含所提供的 8位字节的副本的新
Buffer。Buffer.from(arrayBuffer[, byteOffset[, length]]) 返回一个与给定的
ArrayBuffer共享分配的内存的Buffer。Buffer.from(buffer) 返回一个包含所提供的
Buffer的副本的新Buffer。Buffer.from(str[, encoding]) 返回一个包含所提供的字符串的副本的新
Buffer。Buffer.alloc(size[, fill[, encoding]]) 返回一个指定大小的被填满的
Buffer实例。这种方法会比 Buffer.allocUnsafe(size) 显著地慢,但可确保新创建的Buffer绝不会包含旧的和潜在的敏感数据。Buffer.allocUnsafe(size) 返回一个指定
size的Buffer,但它的内容必须被 buf.fill(0) 初始化或完全写满。
被 Buffer.allocUnsafe(size) 返回的 Buffer 实例,如果它的 size 小于或等于 Buffer.poolSize 的一半,可能被分配进一个共享的内部内存池。
是什么使得 Buffer.allocUnsafe(size) “不安全”?
当调用 Buffer.allocUnsafe() 时,被分配的内存段是没被初始化(它不是被零填充的)过的。虽然这样的设计使得内存的分配相当快,但已分配的存储段可能包含潜在的敏感的旧数据。使用通过 Buffer.allocUnsafe(size) 创建没有被完全覆写内存的 Buffer ,在 Buffer 内存是可读的情况下,可能泄露它的旧数据。
虽然在使用 Buffer.allocUnsafe() 时有明显的性能优势,但必须额外小心,以避免给应用程序引入安全漏洞。