Skip to content
Prev Previous commit
Next Next commit
[squash] buffer: add more options (all enabled by default)
  • Loading branch information
ChALkeR committed Aug 21, 2019
commit 028b6ed5d32874c5d2815dd612b5cd6bec04b139
50 changes: 32 additions & 18 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,15 @@ const zeroFill = bindingZeroFill || [0];
// Hardening Buffer enables Buffer constructor runtime deprecation,
// disables pooling, and enables mandratory zero-fill. This is more secure, but
// has potential performance impact, depending on the usecase.
const harden = {
NONE: 0, // falsy
STRICT: 1,
LAX: 2,
const hardened = {
applied: false,
zeroFill: false,
disablePool: false,
throwOnUnsafe: false,
};
let hardened = harden.NONE;

function createUnsafeBuffer(size) {
zeroFill[0] = hardened ? 1 : 0;
zeroFill[0] = hardened.zeroFill ? 1 : 0;
try {
return new FastBuffer(size);
} finally {
Expand Down Expand Up @@ -151,8 +151,8 @@ const bufferWarning = 'Buffer() is deprecated due to security and usability ' +
'Buffer.allocUnsafe(), or Buffer.from() methods instead.';

function showFlaggedDeprecation() {
if (hardened) {
if (hardened !== harden.LAX) {
if (hardened.applied) {
if (hardened.throwOnUnsafe) {
throw new ERR_ASSERTION(
'Unsafe Buffer() API is forbidden by Buffer strict hardening opt-in.'
);
Expand Down Expand Up @@ -181,8 +181,13 @@ function showFlaggedDeprecation() {
}

// Calling this method does not affect existing buffers, only new ones.
Buffer.harden = function({ strict = true } = {}) {
if (hardened) {
Buffer.harden = function({
zeroFill = true,
disablePool = true,
throwOnUnsafe = true,
freeze = true,
} = {}) {
if (hardened.applied) {
// So that params are not changed afterwards
throw new ERR_ASSERTION(
'Buffer.harden can be called only once'
Expand All @@ -194,14 +199,23 @@ Buffer.harden = function({ strict = true } = {}) {
'Calling Buffer.harden() from dependencies is not supported.'
);
}
hardened = strict ? harden.STRICT : harden.LAX;
Object.defineProperty(Buffer, 'poolSize', {
enumerable: true,
get: () => 0,
set: () => {},
Object.assign(hardened, {
applied: true,
zeroFill: Boolean(zeroFill),
disablePool: Boolean(disablePool),
throwOnUnsafe: Boolean(throwOnUnsafe),
});
Object.freeze(Buffer);
Object.freeze(module.exports);
if (disablePool) {
Object.defineProperty(Buffer, 'poolSize', {
enumerable: true,
get: () => 0,
set: () => {},
});
}
if (freeze) {
Object.freeze(Buffer);
Object.freeze(module.exports);
}
};

function toInteger(n, defaultVal) {
Expand Down Expand Up @@ -412,7 +426,7 @@ function allocate(size) {
if (size <= 0) {
return new FastBuffer();
}
if (size < (Buffer.poolSize >>> 1) && !hardened) {
if (size < (Buffer.poolSize >>> 1) && !hardened.disablePool) {
if (size > (poolSize - poolOffset))
createPool();
const b = new FastBuffer(allocPool, poolOffset, size);
Expand Down