Eval is Evil 3

{ June 12th, 2011 }


cmilfont

Autor: cmilfont

Continuando nossa saga de evitar Eval e conhecer melhor o Javascript, vou brincar com a seguinte situação: parsear um template html escrito com Expression Language da spec JSP.

Imagina o seguinte trecho abaixo:

<c:if test="${sessionScope.cart.numberOfItems > 0}">
  ...
</c:if>

√Č f√°cil montarmos um mapa com todas as express√Ķes encontradas entre ${ e } e depois chamar eval para processar, mas como quero evitar essa chamada, o que podemos fazer?

Encontramos na documentação de referência da Mozilla a resposta, especificamente no objeto nativo Function, onde podemos criar uma new Function passando seu corpo como uma string que será executada ao fazer a chamada dessa function. Montei abaixo um exemplo como funciona:


Caso n√£o veja no seu Feedreader, link do github.

Categories: JavaScript ~ ~ Trackback


Assine os coment√°rios deste artigo.


3 Responses to “Eval is Evil 3”

  1. 1
    Stephen Eilert

    Bem, continua sendo Eval, mas com um bigode postiço (e evil).

    Sugiro expandir o exemplo com a √ļnica vantagem dessa constru√ß√£o: a possibilidade de criar fun√ß√Ķes que aceitam par√Ęmetros:

    Por exemplo:

    var sessionScope = {
    cart: {
    numberOfItems: 10
    }
    }

    var statement = “return scope.cart.numberOfItems > 0”;

    var notsoevil = new Function(“scope”, statement);

    console.log(notsoevil(sessionScope));

    (Ali√°s, pq “quine”? O termo n√£o foi usado no sentido usual…)

  2. 2
    cmilfont

    @Stephen

    Na verdade a chamada de Function n√£o continua evil… quer dizer, eval :)

    A própria recomendação da Mozilla esclarece isso:
    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/eval

    “eval() is also generally slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.”

    √Č percept√≠vel quando a chamada de eval √© realizada, h√° uma travada no navegador, IE e Firefox sentam bonito. Fora que o contexto de execu√ß√£o de eval:

    “More importantly, third party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways of which the similar Function is not susceptible.”

    O exemplo que fiz foi bem simpl√≥rio, n√£o tem nem tratamento de ReferenceError por exemplo. Era s√≥ para dar a id√©ia. No lugar desse replace teria alguma rotina para varrer via RegExp e encontrar senten√ßas…
    Nesse caso aí em específico eu não acho que vale a pena usar argumentos porque quero só uma estratégia de avaliar e executar sentenças.
    Eu vou passar um objeto [como sessionScope] para algum objeto que vai parsear o HTML e ele vai verificar sentenças, não vale a pena fazer um tratamento tão fino.

    O termo quine foi exagero mesmo, na verdade eu estava tentando fazer com quine, mas complicou e resolvi com Function :(

  3. 3
    cmilfont

    @Stephen
    troquei o termo quine para n√£o confundir

Leave a Reply