I'm looking at the alternative that can substitute the use of eval()
and new Function()
javascript techniques. I'm developing a solution build with javascript and the platform on which it is built (Salesforce) recently has announced they're introducing CSP (content security policy) that will block the use of eval()
, and other unsafe functions.
My solution is using eval function to evaluate string expressions and do some other magic stuff. I'm looking for some alternative, ideally without writing my own parser.
As I have mentioned, I use eval to evaluate expressions. Expressions that should be to be supported are usually like:
- String comparison
eval("'something' == 'something'") // return true
- Calculations
eval("2 + 2 * 3)" // return 8
&&
and||
supporteval("1 == 1 && 'cat' == 'dog'") // return false
- Conditional operators,
- at least ternary
eval("(1 == 2 ? 'dog' : 'cat')") // return "cat"
- full
if-else
would be really great:eval("if(1 == 2) { 'dog' } else if (1 == 3) { 'dog' } else { 'nothing' }") // return "nothing"
- at least ternary
- Some basic
Math
class methods, e.g.:eval("Math.ceil(12.313)"); // return 13
Capabilities that would be really great to have
- Inject variable
new Function("var item = this; item.number = 10;", item); // item is variable defined outside of eval and I want to dynamically modify it within eval()
- Inject function definition
eval("invert('123')") // return 321, invert() is a function defined somewhere else
I'm looking for something that is:
- Relatively close to Javascript syntax (but I would accept if it would be some different language that can be interpreted by some js library compliant with CSP)
- Not too much dependent on other libraries
- Can be loaded without node.js etc (standalone js library)
-
Would this work? github.com/NeilFraser/JS-InterpreterRobert Harvey– Robert Harvey2016年06月29日 18:19:51 +00:00Commented Jun 29, 2016 at 18:19
-
1May I ask what your use case is?Populus– Populus2016年06月29日 18:22:24 +00:00Commented Jun 29, 2016 at 18:22
-
1Robert, thank you for that link, I'm looking at it and I'll try if it will not be blocked by CSP tomorrow. @Populus - As I wrote - the use of pure eval() will be blocked by Content Security Policy of the platform. I need something that will allow me to evaluate string expressions.Maciek Simm– Maciek Simm2016年06月29日 20:31:46 +00:00Commented Jun 29, 2016 at 20:31
-
2That's not a use case, that's an implementation you're actively pursuing, one that is full of security holes and SalesForce is blocking it for a very good reason.Populus– Populus2016年06月29日 21:13:33 +00:00Commented Jun 29, 2016 at 21:13
-
1@Populus, yes you're right. I'm looking for an alternative for the evil eval(). The use case is that in the application I'm building I need to be able to evaluate string expressions (I described few examples above). These expressions are used to execute some rules: if (string expression == true) -> execute a rule. I'm looking for a solution that can exectue on the client side (web browser), ideally without too much waiting time.Maciek Simm– Maciek Simm2016年06月30日 08:20:08 +00:00Commented Jun 30, 2016 at 8:20
1 Answer 1
What you are looking for is a simple expression language that can be evaluated from within ECMAScript (which is just another way of saying there exists an interpreter written in ECMAScript). Thankfully, such a language and interpreter already exists: Jexl.
Jexl is a simple ECMAScript expression language that features pretty much everything you listed:
- unary and binary operators, mathematical, logical and string operations,
- comparison operators,
- a conditional operator, and
- you can pass a context object whose properties can be accessed like global variables in the expression.
This last one is not exactly what you are asking about, because you were asking about accessing arbitrary ECMAScript identifiers, but it is arguably more safe: you can only access what is explicitly passed in. And if you really wanted to, you could pass in the context object { window: window }
and then your expression has access to the global window
object and can do every evil thing you never imagined.
It also has some features you didn't list:
- collections with filter operations:
listOfPeople[.name == "John"]
will return a sub-array oflistOfPeople
with only those people whosename
property is"John"
and - transformation pipelines:
"A;B;C"|lower|split(";") // => ["a", "b", "c"]
.
It sounds like this is exactly what you are looking for.
Explore related questions
See similar questions with these tags.