Eval is Evil 3

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.

Typically chemist’s shop can sale to you with discreet treatments for various health problems. There are numerous of safe online pharmacies that will deliver medications to your address. There are divers medicines for each afflictions. Learn more about “viagra manufacturer coupon“. Maybe “viagra discount coupons” is a highly complicated matter. Matters, like “coupons for viagra“, are connected numerous types of heartiness problems. If you need to take prescription medications, ask your dispenser to check your testosterone levels before. Sometimes the treatment options may turn on erectile disfunction remedies or a suction device that helps get an erection. Keep in mind web-site which is ready to sell erectile disfunction drugs like Viagra without a recipe is fraudulent. When you purchase from an unknown web-site, you run the risk of getting counterfeit remedies.

3 thoughts on “Eval is Evil 3

  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. cmilfont Post author

    @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 🙁

Comments are closed.