È una funzione che traccia un uso legittimo di eval () in JavaScript?

6

Da sviluppo PHP so che eval è malvagio e di recente ho letto Cosa costituisce "Uso corretto" della funzione javascript Eval? e Non essere valoroso . L'unico uso corretto di eval che ho letto è Ajax.

Attualmente sto sviluppando uno strumento di visualizzazione che consente agli utenti di vedere come i polinomi possono interpolare le funzioni:

Uso eval per la valutazione di funzioni arbitrarie. È un uso legittimo di eval? Come potrei liberarmi di Eval?

Voglio che l'utente sia in grado di eseguire qualsiasi funzione dei seguenti moduli:

  1. a x ^ i con a, i in R
  2. sin, cos, tan
  3. b ^ x con b in R
  4. qualsiasi combinazione che puoi ottenere
    • aggiunta (ad es. x ^ 2 + x ^ 3 + sin (x)),
    • moltiplicando (ad es. sin (x) * x ^ 2) o
    • inserimento (ad es. sin (x ^ 2))
posta Martin Thoma 01.07.2013 - 10:42
fonte

3 risposte

8

Non vedo nulla di "legittimo", eval non è male di per sé ed è stato progettato proprio per valutare il codice arbitrario. Ti consente di creare un valutatore di espressioni veloce e completo senza ricorrere a librerie complesse e offre all'utente il potere di JavaScript.

Ma in questo momento stai valutando l'input per ogni x . Questo è molto lento.

Lo farei in modo che possa essere usato in modo più efficiente:

var f = Function('x','return '+input);

Quando l'input è Math.sin(x) , questo crea una funzione che puoi semplicemente chiamare come

var x = 3;
var y = f(x);

Prova: jsperf

Se quello che vuoi è lasciare che l'utente entri in funzione con un linguaggio matematico più classico (come x^y ), allora è meglio iniziare a importare un parser di espressioni matematiche.

Un esempio di tale libreria: valutatore di Silent Mat

    
risposta data 01.07.2013 - 10:54
fonte
4

Non vuoi valutare le funzioni Javascript . Vuoi valutare un sottoinsieme delle funzioni computabili dai reali ai reali. Quindi eval non fa quello che vuoi, anche se in linea di principio potresti abusarne per questo. Oltre a questa obiezione filosofica, se vuoi utilizzare ^ per l'esponenziazione, non puoi utilizzare eval perché utilizza la sintassi di Javascript dove ^ è binario xor.

Se vuoi solo essere fatto rapidamente e lasciare questo progetto, puoi usare eval (specialmente perché questo apparentemente gira sul sito del cliente, quindi il potenziale di abuso è limitato). Ma la cosa giusta (tm) da fare sarebbe usare un parser di espressioni specifico per il tipo di sintassi che si desidera consentire, insieme a una routine di valutazione per l'output di analisi.

Non è difficile scrivere una cosa del genere da soli, e molto divertente. Utilizzerei l'algoritmo per lo shunting-yard o un parser di precedenza dell'operatore top-down. In alternativa, utilizza una libreria esistente come raccomandato nei commenti.

    
risposta data 01.07.2013 - 10:54
fonte
2

Un sacco di persone che sanno che eval è pericoloso sul lato server, lo rifuggono in modo riflessivo dal lato client. C'è un'enorme differenza. Non è un buco di sicurezza essere in grado di eseguire il proprio codice arbitrario sul proprio computer. L'unico momento di preoccuparsi della sicurezza eval sul lato client è se lo si sta utilizzando per eseguire codice da una terza parte non attendibile, ad esempio da e-mail o da un feed Twitter.

Tuttavia, ci sono altri fattori da considerare. La soluzione eval sarà molto più semplice per le funzionalità di base, ma molto più difficile aggiungere cose come messaggi di errore utili. Si può finire per implementare il proprio parser in ogni caso per aggiungere quel tipo di funzionalità.

Ci sono anche considerazioni sulle prestazioni, ma penso che la differenza sia probabilmente trascurabile. eval avrà probabilmente tempi di avvio più elevati, ma tempi di esecuzione più rapidi.

Personalmente, utilizzerei eval per uno strumento per uso personale o all'interno della mia azienda, per la sua semplicità di sviluppo. Per una più ampia distribuzione, vorrei lo smalto che un parser personalizzato può fornire.

    
risposta data 01.07.2013 - 16:53
fonte

Leggi altre domande sui tag