aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/db/db_tools.php3
-rw-r--r--phpBB/includes/db/mssqlnative.php2
-rw-r--r--phpBB/includes/error_collector.php12
-rw-r--r--phpBB/includes/functions.php92
-rw-r--r--phpBB/includes/functions_messenger.php26
-rw-r--r--phpBB/includes/template/filter.php70
-rw-r--r--phpBB/includes/template/renderer_eval.php2
7 files changed, 138 insertions, 69 deletions
diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php
index f1947ab0d3..7715d2e854 100644
--- a/phpBB/includes/db/db_tools.php
+++ b/phpBB/includes/db/db_tools.php
@@ -1805,7 +1805,7 @@ class phpbb_db_tools
break;
case 'oracle':
- $statements[] = 'ALTER TABLE ' . $table_name . ' DROP ' . $column_name;
+ $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
break;
case 'postgres':
@@ -1956,6 +1956,7 @@ class phpbb_db_tools
$statements[] = "DROP SEQUENCE {$row['referenced_name']}";
}
$this->db->sql_freeresult($result);
+ break;
case 'postgres':
// PGSQL does not "tightly" bind sequences and tables, we must guess...
diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php
index 2287bc716e..96b4c8a8c8 100644
--- a/phpBB/includes/db/mssqlnative.php
+++ b/phpBB/includes/db/mssqlnative.php
@@ -396,7 +396,7 @@ class dbal_mssqlnative extends dbal
*/
function sql_affectedrows()
{
- return ($this->db_connect_id) ? @sqlsrv_rows_affected($this->db_connect_id) : false;
+ return (!empty($this->query_result)) ? @sqlsrv_rows_affected($this->query_result) : false;
}
/**
diff --git a/phpBB/includes/error_collector.php b/phpBB/includes/error_collector.php
index 55834f354c..3c0a89a1f3 100644
--- a/phpBB/includes/error_collector.php
+++ b/phpBB/includes/error_collector.php
@@ -49,13 +49,15 @@ class phpbb_error_collector
{
$text .= "<br />\n";
}
+
list($errno, $msg_text, $errfile, $errline) = $error;
- $text .= "Errno $errno: $msg_text";
- if (defined('DEBUG_EXTRA') || defined('IN_INSTALL'))
- {
- $text .= " at $errfile line $errline";
- }
+
+ // Prevent leakage of local path to phpBB install
+ $errfile = phpbb_filter_root_path($errfile);
+
+ $text .= "Errno $errno: $msg_text at $errfile line $errline";
}
+
return $text;
}
}
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index b143ffd39d..ab933eb523 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -1999,6 +1999,12 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)
{
global $_SID, $_EXTRA_URL, $phpbb_hook;
+ if ($params === '' || (is_array($params) && empty($params)))
+ {
+ // Do not append the ? if the param-list is empty anyway.
+ $params = false;
+ }
+
// Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropriately.
// They could mimic most of what is within this function
if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id))
@@ -3150,61 +3156,44 @@ function add_log()
}
/**
-* Return a nicely formatted backtrace (parts from the php manual by diz at ysagoon dot com)
+* Return a nicely formatted backtrace.
+*
+* Turns the array returned by debug_backtrace() into HTML markup.
+* Also filters out absolute paths to phpBB root.
+*
+* @return string HTML markup
*/
function get_backtrace()
{
- global $phpbb_root_path;
-
$output = '<div style="font-family: monospace;">';
$backtrace = debug_backtrace();
- $path = phpbb_realpath($phpbb_root_path);
- foreach ($backtrace as $number => $trace)
- {
- // We skip the first one, because it only shows this file/function
- if ($number == 0)
- {
- continue;
- }
+ // We skip the first one, because it only shows this file/function
+ unset($backtrace[0]);
+ foreach ($backtrace as $trace)
+ {
// Strip the current directory from path
- if (empty($trace['file']))
- {
- $trace['file'] = '';
- }
- else
- {
- $trace['file'] = str_replace(array($path, '\\'), array('', '/'), $trace['file']);
- $trace['file'] = substr($trace['file'], 1);
- }
- $args = array();
+ $trace['file'] = (empty($trace['file'])) ? '(not given by php)' : htmlspecialchars(phpbb_filter_root_path($trace['file']));
+ $trace['line'] = (empty($trace['line'])) ? '(not given by php)' : $trace['line'];
- // If include/require/include_once is not called, do not show arguments - they may contain sensible information
- if (!in_array($trace['function'], array('include', 'require', 'include_once')))
+ // Only show function arguments for include etc.
+ // Other parameters may contain sensible information
+ $argument = '';
+ if (!empty($trace['args'][0]) && in_array($trace['function'], array('include', 'require', 'include_once', 'require_once')))
{
- unset($trace['args']);
- }
- else
- {
- // Path...
- if (!empty($trace['args'][0]))
- {
- $argument = htmlspecialchars($trace['args'][0]);
- $argument = str_replace(array($path, '\\'), array('', '/'), $argument);
- $argument = substr($argument, 1);
- $args[] = "'{$argument}'";
- }
+ $argument = htmlspecialchars(phpbb_filter_root_path($trace['args'][0]));
}
$trace['class'] = (!isset($trace['class'])) ? '' : $trace['class'];
$trace['type'] = (!isset($trace['type'])) ? '' : $trace['type'];
$output .= '<br />';
- $output .= '<b>FILE:</b> ' . htmlspecialchars($trace['file']) . '<br />';
+ $output .= '<b>FILE:</b> ' . $trace['file'] . '<br />';
$output .= '<b>LINE:</b> ' . ((!empty($trace['line'])) ? $trace['line'] : '') . '<br />';
- $output .= '<b>CALL:</b> ' . htmlspecialchars($trace['class'] . $trace['type'] . $trace['function']) . '(' . ((sizeof($args)) ? implode(', ', $args) : '') . ')<br />';
+ $output .= '<b>CALL:</b> ' . htmlspecialchars($trace['class'] . $trace['type'] . $trace['function']);
+ $output .= '(' . (($argument !== '') ? "'$argument'" : '') . ')<br />';
}
$output .= '</div>';
return $output;
@@ -3753,9 +3742,8 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
if (strpos($errfile, 'cache') === false && strpos($errfile, 'template.') === false)
{
- // remove complete path to installation, with the risk of changing backslashes meant to be there
- $errfile = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $errfile);
- $msg_text = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $msg_text);
+ $errfile = phpbb_filter_root_path($errfile);
+ $msg_text = phpbb_filter_root_path($msg_text);
$error_name = ($errno === E_WARNING) ? 'PHP Warning' : 'PHP Notice';
echo '<b>[phpBB Debug] ' . $error_name . '</b>: in file <b>' . $errfile . '</b> on line <b>' . $errline . '</b>: <b>' . $msg_text . '</b><br />' . "\n";
@@ -3934,6 +3922,29 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
}
/**
+* Removes absolute path to phpBB root directory from error messages
+* and converts backslashes to forward slashes.
+*
+* @param string $errfile Absolute file path
+* (e.g. /var/www/phpbb3/phpBB/includes/functions.php)
+* Please note that if $errfile is outside of the phpBB root,
+* the root path will not be found and can not be filtered.
+* @return string Relative file path
+* (e.g. /includes/functions.php)
+*/
+function phpbb_filter_root_path($errfile)
+{
+ static $root_path;
+
+ if (empty($root_path))
+ {
+ $root_path = phpbb_realpath(dirname(__FILE__) . '/../');
+ }
+
+ return str_replace(array($root_path, '\\'), array('[ROOT]', '/'), $errfile);
+}
+
+/**
* Queries the session table to get information about online guests
* @param int $item_id Limits the search to the item with this id
* @param string $item The name of the item which is stored in the session table as session_{$item}_id
@@ -4544,6 +4555,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'S_SEARCH_HIDDEN_FIELDS' => build_hidden_fields($s_search_hidden_fields),
+ 'T_ASSETS_PATH' => "{$web_path}assets",
'T_THEME_PATH' => "{$web_path}styles/" . $user->theme['theme_path'] . '/theme',
'T_TEMPLATE_PATH' => "{$web_path}styles/" . $user->theme['template_path'] . '/template',
'T_SUPER_TEMPLATE_PATH' => (isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? "{$web_path}styles/" . $user->theme['template_inherit_path'] . '/template' : "{$web_path}styles/" . $user->theme['template_path'] . '/template',
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 1866733545..b94957a85f 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -976,9 +976,16 @@ function smtpmail($addresses, $subject, $message, &$err_msg, $headers = false)
$smtp->add_backtrace('Connecting to ' . $config['smtp_host'] . ':' . $config['smtp_port']);
// Ok we have error checked as much as we can to this point let's get on it already.
- ob_start();
+ if (!class_exists('phpbb_error_collector'))
+ {
+ global $phpbb_root_path, $phpEx;
+ include($phpbb_root_path . 'includes/error_collector.' . $phpEx);
+ }
+ $collector = new phpbb_error_collector;
+ $collector->install();
$smtp->socket = fsockopen($config['smtp_host'], $config['smtp_port'], $errno, $errstr, 20);
- $error_contents = ob_get_clean();
+ $collector->uninstall();
+ $error_contents = $collector->format_errors();
if (!$smtp->socket)
{
@@ -1609,18 +1616,27 @@ function mail_encode($str, $eol = "\r\n")
*/
function phpbb_mail($to, $subject, $msg, $headers, $eol, &$err_msg)
{
- global $config;
+ global $config, $phpbb_root_path, $phpEx;
// We use the EOL character for the OS here because the PHP mail function does not correctly transform line endings. On Windows SMTP is used (SMTP is \r\n), on UNIX a command is used...
// Reference: http://bugs.php.net/bug.php?id=15841
$headers = implode($eol, $headers);
- ob_start();
+ if (!class_exists('phpbb_error_collector'))
+ {
+ include($phpbb_root_path . 'includes/error_collector.' . $phpEx);
+ }
+
+ $collector = new phpbb_error_collector;
+ $collector->install();
+
// On some PHP Versions mail() *may* fail if there are newlines within the subject.
// Newlines are used as a delimiter for lines in mail_encode() according to RFC 2045 section 6.8.
// Because PHP can't decide what is wanted we revert back to the non-RFC-compliant way of separating by one space (Use '' as parameter to mail_encode() results in SPACE used)
$result = $config['email_function_name']($to, mail_encode($subject, ''), wordwrap(utf8_wordwrap($msg), 997, "\n", true), $headers);
- $err_msg = ob_get_clean();
+
+ $collector->uninstall();
+ $err_msg = $collector->format_errors();
return $result;
}
diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php
index 1d1d92378e..f24c3f4d09 100644
--- a/phpBB/includes/template/filter.php
+++ b/phpBB/includes/template/filter.php
@@ -307,12 +307,13 @@ class phpbb_template_filter extends php_user_filter
}
/**
- * Compile variables
+ * Convert template variables into PHP varrefs
*
* @param string $text_blocks Variable reference in source template
- * @return string compiled template code
+ * @param bool $is_expr Returns whether the source was an expression type variable (i.e. S_FIRST_ROW)
+ * @return string PHP variable name
*/
- private function compile_var_tags(&$text_blocks)
+ private function get_varref($text_blocks, &$is_expr)
{
// change template varrefs into PHP varrefs
$varrefs = array();
@@ -324,17 +325,38 @@ class phpbb_template_filter extends php_user_filter
{
$namespace = $var_val[1];
$varname = $var_val[3];
- $new = $this->generate_block_varref($namespace, $varname, true, $var_val[2]);
+ $new = $this->generate_block_varref($namespace, $varname, $is_expr, $var_val[2]);
$text_blocks = str_replace($var_val[0], $new, $text_blocks);
}
- // Handle special language tags L_ and LA_
- $this->compile_language_tags($text_blocks);
+ // Language variables cannot be reduced to a single varref, so they must be skipped
+ // These two replacements would break language variables, so we can only run them on non-language types
+ if (strpos($text_blocks, '{L_') === false && strpos($text_blocks, '{LA_') === false)
+ {
+ // This will handle the remaining root-level varrefs
+ $text_blocks = preg_replace('#\{(' . self::REGEX_VAR . ')\}#', "\$_rootref['\\1']", $text_blocks);
+ $text_blocks = preg_replace('#\{\$(' . self::REGEX_VAR . ')\}#', "\$_tpldata['DEFINE']['.']['\\1']", $text_blocks);
+ }
- // This will handle the remaining root-level varrefs
- $text_blocks = preg_replace('#\{(' . self::REGEX_VAR . ')\}#', "<?php echo (isset(\$_rootref['\\1'])) ? \$_rootref['\\1'] : ''; /**/?>", $text_blocks);
- $text_blocks = preg_replace('#\{\$(' . self::REGEX_VAR . ')\}#', "<?php echo (isset(\$_tpldata['DEFINE']['.']['\\1'])) ? \$_tpldata['DEFINE']['.']['\\1'] : ''; /**/?>", $text_blocks);
+ return $text_blocks;
+ }
+
+ /**
+ * Compile variables
+ *
+ * @param string $text_blocks Variable reference in source template
+ * @return string compiled template code
+ */
+ private function compile_var_tags(&$text_blocks)
+ {
+ $text_blocks = $this->get_varref($text_blocks, $is_expr);
+ $lang_replaced = $this->compile_language_tags($text_blocks);
+
+ if(!$lang_replaced)
+ {
+ $text_blocks = '<?php echo ' . ($is_expr ? "$text_blocks" : "(isset($text_blocks)) ? $text_blocks : ''") . '; /**/?>';
+ }
return $text_blocks;
}
@@ -343,21 +365,28 @@ class phpbb_template_filter extends php_user_filter
* Handles special language tags L_ and LA_
*
* @param string $text_blocks Variable reference in source template
+ * @return bool Whether a replacement occurred or not
*/
private function compile_language_tags(&$text_blocks)
{
+ $replacements = 0;
+
// transform vars prefixed by L_ into their language variable pendant if nothing is set within the tpldata array
if (strpos($text_blocks, '{L_') !== false)
{
- $text_blocks = preg_replace('#\{L_(' . self::REGEX_VAR . ')\}#', "<?php echo ((isset(\$_rootref['L_\\1'])) ? \$_rootref['L_\\1'] : ((isset(\$_lang['\\1'])) ? \$_lang['\\1'] : '{ \\1 }')); /**/?>", $text_blocks);
+ $text_blocks = preg_replace('#\{L_(' . self::REGEX_VAR . ')\}#', "<?php echo ((isset(\$_rootref['L_\\1'])) ? \$_rootref['L_\\1'] : ((isset(\$_lang['\\1'])) ? \$_lang['\\1'] : '{ \\1 }')); /**/?>", $text_blocks, -1, $replacements);
+ return (bool) $replacements;
}
// Handle addslashed language variables prefixed with LA_
// If a template variable already exist, it will be used in favor of it...
if (strpos($text_blocks, '{LA_') !== false)
{
- $text_blocks = preg_replace('#\{LA_(' . self::REGEX_VAR . '+)\}#', "<?php echo ((isset(\$_rootref['LA_\\1'])) ? \$_rootref['LA_\\1'] : ((isset(\$_rootref['L_\\1'])) ? addslashes(\$_rootref['L_\\1']) : ((isset(\$_lang['\\1'])) ? addslashes(\$_lang['\\1']) : '{ \\1 }'))); /**/?>", $text_blocks);
+ $text_blocks = preg_replace('#\{LA_(' . self::REGEX_VAR . '+)\}#', "<?php echo ((isset(\$_rootref['LA_\\1'])) ? \$_rootref['LA_\\1'] : ((isset(\$_rootref['L_\\1'])) ? addslashes(\$_rootref['L_\\1']) : ((isset(\$_lang['\\1'])) ? addslashes(\$_lang['\\1']) : '{ \\1 }'))); /**/?>", $text_blocks, -1, $replacements);
+ return (bool) $replacements;
}
+
+ return false;
}
/**
@@ -725,6 +754,18 @@ class phpbb_template_filter extends php_user_filter
*/
private function compile_tag_include($tag_args)
{
+ // Process dynamic includes
+ if ($tag_args[0] == '{')
+ {
+ $var = $this->get_varref($tag_args, $is_expr);
+
+ // Make sure someone didn't try to include S_FIRST_ROW or similar
+ if (!$is_expr)
+ {
+ return "if (isset($var)) { \$_template->_tpl_include($var); }";
+ }
+ }
+
return "\$_template->_tpl_include('$tag_args');";
}
@@ -822,17 +863,16 @@ class phpbb_template_filter extends php_user_filter
*
* @param string $namespace Namespace to access (expects a trailing "." on the namespace)
* @param string $varname Variable name to use
- * @param bool $echo If true return an echo statement, otherwise a reference to the internal variable
+ * @param bool $expr Returns whether the source was an expression type
* @param bool $defop If true this is a variable created with the DEFINE construct, otherwise template variable
* @return string Code to access variable or echo it if $echo is true
*/
- private function generate_block_varref($namespace, $varname, $echo = true, $defop = false)
+ private function generate_block_varref($namespace, $varname, &$expr, $defop = false)
{
// Strip the trailing period.
$namespace = substr($namespace, 0, -1);
$expr = true;
- $isset = false;
// S_ROW_COUNT is deceptive, it returns the current row number now the number of rows
// hence S_ROW_COUNT is deprecated in favour of S_ROW_NUM
@@ -868,11 +908,9 @@ class phpbb_template_filter extends php_user_filter
$varref .= "['$varname']";
$expr = false;
- $isset = true;
break;
}
// @todo Test the !$expr more
- $varref = ($echo) ? '<?php echo ' . ($isset ? "isset($varref) ? $varref : ''" : $varref) . '; /**/?>' : (($expr || isset($varref)) ? $varref : '');
return $varref;
}
diff --git a/phpBB/includes/template/renderer_eval.php b/phpBB/includes/template/renderer_eval.php
index 11e2a30f06..2c05a1c1df 100644
--- a/phpBB/includes/template/renderer_eval.php
+++ b/phpBB/includes/template/renderer_eval.php
@@ -55,6 +55,6 @@ class phpbb_template_renderer_eval implements phpbb_template_renderer
$_rootref = &$context->get_root_ref();
$_lang = $lang;
- eval($this->code);
+ eval(' ?>' . $this->code . '<?php ');
}
}