-
-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add safe eval for browser and eval
option
#185
Conversation
@brettz9 Could you please check and see if the approach is right ? I particularly need advice on the rollup/babel/eslint configuration changes as I'm totally new to them. Also, if possible, how should we go with the support of If I get a green flag in these, I'll work on documentation. |
update test html file to use compiled module update demo html file to include sample & prevent submit
I don't have time to look at this now, and no guarantees about getting to it, but I think an optimal solution, if you can't get the multi-line evaluation supported, would be to allow the user to supply their own evaluator, e.g., optionally passing in |
user still has the choice to go with unsafe way using a new options |
@brettz9 Looks like the PR is complete. I'm in no rush, so whenever you (or some other contributor) find time, please look into it and suggest changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plan to give a deeper review later, but wanted to first address these smaller questions, and also ask that we maintain 100% testing coverage. (I see that the coverage badge is no longer reporting 100%, so some of the new lines of code apparently aren't covered in tests.)
I'd prefer we avoid the Babel ESLint parser unless there is really a compelling reason, though it'd be fine to increase the parserOptions.ecmaVersion
to use the latest standard features in source.
From what I can see, the rest all looks very good.
@brettz9, my two unsolicited cents are in agreement with your thoughts about this PR for a few couple reasons.
const customEval = (code: string, context: any): any => {
// evaluate code against context, return any matching result(s)
};
const jsonPath = new JSONPath({ eval: customEval });
jsonPath.evaulate('$.test'); An alternative API that fits into the current architecture a bit better, which would require the consumer to pass in a class to the config. class CustomEval {
constructor(code: string) {
// any compiling you need to do.
this.code = code;
}
eval(context: any) {
// however you'd like to evaluate the code (`this.code`) against `context`
// return undefined, or match(es)
return undefined;
}
}
const jsonPath = new JSONPath({ eval: CustomEval });
jsonPath.evaluate('$.test'); In both scenarios, this library would still replace the shorthand properties(ex While option 2 has a bit more boilerplate, I think it provides more flexibility for consumers of this library and it enables automatic caching of the compiled script. |
@jacobroschen : Thank you for your thoughts. They are most welcome. However, I have a few thoughts in response: As far as adding dependencies, the bundle size is rather good, no less considering what it is doing:
And although it does not support everything eval-wise, for the much more common use case of just accessing properties, it really does deliver something important. I agree we can drop It has been a long-time goal for us to have a safe default, and recently we had still another request for a safe default: #182 . I rejected that because I didn't want to gut the core functionality our users have become accustomed to, but only because we didn't have an alternative. I remain open to further thoughts, as well as to input of others, but unless there are concerns with jsep specifically, it seems like a hearty compromise without coming at much cost. |
Your API proposal looks sound (I agree with the second one too) and perhaps this PR can be adjusted to implement. |
I agree with @brettz9 . The primary reason why I decided to use jsep in this library was to provide a safe & lightweight evaluation out of the box. Another similar library jsonpath achieves this by using static-eval and esprima which have minified + gzip sizes as
However, the idea of allowing the library user to provide his own |
I have implemented the new API eliminating |
evalType
optioneval
option
will this PR ever be merged? |
`ignoreEvalErrors` can be used to supress errors in eval expressions. These errors are common because the expression might be suitable for a particular value but may give error on other values. For such scenarios, we expect it to match the passing values instead of crash entirely
@guoliang Thanks for reminding @brettz9 I have removed the conflicts which had appeared during the time. Also, since your last review, I added a new option |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you can make the mentioned changes, I think I'll be ready for a final review. Looks good so far...
…Error=false to avoid test breaks
@brettz9 All resolved. |
I added one commit to fully pass linting and the testing scripts. Did you mean for the Also, please prepare a message for those upgrading to this breaking change version (e.g., what users of |
I hope this message suffices.
|
If you want to take one last look, I think it should be ready for a release now. |
Tried few expressions in browser demo only, and it looks good to me. |
Released as v9.0.0. Thanks for your contributions! |
Adding a safe alternative to Function/eval in browser.
This is also required since the chrome extensions & chrome apps have already become strict about safety.
I was trying to use it in a chrome extension but couldn't because of unsafe-eval. Hence this fix tries to introduce a safe evaluation method which satisfies Content Security Policy.
eval: "safe"
is effective only in browser and doesn't uses a scripting engine which supports a minimal form of javascript (no functions or complex expressions).PR description
eval: "safe" | "native" | boolean | (code, context) => value | Script)
ignoreEvalError: boolean
which can be used to consider the errors in eval expressions as match.Checklist
npm test
, ensuring linting passesFixes #60 , #182 , #169