summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2017-05-29 15:20:35 -0300
committerRenato Botelho <renato@netgate.com>2017-05-29 15:20:35 -0300
commit7c2ca1543c5e0776711ae53e9c3e83224ac592ad (patch)
treedeed43ebc7fc82796bf559ce5afd3ce55a9192dc /src
parentd4d9aa66acb336eb5a8fd1a13e9afbada5758bb0 (diff)
parentff4e29fb9d048162f0d4d28b0c3e818ed2c1fd8e (diff)
downloadpfsense-7c2ca1543c5e0776711ae53e9c3e83224ac592ad.zip
pfsense-7c2ca1543c5e0776711ae53e9c3e83224ac592ad.tar.gz
Merge pull request #3740 from stilez/patch-59
Diffstat (limited to 'src')
-rw-r--r--src/etc/inc/config.lib.inc3
-rw-r--r--src/etc/inc/globals.inc1
-rwxr-xr-xsrc/usr/local/www/diag_command.php71
3 files changed, 62 insertions, 13 deletions
diff --git a/src/etc/inc/config.lib.inc b/src/etc/inc/config.lib.inc
index 40c3150..b1174fa 100644
--- a/src/etc/inc/config.lib.inc
+++ b/src/etc/inc/config.lib.inc
@@ -908,7 +908,8 @@ function pfSense_clear_globals() {
$error = error_get_last();
- if ($error !== NULL) {
+ // Errors generated by user code (diag_commands.php) are identified by path and not added to notices
+ if ($error !== NULL && !preg_match('^' . $g['tmp_path_user_code'] . '/[^/]{1,16}$', $error['file'])) {
if (in_array($error['type'], array(E_ERROR, E_COMPILE_ERROR, E_CORE_ERROR, E_RECOVERABLE_ERROR))) {
$errorstr = "PHP ERROR: Type: {$error['type']}, File: {$error['file']}, Line: {$error['line']}, Message: {$error['message']}";
print($errorstr);
diff --git a/src/etc/inc/globals.inc b/src/etc/inc/globals.inc
index 9166421..c4533d8 100644
--- a/src/etc/inc/globals.inc
+++ b/src/etc/inc/globals.inc
@@ -50,6 +50,7 @@ $g = array(
"varlog_path" => "/var/log",
"etc_path" => "/etc",
"tmp_path" => "/tmp",
+ "tmp_path_user_code" => "/tmp/user_code",
"conf_path" => "/conf",
"conf_default_path" => "/conf.default",
"cf_path" => "/cf",
diff --git a/src/usr/local/www/diag_command.php b/src/usr/local/www/diag_command.php
index bac4848..6e4e78e 100755
--- a/src/usr/local/www/diag_command.php
+++ b/src/usr/local/www/diag_command.php
@@ -255,34 +255,81 @@ if ($_POST['submit'] == "EXEC" && !isBlank($_POST['txtCommand'])):?>
</div>
</div>
<?php
+
// Experimental version. Writes the user's php code to a file and executes it via a new instance of PHP
// This is intended to prevent bad code from breaking the GUI
if ($_POST['submit'] == "EXECPHP" && !isBlank($_POST['txtPHPCommand'])) {
- puts("<div class=\"panel panel-success responsive\"><div class=\"panel-heading\"><h2 class=\"panel-title\">PHP Response</h2></div>");
- $tmpname = tempnam("/tmp", "");
- $phpfile = fopen($tmpname, "w");
- fwrite($phpfile, "<?php\n");
- fwrite($phpfile, "require_once(\"/etc/inc/config.inc\");\n");
- fwrite($phpfile, "require_once(\"/etc/inc/functions.inc\");\n\n");
- fwrite($phpfile, $_POST['txtPHPCommand'] . "\n");
- fwrite($phpfile, "?>\n");
- fclose($phpfile);
+ safe_mkdir($g[tmp_path_user_code]); //create if doesn't exist
+ $tmpfile = tempnam($g[tmp_path_user_code], "");
+ $phpcode = <<<END_FILE
+<?php
+require_once("/etc/inc/config.inc");
+require_once("/etc/inc/functions.inc");
- $output = array();
- exec("/usr/local/bin/php -d log_errors=off " . $tmpname, $output);
+// USER CODE STARTS HERE:
- unlink($tmpname);
+%s
+?>
+END_FILE;
+ $lineno_correction = 6; // line numbering correction, this should be the number of lines added above, BEFORE the user's code
+
+ file_put_contents($tmpfile, sprintf($phpcode, $_POST['txtPHPCommand']));
+
+ $output = $matches = array();
+ $retval = 0;
+ exec("/usr/local/bin/php -d log_errors=off {$tmpfile}", $output, $retval);
+
+ puts('<div class="panel panel-success responsive"><div class="panel-heading"><h2 class="panel-title">PHP Response</h2></div>');
+
+ // Help user to find bad code line, if it gave an error
+ $errmsg_found = preg_match("`error.*:.* (?:in|File:) {$tmpfile}(?:\(| on line |, Line: )(\d+)(?:, Message:|\).* eval\(\)'d code|$)`i", implode("\n", $output), $matches);
+ if ($retval || $errmsg_found) {
+ /* Trap failed code - test both retval and output message
+ * Typical messages as at 2.3.x:
+ * "Parse error: syntax error, ERR_DETAILS in FILE on line NN"
+ * "PHP ERROR: Type: NN, File: FILE, Line: NN, Message: ERR_DETAILS"
+ * "Parse error: syntax error, unexpected end of file in FILE(NN) : eval()'d code on line 1" [the number in (..) is the error line]
+ */
+ if ($matches[1] > $lineno_correction) {
+ $errline = $matches[1] - $lineno_correction;
+ $errtext = sprintf(gettext('Line %s appears to have generated an error, and has been highlighted. The full response is below.'), $errline);
+ } else {
+ $errline = -1;
+ $errtext = gettext('The code appears to have generated an error, but the line responsible cannot be identified. The full response is below.');
+ }
+ $errtext .= '<br/>' . sprintf(gettext('Note that the line number in the full PHP response will be %s lines too large. Nested code and eval() errors may incorrectly point to "line 1".'), $lineno_correction);
+ $syntax_output = array();
+ $html = "";
+ exec("/usr/local/bin/php -s -d log_errors=off {$tmpfile}", $syntax_output);
+ // Lines 0, 2 and 3 are CSS wrapper for the syntax highlighted code which is at line 1 <br> separated.
+ $syntax_output = explode("<br />", $syntax_output[1]);
+ $margin_layout = '%3s %' . strlen(count($syntax_output)) . 'd:';
+ for ($lineno = 1; $lineno < count($syntax_output) - $lineno_correction; $lineno++) {
+ $margin = str_replace(' ', '&nbsp;', sprintf($margin_layout, ($lineno == $errline ? '&gt;&gt;&gt;' : ''), $lineno));
+ $html .= "<span style='color:black;backgroundcolor:lightgrey'><tt>{$margin}</tt></span>&nbsp;&nbsp;{$syntax_output[$lineno + $lineno_correction - 1]}<br/>\n";
+ }
+ print_info_box($errtext, 'danger');
+ print "<div style='margin:20px'><b>" . gettext("Error locator:") . "</b>\n";
+ print "<div id='errdiv' style='height:7em; width:60%; overflow:auto; white-space: nowrap; border:darkgrey solid 1px; margin-top: 20px'>\n";
+ print $html . "\n</div></div>\n";
+ }
$output = implode("\n", $output);
print("<pre>" . htmlspecialchars($output) . "</pre>");
// echo eval($_POST['txtPHPCommand']);
+
puts("</div>");
+
+ unlink($tmpfile);
?>
<script type="text/javascript">
//<![CDATA[
events.push(function() {
+ // scroll error locator if needed (does nothing if no error)
+ $('#errdiv').scrollTop(<?=max($errline - ($lineno_correction - 3.5), 0);?> * parseFloat($('#errdiv').css('line-height')));
+
// Scroll to the bottom of the page to more easily see the results of a PHP exec command
$("html, body").animate({ scrollTop: $(document).height() }, 1000);
});
OpenPOWER on IntegriCloud