Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Discussion] Eval, oui ou non ?

Pour une calculatrice

Sujet résolu
    25 août 2011 à 5:57:42

    Boujour à tous,

    Je code une calculatrice en ligne afin de m'exercer et je me retrouve à évaluer des expression mathématiques du type "4 * (3 + √2)". Actuellement, j'utilise le terrible eval() pour parser et calculer la solution. J'ai beaucoup lu sur son utilisation et je crois l'utiliser correctement, car j'utilise le constructeur Function() pour la sécurité et je crois que cette utilisation est justifiée, car l'alternative serait d'écrire un parsur, une fonction que remplit déja eval. Néanmoins, c'est un sujet que je considère comme plutot philosophique et j'aimerais avoir vos avis et en discuter.

    Berseker59
    • Partager sur Facebook
    • Partager sur Twitter
      25 août 2011 à 9:46:20

      Salut,

      De ce que j'en sais, le plus gros problème d'eval() est son temps d'exécution. Mais si ta calculatrice n'est que de l'ordre de l'exercice, tu n'a pas besoin de quelque chose de très puissant.

      Mais c'est sur que l'exemple typique d'utilisation d'eval() est une calculatrice !


      ps : j'adore le warning de jsbin avec l'eval xD

      Citation : JS Bin

      eval is evil.

      • Partager sur Facebook
      • Partager sur Twitter
        25 août 2011 à 12:43:56

        En terme de performances pures, la différence entre eval() et new Function() n'est pas évidente à quantifier. ça dépend du navigateur et de ce qui est parsé, et l'avantage va tantôt à l'un ou à l'autre, de peu ou de beaucoup... bref.

        L'utilisation que tu en fais est tout à fait raisonnable à mon sens, et je ne te vois pas t'amuser à identifier tout ce qui est calculs prioritaires etc. Coder une fonction simple pour parser des opérations de base se traduirait par un bond de performances, mais pas si tu réinventes les maths...
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          25 août 2011 à 13:22:59

          En ce qui concerne la sécurité de ce que tu passe dans eval, c'est assez simple : une simple expression régulière devrait suffire.

          Exemple pour des calculs basiques (non testé) :

          var calcul = '2 + 3 * (1 + 9)';
          
          if(calcul.match(new RegExp('^[0-9-/*+.,()\\s]+$', 'g'))) {
              try {
                  eval('var resultat = ' + calcul + ';');
                  alert('Résultat = ' + resultat);
              } catch(e) {
                  alert('Calcul incompréhensible !');
              }
          } else {
              alert('Caractères invalide dans le calcul !');
          }
          
          • Partager sur Facebook
          • Partager sur Twitter
            25 août 2011 à 17:56:26

            Salut, de ce que je vois, contrairement à ce que je pensait, je n'ai pas à préférer new Function() à eval() pour mon cas d'utilisation. Ca va être pas mal plus facile d'implémenter les fonctions trigonométriques avec eval().

            Pour ce qui est de la regexp, ca ne risque pas de devenir plutôt lent si je me retrouve a identifier les fonctions trigonométriques, les racines carrées, les logharithmes et tout ca ? Enfin, je ne vois pas les problèmes de sécurité possibles pour cette utilisation d'eval().

            Berseker59
            • Partager sur Facebook
            • Partager sur Twitter
              25 août 2011 à 18:54:05

              D'une manière général eval c'est le mal

              Mais dans ton cas, on trouve justement l'exception ou eval c'est ce qu'il faut utiliser (on peut toujours construire un parser à la main mais ça va être inutilement compliqué)
              Que tu utilises eval ou new Function, c'est exactement pareil car new Function fait appel à eval.

              Un des problèmes de eval c'est qu'on peut exécuter n'importe quel code javascript. Du coup si un utilisateur arrive à transmettre un code à exécuter sur ton site à un autre utilisateur (que ce soit via ton site, via email, ou via un autre moyen), il pourra faire plein de choses pas très honnête à celui-ci. Alors que ce dernier croyait être bien tranquille sur ton site (c'est ce qu'on appelle une faille XSS).

              Donc pour éviter cette faille, il est préférable de vérifier que la chaine qui sera évaluer ne contient pas de code malveillant.
              Une manière de faire et de n'autoriser que les caractères utiles pour tes calculs (comme le montre sebcap26 en n'autorisant que les nombres et les opérateurs de base).
              Oui cela va ralentir un peu ton calcul mais cela devrait rester marginal.

              Pour autoriser les fonctions trigo je remplacerai tous les mots que tu souhaites utiliser par un caractère spécial avant de vérifier ta chaine (mais ce n'est pas cette chaine que tu évalueras)
              Ça donnerai un truc dans le genre:
              var calcul = '2 + 3 * (1 + 9) + PI';
              
              if(calcul.replace(/cos\(|sin\(|tan\(|PI/gi,"+").match(/^[-0-9/*+.,()%\s]+$/))) { //vérification tous les mots acceptés ont été préalablement remplacé par +
                  calcul=calcul.replace(/(cos\(|sin\(|tan\(|PI)/gi,"Math.$1"); //remplacement des noms trigo par leur équivalent javascript cos-> Math.cos
                  try {
                      eval('var resultat = ' + calcul + ';');
                      alert('Résultat = ' + resultat);
                  } catch(e) {
                      alert('Calcul incompréhensible !');
                  }
              } else {
                  alert('Caractères invalide dans le calcul !');
              }
              
              • Partager sur Facebook
              • Partager sur Twitter
                25 août 2011 à 19:20:13

                http://ariya.ofilabs.com/2011/08/math- [...] pt-part1.html
                https://github.com/DmitrySoshnikov/Ess [...] c/lesson-1.js
                Si tu veux apprendre a parser.
                Mais si ton but c'est juste de faire une calculatrice, eval est tres bien, si tu l'utilise avec les verifications qui vont bien.
                • Partager sur Facebook
                • Partager sur Twitter

                [Discussion] Eval, oui ou non ?

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown