kostenloser Webspace werbefrei: lima-city


eval Fehlerausgabe

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. k**********e

    ne einfache function ist mir da noch net bekannt,
    aber vllt hilft ja outputcontoll weiter...

    $test = 'print "was"';
    
    ob_start();
    eval ($test);
    $e = ob_get_contents();
    
    if ( (strpos($e, 'Parse error') !== FALSE) || (strpos($e, 'Fatal error') !== FALSE) )
    	ob_end_clean();
    else 
    	ob_end_flush();
    
    $test = 'print "was";';
    
    ob_start();
    eval ($test);
    $e = ob_get_contents();
    
    if ( (strpos($e, 'Parse error') !== FALSE) || (strpos($e, 'Fatal error') !== FALSE) )
    	ob_end_clean();
    else 
    	ob_end_flush();

    so als kleiner anreiz....

    ansonsten ein komplexes regex ...^^

    Beitrag ge?ndert am 9.01.2006 01:55 von kirschbluete
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage


  3. Ich mache gerade ein paar Versuche mit der Funktion eval().


    Sei aber sehr vorsichtig mit der Funktion.
    Denn duch sie k?nnen sehr schnell Sicherheitsl?cken entstehen.

    Jens
  4. Was problematisch ist, ist das Code, der durch eval() ausgef?hrt wird, l?nger braucht, weil er ja eben erst durch den PHP-Parser muss.

    Ich w?rde mal nach einem Mathe-Formel-Parser googeln, vielleicht gibts sowas schon fertig ...


    @jacr

    Sicherheitsproblem? Wo?
    Doch nur, wenn der Code im eval()-String von "au?en" kommt. Bei mathematischen Formel kann man das aber ausschlie?en, indem man die Eingabe auf bestimmte Zeichen beschr?nkt. Allerdings k?nnte das im Extremfall auch auf eine Art Parser hinauslaufen ...

    @ttobsen

    Die eleganteste Art, den Parsing-Fehler von eval() abzufangen, ist, sich einen eigenen Error-Handler zu schreiben.

    Der wird dann vor eval() aufgerufen, und nach eval() wird der alte Error-Handler wieder hergestellt. Dass man so was f?r eval() braucht, hab ich noch nicht vorausgesehen, aber f?r regul?re Ausdr?cke (PCRE) hab ich sowas schon gebaut

    function foxy_preg_check_syntax(
      $regex = FALSE
    ) {
      if($regex === FALSE) return(FALSE);
      $eh = set_error_handler('foxy_preg_check_syntax_error_handler');
      $rcx = '';
      ob_start();
      preg_match($regex, EMPTY_STRING);
      $rcx = ob_get_clean();
      // Error-Handler wieder zurueckstellen
      if($eh == EMPTY_STRING) restore_error_handler(); // Normalfall
      else set_error_handler($eh); // falls anderer E-Handler definiert war;
    
      if($rcx === EMPTY_STRING) return(TRUE);
    
      //printf("__rcx(%b)(%s)__<br />", $rcx, $rcx );
    
      return(FALSE);
    }
    /*
    Supportfunktion f?r foxy_preg_check_syntax()
    Hierbei handelt es sich um einen PHP-Error-Handler.
    */
    function foxy_preg_check_syntax_error_handler(
      $error_code = FALSE,
      $error_string = FALSE
    ) {
      if($error_code === FALSE) return;
      if($error_string === FALSE) return;
      print('['.$error_code.']['.$error_string.']');
      return;
    }


    Wer den Code nachvollziehen kann, braucht eigentlich lediglich die Zeile mit preg_match() gegen eine mit eval() auszutauschen ...

    Viel Spa?! :wink:

  5. alopex schrieb:
    @jacr

    Sicherheitsproblem? Wo?
    Doch nur, wenn der Code im eval()-String von 'au?en' kommt. Bei mathematischen Formel kann man das aber ausschlie?en, indem man die Eingabe auf bestimmte Zeichen beschr?nkt.


    Genau das ist der Fall. Der User gibt die Formel ein. Das mit dem beschr?nken auf bestimmte Zeichen mu? ich dann auf alle F?lle wohl einbauen.

    Was w?re da wieder die eleganteste Methode, wenn ich zum Beispiel in ein Array schreibe:

    $ErlaubteTeile = array("+", "-", "*", "/", "%", "sin", "cos", ...);


    Du hast ja erkannt, was ich meinte. ;)
    Es spricht nichts die Eval-Funktion zu benutzen.
    Aber man muss da aufpassen was man macht.
    Das Verbieten von Zeichen ist so eine Sache.

    Lass mich jetzt mal ?berlegen, ob ich was falsches sage.
    Mann m?sste folgende Zeichen L?schen:
    '"$(
    Wenn man dies Zeichen l?scht, dann m?sste nichts schlimmes passieren k?nnen. Aber so ganz sicher bin ich mir da nicht.
    Also eine echo Ausgabe w?rde man so noch immer hin bekommen. Aber mehr vermutlich nicht.

    Jens
  6. ?hm, Sicherheit geht genau andersherum:

    Nicht: verbieten, was sch?dlich sein k?nnte.
    Sondern: nur erlauben, was nicht sch?dlich ist.

    Insofern finde ich ttobsen's Ansatz besser: Nur die Zeichen durchlassen, die man f?r Formeln benutzen darf. Und das Dollarzeichen braucht man da schonmal nicht.

    Mal was anderes: Ich bin zwar kein Fan von JavaScript, aber hier gibts 'nen sch?nen "Taschenrechner", der per Formular eingegebene "Formeln" berechnen kann. Das Sicherheits-Risiko bleibt beim Benutzer (also sch?n weit weg vom Server):

    http://de.selfhtml.org/javascript/beispiele/taschenrechner.htm

    Das Script nutzt ?brigens auch eval(), allerdings funktioniert die JavaScript-Variante anders.

    Trials and Googelations:

    http://lists.phpbar.de/pipermail/php/Week-of-Mon-20040202/006076.html

    http://forum.de.selfhtml.org/archiv/2004/5/t81682/

    ?hm, ...
    http://www.brian-schroeder.de/parser/#source_php

    Eventuell auch das:
    http://pear.php.net/package/Math_RPN

    Beitrag ge?ndert am 9.01.2006 19:24 von alopex
  7. Machs doch so:

    Erst auf unerlaubte Zeichen pr?fen und wenn keine drin sind, dann das:
    $ergebnis = false;
    @eval('$ergebnis = '.$eingabe.';');
    if ($ergebnis == false) {
      echo "Fehlerhafte Eingabe.";
    }
    else {
      echo 'Ergebnis: '.$ergbnis;
    }


    Beitrag ge?ndert am 9.01.2006 19:59 von phattek

  8. Machs doch so:

    Erst auf unerlaubte Zeichen pr?fen und wenn keine drin sind, dann das:
    $ergebnis = false;
    @eval('$ergebnis = '.$eingabe.';');
    if ($ergebnis == false) {
      echo "Fehlerhafte Eingabe.";
    }
    else {
      echo 'Ergebnis: '.$ergbnis;
    }


    Beitrag ge?ndert am 9.01.2006 19:59 von phattek

    ?hm ja. Mach das mal bitte. Am Besten auf denem Root Server, dann habe ich kostenlosen Space und noch ein paar andere Leute auch. :P

    Was passiert wenn jemand f?r $eingabe folgendes eingibt :
    1+1; echo file_get_contents ( 'config.php' );

    So k?nnte man eigene Dateien auf den Server schreiben etc.




    ttobsen schrieb:
    jacr schrieb:
    Lass mich jetzt mal ?berlegen, ob ich was falsches sage.
    Mann m?sste folgende Zeichen L?schen:
    ''$(
    Jens


    Naja, f?r meine Matheformeln ben?tige ich auf alle F?lle das ( Zeichen.

    Aber nicht das ";". Das w?re sinnvoll noch rauszuhauen. Wenn man es nicht wie alopex macht, was ich vorschlagen w?rde.


    @Phattek: Die MEthode werde ich mal durchgehen, allerdings wunder ich mich das diese Methode nicht schon fr?her angesprochen wurde,d aher denke ich mal wird ein Haken dran sein.

    Ricthig. ;-)


    @alopex:

    Naja Javascript w?rde ich gerne nicht verwenden. Gr?nde kannst du dir sicher denken.

    Das ist echt keine sch?ne L?sung. ^^


    Zum Thema Sicherheit:

    Also das ich pr?fe ob nur erlaubte Teile drin sind finde ich gut und sicher, aaaaaber wie pr?ft man einen String ob nur erlaubte Teile drinstehen? Da gibt es doch bestimmt wieder eine halbwegs fertige L?sung von PHP oder?

    Gru? Tobi

    Schreib am besten auf, welche Zeichen du brauchst.
    Also +, -, *, /, cos, sin, tan, pi...

    Ich w?re mir aber nicht sicher, ob es wirklich sicher ist, da man immer noch Kontanten etc. einschleusen k?nnte, wobei das wiederrum keine direkte Sicherheitsl?cke wer, aber etwas ungewolltest und dadurch entstehen Sicehrheitsl?cken....

    MfG Lucas


  9. Machs doch so:

    Erst auf unerlaubte Zeichen pr?fen und wenn keine drin sind, dann das:
    $ergebnis = false;
    @eval('$ergebnis = '.$eingabe.';');
    if ($ergebnis == false) {
      echo "Fehlerhafte Eingabe.";
    }
    else {
      echo 'Ergebnis: '.$ergbnis;
    }


    Beitrag ge?ndert am 9.01.2006 19:59 von phattek

    ?hm ja. Mach das mal bitte. Am Besten auf denem Root Server, dann habe ich kostenlosen Space und noch ein paar andere Leute auch. :P

    Was passiert wenn jemand f?r $eingabe folgendes eingibt :
    1+1; echo file_get_contents ( 'config.php' );

    So k?nnte man eigene Dateien auf den Server schreiben etc.


    Vielleicht mal lesen, was er davor noch geschrieben hat(ist oben Fett). ;)

    Also ich bin mir nicht sicher, ob es so gehen w?rde. Glaube es m?sste aber Funktionieren.

    P.S. alopex ich wei?, dass man das eigendlich andersrum mach. Dann m?sste man eine Parser machen und....
    Aber genau das wollte er ja nicht. ;)



    ttobsen schrieb:
    Zum Thema Sicherheit:

    Also das ich pr?fe ob nur erlaubte Teile drin sind finde ich gut und sicher, aaaaaber wie pr?ft man einen String ob nur erlaubte Teile drinstehen? Da gibt es doch bestimmt wieder eine halbwegs fertige L?sung von PHP oder?


    Ich w?rde es vielleicht so machen:
    preg_match_all("/\d|\*|\\|\+|\-|%|sin|cos|\(|\)/",$eingabe,$treffer);
    $eingabe=implode("", $treffer);

    Habe ich allerdings nicht getestet, wie ich mich kenne stimmt wieder mal was nicht im Regul?renausdruck. :D

    Jens

    Beitrag ge?ndert am 9.01.2006 22:40 von jacr

  10. Hi

    Ich wollte gerade die preg_match_all Methode verwenden, allerdings hab ich einen Fehler darin. Ich hab das Suchmuster mal vereinfacht zum testen da ich preg_match_all zum ersten mal verwende:

    <?php
    
    $term = "x";
    
    preg_match_all("/[a-z]/",$term,$treffer);
    
    echo implode("", $treffer);
    
    ?>


    Warum erhalte ich als Ausgabe nur das W?rtchen:

    array();

    $treffer[0] m?sste in diesem Beispiel doch den Buchstaben x enthalten. Demzufolge macht implode mir daraus den string x oder ?berseh ich hier gerade was?

    Gru? Tobi


    Nee, du ?bersiehst nichts.
    Ich aber.
    Habe jetzt mal was geschrieben, was ich auch getestet habe. :D

    <?
    $term = '222+111/23+ 2 * 3 - sin(3) %t hallo cos()';
    preg_match_all('$\d|\*|/|\+|\-|%|(sin)|cos|\(|\)$',$term,$treffer);
    $term=implode("", $treffer[0]);
    echo $term;
    ?>

    P.S. Das du preg_match_all zum ersten mal verwendest solltest du besser nicht alopex sagen :biggrin:

    Jens

    Beitrag ge?ndert am 10.01.2006 09:46 von jacr

  11. Ahh funzt doch gleich viel ebsser ;)

    Aber 2 Dinge hab ich noch nicht verstanden:

    1.) F?r was ist dieser Ausdruck gut: \d

    2.) Warum ist hier (sin) das Sinus in Klammern und bei cos keine Klammerung? (ich wette das nur eine von beiden Version da sein soll ;) )

    Gru? Tobi


    1. Steht f?r eine Zahl.
    2. Bei sin kannst die Klamma weg machen (habe ich vergessen).
    Die Klammer bewirkt ?brigens, dass sim auch in $treffer[1] rein kommt.
  12. @jacr und alle Mitlesenden:

    Zu sp?t, ich habs schon gelesen ... :wink:

    Aber mal ernsthaft: Eure regul?ren Ausdr?cke d?rften nicht wirklich n?tzlich sein, weil sie fast immer TRUE zur?ckgeben. Ich w?rde das ansatzweise so machen:

    '/\A([\s\d\+\-\*\/\%\(\)\,]|sin|cos|tan|pow|log)+\Z/'

    Ich bin mir zwar nicht ganz sicher, aber das d?rfte die meisten Mathe-Funktionen in PHP f?r Terme abdecken ...

    http://de.php.net/manual/de/ref.math.php

    Das Semikolon darf wegfallen, da man ja in PHP-Code f?r Matheformeln sowas nicht braucht. Es sei denn, es sollen Variablen verarbeitet werden und damit mehrere Sachen hintereinander ausgef?hrt werden. Dann w?re aber auch noch das Dollar-Zeichen n?tig ...

    Wichtig ist, dass der Anfang und das Ende mit im RegEx stehen, sonst sucht sich preg_match() einfach einen Teilstring, der passt -- und da d?rfte ziemlich oft was passen. Aber alles, was rechts oder links davon steht, wird dann einfach ignoriert -- das konnte dann der Schadens-Code sein.

    @lucas9991:

    Bitte schau mal nach, ob du einen Exploit daf?r basteln kannst.^^ W?rde mich echt mal interessieren, ob das geht ...

    @ttobsen:

    $term = "x";
    preg_match_all("/[a-z]/",$term,$treffer);
    echo implode("", $treffer);

    Wenn der RegEx valide ist, und trotzdem nicht das passiert, was ich mir w?nsche, mache ich immer das hier:

    print_r($treffer);

    Dann m?sste dein Code ein Array ausspucken, das so aussieht:

    Array
    (
    [0] => Array
    (
    [0] => x
    )
    )

    Woraus wir messerscharf schlussfolgern, dass dein Implode-Befehl ein Array-of-Arrays zusammengefasst hat, das gibt wieder ein Array und nicht etwa "x". Schau dir mal die Liste der Flags f?r preg_match_all() an. Damit kannst du n?mlich eine Menge am Treffer-Array ?ndern. Das ist fast so komplex wie die Regul?ren Ausdr?cke selbst.^^
  13. alopex du hast nicht wirklich verstanden, was ich mache.
    Und ich dachte du k?nntest PHP verstehen.:biggrin:

    Ich Pr?fe nicht, ob eine String gef?hrlich ist oder nicht.
    Ich wandle jeden String in eine 'harmlosen' String um.

    @ttobsen das w?re alopex umwandlungsvorschlag meines Regul?ren ausdrucks.
    '/[\d\+\-\*\/\%\(\)\,]|sin|cos|tan|pow|log/'
    Ich w?rde noch den Punkt benutzen. Dann kann man noch mit Kommazahlen rechen.

    Jens

    Beitrag ge?ndert am 10.01.2006 14:52 von jacr



  14. Machs doch so:

    Erst auf unerlaubte Zeichen pr?fen und wenn keine drin sind, dann das:
    $ergebnis = false;
    @eval('$ergebnis = '.$eingabe.';');
    if ($ergebnis == false) {
      echo "Fehlerhafte Eingabe.";
    }
    else {
      echo 'Ergebnis: '.$ergbnis;
    }


    Beitrag ge?ndert am 9.01.2006 19:59 von phattek

    ?hm ja. Mach das mal bitte. Am Besten auf denem Root Server, dann habe ich kostenlosen Space und noch ein paar andere Leute auch. :P

    Was passiert wenn jemand f?r $eingabe folgendes eingibt :
    1+1; echo file_get_contents ( 'config.php' );

    So k?nnte man eigene Dateien auf den Server schreiben etc.


    Vielleicht mal lesen, was er davor noch geschrieben hat(ist oben Fett). ;)

    Also ich bin mir nicht sicher, ob es so gehen w?rde. Glaube es m?sste aber Funktionieren.

    P.S. alopex ich wei?, dass man das eigendlich andersrum mach. Dann m?sste man eine Parser machen und....
    Aber genau das wollte er ja nicht. ;)


    [...]

    Mhpf, das habe ich tats?chlich ?berlesen.
    Ich dachte, dass der Code sein Vorschlag zur L?sung w?re, aber er wollte ja nur zeigen, wie man Fehlermeldungen bei eval () abf?ngt...

    alopex regul?re Ausdruck sieht hingegen schon ganz gut aus. ;-)

    MfG Lucas

  15. Man man man, ich bekomm grad Hilfe von den besten PHPlern hier im Forum *freude*

    Alsooooo:

    Das mit dem RegAusdruck von Alopex klappt prima. Ich erweitere allerdings das Muster um ein paar Funktionen die hier stehen:

    http://www.selfphp.de/funktionsreferenz/mathematische_funktionen/index.php

    (zum Beispiel acos, etc.)

    Kommas hab ich erst in Punkte umgewandelt. Macht alelrdings keinen Sinn da die funktion pow wieder Kommas ben?tigt. Naja, so schlimm ist das nicht.

    Die Fehelrabfrage funktioniert allerdings nicht, zumindest nicht so wie phattek es geschrieben hat:
    function GetValue($term, $x)
    {
    	$y = false;
    	$CompleteTerm = "\$y=".$term;
    	@eval($CompleteTerm);
    	if ($y == false)
    	{
    		return false;
    	}
    	return $y;
    }


    Das Problem ist hier allerdings das meine Funktion GetValue nicht false zur?ckgibt.

    Zur Funktionserkl?rung: $term ist die Funktiin die der User eingibt (darin ist als Variable das $x enthalten) und dieses $x ?bergib ich meiner Funktion.

    Das Problem ist wenn der User zum Beispiel sqrt(x) eingibt, dann ist dieser Bereich nunmal nicht definiert in der reelen Zahlenreihe. Ich erhalte aber einen R?ckgabewert von $y und kein false =(

    Jetzt bin ich am ?berlegen ob die anderen Methoden da nicht vielelicht auch evrsagen, da mit PHP nichtmal eine Warnung ausgibt, das ich die Wurzel aus negativen Zahlen nicht ziehen k?nnte.


    Was ein @ vor eine Funktion macht wei?t du anscheined noch nicht. ;)

    In ?brigen hast du ein ; Vergessen.
    Deshalb kam immer ein Fehler.

    Probier mal das:

    function GetValue($term, $x)

    {
    preg_match_all('/[\d\+\-\*\/\%\(\)\,\.]|sin|cos|tan|pow|log/',$term,$treffer);
    $term=implode("", $treffer[0]);
    $y = false;
    $CompleteTerm = '$y='.$term.';';
    @eval($CompleteTerm);
    if ($y == false)
    {
    return false;
    }
    return $y;
    }


    P.S. Wurde in Wiki4you aufgenommen. :D
    http://wiki4you.de/index.php/EvalMath.php


    Beitrag ge?ndert am 10.01.2006 15:34 von jacr

  16. Hi

    Das Semikolon ?bergeb ich schon an die Funktion, daher klappts im Gesamtscript.

    Ich dachte immer das @ Zeichen, unterdr?ckt eine Fehlermeldung, bzw. Warnmeldung.


    Ja, das macht das @ und darum kommen keine Warnmeldungen.


    Den preg_match Aufruf mach ich auch schon fr?her, funktioniert dort einwandfrei. Das einzigste Problem das ich noch hab ist dieses doofe eval. Wenn ich $y mit einem echo ausgebe steht da ein NAN. Vielleicht hilft das weiter.


    Was l?st du denn berechnen?
    NaN (Not a Number) steht in der Regel f?r eine nicht definierte Zahl.

    Ach ja.
    K?nnte ganz interessant f?r dich sein.
    http://www.twmagic.com/misc/evalmath.php

    Jens

  17. [...]
    function GetValue($term, $x)
    {
    	$y = false;
    	$CompleteTerm = "\$y=".$term;
    	@eval($CompleteTerm);
    	if ($y == false)
    	{
    		return false;
    	}
    	return $y;
    }

    [...]

    Schreib doch einfach :
    function GetValue ( $term, $x )
    {
      $y = false;
      $CompleteTerm = "\$result=".$term."\$y = true";
      @eval ( $CompleteTerm );
      if ( $y === false )
      { 
        return ( false );
      } else {
        return ( $resut );
      }
    }

    Ich hoffe das ist verst?ndlich und das ich nicht wieder was ?berlesen habe. xD

    MfG Lucas


  18. [...]
    function GetValue($term, $x)
    {
    	$y = false;
    	$CompleteTerm = "\$y=".$term;
    	@eval($CompleteTerm);
    	if ($y == false)
    	{
    		return false;
    	}
    	return $y;
    }

    [...]

    Schreib doch einfach :
    function GetValue ( $term, $x )
    {
      $y = false;
      $CompleteTerm = "\$result=".$term."\$y = true";
      @eval ( $CompleteTerm );
      if ( $y === false )
      { 
        return ( false );
      } else {
        return ( $resut );
      }
    }

    Ich hoffe das ist verst?ndlich und das ich nicht wieder was ?berlesen habe. xD

    MfG Lucas


    Daran ligt es nicht.
    Ttobsen l?st etwas berechen, was es nicht gibt.

    Jens
  19. Falls du den Term ?ber eine URL ?bergibst versuchs mal mit $term = stripslashes(urldecode($term));

    Edit: schreib mal vor @eval() einfach echo $CompleteTerm; und gucke, was da nicht stimmen kann.

    Beitrag ge?ndert am 10.01.2006 18:16 von phattek

    Beitrag ge?ndert am 10.01.2006 20:22 von phattek
  20. a**e


    Das PRoblem ist eifnach das eine nichtdefinierte Zahl berechnet wird in manchen F?llen (wie zum Beispiel Wurzel aus -1). Und diese F?lle m?cht ich abfangen.


    Wenn du negative Zahlen vermeiden willst, dann f?g doch folgendes hinzu:
    $zahl = $zahl*$zahl;
    $zahl = sqrt($zahl);


    du kannst aber auch mittels if pr?fen, ob der Wert kleiner als 0 ist und, wenn dies der Fall ist, mit -1 multiplizieren. Das bewirkt dann das gleiche.

    mfg
    Arve
  21. a**e

    Die Defizite bestehen nicht!!!
    Ich hatte mich ledeglich auf die negativen Zahlen bezogen.

    vielleicht geht das ja mit
    $i=0;
    $k=1234;
    
    if(($k/$i)==true)
    {
    echo "juhu";
    }


    edit: hattest du ja so gemacht....

    mfg
    Arve

    Beitrag ge?ndert am 10.01.2006 20:55 von arve
  22. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!