Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

expression-eval

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

expression-eval - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

LICENSE

118

index.js
var jsep = require('jsep');
/**
* Evaluation code from JSEP project, under MIT License.
* Copyright (c) 2013 Stephen Oney, http://jsep.from.so/
*/
var binops = {
'||': function (a, b) { return a || b; },
'&&': function (a, b) { return a && b; },
'|': function (a, b) { return a | b; },
'^': function (a, b) { return a ^ b; },
'&': function (a, b) { return a & b; },
'==': function (a, b) { return a == b; }, // jshint ignore:line
'!=': function (a, b) { return a != b; }, // jshint ignore:line
'||': function (a, b) { return a || b; },
'&&': function (a, b) { return a && b; },
'|': function (a, b) { return a | b; },
'^': function (a, b) { return a ^ b; },
'&': function (a, b) { return a & b; },
'==': function (a, b) { return a == b; }, // jshint ignore:line
'!=': function (a, b) { return a != b; }, // jshint ignore:line
'===': function (a, b) { return a === b; },
'!==': function (a, b) { return a !== b; },
'<': function (a, b) { return a < b; },
'>': function (a, b) { return a > b; },
'<=': function (a, b) { return a <= b; },
'>=': function (a, b) { return a >= b; },
'<<': function (a, b) { return a << b; },
'>>': function (a, b) { return a >> b; },
'<': function (a, b) { return a < b; },
'>': function (a, b) { return a > b; },
'<=': function (a, b) { return a <= b; },
'>=': function (a, b) { return a >= b; },
'<<': function (a, b) { return a << b; },
'>>': function (a, b) { return a >> b; },
'>>>': function (a, b) { return a >>> b; },
'+': function (a, b) { return a + b; },
'-': function (a, b) { return a - b; },
'*': function (a, b) { return a * b; },
'/': function (a, b) { return a / b; },
'%': function (a, b) { return a % b; }
'+': function (a, b) { return a + b; },
'-': function (a, b) { return a - b; },
'*': function (a, b) { return a * b; },
'/': function (a, b) { return a / b; },
'%': function (a, b) { return a % b; }
};
var unops = {
'-' : function(a) { return -a; },
'+' : function(a) { return a; },
'~' : function(a) { return ~a; },
'!' : function(a) { return !a; },
'-' : function (a) { return -a; },
'+' : function (a) { return a; },
'~' : function (a) { return ~a; },
'!' : function (a) { return !a; },
};
function evaluate (node, context) {
if(node.type === 'BinaryExpression') {
return binops[node.operator](evaluate(node.left, context), evaluate(node.right, context));
} else if(node.type === 'UnaryExpression') {
return unops[node.operator](evaluate(node.argument, context));
} else if (node.type === 'MemberExpression') {
if (node.computed) {
return evaluate(node.object, context)[evaluate(node.property, context)];
} else {
return evaluate(node.object, context)[node.property.name];
}
} else if (node.type === 'Identifier') {
return context[node.name];
} else if(node.type === 'Literal') {
return node.value;
function evaluate_array( list, context ) {
return list.map( function(v,i,a) { return evaluate( v, context ); } );
}
function evaluate ( node, context ) {
switch ( node.type ) {
case 'ArrayExpression':
return evaluate_array( node.elements, context );
case 'BinaryExpression':
return binops[ node.operator ]( evaluate( node.left, context ), evaluate( node.right, context ) );
case 'CallExpression':
let fn = evaluate( node.callee, context );
if ( typeof( fn ) === "function" ) {
return fn.apply( null, evaluate_array( node.arguments, context ) );
} else {
return undefined;
}
case 'ConditionalExpression':
if ( evaluate( node.test, context ) ) {
return evaluate( node.consequent, context );
} else {
return evaluate( node.alternate, context );
}
case 'Identifier':
return context[ node.name ];
case 'Literal':
return node.value;
case 'LogicalExpression':
return binops[ node.operator ]( evaluate( node.left, context ), evaluate( node.right, context ) );
case 'MemberExpression':
if ( node.computed ) {
return evaluate(node.object, context)[evaluate(node.property, context)];
} else {
return evaluate(node.object, context)[node.property.name];
}
case 'ThisExpression':
return this;
case 'UnaryExpression':
return unops[ node.operator ]( evaluate( node.argument, context ) );
default:
return undefined;
}
}

@@ -51,0 +95,0 @@

{
"name": "expression-eval",
"version": "1.0.1",
"version": "1.1.0",
"description": "JavaScript expression parsing and evaluation, safely.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -55,2 +55,2 @@ # expression-eval

Not yet licensed.
MIT License.

@@ -5,25 +5,114 @@ const expr = require('./');

const fixtures = [
{expr: '1 + 2 + 3', expected: 6},
// array expression
{expr: '([1,2,3])[0]', expected: 1 },
{expr: '(["one","two","three"])[1]', expected: "two" },
{expr: '([true,false,true])[2]', expected: true },
{expr: '([1,true,"three"]).length', expected: 3 },
{expr: 'isArray([1,2,3])', expected: true },
{expr: 'list[3]', expected: 4 },
{expr: 'numMap[1 + two]', expected: 'three'},
// binary expression
{expr: '1+2', expected: 3},
{expr: '2-1', expected: 1},
{expr: '2*2', expected: 4},
{expr: '6/3', expected: 2},
{expr: '5|3', expected: 7},
{expr: '5&3', expected: 1},
{expr: '5^3', expected: 6},
{expr: '4<<2', expected: 16},
{expr: '256>>4', expected: 16},
{expr: '-14>>>2', expected: 1073741820},
{expr: '10%6', expected: 4},
{expr: '"a"+"b"', expected: "ab"},
{expr: 'one + three', expected: 4},
{expr: 'foo.bar + 2', expected: 'baz2'},
{expr: 'foo.bar + 2', expected: 'baz2'},
{expr: 'numMap[1 + two]', expected: 'three'},
{expr: '"run" + "ning"', expected: 'running'}
// call expression
{expr: 'func(5)', expected: 6},
{expr: 'func(1+2)', expected: 4},
// conditional expression
{expr: '(true ? "true" : "false")', expected: "true" },
{expr: '( ( bool || false ) ? "true" : "false")', expected: "true" },
{expr: '( true ? ( 123*456 ) : "false")', expected: 123*456 },
{expr: '( false ? "true" : one + two )', expected: 3 },
// identifier
{expr: 'string', expected: "string" },
{expr: 'number', expected: 123 },
{expr: 'bool', expected: true },
// literal
{expr: '"foo"', expected: "foo" }, // string literal
{expr: "'foo'", expected: "foo" }, // string literal
{expr: '123', expected: 123 }, // numeric literal
{expr: 'true', expected: true }, // boolean literal
// logical expression
{expr: 'true || false', expected: true },
{expr: 'true && false', expected: false },
{expr: '1 == "1"', expected: true },
{expr: '2 != "2"', expected: false },
{expr: '1.234 === 1.234', expected: true },
{expr: '123 !== "123"', expected: true },
{expr: '1 < 2', expected: true },
{expr: '1 > 2', expected: false },
{expr: '2 <= 2', expected: true },
{expr: '1 >= 2', expected: false },
// member expression
{expr: 'foo.bar', expected: 'baz' },
{expr: 'foo["bar"]', expected: 'baz' },
{expr: 'foo[foo.bar]', expected: 'wow' },
// unary expression
{expr: '-one', expected: -1 },
{expr: '+two', expected: 2 },
{expr: '!false', expected: true },
{expr: '!!true', expected: true },
{expr: '~15', expected: -16 },
];
const context = {
string: "string",
number: 123,
bool: true,
one: 1,
two: 2,
three: 3,
foo: {bar: 'baz'},
numMap: {10: 'ten', 3: 'three'}
foo: {bar: 'baz', baz: "wow"},
numMap: {10: 'ten', 3: 'three'},
list: [1,2,3,4,5],
func: function(x) { return x + 1; },
isArray: Array.isArray,
};
var tests = 0;
var passed = 0;
fixtures.forEach((o) => {
tests++;
var val = expr.compile(o.expr)(context);
assert.equal(
expr.compile(o.expr)(context),
val,
o.expected,
'Failed: ' + o.expr + ' === ' + o.expected);
'Failed: ' + o.expr + ' ('+val+') === ' + o.expected);
passed++;
});
console.log('%s/%s tests passed.', fixtures.length, fixtures.length);
// test 'this'
(function testThis() {
tests++;
this.foo = 'bar';
var ast = expr.parse( 'this.foo' );
var val = expr.eval( ast, { 'baz': 'blah' } );
assert.equal( val, 'bar' );
passed++;
})();
console.log('%s/%s tests passed.', passed, tests);
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc