Thomas J.S.: warum wird eval() so verpönnt?

Hallo,

man wird - hier auch - immer wieder darauf hingewisen, dass "eval() ist evil!".
Das möchte ich hinterfragen. Warum soll eval() so "böse" sein?

z.B.
Ich kann so eine Schleife haben:

for(i=0; i < arrSubMenu.length; i++ )
{
if(arrSubMenu[i] == strSubID)
 {
 eval(arrSubMenu[i] + ".style.backgroundColor = '#e3e3e3'");
 eval(arrSubMenu[i] + ".style.fontWeight = 'bold'");
 ...
 }
else
 {
 eval(arrSubMenu[i] + ".style.backgroundColor = '#F5F7F4'");
 eval(arrSubMenu[i] + ".style.fontWeight = 'normal'");
 ...
 }
}

Aber es geht auch so:
for(i=0; i < arrSubMenu.length; i++ )
{
with(document.all(arrSubMenu[i]).style)
 {
 if(arrSubMenu[i] == strSubID)
  {
  backgroundColor = "#e3e3e3";
  fontWeight = "bold";
                ...
  }
 else
  {
  backgroundColor = "#F5F7F4";
  fontWeight = "normal";
                ...
  }
 }
}

Was ist der wirkliche Unterschied? (und ich meine jetzt nicht die Tatsache, dass ich der zweiten Version mehrere Anweisungen an einem Objekt knüpfen kann)
Gibt es (wirklich) einen Performanceunterschied?
Warum ist also eval() böse?

Grüße
Thomas

  1. Hallo Thomas,

    Gibt es (wirklich) einen Performanceunterschied?

    Ja.
    eval() ist deutlich langsamer und verleitet schnell dazu,
    unsicheren Code zu schreiben. Nun ist das bei JS vielleicht nicht
    das wichtigste Thema, aber was man in JS anfaengt uebertraegt man
    auch auf andere Sprachen.

    Im Informatik-Studium wird einem ausserdem beigebracht, dass eval()
    Spagetthi-Code ergibt. Das finde ich uebertrieben, das kann durchaus
    auch zutreffen, ist aber nicht zwingend so.

    Grüße,
     CK

    --
    Der Mund ist das Portal zum Unglück.
    http://wwwtech.de/
  2. Hallo.

    Was ist der wirkliche Unterschied? (und ich meine jetzt nicht die Tatsache, dass ich der zweiten Version mehrere Anweisungen an einem Objekt knüpfen kann)
    Gibt es (wirklich) einen Performanceunterschied?
    Warum ist also eval() böse?

    Die selbe Frage habe ich auch mal gestellt (nur nicht als eigener Thread).
    Und hier die Antwort von Struppi darauf:
    </archiv/2004/7/84641/#m496808>

    Schönen Tag noch, H2O

    --
    #*~!:     Endlich Ferien.
    Selfcode: ie:% fl:| br:^ va:| ls:# fo:) rl:? n4:| ss:{ de:] js:) ch:? sh:( mo:? zu:|
    Infos:    http://emmanuel.dammerer.at/selfcode.html
    1. Hallo,

      Warum ist also eval() böse?

      Die selbe Frage habe ich auch mal gestellt (nur nicht als eigener Thread).
      Und hier die Antwort von Struppi darauf:
      </archiv/2004/7/84641/#m496808>

      Die drei Antworten lauteten:
      »»1. langsam
      Das war auch meine Frage, aber ich konnte da keinen signifikanten Unterschied feststellen, deshalb auch die Nachfrage. Und die beantwortete Struppis Antwort nicht.

      1. Überflüssig

      Das ist ein Argument. Deshalb "quälte" ich mich heute damit, evals zu eliminieren, aber ich fand nicht immer eine Alternative (wie z.B. das with() in meinem Bsp.).

      »»3. Fehlersuche
      Das stimmt so nicht. Es kommt auf den Fehler an, sowohl Wenkman (JS-Debugger von NS) als auch der Windows SriptDebugger von M$ melden in entsprechenden Zeilen den Fehler, aber wie gesagt: das kommt auf den Fehler an.

      Grüße
      Thomas

      1. Hallo.

        Entschuldige, wenn davon etwas nicht stimmt, aber lasse die Kritik bitte nicht an mir aus.
        Schließlich habe ich es nicht geschrieben. Ich gab dir nur einen Link zu Struppi's Posting.

        Dennoch Sorry, H2O

        --
        #*~!:     Endlich Ferien.
        Selfcode: ie:% fl:| br:^ va:| ls:# fo:) rl:? n4:| ss:{ de:] js:) ch:? sh:( mo:? zu:|
        Infos:    http://emmanuel.dammerer.at/selfcode.html
        1. Hallo,

          Entschuldige, wenn davon etwas nicht stimmt, aber lasse die Kritik bitte nicht an mir aus.

          So war es auch nicht gemeint.
          Damit wollte ich lediglich sagen, dass ich die Posting kannte und mich die Antworten dort nicht vollend überzeugt haben.

          Grüße
          Thomas

          PS: um so mehr: danke, dass du dir die Mühe gemacht hast, den Link für mich auszusuchen.

          1. Hallo.

            So war es auch nicht gemeint.

            Oh, dann habe ich nichts gesagt ;)

            Damit wollte ich lediglich sagen, dass ich die Posting kannte und mich die Antworten dort nicht vollend überzeugt haben.

            Ach so.

            PS: um so mehr: danke, dass du dir die Mühe gemacht hast, den Link für mich auszusuchen.

            Kein Problem.

            Schönen Abend, H2O

            --
            #*~!:     Endlich Ferien.
            Selfcode: ie:% fl:| br:^ va:| ls:# fo:) rl:? n4:| ss:{ de:] js:) ch:? sh:( mo:? zu:|
            Infos:    http://emmanuel.dammerer.at/selfcode.html
      2. Die drei Antworten lauteten:
        »»1. langsam
        Das war auch meine Frage, aber ich konnte da keinen signifikanten Unterschied feststellen, deshalb auch die Nachfrage. Und die beantwortete Struppis Antwort nicht.

        Probier's doch einfach selber mal aus!

        einfach vor deinem eval
        start = new Date();

        eval ist evil x 1000

        end = new Date();

        alert(end - start);

        Du wirst darauf kommen, das eval das Programm ca. 10x langsamer macht.

        1. Überflüssig
          Das ist ein Argument. Deshalb "quälte" ich mich heute damit, evals zu eliminieren, aber ich fand nicht immer eine Alternative (wie z.B. das with() in meinem Bsp.).

        Wisoe sollte with eine alternative sein?
        In deinem Fall ist einfach die richtige Verwendung die Alternative

        Mathiashat dir ja schon erklärt, dass das falsch ist:
         eval(arrSubMenu[i] + ".style.backgroundColor = '#e3e3e3'");

        »»3. Fehlersuche
        Das stimmt so nicht. Es kommt auf den Fehler an, sowohl Wenkman (JS-Debugger von NS) als auch der Windows SriptDebugger von M$ melden in entsprechenden Zeilen den Fehler, aber wie gesagt: das kommt auf den Fehler an.

        Naja, wenn du bei jeden kleinen Tippfehler erst den Debugger anwirst ist das ok, aber ziemlicher Aufwand um etwas überflüssiges zu benutzen, oder?

        Struppi.

        1. Hallo,

          Probier's doch einfach selber mal aus!
          Du wirst darauf kommen, das eval das Programm ca. 10x langsamer macht.

          Das das _so_ langsam ist, ist klar. Aber es ging mir halt um einen Zusammenhang. Aber die anderen Beispiele waren überzeugend. ;-)

          1. Überflüssig
            Das ist ein Argument. Deshalb "quälte" ich mich heute damit, evals zu eliminieren, aber ich fand nicht immer eine Alternative (wie z.B. das with() in meinem Bsp.).

          Wisoe sollte with eine alternative sein?
          In deinem Fall ist einfach die richtige Verwendung die Alternative

          Weil ich erst zu with() kam, als ich (eigentlich) evel() eliminieren wollte und nach einer Möglichkeit suchte den Code zu verkürzen. ;-)

          »»3. Fehlersuche
          Naja, wenn du bei jeden kleinen Tippfehler erst den Debugger anwirst ist das ok, aber ziemlicher Aufwand um etwas überflüssiges zu benutzen, oder?

          Ich muss ihn nicht anverwfen, der ist ständig "an" ;-)

          Grüße
          Thomas

  3. Hi,

    man wird - hier auch - immer wieder darauf hingewisen, dass "eval() ist evil!".
    Das möchte ich hinterfragen. Warum soll eval() so "böse" sein?

    Neben den genannten Gründen:
    es erschwert die Fehlersuche (wie sehr das der Fall ist, hängt natürlich auch von der Qualität des Interpreters ab).

    Hier mal ein Beispiel anhand von Javascript:

    <script type="text/javascript">
    //absichtlich fehlerhafter Code
    var bla = "alert('bla')";
    bla += "alert('bla')";
    eval(bla);
    </script>

    führt im IE dazu, daß noch nicht mal eine Fehlermeldung angezeigt wird, geschweige denn ein Alert.
    Es kommt auch nicht das Symbol in der Statuszeile, das normalerweise bei Scriptfehlern vorhanden ist.
    (ok, IE ist ja eh nicht der beste Browser zum Debuggen...)

    Opera zeigt in der Javascript-Konsole folgendes (auch kein Alert):

    Inline script thread
    Error:
    name: SyntaxError
    message: Syntax error in call to eval (line 1)
    alert('bla')alert('bla')
    ------------------^

    In Zeile 1 befindet sich aber kein Script, schon gar nicht ein eval-Aufruf.
    Bei einem einzigen eval ist ja noch rauszufinden, welches nun den Fehler verursacht hat.
    Aber bei mehreren wird es schon komplizierter.
    Die Zeile 1 kommt natürlich daher, daß im aktuellen Script (also dem Argument der eval-Funktion) in der ersten (und einzigen) Zeile der Fehler auftritt.

    Mozilla liefert folgende Ausgabe:
    Error: missing ; before statement
    Source File: http://localhost/eval.html
    Line: 15, Column: 12
    Source Code:
    alert('bla')alert('bla')
    ------------^
    immerhin, die Zeilennummer ist die des eval-Aufrufs, die markierte Stelle und die Fehlerursache (missing ;) ist richtig - dafür fehlt aber der Hinweis, das hier der Code innerhalb eines eval-Aufrufs den Fehler verursacht hat - auch nicht unbedingt hilfreich.

    (und nein, der Source File name ist natürlich kein Indiz für das eval - ich hätte die Datei auch blablubb nennen können)

    cu,
    Andreas

    --
    MudGuard? Siehe http://www.Mud-Guard.de/
    Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. Hallo Andreas,

      Danke für diese gute Analyse! ;-)

      Mozilla liefert folgende Ausgabe:
      Error: missing ; before statement
      Source File: http://localhost/eval.html
      Line: 15, Column: 12
      Source Code:
      alert('bla')alert('bla')
      ------------^
      immerhin, die Zeilennummer ist die des eval-Aufrufs, die markierte Stelle und die Fehlerursache (missing ;) ist richtig - dafür fehlt aber der Hinweis, das hier der Code innerhalb eines eval-Aufrufs den Fehler verursacht hat - auch nicht unbedingt hilfreich.

      Nun ja, deshalb habe ich gesagt, dass es auf den Fehler ankommt: gerade die Meldungen von Mozilla fand ich hilfreich, denn da wusste ich wo der Fehler ensteht und konnte eben nachvollziehen (vom "Source Code:...") wo genau was schief ging.

      Aber deine Argumente sind durchwegs überzeugend.

      Grüße
      Thomas

  4. Hallo,

    man wird - hier auch - immer wieder darauf hingewisen, dass "eval() ist evil!".
    Das möchte ich hinterfragen. Warum soll eval() so "böse" sein?

    z.B.
    Ich kann so eine Schleife haben:

    for(i=0; i < arrSubMenu.length; i++ )
    {
    if(arrSubMenu[i] == strSubID)
    {
    eval(arrSubMenu[i] + ".style.backgroundColor = '#e3e3e3'");
    eval(arrSubMenu[i] + ".style.fontWeight = 'bold'");
    ...
    }
    else
    {
    eval(arrSubMenu[i] + ".style.backgroundColor = '#F5F7F4'");
    eval(arrSubMenu[i] + ".style.fontWeight = 'normal'");
    ...
    }
    }

    Hm, es schein, als stände in arrSubMenu[i] ein String, welcher eine ID repräsentieren soll. Damit kann
    eval(arrSubMenu[i] + ".style.backgroundColor = '#e3e3e3'");
    nur zufällig funktionieren, weil [ID].style nach keiner Regel die style-Eigenschaft eines HTML-Elementes ansprechen muss. Der Code ist also nicht nur evil, sondern falsch.

    Aber es geht auch so:
    for(i=0; i < arrSubMenu.length; i++ )
    {
    with(document.all(arrSubMenu[i]).style)
     {
     if(arrSubMenu[i] == strSubID)
      {
      backgroundColor = "#e3e3e3";
      fontWeight = "bold";
                    ...
      }
     else
      {
      backgroundColor = "#F5F7F4";
      fontWeight = "normal";
                    ...
      }
     }
    }

    Hm, das mit dem document.all meinst Du ernst?

    Aber es geht auch so:

    for(i=0; i < arrSubMenu.length; i++ )
     {
     if(arrSubMenu[i] == strSubID)
      {
      document.getElementById(arrSubMenu[i]).style.backgroundColor = "#e3e3e3";
      document.getElementById(arrSubMenu[i]).style.fontWeight = "bold";
      ...
      }
     else
      {
      document.getElementById(arrSubMenu[i]).style.backgroundColor = "#F5F7F4";
      document.getElementById(arrSubMenu[i]).style.fontWeight = "normal";
      ...
      }
     }

    Was ist der wirkliche Unterschied? (und ich meine jetzt nicht die Tatsache, dass ich der zweiten Version mehrere Anweisungen an einem Objekt knüpfen kann)

    Fragen wir doch mal anders herum:
    Nenne Gründe, die von mir vorgeschlagende Methode _nicht_ und statt dessen eval() zu nutzen. Das ist, meiner Meinung nach, die grundsätzliche Frage. Die Funktion eval() ist dafür gemacht, eine vom Nutzer als String eingegebene mathematische Funktion zu evaluieren, das ist ihre Funktion, nicht weiniger, aber auch nicht mehr.

    viele Grüße

    Axel

    1. Hi,

      Aber es geht auch so:

      for(i=0; i < arrSubMenu.length; i++ )
      {
      if(arrSubMenu[i] == strSubID)
        {
        document.getElementById(arrSubMenu[i]).style.backgroundColor = "#e3e3e3";
        document.getElementById(arrSubMenu[i]).style.fontWeight = "bold";
        ...
        }
      else
        {
        document.getElementById(arrSubMenu[i]).style.backgroundColor = "#F5F7F4";
        document.getElementById(arrSubMenu[i]).style.fontWeight = "normal";
        ...
        }
      }

      oder gar
      for(i=0; i < arrSubMenu.length; i++ )
      {
         var obj = document.getElementById(arrSubMenu[i]);
         if (obj != null)
         {
            if(arrSubMenu[i] == strSubID)
            {
               obj.style.backgroundColor = "#e3e3e3";
               obj.style.fontWeight = "bold";
               //...
            }
            else
            {
               obj.style.backgroundColor = "#F5F7F4";
               obj.style.fontWeight = "normal";
               //...
            }
         }
      }

      Das vermeidet das mehrfache Auswerten von document.getElementById - da wurde doch erst vor kurzem hier im Forum festgestellt, daß es "teuer" ist (und prüft auch noch, ob das Element mit der id überhaupt existiert).

      cu,
      Andreas

      --
      MudGuard? Siehe http://www.Mud-Guard.de/
      Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
      1. Hallo Andreas,

        Aber es geht auch so:
        oder gar

        Das ist gut ;-)
        Deshalb bin ich kein begeisterter JavaScripter, weil es keine "vernünftige" Syntax gibt ( zumindest keine die ich mögen könnnte).

        Das vermeidet das mehrfache Auswerten von document.getElementById - da wurde doch erst vor kurzem hier im Forum festgestellt, daß es "teuer" ist (und prüft auch noch, ob das Element mit der id überhaupt existiert).

        Ja, dass es prüft ob ein Element mit der ID gibt, habe ich auch schon feststellen dürfen (ich erzeuge das Array mit XSL und habe darin alle IDs gehabt im HTML-quelltext gab es aber nur die IDs wo das dazugehörige Element auch dargestellt werden durfte. Tja und da gabs immer gemeckere *g*)

        Danke und Grüße
        Thomas

    2. Hallo,

      Hm, es schein, als stände in arrSubMenu[i] ein String, welcher eine ID repräsentieren soll.

      Das ist richtig.

      Damit kann
      eval(arrSubMenu[i] + ".style.backgroundColor = '#e3e3e3'");
      nur zufällig funktionieren, weil [ID].style nach keiner Regel die style-Eigenschaft eines HTML-Elementes ansprechen muss.

      Sondern welche andere Eigenschaft?

      Der Code ist also nicht nur evil, sondern falsch.

      Hm ... das verstehe ich nicht. Er hat aber auf alle Fälle funktioniert ;-)

      Hm, das mit dem document.all meinst Du ernst?

      Ja.
      Ich muss die IEs extra berücksichtigen. Ein nur W3C-DOM variante wäre mir auch lieber.

      Aber es geht auch so:

      Habe ich auch gehabt.
      Hatte vorher das auch mit eval() gemacht, vor allem weil es auch noch Teile gibt wo ich ein "getElementById('abc_' + arrSubMenu[i]).style" brauche.
      Dann wollte ich eval() weghaben und gleichzeitig den Code etwas weniger redudant machen; deshalb with().

      Was ist der wirkliche Unterschied? (und ich meine jetzt nicht die Tatsache, dass ich der zweiten Version mehrere Anweisungen an einem Objekt knüpfen kann)
      Fragen wir doch mal anders herum:
      Nenne Gründe, die von mir vorgeschlagende Methode _nicht_ und statt dessen eval() zu nutzen.

      Nun ... kann ich nicht, aber genau deshalb habe ich nachgefragt ;-)

      Grüße
      Thomas

      1. Hi,

        Ich muss die IEs extra berücksichtigen. Ein nur W3C-DOM variante wäre mir auch lieber.

        Mußt Du IE 4.x auch berücksichtigen?
        Seit IE 5.0 kennt der IE auch getElementById().

        cu,
        Andreas

        --
        MudGuard? Siehe http://www.Mud-Guard.de/
        Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
        1. Hallo,

          Ich muss die IEs extra berücksichtigen. Ein nur W3C-DOM variante wäre mir auch lieber.

          Mußt Du IE 4.x auch berücksichtigen?
          Seit IE 5.0 kennt der IE auch getElementById().

          Es gibt IE auch auf dem Mac, aber das ist es nicht. In einigen Fällen muss ich immer wieder auf IE-sytanx zurückgreifen und da nützt ich das document.all. In diesem Bsp. könnte ich vermutlich darauf verzichten, aber ich muss das trotzdem erst austesten.

          Grüße
          Thomas

      2. Hallo,

        Damit kann
        eval(arrSubMenu[i] + ".style.backgroundColor = '#e3e3e3'");
        nur zufällig funktionieren, weil [ID].style nach keiner Regel die style-Eigenschaft eines HTML-Elementes ansprechen muss.

        Sondern welche andere Eigenschaft?

        Keine definierte.

        Gegeben sei folgendes HTML-P-Element, durch einen Tag beschrieben:
        ...
        <p id = "TestID">Test</p>
        ...
        Du versuchst mit JavaScript auf die style-Eigenschaft eines solchen Elementes zuzugreifen:
        ...
        TestID.style.backgroundColor = "#e3e3e3";
        ...
        Das ist _so_ nirgendwo beschrieben. Beschrieben ist:
        1. lt. DOM
        document.getElementById("TestID").style.backgroundColor = "#e3e3e3";
        2. für Browser, welche ein document.all-Objekt kennen:
        document.all["TestID"].style.backgroundColor = "#e3e3e3";
        mit allen alternativen Schreibweisen.

        Der Code ist also nicht nur evil, sondern falsch.
        Hm ... das verstehe ich nicht. Er hat aber auf alle Fälle funktioniert ;-)

        *g* Du kennst Cheatahs Meinung zu der Aussage: "Es muss ja richtig sein, weil es ja schließlich funktioniert."? Sie deckt sich mit meiner.

        viele Grüße

        Axel

        1. Hallo,

          TestID.style.backgroundColor = "#e3e3e3";
          ...
          Das ist _so_ nirgendwo beschrieben.

          Ah, ok danke für die Eklärung.

          Der Code ist also nicht nur evil, sondern falsch.
          Hm ... das verstehe ich nicht. Er hat aber auf alle Fälle funktioniert ;-)
          *g* Du kennst Cheatahs Meinung zu der Aussage: "Es muss ja richtig sein, weil es ja schließlich funktioniert."? Sie deckt sich mit meiner.

          Du meinst: "ah so, dann ist es ok" oder? ;-)
          Ich kann sehr pragmatisch sein: "haputsache es funktioniert" ;-)

          Grüße
          Thomas

  5. Hallo,

    man wird - hier auch - immer wieder darauf hingewisen, dass "eval() ist evil!".
    Das möchte ich hinterfragen. Warum soll eval() so "böse" sein?

    z.B.
    Ich kann so eine Schleife haben:

    for(i=0; i < arrSubMenu.length; i++ )
    {
    if(arrSubMenu[i] == strSubID)
     {
     eval(arrSubMenu[i] + ".style.backgroundColor = '#e3e3e3'");
    (...)

    Dazu sagtest du:

    (...) Deshalb "quälte" ich mich heute damit, evals zu eliminieren, aber ich fand nicht immer eine Alternative (wie z.B. das with() in meinem Bsp.)

    Was steht in den Arrayelementen von arrSubMenu eigentlich drin? Offenbar IDs, also Strings. Dann frage ich mich, wie dieser Code funktionieren kann. Lediglich MSIE und Opera und Kompatibilitätsgründen erlauben den Zugriff auf Element mit IDs über window.id (wenn also ein Element bspw. id="bla" hat, ist der Zugriff in JavaScript direkt über bla, also window.bla möglich).

    Ich verstehe nicht, wieso das eval() hier schwer zu ersetzen war? document.getElementById(arrSubMenu[i]) wäre bekanntermaßen die allgemeine Methode, mit der solche Aufgaben gelöst werden können. Selbst wenn man die eigensinnige MSIE-Syntax nimmt, wäre folgendes möglich:
    window[arrSubMenu[i]]
    document.all(arrSubMenu[i])
    document.all[arrSubMenu[i]]
    document.all.namedItem(arrSubMenu[i])
    Die sind für MSIE allesamt äquivalent.

    Zugegeben, die Methoden muss man natürlich kennen. Gemäß Microsoft ist all() bzw. namedItem() vorgesehen, daher sind diese Methoden auch im MSDN dokumentiert. (Sie sind ja weiterhin für MSIE 4 relevant.) Und die Äquivalenz von ID, window.ID und window['ID'] sowie die Äquivalenz von document.all.ID und document.all['ID'] ergibt sich aus ECMAScript.

    Hast du vielleicht noch andere Beispiele?

    Mathias

  6. Moin!

    man wird - hier auch - immer wieder darauf hingewisen, dass "eval() ist evil!".
    Das möchte ich hinterfragen. Warum soll eval() so "böse" sein?

    Wie anderweitig schon festgestellt wurde, hat eval() den in den meisten Fällen unnötigen Overhead, "Javascript in Javascript" zu sein, also zweimal den Interpreter anschmeißen zu müssen. Die Debug-Problematik wurde ebenfalls erwähnt. Performanter Code meidet mehrfache und in Schleifen vorkommende Aufrufe von eval() also ebenso stark, wie getElement(s)By(Id|Name|TagName), weil dies alles extrem lange dauert.

    Andererseits ist eval() eine extrem mächtige Funktion. Wie Christian Kruse schon ausführte: Wer eval() in Javascript leichtfertig einsetzt, der tut das vielleicht auch in PHP, Perl oder sonst einer Skriptsprache.

    Wie mächtig eval() ist, demonstrieren immer wieder Javascript-Webseitenverschlüsselungen. Na klar, ihre eigentliche Aufgabe, den Quellcode vor neugierigen und wissenden Augen zu verbergen, erfüllen sie nicht - aber dazu nutzen sie intensiv eval(). Eine mögliche Vorgehensweise ist, die Dekodierungsroutine (also eine komplette Funktion) mit urldecode() in einen String zu entschlüsseln und dann durch eval() überhaupt erst zu definieren.

    Das Beispiel in SELFHTML http://de.selfhtml.org/javascript/objekte/unabhaengig.htm#eval ist wirklich harmlos. Viel spannender ist z.B. dies hier (ich hab einfach mal irgendeine der angeblichen Copy-Protection-Tools genommen und dies aus dem Demo-Seitencode kopiert):

    <script>eval(unescape('%6b%3d%75%6e%65%73%63%61%70%65%28%22%25%30%44%25%30%41%22%29%3b%67%31%3d%20%63%6b%6a%28%6f%63%29%3b%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%67%31%29%3b%66%75%6e%63%74%69%6f%6e%20%63%6b%6a%28%73%29%20%7b%76%61%72%20%75%6e%3d%22%22%3b%6c%3d%73%2e%6c%65%6e%67%74%68%3b%6f%68%3d%4d%61%74%68%2e%72%6f%75%6e%64%28%6c%2f%32%29%3b%66%6f%72%28%69%3d%30%3b%69%3c%3d%6f%68%3b%69%2b%2b%29%7b%61%3d%73%2e%63%68%61%72%41%74%28%69%29%3b%62%3d%73%2e%63%68%61%72%41%74%28%69%2b%6f%68%29%3b%63%3d%61%2b%62%3b%75%6e%3d%75%6e%2b%63%3b%7d%3b%4c%3d%75%6e%2e%73%75%62%73%74%72%28%30%2c%6c%29%3b%4c%3d%4c%2e%72%65%70%6c%61%63%65%28%2f%60%2f%67%2c%22%27%22%29%3b%4c%3d%4c%2e%72%65%70%6c%61%63%65%28%2f%40%40%2f%67%2c%22%5c%5c%22%29%3b%66%20%3d%20%2f%71%67%2f%67%3b%4c%3d%4c%2e%72%65%70%6c%61%63%65%28%66%2c%6b%29%3b%72%65%74%75%72%6e%20%4c%3b%7d%3b'));</script>

    Nach der Funktion unescape() kommt raus:

    k=unescape("%0D%0A");g1= ckj(oc);document.write(g1);function ckj(s) {var un="";l=s.length;oh=Math.round(l/2);for(i=0;i<=oh;i++){a=s.charAt(i);b=s.charAt(i+oh);c=a+b;un=un+c;};L=un.substr(0,l);L=L.replace(/`/g,"'");L=L.replace(/@@/g,"\");f = /qg/g;L=L.replace(f,k);return L;};

    Übersichtlicher geschrieben:

    k=unescape("%0D%0A");
    g1= ckj(oc);
    document.write(g1);
    function ckj(s) {
      var un="";
      l=s.length;
      oh=Math.round(l/2);
      for(i=0;i<=oh;i++) {
        a=s.charAt(i);
        b=s.charAt(i+oh);
        c=a+b;
        un=un+c;
      };
      L=un.substr(0,l);
      L=L.replace(/`/g,"'");
      L=L.replace(/@@/g,"\");
      f = /qg/g;
      L=L.replace(f,k);
      return L;
    };

    Hier wird also sowohl die Funktion als auch ihr Aufruf innerhalb von eval() realisiert.

    In PHP kann man auf diese Weise mit eval() auch im laufenden Skript Funktionen definieren, die auch außerhalb von PHP gelten. Für Javascript nehme ich ähnliche Dinge an.

    Damit ist man aber sehr schnell bei selbstmodifizierendem Code! Und DER ist nun wirklich richtig eklig, nur was für echte Hacker, und auch nur was für hinreichend simple Aufgaben, wenn man nicht a) den Überblick verlieren und b) beim Debugging wahnsinnig werden will.

    Deshalb ist eval() böse - abgesehen davon, dass man eben in 99% aller Fälle ohne eval() auskommen kann.

    Zitat: "If eval() is the answer, you're almost certainly asking the
    wrong question." -- Rasmus Lerdorf, BDFL of PHP

    - Sven Rautenberg

    1. Hallo Sven,

      Wie mächtig eval() ist, demonstrieren immer wieder Javascript-Webseitenverschlüsselungen. [...]

      Viel spannender ist z.B. dies hier (ich hab einfach mal irgendeine der angeblichen Copy-Protection-Tools genommen und dies aus dem Demo-Seitencode kopiert):

      Hier wird also sowohl die Funktion als auch ihr Aufruf innerhalb von eval() realisiert.

      Danke, das ist überzeugend für die Mächtigkeit und Einsatzmöglichkeiten von eval().

      Deshalb ist eval() böse - abgesehen davon, dass man eben in 99% aller Fälle ohne eval() auskommen kann.

      Das wurde ja schon immer gesagt und ich wollte dafür die Begründung kennen, und es wurden einige sehr gute Argumente hier im Thread dazu gelifert.

      Danke auch dir
      Thomas