diff options
author | Renato Botelho <renato@netgate.com> | 2017-05-29 15:20:35 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2017-05-29 15:20:35 -0300 |
commit | 7c2ca1543c5e0776711ae53e9c3e83224ac592ad (patch) | |
tree | deed43ebc7fc82796bf559ce5afd3ce55a9192dc /src/usr/local/www/diag_command.php | |
parent | d4d9aa66acb336eb5a8fd1a13e9afbada5758bb0 (diff) | |
parent | ff4e29fb9d048162f0d4d28b0c3e818ed2c1fd8e (diff) | |
download | pfsense-7c2ca1543c5e0776711ae53e9c3e83224ac592ad.zip pfsense-7c2ca1543c5e0776711ae53e9c3e83224ac592ad.tar.gz |
Merge pull request #3740 from stilez/patch-59
Diffstat (limited to 'src/usr/local/www/diag_command.php')
-rwxr-xr-x | src/usr/local/www/diag_command.php | 71 |
1 files changed, 59 insertions, 12 deletions
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(' ', ' ', sprintf($margin_layout, ($lineno == $errline ? '>>>' : ''), $lineno)); + $html .= "<span style='color:black;backgroundcolor:lightgrey'><tt>{$margin}</tt></span> {$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); }); |