Fix math_evaluator: function whitelist (sqrt/sin/cos/log/pow/pi) instead of broken char-strip

This commit is contained in:
drjones
2026-08-14 01:41:56 +00:00
parent 6993e81221
commit 1d2c5092ea

View File

@@ -482,9 +482,24 @@ export async function executeTool(toolName: string, args: any): Promise<ToolExec
interestEarned: Number(interestEarned.toFixed(2)),
};
} else {
// Eval standard expression safely using Function constructor
const cleanExpr = String(expression || '0').replace(/[^0-9+\-*/().%\s^Math.pi]/g, '');
const evalResult = new Function(`return (${cleanExpr})`)();
// Safely evaluate math expressions via a function/constant whitelist
const fnMap: Record<string, string> = {
atan2: 'Math.atan2', sqrt: 'Math.sqrt', cbrt: 'Math.cbrt',
sin: 'Math.sin', cos: 'Math.cos', tan: 'Math.tan',
asin: 'Math.asin', acos: 'Math.acos', atan: 'Math.atan',
abs: 'Math.abs', log10: 'Math.log10', log2: 'Math.log2', log: 'Math.log',
exp: 'Math.exp', pow: 'Math.pow', floor: 'Math.floor', ceil: 'Math.ceil',
round: 'Math.round', min: 'Math.min', max: 'Math.max',
sign: 'Math.sign', trunc: 'Math.trunc',
pi: 'Math.PI', PI: 'Math.PI', e: 'Math.E', E: 'Math.E',
};
let cleanExpr = String(expression || '0').replace(/Math\./g, '');
for (const [fn, mapped] of Object.entries(fnMap)) {
cleanExpr = cleanExpr.replace(new RegExp(`\\b${fn}\\b`, 'g'), mapped);
}
cleanExpr = cleanExpr.replace(/\^/g, '**'); // support ^ as exponentiation
const safeExpr = cleanExpr.replace(/[^0-9a-zA-Z_$.+\-*/(),%\s]/g, '');
const evalResult = new Function(`"use strict"; return (${safeExpr})`)();
resultData = {
expression,
result: evalResult,