lib,tools: enforce access to prototype from primordials

PR-URL: https://github.com/nodejs/node/pull/36025
Reviewed-By: Shingo Inoue <leko.noor@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
Antoine du Hamel
2020-11-07 17:23:14 +01:00
committed by Rich Trott
parent 382ed92fa8
commit 5c3944fa20
4 changed files with 98 additions and 52 deletions

View File

@@ -25,25 +25,42 @@
const {
Array,
ArrayBuffer,
ArrayBufferPrototype,
ArrayPrototype,
ArrayPrototypeForEach,
ArrayPrototypePush,
BigInt,
BigInt64Array,
BigInt64ArrayPrototype,
BigIntPrototype,
BigUint64Array,
BigUint64ArrayPrototype,
Boolean,
BooleanPrototype,
DataView,
DataViewPrototype,
Date,
DatePrototype,
Error,
ErrorPrototype,
EvalError,
EvalErrorPrototype,
Float32Array,
Float32ArrayPrototype,
Float64Array,
Float64ArrayPrototype,
Function,
FunctionPrototype,
Int16Array,
Int16ArrayPrototype,
Int32Array,
Int32ArrayPrototype,
Int8Array,
JSON,
Int8ArrayPrototype,
Map,
Math,
MapPrototype,
Number,
NumberPrototype,
Object,
ObjectDefineProperty,
ObjectFreeze,
@@ -52,28 +69,44 @@ const {
ObjectGetOwnPropertyNames,
ObjectGetOwnPropertySymbols,
ObjectGetPrototypeOf,
ObjectPrototype,
ObjectPrototypeHasOwnProperty,
Promise,
PromisePrototype,
RangeError,
RangeErrorPrototype,
ReferenceError,
Reflect,
ReferenceErrorPrototype,
ReflectOwnKeys,
RegExp,
RegExpPrototype,
SafeSet,
Set,
SetPrototype,
String,
StringPrototype,
Symbol,
SymbolIterator,
SyntaxError,
SyntaxErrorPrototype,
TypeError,
TypeErrorPrototype,
TypedArray,
TypedArrayPrototype,
Uint16Array,
Uint16ArrayPrototype,
Uint32Array,
Uint32ArrayPrototype,
Uint8Array,
Uint8ArrayPrototype,
Uint8ClampedArray,
Uint8ClampedArrayPrototype,
URIError,
URIErrorPrototype,
WeakMap,
WeakMapPrototype,
WeakSet,
WeakSetPrototype,
} = primordials;
module.exports = function() {
@@ -110,55 +143,55 @@ module.exports = function() {
TypedArrayPrototype,
// 19 Fundamental Objects
Object.prototype, // 19.1
Function.prototype, // 19.2
Boolean.prototype, // 19.3
ObjectPrototype, // 19.1
FunctionPrototype, // 19.2
BooleanPrototype, // 19.3
Error.prototype, // 19.5
EvalError.prototype,
RangeError.prototype,
ReferenceError.prototype,
SyntaxError.prototype,
TypeError.prototype,
URIError.prototype,
ErrorPrototype, // 19.5
EvalErrorPrototype,
RangeErrorPrototype,
ReferenceErrorPrototype,
SyntaxErrorPrototype,
TypeErrorPrototype,
URIErrorPrototype,
// 20 Numbers and Dates
Number.prototype, // 20.1
Date.prototype, // 20.3
NumberPrototype, // 20.1
DatePrototype, // 20.3
// 21 Text Processing
String.prototype, // 21.1
RegExp.prototype, // 21.2
StringPrototype, // 21.1
RegExpPrototype, // 21.2
// 22 Indexed Collections
Array.prototype, // 22.1
ArrayPrototype, // 22.1
Int8Array.prototype,
Uint8Array.prototype,
Uint8ClampedArray.prototype,
Int16Array.prototype,
Uint16Array.prototype,
Int32Array.prototype,
Uint32Array.prototype,
Float32Array.prototype,
Float64Array.prototype,
BigInt64Array.prototype,
BigUint64Array.prototype,
Int8ArrayPrototype,
Uint8ArrayPrototype,
Uint8ClampedArrayPrototype,
Int16ArrayPrototype,
Uint16ArrayPrototype,
Int32ArrayPrototype,
Uint32ArrayPrototype,
Float32ArrayPrototype,
Float64ArrayPrototype,
BigInt64ArrayPrototype,
BigUint64ArrayPrototype,
// 23 Keyed Collections
Map.prototype, // 23.1
Set.prototype, // 23.2
WeakMap.prototype, // 23.3
WeakSet.prototype, // 23.4
MapPrototype, // 23.1
SetPrototype, // 23.2
WeakMapPrototype, // 23.3
WeakSetPrototype, // 23.4
// 24 Structured Data
ArrayBuffer.prototype, // 24.1
DataView.prototype, // 24.3
Promise.prototype, // 25.4
ArrayBufferPrototype, // 24.1
DataViewPrototype, // 24.3
PromisePrototype, // 25.4
// Other APIs / Web Compatibility
console.Console.prototype,
BigInt.prototype,
BigIntPrototype,
WebAssembly.Module.prototype,
WebAssembly.Instance.prototype,
WebAssembly.Table.prototype,
@@ -171,7 +204,7 @@ module.exports = function() {
const intrinsics = [
// Anonymous Intrinsics
// ThrowTypeError
ObjectGetOwnPropertyDescriptor(Function.prototype, 'caller').get,
ObjectGetOwnPropertyDescriptor(FunctionPrototype, 'caller').get,
// IteratorPrototype
ObjectGetPrototypeOf(
ObjectGetPrototypeOf(new Array()[SymbolIterator]())
@@ -224,6 +257,7 @@ module.exports = function() {
// 20 Numbers and Dates
Number, // 20.1
// eslint-disable-next-line node-core/prefer-primordials
Math, // 20.2
Date, // 20.3
@@ -255,10 +289,12 @@ module.exports = function() {
// 24 Structured Data
ArrayBuffer, // 24.1
DataView, // 24.3
// eslint-disable-next-line node-core/prefer-primordials
JSON, // 24.5
Promise, // 25.4
// 26 Reflection
// eslint-disable-next-line node-core/prefer-primordials
Reflect, // 26.1
Proxy, // 26.2
@@ -281,19 +317,21 @@ module.exports = function() {
];
if (typeof Intl !== 'undefined') {
intrinsicPrototypes.push(Intl.Collator.prototype);
intrinsicPrototypes.push(Intl.DateTimeFormat.prototype);
intrinsicPrototypes.push(Intl.ListFormat.prototype);
intrinsicPrototypes.push(Intl.NumberFormat.prototype);
intrinsicPrototypes.push(Intl.PluralRules.prototype);
intrinsicPrototypes.push(Intl.RelativeTimeFormat.prototype);
intrinsics.push(Intl);
ArrayPrototypePush(intrinsicPrototypes,
Intl.Collator.prototype,
Intl.DateTimeFormat.prototype,
Intl.ListFormat.prototype,
Intl.NumberFormat.prototype,
Intl.PluralRules.prototype,
Intl.RelativeTimeFormat.prototype,
);
ArrayPrototypePush(intrinsics, Intl);
}
intrinsicPrototypes.forEach(enableDerivedOverrides);
ArrayPrototypeForEach(intrinsicPrototypes, enableDerivedOverrides);
const frozenSet = new WeakSet();
intrinsics.forEach(deepFreeze);
ArrayPrototypeForEach(intrinsics, deepFreeze);
// Objects that are deeply frozen.
function deepFreeze(root) {
@@ -306,7 +344,7 @@ module.exports = function() {
*/
function innerDeepFreeze(node) {
// Objects that we have frozen in this round.
const freezingSet = new Set();
const freezingSet = new SafeSet();
// If val is something we should be freezing but aren't yet,
// add it to freezingSet.

View File

@@ -3,6 +3,7 @@
const {
ArrayIsArray,
Error,
ErrorPrototypeToString,
ErrorCaptureStackTrace,
String,
} = primordials;
@@ -81,10 +82,10 @@ function onWarning(warning) {
if (trace && warning.stack) {
msg += `${warning.stack}`;
} else {
const toString =
msg +=
typeof warning.toString === 'function' ?
warning.toString : Error.prototype.toString;
msg += `${toString.apply(warning)}`;
`${warning.toString()}` :
ErrorPrototypeToString(warning);
}
if (typeof warning.detail === 'string') {
msg += `\n${warning.detail}`;

View File

@@ -163,5 +163,13 @@ new RuleTester({
options: [{ name: 'Map', into: 'Safe' }],
errors: [{ message: /const { SafeMap } = primordials/ }]
},
{
code: `
const { Function } = primordials;
const noop = Function.prototype;
`,
options: [{ name: 'Function' }],
errors: [{ message: /const { FunctionPrototype } = primordials/ }]
},
]
});

View File

@@ -75,7 +75,6 @@ module.exports = {
acc.set(
option.name,
(option.ignore || [])
.concat(['prototype'])
.reduce((acc, name) => acc.set(name, {
ignored: true
}), new Map())