I have this function to validate command in php?
public function validate_command($command) {
if (isset($this->config->settings->guest_commands)) {
$commands = $this->config->settings->guest_commands;
} else {
$commands = array('echo', 'cat', 'ls', 'find', 'cd', 'grep', 'test', 'xargs');
}
$cmd_re = "(" . implode("|", array_diff($commands, array("xargs"))) . ")";
if (in_array("xargs", $commands)) {
$re = "/^\s*($cmd_re|xargs\s*$cmd_re)/";
} else {
$re = "/^\s*$cmd_re/";
}
$separators = "/(&&|\|\||\||;)/";
$parts = preg_split($separators, $command, null, PREG_SPLIT_DELIM_CAPTURE);
$result = array();
foreach ($parts as $part) {
if (!preg_match($re, trim($part)) && !preg_match($separators, $part)) {
$last = array_pop($commands);
$message = "guest user can only execute: " .
implode(", ", $commands) . " and " . $last;
throw new Exception($message);
} else if (preg_match('/(>|`|\$\()/', $part)) {
throw new Exception("guest user can't use redirect to write to files" .
" or execute subshell");
} else {
$result[] = $part;
}
}
return implode($result);
}
it splits command using:
$separators = "/(&&|\|\||\||;)/";
$parts = preg_split($separators, $command, null, PREG_SPLIT_DELIM_CAPTURE);
How can I make it work for commands like echo "©"
? it should return the same command but it throw exception.
Can I use single regex with look behind? How it should look like? It should work with cases like this:
echo "©\"©" && echo "©"
$parts
should have array('echo "©\"©"', '&&', 'echo "©"')
(the spaces around && or commands can be included)
I've try $separators = "/(?<*)(&&|\|\||\||;)/";
but got exception:
preg_split(): Compilation failed: lookbehind assertion is not fixed length at offset 24
Is iterating over the string the only option?