469,352 Members | 1,697 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,352 developers. It's quick & easy.

before eval(), how can one test a string to see if it is valid PHP code?

I have a string which I want to send to eval(). How can I test it
ahead of time to make sure it is valid code? I don't want to send it
to eval and get parse errors. I want to do something like this:

$valid = checkPHP($string);
if ($valid) {
eval($string);
} else {
$resultsObject->addToErrorResults("We wanted to send our
template to eval(), but the PHP it contained was invalid.");
}
Is there anything like checkPHP()?
Jul 17 '05 #1
12 7311
On 8 Mar 2004 15:31:16 -0800, lk******@geocities.com (lawrence) wrote:
I have a string which I want to send to eval(). How can I test it
ahead of time to make sure it is valid code? I don't want to send it
to eval and get parse errors. I want to do something like this:

$valid = checkPHP($string);
if ($valid) {
eval($string);
} else {
$resultsObject->addToErrorResults("We wanted to send our
template to eval(), but the PHP it contained was invalid.");
}
Is there anything like checkPHP()?


Pipe it through the command-line version of PHP with the -l flag?

--
Andy Hassall <an**@andyh.co.uk> / Space: disk usage analysis tool
<http://www.andyh.co.uk> / <http://www.andyhsoftware.co.uk/space>
Jul 17 '05 #2
Andy Hassall wrote:
On 8 Mar 2004 15:31:16 -0800, lk******@geocities.com (lawrence) wrote:

Is there anything like checkPHP()?


Pipe it through the command-line version of PHP with the -l flag?


Right!
But I prefer another name for the function :)

<?php
function is_validPHP($code) {
$code = escapeshellarg('<?php ' . $code . ' ?>');

$lint = `echo $code | php -l`; // command-line PHP

// maybe there are other messages for good code?
return (preg_match('/No syntax errors detected in -/', $lint));
}

# usage example
$code1 = '$xx=date("Y-m-d"); return $xx;';
if (is_validPHP($code1)) echo "code1 is valid PHP code\n";
else echo "code1 is invalid\n";

$code2 = '$xx=date("Y-m-d") return $xx;'; // no semicolon
if (is_validPHP($code2)) echo "code2 is valid PHP code\n";
else echo "code2 is invalid\n";

#################################
#### WARNING ####
#### DO NOT TRY THIS AT HOME ####
#################################

$code3 = '$dummy = `rm -rf ..`;'; // VALID CODE!!!!!!!
if (is_validPHP($code3)) echo "code3 is valid PHP code\n";
else echo "code3 is invalid\n";
?>
Output is:
code1 is valid PHP code
code2 is invalid
code3 is valid PHP code
--
--= my mail box only accepts =--
--= Content-Type: text/plain =--
--= Size below 10001 bytes =--
Jul 17 '05 #3
"Pedro Graca" <he****@hotpop.com> wrote in message
news:c2*************@ID-203069.news.uni-berlin.de...
#################################
#### WARNING ####
#### DO NOT TRY THIS AT HOME ####
#################################

$code3 = '$dummy = `rm -rf ..`;'; // VALID CODE!!!!!!!
if (is_validPHP($code3)) echo "code3 is valid PHP code\n";
else echo "code3 is invalid\n";
?>


However, please feel free to try it at work :)

And if you do, I also have a bridge for sale if you are interested.

--
Mike Bradley
http://www.gzentools.com -- free online php tools
Jul 17 '05 #4
CountScubula wrote:
"Pedro Graca" <he****@hotpop.com> wrote in message
news:c2*************@ID-203069.news.uni-berlin.de...
#################################
#### WARNING ####
#### DO NOT TRY THIS AT HOME ####
#################################

$code3 = '$dummy = `rm -rf ..`;'; // VALID CODE!!!!!!!
if (is_validPHP($code3)) echo "code3 is valid PHP code\n";
else echo "code3 is invalid\n";
?>
However, please feel free to try it at work :)
Well ... I did try that at home.

And if you do, I also have a bridge for sale if you are interested.
I think I'm entitled to a discount for the Brooklyn bridge :)
--
Mike Bradley
http://www.gzentools.com -- free online php tools


Hey Mike! Your sig is broken.
--
--= my mail box only accepts =--
--= Content-Type: text/plain =--
--= Size below 10001 bytes =--
Jul 17 '05 #5
Hi Lawrence,

I think there really ought to be a check() function that parses but does not
evaluate PHP code. But AFAIK there isn't.

Since the eval command is executing in the same environment as the rest of
the PHP code, when it returns an error and dies it affects the whole
environment. So, the workaround solution is to execute a sub-process to
evaluate the code and return the result to the main process. This can be
done using exec and command-line PHP:

<?PHP
$string1 = "php -r 'pint ('foo');'";
$string2 = "php -r 'print ('foo');'";
$result1 = exec($string1);
$result2 = exec($string2);
print $string1." returned: ".$result1."<br />\n";
print $string2." returned: ".$result2."<br />\n";
?>

From here you can probably create your checkPHP() function by grepping the
output for words like "Fatal error." Better would be if you know the
expected output to grep for that. Or maybe you can check the command-line
PHP exit status. Use the return_var for this.

Either way by spawning a sub-process to evaluate your code you are saved
from this affecting the main environment and therefore well on your way to a
solution.

Good luck.

Cheers,
Robert

On 3/8/04 3:31 PM, in article
da**************************@posting.google.com, "lawrence"
<lk******@geocities.com> wrote:
I have a string which I want to send to eval(). How can I test it
ahead of time to make sure it is valid code? I don't want to send it
to eval and get parse errors. I want to do something like this:

$valid = checkPHP($string);
if ($valid) {
eval($string);
} else {
$resultsObject->addToErrorResults("We wanted to send our
template to eval(), but the PHP it contained was invalid.");
}
Is there anything like checkPHP()?


Jul 17 '05 #6
I posted earlier but my messages are not getting through via Comcast.
Weird...

A parse error in eval() doesn't cause the running script to die, so
all you have to do is stick a @ in front of the call:

$php_errormsg = false;
$track_errors = ini_set('track_errors', 1);
@eval("How much wood would a woodchuck chuck if a wood chuck could
chuck
wood?");
ini_set('track_errors', $track_errors);

echo "Error: $php_errormsg";

A fatal error (e.g. call to undefined function) would still kill the
script,
however.
Pedro Graca <he****@hotpop.com> wrote in message news:<c2*************@ID-203069.news.uni-berlin.de>...
Andy Hassall wrote:
On 8 Mar 2004 15:31:16 -0800, lk******@geocities.com (lawrence) wrote:

Is there anything like checkPHP()?


Pipe it through the command-line version of PHP with the -l flag?


Right!
But I prefer another name for the function :)

<?php
function is_validPHP($code) {
$code = escapeshellarg('<?php ' . $code . ' ?>');

$lint = `echo $code | php -l`; // command-line PHP

// maybe there are other messages for good code?
return (preg_match('/No syntax errors detected in -/', $lint));
}

# usage example
$code1 = '$xx=date("Y-m-d"); return $xx;';
if (is_validPHP($code1)) echo "code1 is valid PHP code\n";
else echo "code1 is invalid\n";

$code2 = '$xx=date("Y-m-d") return $xx;'; // no semicolon
if (is_validPHP($code2)) echo "code2 is valid PHP code\n";
else echo "code2 is invalid\n";

#################################
#### WARNING ####
#### DO NOT TRY THIS AT HOME ####
#################################

$code3 = '$dummy = `rm -rf ..`;'; // VALID CODE!!!!!!!
if (is_validPHP($code3)) echo "code3 is valid PHP code\n";
else echo "code3 is invalid\n";
?>
Output is:
code1 is valid PHP code
code2 is invalid
code3 is valid PHP code

Jul 17 '05 #7
Pedro Graca <he****@hotpop.com> wrote in message news:<c2*************@ID-203069.news.uni-berlin.de>...
Andy Hassall wrote:
On 8 Mar 2004 15:31:16 -0800, lk******@geocities.com (lawrence) wrote:
Is there anything like checkPHP()?


Pipe it through the command-line version of PHP with the -l flag?


Right!
But I prefer another name for the function :)

<?php
function is_validPHP($code) {
$code = escapeshellarg('<?php ' . $code . ' ?>');

$lint = `echo $code | php -l`; // command-line PHP

// maybe there are other messages for good code?
return (preg_match('/No syntax errors detected in -/', $lint));
}


Thanks much. Sadly, it doesn't work for my purposes. I'm trying to
offer end-users the option of editing the template for the admin
control panel that runs their websites, but I'm pretty sure some of
them will screw it up and destroy the control panel. Even experienced
PHP programmers can make a simple gramatical mistake. So I'd love to
take the template and test it for mistakes and maybe do a roll back to
the previous version, before their changes, if there are errors.

I found that I can send ordinary HTML pages to eval() so long as I put
"?>" at the beginning. This lets eval() know that it is breaking out
of PHP and into normal HTML. This is how the system currently works on
the sites that are run with this software (www.alexmarshall.org, for
instance).

I'm trying to run it through here:

function renderControlPanelTemplate() {
$builtInControPanelTemplates =
$GLOBALS["builtInControPanelTemplates"];
$defaultTemplate = $builtInControPanelTemplates["misty"];
$end = "?";
$end .= ">";
$defaultTemplate = $end.$defaultTemplate;
if ($valid = is_valid($defaultTemplate)) {
eval($defaultTemplate);
} else {
echo "<h1>We tried to load the template for the control panel but it
was full of errors in its PHP.";
}
}

Would all be well if I change this line:
$code = escapeshellarg('<?php ' . $code . ' ?>');
to this:

$code = escapeshellarg(' $code ');

Jul 17 '05 #8
lawrence wrote:
Pedro Graca <he****@hotpop.com> wrote in message news:<c2*************@ID-203069.news.uni-berlin.de>... Would all be well if I change this line:
$code = escapeshellarg('<?php ' . $code . ' ?>');


to this:

$code = escapeshellarg(' $code ');


I think yes.

"eval($string)" start in PHP mode
"`php -l $string`" starts out of PHP mode

You just have to make sure you get into the right mode for whatever
instruction you're going to call.
--
--= my mail box only accepts =--
--= Content-Type: text/plain =--
--= Size below 10001 bytes =--
Jul 17 '05 #9
On 3/9/04 5:00 PM, in article
da**************************@posting.google.com, "lawrence"
<lk******@geocities.com> wrote:
Pedro Graca <he****@hotpop.com> wrote in message
news:<c2*************@ID-203069.news.uni-berlin.de>...
I'm trying to
offer end-users the option of editing the template for the admin
control panel that runs their websites, but I'm pretty sure some of
them will screw it up and destroy the control panel.


First of all, never allow end users the option of executing arbitrary code
on your system. Ever. There are a lot of things far worse a PHP error
message that can happen.

That said, I wrote the function for you. Since the php command line function
returns a non-zero (i.e. not 'clean') exit status for every error type
(fatal, parse, warning) that would also appear on your site via default PHP
error reporting, you can write the function this way:

<?PHP

function checkPHP($string) {
$string = escapeshellcmd($string);
exec("php -r \"$string\"",$output,$exit);
if($exit==0) return TRUE;
else return FALSE;
}

/* tests */
$test = array ("print ('foo');",
"print (\"foo\");",
"pint ('foo');",
"print ('foo);",
"print ('foo','bar');"
);

for($i=0;$i<sizeof($test);$i++) {
print $test[$i];
if(checkPHP($test[$i])) {
print " is ok.<br />\n";
} else {
print " not ok.<br />\n";
}
}

/* browser output:

print ('foo'); is ok.
print ("foo"); is ok.
pint ('foo'); not ok. <- fatal
print ('foo); not ok. <- parse
print ('foo','bar'); not ok. <- warning
*/
?>

Cheers,
Robert
--
Robert Peake | Peake Professional Consulting
Ro****@PeakePro.com | http://www.peakepro.com/

Jul 17 '05 #10
Robert Peake <ro****@peakepro.com> wrote in message
First of all, never allow end users the option of executing arbitrary code
on your system. Ever. There are a lot of things far worse a PHP error
message that can happen.
Thanks. They don't get to write arbitrary code. There are 500
functions they are allowed. The names of the functions are kept in an
array and a regex makes sure they only use the allowed functions.


That said, I wrote the function for you. Since the php command line function
returns a non-zero (i.e. not 'clean') exit status for every error type
(fatal, parse, warning) that would also appear on your site via default PHP
error reporting, you can write the function this way:
Thanks much for the rewrite.



<?PHP

function checkPHP($string) {
$string = escapeshellcmd($string);
exec("php -r \"$string\"",$output,$exit);
if($exit==0) return TRUE;
else return FALSE;
}

/* tests */
$test = array ("print ('foo');",
"print (\"foo\");",
"pint ('foo');",
"print ('foo);",
"print ('foo','bar');"
);

for($i=0;$i<sizeof($test);$i++) {
print $test[$i];
if(checkPHP($test[$i])) {
print " is ok.<br />\n";
} else {
print " not ok.<br />\n";
}
}

Jul 17 '05 #11
On 3/12/04 10:45 AM, in article
da**************************@posting.google.com, "lawrence"
<lk******@geocities.com> wrote:
Thanks. They don't get to write arbitrary code. There are 500
functions they are allowed. The names of the functions are kept in an
array and a regex makes sure they only use the allowed functions.


Interesting. I'm working on a project:

http://sourceforge.net/projects/simpletags/

To add a layer of abstraction to the Smarty template engine to make
customized skinning of sites very, very user friendly and system safe.
Sounds like there's a need for it.

Cheers,
Robert

--
Robert Peake | Peake Professional Consulting
Ro****@PeakePro.com | http://www.peakepro.com/

Jul 17 '05 #12
Robert Peake <ro****@peakepro.com> wrote in message news:<BC78EF0B.21BE%ro****@peakepro.com>...
On 3/12/04 10:45 AM, in article
da**************************@posting.google.com, "lawrence"
<lk******@geocities.com> wrote:
Thanks. They don't get to write arbitrary code. There are 500
functions they are allowed. The names of the functions are kept in an
array and a regex makes sure they only use the allowed functions.


Interesting. I'm working on a project:

http://sourceforge.net/projects/simpletags/

To add a layer of abstraction to the Smarty template engine to make
customized skinning of sites very, very user friendly and system safe.
Sounds like there's a need for it.

Could you expand on this, in English, and then maybe give an example?
I don't know much smarty, but I'm curious.
Jul 17 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

12 posts views Thread by Kamilche | last post: by
9 posts views Thread by HikksNotAtHome | last post: by
3 posts views Thread by McKirahan | last post: by
9 posts views Thread by Mike | last post: by
15 posts views Thread by manstey | last post: by
7 posts views Thread by Darko | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.