sec: Replace eval with safe expression parser (expr-eval) for material formulas
This commit is contained in:
Generated
+7
@@ -12,6 +12,7 @@
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"expr-eval": "^2.0.2",
|
||||
"express": "^4.18.2",
|
||||
"graphql": "^16.8.1",
|
||||
"graphql-request": "^6.1.0",
|
||||
@@ -2782,6 +2783,12 @@
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/expr-eval": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/expr-eval/-/expr-eval-2.0.2.tgz",
|
||||
"integrity": "sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"expr-eval": "^2.0.2",
|
||||
"express": "^4.18.2",
|
||||
"graphql": "^16.8.1",
|
||||
"graphql-request": "^6.1.0",
|
||||
|
||||
@@ -1565,15 +1565,11 @@ class SmartPackageManagementService {
|
||||
console.log('🧮 [FORMULA] After substitution:', expr);
|
||||
logger.info('After variable substitution:', { expr, geometry: { length: geometry.length_main, width: geometry.width_main, area: geometry.total_area } });
|
||||
|
||||
// Evaluer matematisk udtryk (sikker måde)
|
||||
// Tillad kun tal, +, -, *, /, (, ), .
|
||||
if (!/^[\d\s+\-*/.()]+$/.test(expr)) {
|
||||
console.log('⚠️ [FORMULA] Invalid expression:', expr);
|
||||
logger.warn('Invalid formula expression:', { expr, original: formula });
|
||||
return 1; // Fallback
|
||||
}
|
||||
|
||||
const result = eval(expr);
|
||||
// Evaluer matematisk udtryk via sikker parser
|
||||
const { Parser } = require('expr-eval');
|
||||
const parser = new Parser({});
|
||||
const parsed = parser.parse(String(expr || '0'));
|
||||
const result = Number(parsed.evaluate(variables)) || 0;
|
||||
console.log('✅ [FORMULA] Result:', result);
|
||||
logger.info('Formula result:', { result, expr });
|
||||
return Math.max(0, result); // Ingen negative værdier
|
||||
|
||||
@@ -6,6 +6,7 @@ const http = require('http');
|
||||
const { Server } = require('socket.io');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const axios = require('axios');
|
||||
const { Parser } = require('expr-eval');
|
||||
// const HistoricalQuoteCalculator = require('./historical-quote-calculator.js'); // Temporarily disabled
|
||||
|
||||
// Load environment variables FIRST
|
||||
@@ -211,14 +212,23 @@ async function calculateMaterialQuantities(projectId, geometry) {
|
||||
|
||||
for (const formula of formulas) {
|
||||
try {
|
||||
// Create safe evaluation context
|
||||
// Build evaluation context (support both GEOM.xxx and direct vars)
|
||||
const GEOM = {
|
||||
area_m2: geometry.area_m2 || 0,
|
||||
vindskede_lbm: geometry.vindskede_lbm || 0
|
||||
area_m2: Number(geometry.area_m2) || 0,
|
||||
vindskede_lbm: Number(geometry.vindskede_lbm) || 0
|
||||
};
|
||||
|
||||
// Evaluate formula safely
|
||||
const calculatedValue = eval(formula.qty_formula);
|
||||
const vars = { GEOM, ...GEOM };
|
||||
|
||||
// Evaluate formula using a safe math parser
|
||||
let calculatedValue = 0;
|
||||
try {
|
||||
const parser = new Parser({});
|
||||
const expr = parser.parse(String(formula.qty_formula || '0'));
|
||||
calculatedValue = Number(expr.evaluate(vars)) || 0;
|
||||
} catch (e) {
|
||||
console.error(`❌ Formula parse/eval error for ${formula.material_sku}:`, e.message);
|
||||
calculatedValue = 0;
|
||||
}
|
||||
const quantity = Math.ceil(calculatedValue * formula.unit_per_formula * formula.waste_factor);
|
||||
|
||||
if (quantity > 0) {
|
||||
|
||||
Reference in New Issue
Block a user