eval Fehlerausgabe
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
abs
beispiel
beitrag
buchstabe
eingabe
ergebnis
error
fehler
fehlerhafte eingabe
fehlermeldung
formel
funktion
log
mache
methode
sicherheit
stehen
term
test
wurzel
-
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 -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
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 -
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?! -
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 -
?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 -
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 -
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 -
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 -
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
Jens
Beitrag ge?ndert am 10.01.2006 09:46 von jacr -
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.
-
@jacr und alle Mitlesenden:
Zu sp?t, ich habs schon gelesen ...
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.^^ -
alopex du hast nicht wirklich verstanden, was ich mache.
Und ich dachte du k?nntest PHP verstehen.
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 -
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 -
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 -
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 -
[...]
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 -
[...]
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 -
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 -
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 -
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 -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage