From e6f15d899af48be9a70da2489130be685028f753 Mon Sep 17 00:00:00 2001 From: Vijay Sarvepalli Date: Tue, 25 Nov 2025 01:03:52 -0500 Subject: [PATCH] Updated hardenings --- src/evaluate.js | 54 +++++++++++++++++++++++++++++++++++------------ test/operators.js | 10 +++++---- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/evaluate.js b/src/evaluate.js index 580da439..f8159576 100644 --- a/src/evaluate.js +++ b/src/evaluate.js @@ -7,16 +7,52 @@ import { INUMBER, IOP1, IOP2, IOP3, IVAR, IVARNAME, IFUNCALL, IFUNDEF, IEXPR, IE function isAllowedFunc(f, expr, values) { // function definition is included in registered functions if (Object.values(expr.functions).includes(f)) return true; - // marked as safe already - if (f.__expr_eval_safe_def) return true; for (const v of Object.values(values)) { if (typeof v === 'object' && v !== null) { for (const subV of Object.values(v)) { if (subV === f) { // allow Math functions - for (var key of Object.getOwnPropertyNames(Math)) { - if (Math[key] === subV) return true; + const SAFE_MATH = Object.freeze({ + abs: Math.abs, + acos: Math.acos, + asin: Math.asin, + atan: Math.atan, + atan2: Math.atan2, + ceil: Math.ceil, + clz32: Math.clz32, + cos: Math.cos, + exp: Math.exp, + floor: Math.floor, + imul: Math.imul, + fround: Math.fround, + f16round: Math.f16round, + log: Math.log, + max: Math.max, + min: Math.min, + pow: Math.pow, + random: Math.random, + round: Math.round, + sin: Math.sin, + sqrt: Math.sqrt, + tan: Math.tan, + log10: Math.log10, + log2: Math.log2, + log1p: Math.log1p, + expm1: Math.expm1, + cosh: Math.cosh, + sinh: Math.sinh, + tanh: Math.tanh, + acosh: Math.acosh, + asinh: Math.asinh, + atanh: Math.atanh, + hypot: Math.hypot, + trunc: Math.trunc, + sign: Math.sign, + cbrt: Math.cbrt, + }); + for (var key of Object.getOwnPropertyNames(SAFE_MATH)) { + if (SAFE_MATH[key] === subV) return true; } // function definition is included in registered functions return Object.values(expr.functions).includes(subV); @@ -124,15 +160,7 @@ export default function evaluate(tokens, expr, values) { } return evaluate(n2, expr, scope); }; - // f.name = n1 - Object.defineProperty(f, 'name', { - value: n1, - writable: false - }); - Object.defineProperty(f, '__expr_eval_safe_def', { - value: true, - writable: false - }); + expr.functions["lambda_" + expr.functions.__counter++] = f; values[n1] = f; return f; })()); diff --git a/test/operators.js b/test/operators.js index 80011eb7..f455c4b5 100644 --- a/test/operators.js +++ b/test/operators.js @@ -171,8 +171,9 @@ describe('Operators', function () { it('evaluates rhs when lhs is true', function () { var called = spy(returnFalse); - - assert.strictEqual(Parser.evaluate('true and spies.called()', { spies: { called: called } }), false); + var parser = new Parser(); + parser.functions = {f: called}; + assert.strictEqual(parser.evaluate('true and spies.called()', { spies: { called: called } }), false); assert.strictEqual(called.called, true); }); }); @@ -211,8 +212,9 @@ describe('Operators', function () { it('evaluates rhs when lhs is false', function () { var called = spy(returnTrue); - - assert.strictEqual(Parser.evaluate('false or spies.called()', { spies: { called: called } }), true); + var parser = new Parser(); + parser.functions = {f: called}; + assert.strictEqual(parser.evaluate('false or spies.called()', { spies: { called: called } }), true); assert.strictEqual(called.called, true); }); });