0

What would be the best way to do this? I'm given a template with some things in it like {:HELLO-WORLD:} tags in it.

I'm also given an array like:

Array
(
[0] => Array
    (
        [Name] => {:HELLO-WORLD:}
        [Plugin] => "<?php return 'Hello World'; ?>"
        [Settings] => 
    )

)

What can I do to make sure {:HELLO-WORLD:} gets replaced with the output of Hello World?

I am currently attempting:

    private function PluginReplacer($arr, $str){
        $gsCt = count($arr);
        $kv = array();
        for ($i=0;$i<$gsCt;++$i){
            $kv[$arr[$i]['Name']] = $arr[$i]['Plugin'];
        }
        return str_replace(array_keys($kv), $this->EvalCode(array_values($kv)), $str);
    }

    // Eval Some Code
    private function EvalCode($var){
        require_once('plugins.php');
        $pr = new CloudCMSPluginRunner();
        $pr->Code = $var;
        $pr->SitePath = GetSiteAssetsPath($this->SiteID);
        $pr->RunIt();
        echo $pr->Error;
    }

<?php

class CloudCMSPluginRunner {

public $Code = '';
public $Error = '';
public $SitePath = '';
private $DoNotAllow = array('echo', 'eval', 'phpinfo', '/`/', 'chmod', 'chown', 'umask', 'shell_exec', 
                            'exec', 'escapeshellcmd', 'proc_open', 'proc_terminate', 'proc_get_status', 
                            'passthru', 'proc_nice', 'system', 'escapeshellarg', 'ob_start', 'ob_end_clean', 
                            'ob_get_clean', 'session_start', 'putenv', 'header', 'sleep', 'uwait', 'ini_set', 
                            'error_reporting', 'chgrp', 'basename', 'clearstatcache', 'copy', 'delete', 
                            'dirname', 'disk_free_space', 'disk_total_space', 'diskfreespace', 'fclose', 
                            'feof', 'fflush', 'fgetc', 'fgetcsv', 'fgets', 'fgetss', 'file_exists', 'file_get_contents', 
                            'file_put_contents', 'file', 'fileatime', 'filectime', 'filegroup', 'fileinode', 'filemtime', 
                            'fileowner', 'fileperms', 'filesize', 'filetype', 'flock', 'fnmatch', 'fopen', 'fpassthru', 
                            'fputcsv', 'fputs', 'fread', 'fscanf', 'fseek', 'fstat', 'ftell', 'ftruncate', 'fwrite', 'glob', 
                            'is_dir', 'is_executable', 'is_file', 'is_link', 'is_readable', 'is_uploaded_file', 'is_writeable', 
                            'is_writable', 'lchgrp', 'lchown', 'link', 'linkinfo', 'lstat', 'mkdir', 'move_uploaded_file', 
                            'parse_ini_file', 'parse_ini_string', 'pathinfo', 'pclose', 'popen', 'readfile', 'readlink', 
                            'realpath_cache_get', 'realpath_cache_size', 'realpath', 'rename', 'rewind', 'rmdir', 'set_file_buffer', 
                            'stat', 'symlink', 'tempnam', 'tmpfile', 'touch', 'unlink', 'chdir', 'chroot', 'closedir', 'dir', 
                            'getcwd', 'opendir', 'readdir', 'rewinddir', 'scandir', 'dio_close', 'dio_fcntl', 'dio_open', 'dio_read', 
                            'dio_seek', 'dio_stat', 'dio_tcsetattr', 'dio_truncate', 'dio_write', 'finfo_buffer', 'finfo_close', 
                            'finfo_file', 'finfo_open', 'finfo_set_flags', 'mime_content_type', 'inotify_add_watch', 'inotify_init', 
                            'inotify_queue_len', 'inotify_read', 'inotify_rm_watch', 'setproctitle', 'setthreadtitle', 'xattr_get', 
                            'xattr_list', 'xattr_remove', 'xattr_set', 'xattr_supported');

public function RunIt(){
    $valid = $this->CheckIt();
    if($valid){
        eval($this->Code);
    }else{
        // code is invalid
        $this->Error = 'The code in this plugin is invalid.';
        return null;    
    }
}

private function CheckIt(){
    $ret = false;
    ob_start(); // Catch potential parse error messages
    $code = eval('if(0){' . "\n" . $this->Code . "\n" . '}');
    ob_end_clean();
    $ret = ($code !== false);
    // run a check against the dissallowed
    $ret = (stripos($this->Code , $this->DoNotAllow) !== false);
    // make sure any path is there's and there's alone
    $ret = (stripos($this->Code , $this->SitePath) !== false);
    return $ret;
}

}

?>

But nothing is happenning... in fact the page I am attempting to run this on blanks out (meaning there is an error happenning)

Kevin
  • 2,684
  • 6
  • 35
  • 64
  • Have you looked in the server error logs to see what error's being reported? – andrewsi Jul 19 '13 at 15:58
  • I have, and nothing is being reported – Kevin Jul 19 '13 at 16:03
  • Have a look at http://stackoverflow.com/questions/845021/how-to-get-useful-error-messages-in-php - it'll show you how to get the error messages output to the screen while you're debugging. – andrewsi Jul 19 '13 at 16:06
  • Yes, thank you, that is already implemented, so back to the question at hand... I guess this is similar to what Wordpress does... quesion is, how dey do dat? – Kevin Jul 19 '13 at 17:39
  • I'd suggest switching your `eval(...` to `echo(...` and see what code you're actually generating. – andrewsi Jul 19 '13 at 17:43
  • here's one instance (different example code) `eval("function GetPageWeAreOn(){$p=explode('/',$_SERVER['REQUEST_URI']);return $p[1];}");` returns me an error: `Parse error: syntax error, unexpected '=', expecting '}' ` – Kevin Jul 19 '13 at 18:01
  • I'll add this as an answer; it's a little long for the comment box. – andrewsi Jul 19 '13 at 18:06

1 Answers1

0

You're generating code formatted as:

eval("function GetPageWeAreOn(){$p=explode('/',$_SERVER['REQUEST_URI']);return $p[1];}");

What's happening is that PHP is interpreting the variables wrongly - instead of passing them in to the eval'ed function, it's interpolating them first.

I've avoided the error by escaping them:

eval("function GetPageWeAreOn(){\$p=explode('/',\$_SERVER['REQUEST_URI']);return \$p[1];}");

You can avoid the need for escaping by putting your string to be eval'ed into single quotes, too - that doesn't try to interpolate variables:

eval('function GetPageWeAreOn(){$p=explode("/",$_SERVER["REQUEST_URI"]);return $p[1];}');
andrewsi
  • 10,807
  • 132
  • 35
  • 51