Skip to content

Commit a6505eb

Browse files
committed
chore: update build files
1 parent 63993cb commit a6505eb

10 files changed

Lines changed: 102 additions & 14 deletions

badges/coverage-badge.svg

Lines changed: 1 addition & 1 deletion
Loading

badges/tests-badge.svg

Lines changed: 1 addition & 1 deletion
Loading

dist/index-browser-esm.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,25 @@ jsep.addLiteral('null', null);
12261226
jsep.addLiteral('undefined', undefined);
12271227
const BLOCKED_PROTO_PROPERTIES = new Set(['constructor', '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__']);
12281228

1229+
// Every function-constructor variant, along with the invocation helpers which
1230+
// could otherwise reach them indirectly, e.g., `Function.call(0, 'code')()`
1231+
/** @type {WeakSet<object>} */
1232+
const BLOCKED_FUNCTIONS = new WeakSet([Function,
1233+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1234+
function* () {}.constructor,
1235+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1236+
async function () {}.constructor,
1237+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1238+
async function* () {}.constructor, Function.prototype.call, Function.prototype.apply, Function.prototype.bind, Reflect.apply, Reflect.construct]);
1239+
1240+
/**
1241+
* @param {UnknownResult} value
1242+
* @returns {boolean}
1243+
*/
1244+
const isBlockedFunction = value => {
1245+
return typeof value === 'function' && BLOCKED_FUNCTIONS.has(value);
1246+
};
1247+
12291248
/**
12301249
* @typedef {Record<
12311250
* string,
@@ -1393,7 +1412,10 @@ const SafeEval = {
13931412
throw new TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);
13941413
}
13951414
const result = /** @type {Record<string, UnknownResult>} */obj[prop];
1396-
if (typeof result === 'function' && result !== Function) {
1415+
if (isBlockedFunction(result)) {
1416+
throw new TypeError('Function constructor is disabled');
1417+
}
1418+
if (typeof result === 'function') {
13971419
return result.bind(obj); // arrow functions aren't affected by bind.
13981420
}
13991421
return result;
@@ -1428,7 +1450,7 @@ const SafeEval = {
14281450
evalCallExpression(ast, subs) {
14291451
const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
14301452
const func = SafeEval.evalAst(ast.callee, subs);
1431-
if (func === Function) {
1453+
if (isBlockedFunction(func) || args.some(arg => isBlockedFunction(arg))) {
14321454
throw new Error('Function constructor is disabled');
14331455
}
14341456
return (/** @type {(...args: AnyParameter[]) => UnknownResult} */

dist/index-browser-esm.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index-browser-esm.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index-browser-umd.cjs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,25 @@
12321232
jsep.addLiteral('undefined', undefined);
12331233
const BLOCKED_PROTO_PROPERTIES = new Set(['constructor', '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__']);
12341234

1235+
// Every function-constructor variant, along with the invocation helpers which
1236+
// could otherwise reach them indirectly, e.g., `Function.call(0, 'code')()`
1237+
/** @type {WeakSet<object>} */
1238+
const BLOCKED_FUNCTIONS = new WeakSet([Function,
1239+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1240+
function* () {}.constructor,
1241+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1242+
async function () {}.constructor,
1243+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1244+
async function* () {}.constructor, Function.prototype.call, Function.prototype.apply, Function.prototype.bind, Reflect.apply, Reflect.construct]);
1245+
1246+
/**
1247+
* @param {UnknownResult} value
1248+
* @returns {boolean}
1249+
*/
1250+
const isBlockedFunction = value => {
1251+
return typeof value === 'function' && BLOCKED_FUNCTIONS.has(value);
1252+
};
1253+
12351254
/**
12361255
* @typedef {Record<
12371256
* string,
@@ -1399,7 +1418,10 @@
13991418
throw new TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);
14001419
}
14011420
const result = /** @type {Record<string, UnknownResult>} */obj[prop];
1402-
if (typeof result === 'function' && result !== Function) {
1421+
if (isBlockedFunction(result)) {
1422+
throw new TypeError('Function constructor is disabled');
1423+
}
1424+
if (typeof result === 'function') {
14031425
return result.bind(obj); // arrow functions aren't affected by bind.
14041426
}
14051427
return result;
@@ -1434,7 +1456,7 @@
14341456
evalCallExpression(ast, subs) {
14351457
const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
14361458
const func = SafeEval.evalAst(ast.callee, subs);
1437-
if (func === Function) {
1459+
if (isBlockedFunction(func) || args.some(arg => isBlockedFunction(arg))) {
14381460
throw new Error('Function constructor is disabled');
14391461
}
14401462
return (/** @type {(...args: AnyParameter[]) => UnknownResult} */

dist/index-browser-umd.min.cjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/index-browser-umd.min.cjs.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index-node-cjs.cjs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,25 @@ jsep.addLiteral('null', null);
12301230
jsep.addLiteral('undefined', undefined);
12311231
const BLOCKED_PROTO_PROPERTIES = new Set(['constructor', '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__']);
12321232

1233+
// Every function-constructor variant, along with the invocation helpers which
1234+
// could otherwise reach them indirectly, e.g., `Function.call(0, 'code')()`
1235+
/** @type {WeakSet<object>} */
1236+
const BLOCKED_FUNCTIONS = new WeakSet([Function,
1237+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1238+
function* () {}.constructor,
1239+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1240+
async function () {}.constructor,
1241+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1242+
async function* () {}.constructor, Function.prototype.call, Function.prototype.apply, Function.prototype.bind, Reflect.apply, Reflect.construct]);
1243+
1244+
/**
1245+
* @param {UnknownResult} value
1246+
* @returns {boolean}
1247+
*/
1248+
const isBlockedFunction = value => {
1249+
return typeof value === 'function' && BLOCKED_FUNCTIONS.has(value);
1250+
};
1251+
12331252
/**
12341253
* @typedef {Record<
12351254
* string,
@@ -1397,7 +1416,10 @@ const SafeEval = {
13971416
throw new TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);
13981417
}
13991418
const result = /** @type {Record<string, UnknownResult>} */obj[prop];
1400-
if (typeof result === 'function' && result !== Function) {
1419+
if (isBlockedFunction(result)) {
1420+
throw new TypeError('Function constructor is disabled');
1421+
}
1422+
if (typeof result === 'function') {
14011423
return result.bind(obj); // arrow functions aren't affected by bind.
14021424
}
14031425
return result;
@@ -1432,7 +1454,7 @@ const SafeEval = {
14321454
evalCallExpression(ast, subs) {
14331455
const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
14341456
const func = SafeEval.evalAst(ast.callee, subs);
1435-
if (func === Function) {
1457+
if (isBlockedFunction(func) || args.some(arg => isBlockedFunction(arg))) {
14361458
throw new Error('Function constructor is disabled');
14371459
}
14381460
return (/** @type {(...args: AnyParameter[]) => UnknownResult} */

dist/index-node-esm.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,25 @@ jsep.addLiteral('null', null);
12281228
jsep.addLiteral('undefined', undefined);
12291229
const BLOCKED_PROTO_PROPERTIES = new Set(['constructor', '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__']);
12301230

1231+
// Every function-constructor variant, along with the invocation helpers which
1232+
// could otherwise reach them indirectly, e.g., `Function.call(0, 'code')()`
1233+
/** @type {WeakSet<object>} */
1234+
const BLOCKED_FUNCTIONS = new WeakSet([Function,
1235+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1236+
function* () {}.constructor,
1237+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1238+
async function () {}.constructor,
1239+
// eslint-disable-next-line no-empty-function -- Only need the constructor
1240+
async function* () {}.constructor, Function.prototype.call, Function.prototype.apply, Function.prototype.bind, Reflect.apply, Reflect.construct]);
1241+
1242+
/**
1243+
* @param {UnknownResult} value
1244+
* @returns {boolean}
1245+
*/
1246+
const isBlockedFunction = value => {
1247+
return typeof value === 'function' && BLOCKED_FUNCTIONS.has(value);
1248+
};
1249+
12311250
/**
12321251
* @typedef {Record<
12331252
* string,
@@ -1395,7 +1414,10 @@ const SafeEval = {
13951414
throw new TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);
13961415
}
13971416
const result = /** @type {Record<string, UnknownResult>} */obj[prop];
1398-
if (typeof result === 'function' && result !== Function) {
1417+
if (isBlockedFunction(result)) {
1418+
throw new TypeError('Function constructor is disabled');
1419+
}
1420+
if (typeof result === 'function') {
13991421
return result.bind(obj); // arrow functions aren't affected by bind.
14001422
}
14011423
return result;
@@ -1430,7 +1452,7 @@ const SafeEval = {
14301452
evalCallExpression(ast, subs) {
14311453
const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));
14321454
const func = SafeEval.evalAst(ast.callee, subs);
1433-
if (func === Function) {
1455+
if (isBlockedFunction(func) || args.some(arg => isBlockedFunction(arg))) {
14341456
throw new Error('Function constructor is disabled');
14351457
}
14361458
return (/** @type {(...args: AnyParameter[]) => UnknownResult} */

0 commit comments

Comments
 (0)