function ViewFile() { global $context, $txt, $boarddir, $sourcedir; // Check for the administrative permission to do this. isAllowedTo('admin_forum'); // decode the file and get the line $file = base64_decode($_REQUEST['file']); $line = isset($_REQUEST['line']) ? (int) $_REQUEST['line'] : 0; // Make sure the file we are looking for is one they are allowed to look at if (!is_readable($file) || strpos($file, '../') !== false && (strpos($file, $boarddir) === false || strpos($file, $sourcedir) === false)) { fatal_lang_error('error_bad_file', true, array(htmlspecialchars($file))); } // get the min and max lines $min = $line - 20 <= 0 ? 1 : $line - 20; $max = $line + 21; // One additional line to make everything work out correctly if ($max <= 0 || $min >= $max) { fatal_lang_error('error_bad_line'); } $file_data = explode('<br />', highlight_php_code(htmlspecialchars(implode('', file($file))))); // We don't want to slice off too many so lets make sure we stop at the last one $max = min($max, max(array_keys($file_data))); $file_data = array_slice($file_data, $min - 1, $max - $min); $context['file_data'] = array('contents' => $file_data, 'min' => $min, 'target' => $line, 'file' => strtr($file, array('"' => '\\"'))); loadTemplate('Errors'); $context['template_layers'] = array(); $context['sub_template'] = 'show_file'; }
function template_include($filename, $once = false) { global $context, $settings, $options, $txt, $scripturl, $modSettings; global $language_dir, $user_info, $boardurl, $boarddir, $sourcedir; global $maintenance, $mtitle, $mmessage; static $templates = array(); // We want to be able to figure out any errors... @ini_set('track_errors', '1'); // Don't include the file more than once, if $once is true. if ($once && in_array($filename, $templates)) { return; } else { $templates[] = $filename; } // Are we going to use eval? if (empty($modSettings['disableTemplateEval'])) { $file_found = file_exists($filename) && eval('?' . '>' . rtrim(file_get_contents($filename))) !== false; $settings['current_include_filename'] = $filename; } else { $file_found = file_exists($filename); if ($once && $file_found) { require_once $filename; } elseif ($file_found) { require $filename; } } if ($file_found !== true) { ob_end_clean(); if (!empty($modSettings['enableCompressedOutput'])) { @ob_start('ob_gzhandler'); } else { ob_start(); } if (isset($_GET['debug']) && !WIRELESS) { header('Content-Type: application/xhtml+xml; charset=' . (empty($context['character_set']) ? 'ISO-8859-1' : $context['character_set'])); } // Don't cache error pages!! header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); header('Cache-Control: no-cache'); if (!isset($txt['template_parse_error'])) { $txt['template_parse_error'] = 'Template Parse Error!'; $txt['template_parse_error_message'] = 'It seems something has gone sour on the forum with the template system. This problem should only be temporary, so please come back later and try again. If you continue to see this message, please contact the administrator.<br /><br />You can also try <a href="javascript:location.reload();">refreshing this page</a>.'; $txt['template_parse_error_details'] = 'There was a problem loading the <tt><b>%1$s</b></tt> template or language file. Please check the syntax and try again - remember, single quotes (<tt>\'</tt>) often have to be escaped with a slash (<tt>\\</tt>). To see more specific error information from PHP, try <a href="' . $boardurl . '%1$s" target="_blank">accessing the file directly</a>.<br /><br />You may want to try to <a href="javascript:location.reload();">refresh this page</a> or <a href="' . $scripturl . '?theme=1">use the default theme</a>.'; } // First, let's get the doctype and language information out of the way. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"', !empty($context['right_to_left']) ? ' dir="rtl"' : '', '> <head>'; // echo '<META HTTP-EQUIV="'.'control-cache''" CONTENT="no-cache">'; if (isset($context['character_set'])) { echo ' <meta http-equiv="Content-Type" content="text/html; charset=', $context['character_set'], '" />'; } if (!empty($maintenance) && !allowedTo('admin_forum')) { echo ' <title>', $mtitle, '</title> </head> <body> <h3>', $mtitle, '</h3> ', $mmessage, ' </body> </html>'; } elseif (!allowedTo('admin_forum')) { echo ' <title>', $txt['template_parse_error'], '</title> </head> <body> <h3>', $txt['template_parse_error'], '</h3> ', $txt['template_parse_error_message'], ' </body> </html>'; } else { require_once $sourcedir . '/Subs-Package.php'; $error = fetch_web_data($boardurl . strtr($filename, array($boarddir => '', strtr($boarddir, '\\', '/') => ''))); if (empty($error)) { $error = $php_errormsg; } echo ' <title>', $txt['template_parse_error'], '</title> </head> <body> <h3>', $txt['template_parse_error'], '</h3> ', sprintf($txt['template_parse_error_details'], strtr($filename, array($boarddir => '', strtr($boarddir, '\\', '/') => ''))); if (!empty($error)) { echo ' <hr /> <div style="margin: 0 20px;"><tt>', strtr(strtr($error, array('<b>' . $boarddir => '<b>...', '<b>' . strtr($boarddir, '\\', '/') => '<b>...')), '\\', '/'), '</tt></div>'; } // I know, I know... this is VERY COMPLICATED. Still, it's good. if (preg_match('~ <b>(\\d+)</b><br( /)?' . '>$~i', $error, $match) != 0) { $data = file($filename); $data2 = highlight_php_code(implode('', $data)); $data2 = preg_split('~\\<br( /)?\\>~', $data2); // Fix the PHP code stuff... if ($context['browser']['is_ie4'] || $context['browser']['is_ie5'] || $context['browser']['is_ie5.5']) { $data2 = str_replace("\t", "<pre style=\"display: inline;\">\t</pre>", $data2); } elseif (!$context['browser']['is_gecko']) { $data2 = str_replace("\t", "<span style=\"white-space: pre;\">\t</span>", $data2); } else { $data2 = str_replace("<pre style=\"display: inline;\">\t</pre>", "\t", $data2); } // Now we get to work around a bug in PHP where it doesn't escape <br />s! $j = -1; foreach ($data as $line) { $j++; if (substr_count($line, '<br />') == 0) { continue; } $n = substr_count($line, '<br />'); for ($i = 0; $i < $n; $i++) { $data2[$j] .= '<br />' . $data2[$j + $i + 1]; unset($data2[$j + $i + 1]); } $j += $n; } $data2 = array_values($data2); array_unshift($data2, ''); echo ' <div style="margin: 2ex 20px; width: 96%; overflow: auto;"><pre style="margin: 0;">'; // Figure out what the color coding was before... $line = max($match[1] - 9, 1); $last_line = ''; for ($line2 = $line - 1; $line2 > 1; $line2--) { if (strpos($data2[$line2], '<') !== false) { if (preg_match('~(<[^/>]+>)[^<]*$~', $data2[$line2], $color_match) != 0) { $last_line = $color_match[1]; } break; } } // Show the relevant lines... for ($n = min($match[1] + 4, count($data2) + 1); $line <= $n; $line++) { if ($line == $match[1]) { echo '</pre><div style="background-color: #ffb0b5;"><pre style="margin: 0;">'; } echo '<span style="color: black;">', sprintf('%' . strlen($n) . 's', $line), ':</span> '; if ($data2[$line] != '') { echo substr($data2[$line], 0, 2) == '</' ? preg_replace('~^</[^>]+>~', '', $data2[$line]) : $last_line . $data2[$line]; } if (preg_match('~(<[^/>]+>)[^<]*$~', $data2[$line], $color_match) != 0) { $last_line = $color_match[1]; echo '</', substr($last_line, 1, 4), '>'; } elseif ($last_line != '' && strpos($data2[$line], '<') !== false) { $last_line = ''; } elseif ($last_line != '' && $data2[$line] != '') { echo '</', substr($last_line, 1, 4), '>'; } if ($line == $match[1]) { echo '</pre></div><pre style="margin: 0;">'; } else { echo "\n"; } } echo '</pre></div>'; } echo ' </body> </html>'; } die; } }
function ExamineFile() { global $txt, $scripturl, $boarddir, $context, $sourcedir; checkSession('get'); require_once $sourcedir . '/Subs-Package.php'; // No package? Show him or her the door. if (empty($_REQUEST['package']) || preg_match('~[^\\w0-9.\\-_]~', $_REQUEST['package']) === 1 || strpos($_REQUEST['package'], '..') !== false) { redirectexit('action=packages'); } // No file? Show him or her the door. if (!isset($_REQUEST['file']) || $_REQUEST['file'] == '') { redirectexit('action=packages'); } $_REQUEST['package'] = preg_replace('~[\\.]+~', '.', $_REQUEST['package']); $_REQUEST['file'] = preg_replace('~[\\.]+~', '.', $_REQUEST['file']); if (isset($_REQUEST['raw'])) { if (is_file($boarddir . '/Packages/' . $_REQUEST['package'])) { echo read_tgz_file($boarddir . '/Packages/' . $_REQUEST['package'], $_REQUEST['file'], true); } elseif (is_dir($boarddir . '/Packages/' . $_REQUEST['package'])) { echo file_get_contents($boarddir . '/Packages/' . $_REQUEST['package'] . '/' . $_REQUEST['file']); } obExit(false); } $context['linktree'][] = array('url' => $scripturl . '?action=packages;sa=list;package=' . $_REQUEST['package'], 'name' => &$txt['package_examine_file']); $context['page_title'] .= ' - ' . $txt['package_examine_file']; $context['sub_template'] = 'examine'; // The filename... $context['package'] = $_REQUEST['package']; $context['filename'] = $_REQUEST['file']; // Let the unpacker do the work.... but make sure we handle images properly. if (in_array(strtolower(strrchr($_REQUEST['file'], '.')), array('.bmp', '.gif', '.jpeg', '.jpg', '.png'))) { $context['filedata'] = '<img src="' . $scripturl . '?action=packages;sa=examine;package=' . $_REQUEST['package'] . ';file=' . $_REQUEST['file'] . ';raw;sesc=' . $context['session_id'] . '" alt="' . $_REQUEST['file'] . '" />'; } else { if (is_file($boarddir . '/Packages/' . $_REQUEST['package'])) { $context['filedata'] = htmlspecialchars(read_tgz_file($boarddir . '/Packages/' . $_REQUEST['package'], $_REQUEST['file'], true)); } elseif (is_dir($boarddir . '/Packages/' . $_REQUEST['package'])) { $context['filedata'] = htmlspecialchars(file_get_contents($boarddir . '/Packages/' . $_REQUEST['package'] . '/' . $_REQUEST['file'])); } if (strtolower(strrchr($_REQUEST['file'], '.')) == '.php') { $context['filedata'] = highlight_php_code($context['filedata']); } } }
/** * Display one of the files in a package. */ public function action_examine() { global $txt, $scripturl, $context; require_once SUBSDIR . '/Package.subs.php'; // No package? Show him or her the door. if (!isset($_REQUEST['package']) || $_REQUEST['package'] == '') { redirectexit('action=admin;area=packages'); } // No file? Show him or her the door. if (!isset($_REQUEST['file']) || $_REQUEST['file'] == '') { redirectexit('action=admin;area=packages'); } $_REQUEST['package'] = preg_replace('~[\\.]+~', '.', strtr($_REQUEST['package'], array('/' => '_', '\\' => '_'))); $_REQUEST['file'] = preg_replace('~[\\.]+~', '.', $_REQUEST['file']); if (isset($_REQUEST['raw'])) { if (is_file(BOARDDIR . '/packages/' . $_REQUEST['package'])) { echo read_tgz_file(BOARDDIR . '/packages/' . $_REQUEST['package'], $_REQUEST['file'], true); } elseif (is_dir(BOARDDIR . '/packages/' . $_REQUEST['package'])) { echo file_get_contents(BOARDDIR . '/packages/' . $_REQUEST['package'] . '/' . $_REQUEST['file']); } obExit(false); } $context['linktree'][count($context['linktree']) - 1] = array('url' => $scripturl . '?action=admin;area=packages;sa=list;package=' . $_REQUEST['package'], 'name' => $txt['package_examine_file']); $context['page_title'] .= ' - ' . $txt['package_examine_file']; $context['sub_template'] = 'examine'; // The filename... $context['package'] = $_REQUEST['package']; $context['filename'] = $_REQUEST['file']; // Let the unpacker do the work.... but make sure we handle images properly. if (in_array(strtolower(strrchr($_REQUEST['file'], '.')), array('.bmp', '.gif', '.jpeg', '.jpg', '.png'))) { $context['filedata'] = '<img src="' . $scripturl . '?action=admin;area=packages;sa=examine;package=' . $_REQUEST['package'] . ';file=' . $_REQUEST['file'] . ';raw" alt="' . $_REQUEST['file'] . '" />'; } else { if (is_file(BOARDDIR . '/packages/' . $_REQUEST['package'])) { $context['filedata'] = htmlspecialchars(read_tgz_file(BOARDDIR . '/packages/' . $_REQUEST['package'], $_REQUEST['file'], true)); } elseif (is_dir(BOARDDIR . '/packages/' . $_REQUEST['package'])) { $context['filedata'] = htmlspecialchars(file_get_contents(BOARDDIR . '/packages/' . $_REQUEST['package'] . '/' . $_REQUEST['file'])); } if (strtolower(strrchr($_REQUEST['file'], '.')) == '.php') { $context['filedata'] = highlight_php_code($context['filedata']); } } }
/** * View a file specified in $_REQUEST['file'], with php highlighting on it * * Preconditions: * - file must be readable, * - full file path must be base64 encoded, * * - The line number number is specified by $_REQUEST['line']... * - The function will try to get the 20 lines before and after the specified line. */ protected function action_viewfile() { global $context; // We can't help you if you don't spell it out loud :P if (!isset($_REQUEST['file'])) { redirectexit(); } // Decode the file and get the line $filename = base64_decode($_REQUEST['file']); $file = realpath($filename); $line = isset($_REQUEST['line']) ? (int) $_REQUEST['line'] : 0; // Make sure things are normalized $real_board = realpath(BOARDDIR); $real_source = realpath(SOURCEDIR); $real_cache = realpath(CACHEDIR); // Make sure the file requested is one they are allowed to look at $excluded = array('settings.php', 'settings_bak.php'); $basename = strtolower(basename($file)); $ext = strrchr($basename, '.'); if ($ext !== '.php' || strpos($file, $real_board) === false && strpos($file, $real_source) === false || strpos($file, $real_cache) !== false || in_array($basename, $excluded) || !is_readable($file)) { fatal_lang_error('error_bad_file', true, array(htmlspecialchars($filename, ENT_COMPAT, 'UTF-8'))); } // Get the min and max lines $min = $line - 16 <= 0 ? 1 : $line - 16; $max = $line + 21; // One additional line to make everything work out correctly if ($max <= 0 || $min >= $max) { fatal_lang_error('error_bad_line'); } $file_data = explode('<br />', highlight_php_code(htmlspecialchars(implode('', file($file)), ENT_COMPAT, 'UTF-8'))); // We don't want to slice off too many so lets make sure we stop at the last one $max = min($max, max(array_keys($file_data))); $file_data = array_slice($file_data, $min - 1, $max - $min); $context['file_data'] = array('contents' => $file_data, 'min' => $min, 'target' => $line, 'file' => strtr($file, array('"' => '\\"'))); loadTemplate('Errors'); Template_Layers::getInstance()->removeAll(); $context['sub_template'] = 'show_file'; }