web-dev-qa-db-fra.com

Alternative pour Eval () dans JavaScript pour l'évaluation de l'expression

Je regarde l'alternative qui peut substituer l'utilisation de eval() et new Function() Techniques JavaScript. Je développe une solution construite avec JavaScript et la plate-forme sur laquelle elle est construite (Salesforce) a récemment annoncé qu'ils introduisent les CSP (Content Security Policy) qui bloquera l'utilisation de eval() et d'autres personnes dangereuses. les fonctions.

Ma solution utilise une fonction EVAL pour évaluer les expressions de chaîne et faire d'autres trucs magiques. Je cherche une alternative, idéalement sans écrire mon propre analyseur.

Comme je l'ai mentionné, j'utilise Eval pour évaluer les expressions. Les expressions à prendre en charge sont généralement comme:

  • Comparaison de chaîne eval("'something' == 'something'") // return true
  • Calculs eval("2 + 2 * 3)" // return 8
  • && Et || Support eval("1 == 1 && 'cat' == 'dog'") // return false
  • Opérateurs conditionnels,
    • au moins ternaire eval("(1 == 2 ? 'dog' : 'cat')") // return "cat"
    • plein if-else serait vraiment génial: eval("if(1 == 2) { 'dog' } else if (1 == 3) { 'dog' } else { 'nothing' }") // return "nothing"
  • Quelques méthodes de base Math, par exemple: eval("Math.ceil(12.313)"); // return 13

Capacités qui seraient vraiment géniales d'avoir

  • Injectez la 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()
  • Injecter la fonction de fonction eval("invert('123')") // return 321, invert() is a function defined somewhere else

Je cherche quelque chose qui est:

  • Relativement proche de la syntaxe JavaScript (mais j'accepterais si ce serait une langue différente pouvant être interprétée par une bibliothèque JS conforme à CSP)
  • Pas trop dépendant d'autres bibliothèques
  • Peut être chargé sans nœud.js etc (bibliothèque JS autonome)
5
Maciek Simm

Ce que vous cherchez, c'est un langage d'expression simple qui peut être évalué à partir de ECMAScript (qui est juste une autre façon de dire qu'il existe un interprète écrit dans ECMAScript). Heureusement, une telle langue et une interprétation existe déjà: JEXL .

JEXL est un simple langage d'expression ECMAScript qui comporte à peu près tout ce que vous avez répertorié:

  • opérateurs unia et binaires, opérations mathématiques, logiques et cordes,
  • les opérateurs de comparaison,
  • un opérateur conditionnel, et
  • vous pouvez passer un objet contextuel dont les propriétés sont accessibles comme des variables globales dans l'expression.

Ce dernier n'est pas exactement Ce que vous demandez, car vous avez demandé d'accéder à des identifiants arbitraires d'Ecmascript, mais il est sans doute plus sûr: vous ne pouvez que accès ce qui est explicitement transmis. Et si vous vraiment voulait, vous pouvez passer dans l'objet contextuel { window: window } Et puis votre expression a Accès à l'objet Global window et peut faire chaque mauvaise chose que vous n'avez jamais imaginée.

Il dispose également de certaines fonctionnalités que vous n'avez pas énuméré:

  • collections avec les opérations de filtrage: listOfPeople[.name == "John"] retournera un sous-tableau de listOfPeople avec uniquement les personnes dont la propriété name est "John" et
  • pipelines de transformation: "A;B;C"|lower|split(";") // => ["a", "b", "c"].

On dirait que c'est exactement ce que vous recherchez.

5
Jörg W Mittag