Alternativa per eval () in javascript per la valutazione dell'espressione

6

Sto osservando l'alternativa che può sostituire l'uso delle tecniche eval() e new Function() javascript. Sto sviluppando una soluzione build con javascript e la piattaforma su cui è stata costruita (Salesforce) ha recentemente annunciato che stanno introducendo CSP (Content Security Policy) che bloccherà l'utilizzo di eval() e altre funzioni non sicure.

La mia soluzione utilizza la funzione eval per valutare le espressioni di stringa e fare altre cose magiche. Sto cercando un'alternativa, idealmente senza scrivere il mio parser.

Come ho già detto, io uso eval per valutare le espressioni. Le espressioni che dovrebbero essere supportate sono solitamente come:

  • Confronto stringa eval("'something' == 'something'") // return true
  • Calcoli eval("2 + 2 * 3)" // return 8
  • && e || supporto eval("1 == 1 && 'cat' == 'dog'") // return false
  • Operatori condizionali,
    • almeno ternario eval("(1 == 2 ? 'dog' : 'cat')") // return "cat"
    • full if-else sarebbe davvero eccezionale: eval("if(1 == 2) { 'dog' } else if (1 == 3) { 'dog' } else { 'nothing' }") // return "nothing"
  • Alcuni metodi di classe Math di base, ad esempio eval("Math.ceil(12.313)"); // return 13

Capacità che sarebbe davvero grandiosa avere

  • 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()
  • Inietta la definizione della funzione eval("invert('123')") // return 321, invert() is a function defined somewhere else

Sto cercando qualcosa che sia:

  • Relativamente vicino alla sintassi di Javascript (ma accetterei se sarebbe una lingua diversa che può essere interpretata da qualche libreria js compatibile con CSP)
  • Non troppo dipendente da altre librerie
  • Può essere caricato senza node.js ecc. (libreria js standalone)
posta Maciek Simm 29.06.2016 - 19:50
fonte

1 risposta

4

Quello che stai cercando è un linguaggio di espressione semplice che può essere valutato all'interno di ECMAScript (che è solo un altro modo di dire che esiste un interprete scritto in ECMAScript). Per fortuna, un tale linguaggio e interprete esiste già: Jexl .

Jexl è un semplice linguaggio di espressione ECMAScript che presenta praticamente tutto ciò che hai elencato:

  • operatori unari e binari, operazioni matematiche, logiche e di stringa
  • operatori di confronto,
  • un operatore condizionale e
  • puoi passare un oggetto di contesto di cui è possibile accedere alle proprietà come variabili globali nell'espressione.

Quest'ultimo non è esattamente quello che stai chiedendo, perché stavi chiedendo di accedere agli identificatori ECMAScript arbitrari, ma è probabilmente più sicuro: puoi solo accedere a ciò che è esplicitamente passato. E se vuoi davvero , puoi passare l'oggetto di contesto { window: window } e quindi l'espressione ha accesso all'oggetto window globale e può fare ogni cosa malvagia che non hai mai immaginato.

Ha anche alcune funzionalità che non hai elencato:

  • raccolte con operazioni di filtro: listOfPeople[.name == "John"] restituirà un sotto-array di listOfPeople con solo le persone la cui proprietà name è "John" e
  • pipeline di trasformazione: "A;B;C"|lower|split(";") // => ["a", "b", "c"] .

Sembra che questo sia esattamente quello che stai cercando.

    
risposta data 01.07.2016 - 02:38
fonte

Leggi altre domande sui tag