Skip to content

Commit

Permalink
lib,tools: enforce access to prototype from primordials
Browse files Browse the repository at this point in the history
PR-URL: nodejs#36025
Reviewed-By: Shingo Inoue <leko.noor@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
aduh95 authored and sbaayel committed Nov 2, 2023
1 parent 0c44930 commit 1383d00
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 54 deletions.
138 changes: 88 additions & 50 deletions lib/internal/freeze_intrinsics.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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() {
Expand Down Expand Up @@ -110,55 +143,55 @@ module.exports = function() {
TypedArrayPrototype,

// 19 Fundamental Objects
Object.prototype, // 19.1
Function.prototype, // 19.2
Boolean.prototype, // 19.3

Error.prototype, // 19.5
EvalError.prototype,
RangeError.prototype,
ReferenceError.prototype,
SyntaxError.prototype,
TypeError.prototype,
URIError.prototype,
ObjectPrototype, // 19.1
FunctionPrototype, // 19.2
BooleanPrototype, // 19.3

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

Int8Array.prototype,
Uint8Array.prototype,
Uint8ClampedArray.prototype,
Int16Array.prototype,
Uint16Array.prototype,
Int32Array.prototype,
Uint32Array.prototype,
Float32Array.prototype,
Float64Array.prototype,
BigInt64Array.prototype,
BigUint64Array.prototype,
ArrayPrototype, // 22.1

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,
Expand All @@ -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]())
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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) {
Expand All @@ -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.
Expand Down
7 changes: 4 additions & 3 deletions lib/internal/process/warning.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const {
ArrayIsArray,
Error,
ErrorPrototypeToString,
ErrorCaptureStackTrace,
String,
} = primordials;
Expand Down Expand Up @@ -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}`;
Expand Down
8 changes: 8 additions & 0 deletions test/parallel/test-eslint-prefer-primordials.js
Original file line number Diff line number Diff line change
Expand Up @@ -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/ }]
},
]
});
1 change: 0 additions & 1 deletion tools/eslint-rules/prefer-primordials.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ module.exports = {
acc.set(
option.name,
(option.ignore || [])
.concat(['prototype'])
.reduce((acc, name) => acc.set(name, {
ignored: true
}), new Map())
Expand Down

0 comments on commit 1383d00

Please sign in to comment.