aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rwxr-xr-xgit-tools/hooks/commit-msg258
-rwxr-xr-xgit-tools/hooks/install17
-rwxr-xr-xgit-tools/hooks/pre-commit7
-rwxr-xr-xgit-tools/hooks/prepare-commit-msg10
-rwxr-xr-xgit-tools/hooks/uninstall16
-rw-r--r--phpBB/adm/index.php16
-rw-r--r--phpBB/adm/style/admin.css6
-rw-r--r--phpBB/common.php6
-rw-r--r--phpBB/config.php0
-rw-r--r--phpBB/docs/AUTHORS3
-rw-r--r--phpBB/docs/README.html2
-rw-r--r--phpBB/download/file.php23
-rw-r--r--phpBB/includes/acm/acm_file.php16
-rw-r--r--phpBB/includes/acm/acm_memory.php8
-rw-r--r--phpBB/includes/acp/acp_attachments.php2
-rw-r--r--phpBB/includes/acp/acp_board.php1
-rw-r--r--phpBB/includes/acp/acp_forums.php3
-rw-r--r--phpBB/includes/acp/acp_groups.php2
-rw-r--r--phpBB/includes/acp/acp_styles.php29
-rw-r--r--phpBB/includes/acp/acp_users.php7
-rw-r--r--phpBB/includes/cache.php9
-rw-r--r--phpBB/includes/captcha/plugins/captcha_abstract.php8
-rw-r--r--phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php5
-rw-r--r--phpBB/includes/db/db_tools.php18
-rw-r--r--[-rwxr-xr-x]phpBB/includes/db/mssqlnative.php0
-rw-r--r--phpBB/includes/functions.php206
-rw-r--r--phpBB/includes/functions_admin.php82
-rw-r--r--phpBB/includes/functions_compress.php6
-rw-r--r--phpBB/includes/functions_convert.php6
-rw-r--r--phpBB/includes/functions_posting.php4
-rw-r--r--phpBB/includes/functions_privmsgs.php3
-rw-r--r--phpBB/includes/functions_profile_fields.php5
-rw-r--r--phpBB/includes/functions_upload.php5
-rw-r--r--phpBB/includes/functions_user.php40
-rw-r--r--phpBB/includes/mcp/mcp_main.php35
-rw-r--r--phpBB/includes/mcp/mcp_queue.php2
-rw-r--r--phpBB/includes/search/fulltext_native.php13
-rw-r--r--phpBB/includes/session.php19
-rw-r--r--phpBB/includes/ucp/ucp_groups.php2
-rw-r--r--phpBB/includes/ucp/ucp_pm_viewmessage.php2
-rw-r--r--phpBB/includes/ucp/ucp_profile.php7
-rw-r--r--phpBB/includes/ucp/ucp_register.php6
-rw-r--r--phpBB/includes/ucp/ucp_remind.php4
-rw-r--r--phpBB/install/convertors/functions_phpbb20.php2
-rw-r--r--phpBB/install/database_update.php70
-rw-r--r--phpBB/install/install_convert.php2
-rw-r--r--phpBB/install/install_install.php5
-rw-r--r--phpBB/install/schemas/schema_data.sql1
-rw-r--r--phpBB/language/en/acp/board.php5
-rw-r--r--phpBB/language/en/search.php1
-rw-r--r--phpBB/memberlist.php2
-rw-r--r--phpBB/posting.php31
-rw-r--r--phpBB/search.php21
-rw-r--r--phpBB/styles/prosilver/template/index_body.html2
-rw-r--r--phpBB/styles/prosilver/template/login_body.html2
-rw-r--r--phpBB/styles/prosilver/theme/bidi.css1
-rw-r--r--phpBB/styles/prosilver/theme/print.css2
-rw-r--r--phpBB/styles/subsilver2/template/login_body.html2
-rw-r--r--phpBB/styles/subsilver2/template/overall_header.html2
-rw-r--r--phpBB/ucp.php2
-rw-r--r--phpBB/viewtopic.php2
-rw-r--r--tests/all_tests.php4
-rw-r--r--tests/dbal/dbal.php5
-rw-r--r--tests/network/all_tests.php40
-rw-r--r--tests/network/checkdnsrr.php63
-rw-r--r--tests/random/all_tests.php40
-rw-r--r--tests/random/gen_rand_string.php63
-rw-r--r--tests/test_framework/phpbb_database_test_case.php59
-rw-r--r--tests/test_framework/phpbb_test_case_helpers.php37
70 files changed, 1189 insertions, 201 deletions
diff --git a/.gitignore b/.gitignore
index 3e0f454e0c..b825007244 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
+*~
phpBB/cache/*.php
-*~ \ No newline at end of file
+phpBB/config.php
+tests/phpbb_unit_tests.sqlite2
+tests/test_config.php
diff --git a/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg
new file mode 100755
index 0000000000..a6777ff9c9
--- /dev/null
+++ b/git-tools/hooks/commit-msg
@@ -0,0 +1,258 @@
+#!/bin/sh
+#
+# A hook to check syntax of a phpBB3 commit message, per:
+# * <http://wiki.phpbb.com/display/DEV/Git>
+# * <http://area51.phpbb.com/phpBB/viewtopic.php?p=209919#p209919>
+#
+# This is a commit-msg hook.
+#
+# To install this you can either copy or symlink it to
+# $GIT_DIR/hooks, example:
+#
+# ln -s ../../git-tools/hooks/commit-msg \\
+# .git/hooks/commit-msg
+
+config_ns="phpbb.hooks.commit-msg";
+
+if [ "$(git config --bool $config_ns.fatal)" = "false" ]
+then
+ fatal=0;
+else
+ fatal=1;
+fi
+
+debug_level=$(git config --int $config_ns.debug || echo 0);
+
+# Error codes
+ERR_LENGTH=1;
+ERR_HEADER=2;
+ERR_EMPTY=3;
+ERR_DESCRIPTION=4;
+ERR_FOOTER=5;
+ERR_EOF=6;
+ERR_UNKNOWN=42;
+
+debug()
+{
+ local level;
+
+ level=$1;
+ shift;
+
+ if [ $debug_level -ge $level ]
+ then
+ echo $@;
+ fi
+}
+
+quit()
+{
+ if [ $1 -gt 0 ] && [ $1 -ne $ERR_UNKNOWN ] && [ $fatal -eq 0 ]
+ then
+ exit 0;
+ else
+ exit $1;
+ fi
+}
+
+msg=$(grep -nE '.{81,}' "$1");
+
+if [ $? -eq 0 ]
+then
+ echo "The following lines are greater than 80 characters long:\n" >&2;
+ echo $msg >&2;
+
+ quit $ERR_LENGTH;
+fi
+
+lines=$(wc -l "$1" | awk '{ print $1; }');
+expecting=header;
+in_description=0;
+in_empty=0;
+ticket=0;
+branch_regex="[a-z]+[a-z0-9-]*[a-z0-9]+";
+i=1;
+tickets="";
+
+while [ $i -le $lines ]
+do
+ # Grab the line we are studying
+ line=$(head -n$i "$1" | tail -n1);
+
+ debug 1 "==> [$i] $line (description: $in_description, empty: $in_empty)";
+
+ err=$ERR_UNKNOWN;
+
+ if [ -z "$expecting" ]
+ then
+ quit $err;
+ fi
+
+ if [ "${expecting#comment}" = "$expecting" ]
+ then
+ # Prefix comments to the expected tokens list
+ expecting="comment $expecting";
+ fi
+
+ debug 2 "Expecting: $expecting";
+
+ # Loop over each of the expected line formats
+ for expect in $expecting
+ do
+ # Reset the error code each iteration
+ err=$ERR_UNKNOWN;
+
+ # Test for validity of each line format
+ # This is done first so $? contains the result
+ case $expect in
+ "header")
+ err=$ERR_HEADER;
+ echo "$line" | grep -Eq "^\[(ticket/[0-9]+|feature/$branch_regex|task/$branch_regex)\] [A-Z].+$"
+ ;;
+ "empty")
+ err=$ERR_EMPTY;
+ echo "$line" | grep -Eq "^$"
+ ;;
+ "description")
+ err=$ERR_DESCRIPTION;
+ # Free flow text, the line length was constrained by the initial check
+ echo "$line" | grep -Eq "^.+$";
+ ;;
+ "footer")
+ err=$ERR_FOOTER;
+ # Each ticket is on its own line
+ echo "$line" | grep -Eq "^PHPBB3-[0-9]+$";
+ ;;
+ "eof")
+ err=$ERR_EOF;
+ # Should not end up here
+ false
+ ;;
+ "comment")
+ echo "$line" | grep -Eq "^#";
+ ;;
+ *)
+ echo "Unrecognised token $expect" >&2;
+ quit $err;
+ ;;
+ esac
+
+ # Preserve the result of the line check
+ result=$?;
+
+ debug 2 "$expect - '$line' - $result";
+
+ if [ $result -eq 0 ]
+ then
+ # Break out the loop on success
+ # otherwise roll on round and keep looking for a match
+ break;
+ fi
+ done
+
+ if [ $result -eq 0 ]
+ then
+ # Have we switched out of description mode?
+ if [ $in_description -eq 1 ] && [ "$expect" != "description" ] && [ "$expect" != "empty" ] && [ "$expect" != "comment" ]
+ then
+ # Yes, okay we need to backtrace one line and reanalyse
+ in_description=0;
+ i=$(( $i - $in_empty ));
+
+ # Reset the empty counter
+ in_empty=0;
+ continue;
+ fi
+
+ # Successful match, but on which line format
+ case $expect in
+ "header")
+ expecting="empty";
+
+ echo "$line" | grep -Eq "^\[ticket/[0-9]+\]$" && (
+ ticket=$(echo "$line" | sed 's,\[ticket/\([0-9]*\)\].*,\1,');
+ )
+ ;;
+ "empty")
+ # Description might have empty lines as spacing
+ expecting="footer description";
+ in_empty=$(($in_empty + 1));
+
+ if [ $in_description -eq 1 ]
+ then
+ expecting="$expecting empty";
+ fi
+ ;;
+ "description")
+ expecting="description empty";
+ in_description=1;
+ ;;
+ "footer")
+ expecting="footer eof";
+ if [ "$tickets" = "" ]
+ then
+ tickets="$line";
+ else
+ tickets="$tickets $line";
+ fi
+ ;;
+ "comment")
+ # Comments should expect the same thing again
+ ;;
+ *)
+ echo "Unrecognised token $expect" >&2;
+ quit 254;
+ ;;
+ esac
+
+ if [ "$expect" != "empty" ]
+ then
+ in_empty=0;
+ fi
+
+ debug 3 "Now expecting: $expecting";
+ else
+ # None of the expected line formats matched
+ # Guess we'll call it a day here then
+ echo "Syntax error on line $i:" >&2;
+ echo ">> $line" >&2;
+ echo -n "Expecting: " >&2;
+ echo "$expecting" | sed 's/ /, /g' >&2;
+ exit $err;
+ fi
+
+ i=$(( $i + 1 ));
+done
+
+# If EOF is expected exit cleanly
+echo "$expecting" | grep -q "eof" || (
+ # Unexpected EOF, error
+ echo "Unexpected EOF encountered" >&2;
+ quit $ERR_EOF;
+) && (
+ # Do post scan checks
+ if [ ! -z "$tickets" ]
+ then
+ # Check for duplicate tickets
+ dupes=$(echo "$tickets" | sed 's/ /\n/g' | sort | uniq -d);
+
+ if [ ! -z "$dupes" ]
+ then
+ echo "The following tickets are repeated:" >&2;
+ echo "$dupes" | sed 's/ /\n/g;s/^/* /g' >&2;
+ quit $ERR_FOOTER;
+ fi
+ fi
+ # Check the branch ticket is mentioned, doesn't make sense otherwise
+ if [ $ticket -gt 0 ]
+ then
+ echo "$tickets" | grep -Eq "\bPHPBB3-$ticket\b" || (
+ echo "Ticket ID [$ticket] of branch missing from list of tickets:" >&2;
+ echo "$tickets" | sed 's/ /\n/g;s/^/* /g' >&2;
+ quit $ERR_FOOTER;
+ ) || exit $?;
+ fi
+ # Got here okay exit to reality
+ exit 0;
+);
+exit $?;
diff --git a/git-tools/hooks/install b/git-tools/hooks/install
new file mode 100755
index 0000000000..a42c55a769
--- /dev/null
+++ b/git-tools/hooks/install
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Script to install the git hooks
+# by symlinking them into the .git/hooks directory
+#
+# Usage (from within git-tools/hooks):
+# ./install
+
+dir=$(dirname $0)
+
+for file in $(ls $dir)
+do
+ if [ $file != "install" ] && [ $file != "uninstall" ]
+ then
+ ln -s "../../git-tools/hooks/$file" "$dir/../../.git/hooks/$file"
+ fi
+done
diff --git a/git-tools/hooks/pre-commit b/git-tools/hooks/pre-commit
index 9719b91746..4d03359773 100755
--- a/git-tools/hooks/pre-commit
+++ b/git-tools/hooks/pre-commit
@@ -27,6 +27,13 @@ fi
error=0
errors=""
+if ! which $PHP_BIN >/dev/null 2>&1
+then
+ echo "PHP Syntax check failed:"
+ echo "PHP binary does not exist or is not in path: $PHP_BIN"
+ exit 1
+fi
+
# dash does not support $'\n':
# http://forum.soft32.com/linux2/Bug-409179-DASH-Settings-IFS-work-properly-ftopict70039.html
IFS='
diff --git a/git-tools/hooks/prepare-commit-msg b/git-tools/hooks/prepare-commit-msg
index 033cb187c7..2bf25e58a4 100755
--- a/git-tools/hooks/prepare-commit-msg
+++ b/git-tools/hooks/prepare-commit-msg
@@ -30,5 +30,13 @@ branch="$(echo "$branch" | sed "s/refs\/heads\///g")"
# * also make sure the branch name begins with bug/ or feature/
if [ "$2" = "" ]
then
- echo "[$branch] $(cat "$1")" > "$1"
+ tail="";
+
+ # Branch is prefixed with 'ticket/', append ticket ID to message
+ if [ "$branch" != "${branch##ticket/}" ];
+ then
+ tail="\n\nPHPBB3-${branch##ticket/}";
+ fi
+
+ echo "[$branch]$tail $(cat "$1")" > "$1"
fi
diff --git a/git-tools/hooks/uninstall b/git-tools/hooks/uninstall
new file mode 100755
index 0000000000..1b3b7fd2c9
--- /dev/null
+++ b/git-tools/hooks/uninstall
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Script to uninstall the git hooks
+#
+# Usage (from within git-tools/hooks):
+# ./uninstall
+
+dir=$(dirname $0)
+
+for file in $(ls $dir)
+do
+ if [ $file != "install" ] && [ $file != "uninstall" ]
+ then
+ rm -f "$dir/../../.git/hooks/$file"
+ fi
+done
diff --git a/phpBB/adm/index.php b/phpBB/adm/index.php
index 26f934f6bf..92bcf90039 100644
--- a/phpBB/adm/index.php
+++ b/phpBB/adm/index.php
@@ -432,6 +432,20 @@ function validate_config_vars($config_vars, &$cfg_array, &$error)
{
$error[] = sprintf($user->lang['SETTING_TOO_BIG'], $user->lang[$config_definition['lang']], $validator[$max]);
}
+
+ if (strpos($config_name, '_max') !== false)
+ {
+ // Min/max pairs of settings should ensure that min <= max
+ // Replace _max with _min to find the name of the minimum
+ // corresponding configuration variable
+ $min_name = str_replace('_max', '_min', $config_name);
+
+ if (isset($cfg_array[$min_name]) && is_numeric($cfg_array[$min_name]) && $cfg_array[$config_name] < $cfg_array[$min_name])
+ {
+ // A minimum value exists and the maximum value is less than it
+ $error[] = sprintf($user->lang['SETTING_TOO_LOW'], $user->lang[$config_definition['lang']], (int) $cfg_array[$min_name]);
+ }
+ }
break;
// Absolute path
@@ -533,7 +547,7 @@ function validate_config_vars($config_vars, &$cfg_array, &$error)
// Check if the path is writable
if ($config_definition['validate'] == 'wpath' || $config_definition['validate'] == 'rwpath')
{
- if (file_exists($phpbb_root_path . $cfg_array[$config_name]) && !@is_writable($phpbb_root_path . $cfg_array[$config_name]))
+ if (file_exists($phpbb_root_path . $cfg_array[$config_name]) && !phpbb_is_writable($phpbb_root_path . $cfg_array[$config_name]))
{
$error[] = sprintf($user->lang['DIRECTORY_NOT_WRITABLE'], $cfg_array[$config_name]);
}
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css
index 5f1f01c0a9..4c3fa51af3 100644
--- a/phpBB/adm/style/admin.css
+++ b/phpBB/adm/style/admin.css
@@ -670,14 +670,10 @@ legend {
position: relative;
text-transform: none;
line-height: 1.2em;
- top: 0;
+ top: -.2em;
vertical-align: middle;
}
-/* Hide from macIE \*/
-legend { top: -1.2em; }
-/* end */
-
* html legend {
margin: 0 0 -10px -7px;
line-height: 1em;
diff --git a/phpBB/common.php b/phpBB/common.php
index 9b6913e95f..c8b2fb9609 100644
--- a/phpBB/common.php
+++ b/phpBB/common.php
@@ -123,13 +123,11 @@ if (defined('IN_CRON'))
$phpbb_root_path = dirname(__FILE__) . DIRECTORY_SEPARATOR;
}
-if (!file_exists($phpbb_root_path . 'config.' . $phpEx))
+if (file_exists($phpbb_root_path . 'config.' . $phpEx))
{
- die("<p>The config.$phpEx file could not be found.</p><p><a href=\"{$phpbb_root_path}install/index.$phpEx\">Click here to install phpBB</a></p>");
+ require($phpbb_root_path . 'config.' . $phpEx);
}
-require($phpbb_root_path . 'config.' . $phpEx);
-
if (!defined('PHPBB_INSTALLED'))
{
// Redirect the user to the installer
diff --git a/phpBB/config.php b/phpBB/config.php
deleted file mode 100644
index e69de29bb2..0000000000
--- a/phpBB/config.php
+++ /dev/null
diff --git a/phpBB/docs/AUTHORS b/phpBB/docs/AUTHORS
index 84677c4e15..b3166313c3 100644
--- a/phpBB/docs/AUTHORS
+++ b/phpBB/docs/AUTHORS
@@ -26,8 +26,8 @@ phpBB Developers: A_Jelly_Doughnut (Josh Woody)
Acyd Burn (Meik Sievertsen) [Lead 09/2005 - 01/2010]
APTX (Marek A. R.)
bantu (Andreas Fischer)
- DavidMJ (David M.)
dhn (Dominik Dröscher)
+ igorw (Igor Wiedler)
kellanved (Henry Sudhof)
nickvergessen (Joas Schilling)
rxu (Ruslan Uzdenov)
@@ -49,6 +49,7 @@ phpBB Lead Developer: psoTFX (Paul S. Owen) [2001 - 09/2005]
phpBB Developers: Ashe (Ludovic Arnaud) [10/2002 - 11/2003, 06/2006 - 10/2006]
BartVB (Bart van Bragt) [11/2000 - 03/2006]
+ DavidMJ (David M.) [12/2005 - 08/2009]
GrahamJE (Graham Eames) [09/2005 - 11/2006]
Vic D'Elfant (Vic D'Elfant) [04/2007 - 04/2009]
diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html
index 3510bc448e..bb88fdc01f 100644
--- a/phpBB/docs/README.html
+++ b/phpBB/docs/README.html
@@ -242,7 +242,7 @@
<p>The phpBB Group uses a bug tracking system to store, list and manage all reported bugs, it can be found at the location listed below. Please <strong>DO NOT</strong> post bug reports to our forums, they will be locked. In addition please <strong>DO NOT</strong> use the bug tracker for support requests. Posting such a request will only see you directed to the support forums (while taking time away from working on real bugs).</p>
- <p><a href="http://www.phpbb.com/bugs/">http://www.phpbb.com/bugs/</a></p>
+ <p><a href="http://tracker.phpbb.com/">http://tracker.phpbb.com/</a></p>
<p>While we very much appreciate receiving bug reports (the more reports the more stable phpBB will be) we ask you carry out a few steps before adding new entries:</p>
diff --git a/phpBB/download/file.php b/phpBB/download/file.php
index 2154847865..5f45b88359 100644
--- a/phpBB/download/file.php
+++ b/phpBB/download/file.php
@@ -31,6 +31,12 @@ else if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'
if (isset($_GET['avatar']))
{
+ if (!defined('E_DEPRECATED'))
+ {
+ define('E_DEPRECATED', 8192);
+ }
+ error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);
+
require($phpbb_root_path . 'config.' . $phpEx);
if (!defined('PHPBB_INSTALLED') || empty($dbms) || empty($acm_type))
@@ -42,6 +48,7 @@ if (isset($_GET['avatar']))
require($phpbb_root_path . 'includes/cache.' . $phpEx);
require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
require($phpbb_root_path . 'includes/constants.' . $phpEx);
+ require($phpbb_root_path . 'includes/functions.' . $phpEx);
$db = new $sql_db();
$cache = new cache();
@@ -61,7 +68,7 @@ if (isset($_GET['avatar']))
$avatar_group = false;
$exit = false;
- if ($filename[0] === 'g')
+ if (isset($filename[0]) && $filename[0] === 'g')
{
$avatar_group = true;
$filename = substr($filename, 1);
@@ -70,7 +77,7 @@ if (isset($_GET['avatar']))
// '==' is not a bug - . as the first char is as bad as no dot at all
if (strpos($filename, '.') == false)
{
- header('HTTP/1.0 403 Forbidden');
+ send_status_line(403, 'Forbidden');
$exit = true;
}
@@ -84,7 +91,7 @@ if (isset($_GET['avatar']))
if (!$exit && !in_array($ext, array('png', 'gif', 'jpg', 'jpeg')))
{
// no way such an avatar could exist. They are not following the rules, stop the show.
- header("HTTP/1.0 403 Forbidden");
+ send_status_line(403, 'Forbidden');
$exit = true;
}
@@ -94,7 +101,7 @@ if (isset($_GET['avatar']))
if (!$filename)
{
// no way such an avatar could exist. They are not following the rules, stop the show.
- header("HTTP/1.0 403 Forbidden");
+ send_status_line(403, 'Forbidden');
}
else
{
@@ -192,7 +199,7 @@ else
$row['forum_id'] = false;
if (!$auth->acl_get('u_pm_download'))
{
- header('HTTP/1.0 403 Forbidden');
+ send_status_line(403, 'Forbidden');
trigger_error('SORRY_AUTH_VIEW_ATTACH');
}
@@ -215,7 +222,7 @@ else
if (!$allowed)
{
- header('HTTP/1.0 403 Forbidden');
+ send_status_line(403, 'Forbidden');
trigger_error('ERROR_NO_ATTACHMENT');
}
}
@@ -230,7 +237,7 @@ else
if (!download_allowed())
{
- header('HTTP/1.0 403 Forbidden');
+ send_status_line(403, 'Forbidden');
trigger_error($user->lang['LINKAGE_FORBIDDEN']);
}
@@ -376,7 +383,7 @@ function send_avatar_to_browser($file, $browser)
}
else
{
- header('HTTP/1.0 404 Not Found');
+ send_status_line(404, 'Not Found');
}
}
diff --git a/phpBB/includes/acm/acm_file.php b/phpBB/includes/acm/acm_file.php
index 5a758aa2bb..5c1876d006 100644
--- a/phpBB/includes/acm/acm_file.php
+++ b/phpBB/includes/acm/acm_file.php
@@ -78,8 +78,14 @@ class acm
if (!$this->_write('data_global'))
{
+ if (!function_exists('phpbb_is_writable'))
+ {
+ global $phpbb_root_path;
+ include($phpbb_root_path . 'includes/functions.' . $phpEx);
+ }
+
// Now, this occurred how often? ... phew, just tell the user then...
- if (!@is_writable($this->cache_dir))
+ if (!phpbb_is_writable($this->cache_dir))
{
// We need to use die() here, because else we may encounter an infinite loop (the message handler calls $cache->unload())
die($this->cache_dir . ' is NOT writable.');
@@ -707,7 +713,13 @@ class acm
*/
function remove_file($filename, $check = false)
{
- if ($check && !@is_writable($this->cache_dir))
+ if (!function_exists('phpbb_is_writable'))
+ {
+ global $phpbb_root_path, $phpEx;
+ include($phpbb_root_path . 'includes/functions.' . $phpEx);
+ }
+
+ if ($check && !phpbb_is_writable($this->cache_dir))
{
// E_USER_ERROR - not using language entry - intended.
trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR);
diff --git a/phpBB/includes/acm/acm_memory.php b/phpBB/includes/acm/acm_memory.php
index efbfd4dd62..2936ea0bae 100644
--- a/phpBB/includes/acm/acm_memory.php
+++ b/phpBB/includes/acm/acm_memory.php
@@ -407,7 +407,13 @@ class acm_memory
*/
function remove_file($filename, $check = false)
{
- if ($check && !@is_writable($this->cache_dir))
+ if (!function_exists('phpbb_is_writable'))
+ {
+ global $phpbb_root_path, $phpEx;
+ include($phpbb_root_path . 'includes/functions.' . $phpEx);
+ }
+
+ if ($check && !phpbb_is_writable($this->cache_dir))
{
// E_USER_ERROR - not using language entry - intended.
trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR);
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index 980558c830..fc5f44e14f 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -1222,7 +1222,7 @@ class acp_attachments
return;
}
- if (!is_writable($phpbb_root_path . $upload_dir))
+ if (!phpbb_is_writable($phpbb_root_path . $upload_dir))
{
$error[] = sprintf($user->lang['NO_WRITE_UPLOAD'], $upload_dir);
return;
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 927e72010e..a5e80e1f6d 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -319,6 +319,7 @@ class acp_board
'load_online_guests' => array('lang' => 'YES_ONLINE_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'load_onlinetrack' => array('lang' => 'YES_ONLINE_TRACK', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'load_birthdays' => array('lang' => 'YES_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'load_unreads_search' => array('lang' => 'YES_UNREAD_SEARCH', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'load_user_activity' => array('lang' => 'LOAD_USER_ACTIVITY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index f2f1bd80e2..4d9b9f01e0 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -1642,6 +1642,9 @@ class acp_forums
delete_attachments('topic', $topic_ids, false);
+ // Delete shadow topics pointing to topics in this forum
+ delete_topic_shadows($forum_id);
+
// Before we remove anything we make sure we are able to adjust the post counts later. ;)
$sql = 'SELECT poster_id
FROM ' . POSTS_TABLE . '
diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php
index 3df61ff4e2..60512c67b8 100644
--- a/phpBB/includes/acp/acp_groups.php
+++ b/phpBB/includes/acp/acp_groups.php
@@ -49,7 +49,7 @@ class acp_groups
// Clear some vars
- $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && @is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
+ $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
$group_row = array();
// Grab basic data for group, if group_id is set and exists
diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php
index 3310560c73..2ccc728031 100644
--- a/phpBB/includes/acp/acp_styles.php
+++ b/phpBB/includes/acp/acp_styles.php
@@ -748,7 +748,7 @@ parse_css_file = {PARSE_CSS_FILE}
$additional = '';
// If the template is stored on the filesystem try to write the file else store it in the database
- if (!$safe_mode && !$template_info['template_storedb'] && file_exists($file) && @is_writable($file))
+ if (!$safe_mode && !$template_info['template_storedb'] && file_exists($file) && phpbb_is_writable($file))
{
if (!($fp = @fopen($file, 'wb')))
{
@@ -1155,7 +1155,7 @@ parse_css_file = {PARSE_CSS_FILE}
$message = $user->lang['THEME_UPDATED'];
// If the theme is stored on the filesystem try to write the file else store it in the database
- if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($file) && @is_writable($file))
+ if (!$safe_mode && !$theme_info['theme_storedb'] && file_exists($file) && phpbb_is_writable($file))
{
if (!($fp = @fopen($file, 'wb')))
{
@@ -2040,23 +2040,18 @@ parse_css_file = {PARSE_CSS_FILE}
{
case 'tar':
$ext = '.tar';
- $mimetype = 'x-tar';
- $compress = 'compress_tar';
break;
case 'zip':
$ext = '.zip';
- $mimetype = 'zip';
break;
case 'tar.gz':
$ext = '.tar.gz';
- $mimetype = 'x-gzip';
break;
case 'tar.bz2':
$ext = '.tar.bz2';
- $mimetype = 'x-bzip2';
break;
default:
@@ -2246,7 +2241,7 @@ parse_css_file = {PARSE_CSS_FILE}
{
// a rather elaborate check we have to do here once to avoid trouble later
$check = "{$phpbb_root_path}styles/" . $style_row["{$mode}_path"] . (($mode === 'theme') ? '/theme/stylesheet.css' : '/template');
- if (($style_row["{$mode}_storedb"] != $store_db) && !$store_db && ($safe_mode || !@is_writable($check)))
+ if (($style_row["{$mode}_storedb"] != $store_db) && !$store_db && ($safe_mode || !phpbb_is_writable($check)))
{
$error[] = $user->lang['EDIT_' . strtoupper($mode) . '_STORED_DB'];
$store_db = 1;
@@ -2326,7 +2321,7 @@ parse_css_file = {PARSE_CSS_FILE}
{
$theme_data = $this->db_theme_data($style_row);
}
- else if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css"))
+ else if (!$store_db && !$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$style_row['theme_path']}/theme/stylesheet.css"))
{
$store_db = 1;
$theme_data = $style_row['theme_data'];
@@ -2357,7 +2352,7 @@ parse_css_file = {PARSE_CSS_FILE}
}
else
{
- if (!$store_db && !$safe_mode && @is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template"))
+ if (!$store_db && !$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$style_row['template_path']}/template"))
{
$err = $this->store_in_fs('template', $style_row['template_id']);
if ($err)
@@ -2531,13 +2526,21 @@ parse_css_file = {PARSE_CSS_FILE}
// Match CSS imports
$matches = array();
- preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches);
+ preg_match_all('/@import url\((["\'])(.*)\1\);/i', $stylesheet, $matches);
+
+ // remove commented stylesheets (very simple parser, allows only whitespace
+ // around an @import statement)
+ preg_match_all('#/\*\s*@import url\((["\'])(.*)\1\);\s\*/#i', $stylesheet, $commented);
+ $matches[2] = array_diff($matches[2], $commented[2]);
if (sizeof($matches))
{
foreach ($matches[0] as $idx => $match)
{
- $stylesheet = str_replace($match, acp_styles::load_css_file($theme_row['theme_path'], $matches[1][$idx]), $stylesheet);
+ if (isset($matches[2][$idx]))
+ {
+ $stylesheet = str_replace($match, acp_styles::load_css_file($theme_row['theme_path'], $matches[2][$idx]), $stylesheet);
+ }
}
}
@@ -3728,7 +3731,7 @@ parse_css_file = {PARSE_CSS_FILE}
$store_db = 0;
$error = array();
- if (!$safe_mode && @is_writable("{$phpbb_root_path}styles/{$path}/template"))
+ if (!$safe_mode && phpbb_is_writable("{$phpbb_root_path}styles/{$path}/template"))
{
$sql = 'SELECT *
FROM ' . STYLES_TEMPLATE_DATA_TABLE . "
diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php
index 1f10893781..6be0760be0 100644
--- a/phpBB/includes/acp/acp_users.php
+++ b/phpBB/includes/acp/acp_users.php
@@ -319,10 +319,7 @@ class acp_users
$server_url = generate_board_url();
- $user_actkey = gen_rand_string(10);
- $key_len = 54 - (strlen($server_url));
- $key_len = ($key_len > 6) ? $key_len : 6;
- $user_actkey = substr($user_actkey, 0, $key_len);
+ $user_actkey = gen_rand_string(mt_rand(6, 10));
$email_template = ($user_row['user_type'] == USER_NORMAL) ? 'user_reactivate_account' : 'user_resend_inactive';
if ($user_row['user_type'] == USER_NORMAL)
@@ -1701,7 +1698,7 @@ class acp_users
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && @is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
+ $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
if ($submit)
{
diff --git a/phpBB/includes/cache.php b/phpBB/includes/cache.php
index 6b1e078ca4..b50fab4ca2 100644
--- a/phpBB/includes/cache.php
+++ b/phpBB/includes/cache.php
@@ -88,7 +88,14 @@ class cache extends acm
{
if ($unicode)
{
- $censors['match'][] = '#(?<![\p{Nd}\p{L}_])(' . str_replace('\*', '[\p{Nd}\p{L}_]*?', preg_quote($row['word'], '#')) . ')(?![\p{Nd}\p{L}_])#iu';
+ // Unescape the asterisk to simplify further conversions
+ $row['word'] = str_replace('\*', '*', preg_quote($row['word'], '#'));
+
+ // Replace the asterisk inside the pattern, at the start and at the end of it with regexes
+ $row['word'] = preg_replace(array('#(?<=[\p{Nd}\p{L}_])\*(?=[\p{Nd}\p{L}_])#iu', '#^\*#', '#\*$#'), array('([\x20]*?|[\p{Nd}\p{L}_-]*?)', '[\p{Nd}\p{L}_-]*?', '[\p{Nd}\p{L}_-]*?'), $row['word']);
+
+ // Generate the final substitution
+ $censors['match'][] = '#(?<![\p{Nd}\p{L}_-])(' . $row['word'] . ')(?![\p{Nd}\p{L}_-])#iu';
}
else
{
diff --git a/phpBB/includes/captcha/plugins/captcha_abstract.php b/phpBB/includes/captcha/plugins/captcha_abstract.php
index e7b8742b05..21cacd730c 100644
--- a/phpBB/includes/captcha/plugins/captcha_abstract.php
+++ b/phpBB/includes/captcha/plugins/captcha_abstract.php
@@ -59,7 +59,7 @@ class phpbb_default_captcha
{
global $user;
- $this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
+ $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
$this->seed = hexdec(substr(unique_id(), 4, 10));
// compute $seed % 0x7fffffff
@@ -235,7 +235,7 @@ class phpbb_default_captcha
{
global $db, $user;
- $this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
+ $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
$this->confirm_id = md5(unique_id($user->ip));
$this->seed = hexdec(substr(unique_id(), 4, 10));
$this->solved = 0;
@@ -259,7 +259,7 @@ class phpbb_default_captcha
{
global $db, $user;
- $this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
+ $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
$this->seed = hexdec(substr(unique_id(), 4, 10));
$this->solved = 0;
// compute $seed % 0x7fffffff
@@ -281,7 +281,7 @@ class phpbb_default_captcha
{
global $db, $user;
- $this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
+ $this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
$this->seed = hexdec(substr(unique_id(), 4, 10));
$this->solved = 0;
// compute $seed % 0x7fffffff
diff --git a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php
index 0f0bfc4156..ea171dbe2c 100644
--- a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php
+++ b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php
@@ -314,10 +314,7 @@ class phpbb_recaptcha extends phpbb_default_captcha
}
else
{
- if ($answers[1] === 'incorrect-captcha-sol')
- {
- return $user->lang['RECAPTCHA_INCORRECT'];
- }
+ return $user->lang['RECAPTCHA_INCORRECT'];
}
}
diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php
index 819ef69c96..f4b181c6ad 100644
--- a/phpBB/includes/db/db_tools.php
+++ b/phpBB/includes/db/db_tools.php
@@ -611,7 +611,7 @@ class phpbb_db_tools
* drop_columns: Removing/Dropping columns
* add_primary_keys: adding primary keys
* add_unique_index: adding an unique index
- * add_index: adding an index
+ * add_index: adding an index (can be column:index_size if you need to provide size)
*
* The values are in this format:
* {TABLE NAME} => array(
@@ -1804,6 +1804,12 @@ class phpbb_db_tools
{
$statements = array();
+ // remove index length unless MySQL4
+ if ('mysql_40' != $this->sql_layer)
+ {
+ $column = preg_replace('#:.*$#', '', $column);
+ }
+
switch ($this->sql_layer)
{
case 'firebird':
@@ -1814,6 +1820,16 @@ class phpbb_db_tools
break;
case 'mysql_40':
+ // add index size to definition as required by MySQL4
+ foreach ($column as $i => $col)
+ {
+ if (false !== strpos($col, ':'))
+ {
+ list($col, $index_size) = explode(':', $col);
+ $column[$i] = "$col($index_size)";
+ }
+ }
+ // no break
case 'mysql_41':
$statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
break;
diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php
index 44d5722e4f..44d5722e4f 100755..100644
--- a/phpBB/includes/db/mssqlnative.php
+++ b/phpBB/includes/db/mssqlnative.php
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index bc3d721de5..9aec98dce2 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -195,10 +195,27 @@ function set_config_count($config_name, $increment, $is_dynamic = false)
/**
* Generates an alphanumeric random string of given length
+*
+* @return string
*/
function gen_rand_string($num_chars = 8)
{
+ // [a, z] + [0, 9] = 36
+ return substr(strtoupper(base_convert(unique_id(), 16, 36)), 0, $num_chars);
+}
+
+/**
+* Generates a user-friendly alphanumeric random string of given length
+* We remove 0 and O so users cannot confuse those in passwords etc.
+*
+* @return string
+*/
+function gen_rand_string_friendly($num_chars = 8)
+{
$rand_str = unique_id();
+
+ // Remove Z and Y from the base_convert(), replace 0 with Z and O with Y
+ // [a, z] + [0, 9] - {z, y} = [a, z] + [0, 9] - {0, o} = 34
$rand_str = str_replace(array('0', 'O'), array('Z', 'Y'), strtoupper(base_convert($rand_str, 16, 34)));
return substr($rand_str, 0, $num_chars);
@@ -701,7 +718,7 @@ function phpbb_chmod($filename, $perms = CHMOD_READ)
clearstatcache();
- if (is_readable($filename) && is_writable($filename))
+ if (is_readable($filename) && phpbb_is_writable($filename))
{
break;
}
@@ -711,7 +728,7 @@ function phpbb_chmod($filename, $perms = CHMOD_READ)
clearstatcache();
- if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))
+ if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || phpbb_is_writable($filename)))
{
break;
}
@@ -721,7 +738,7 @@ function phpbb_chmod($filename, $perms = CHMOD_READ)
clearstatcache();
- if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))
+ if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || phpbb_is_writable($filename)))
{
break;
}
@@ -2519,6 +2536,11 @@ function build_url($strip_vars = false)
$key = $arguments[0];
unset($arguments[0]);
+ if ($key === '')
+ {
+ continue;
+ }
+
$query[$key] = implode('=', $arguments);
}
@@ -3440,26 +3462,110 @@ function short_ipv6($ip, $length)
/**
* Wrapper for php's checkdnsrr function.
*
-* The windows failover is from the php manual
-* Please make sure to check the return value for === true and === false, since NULL could
-* be returned too.
+* @param string $host Fully-Qualified Domain Name
+* @param string $type Resource record type to lookup
+* Supported types are: MX (default), A, AAAA, NS, TXT, CNAME
+* Other types may work or may not work
+*
+* @return mixed true if entry found,
+* false if entry not found,
+* null if this function is not supported by this environment
*
-* @return true if entry found, false if not, NULL if this function is not supported by this environment
+* Since null can also be returned, you probably want to compare the result
+* with === true or === false,
+*
+* @author bantu
*/
-function phpbb_checkdnsrr($host, $type = '')
+function phpbb_checkdnsrr($host, $type = 'MX')
{
- $type = (!$type) ? 'MX' : $type;
+ // The dot indicates to search the DNS root (helps those having DNS prefixes on the same domain)
+ if (substr($host, -1) == '.')
+ {
+ $host_fqdn = $host;
+ $host = substr($host, 0, -1);
+ }
+ else
+ {
+ $host_fqdn = $host . '.';
+ }
+ // $host has format some.host.example.com
+ // $host_fqdn has format some.host.example.com.
+
+ // If we're looking for an A record we can use gethostbyname()
+ if ($type == 'A' && function_exists('gethostbyname'))
+ {
+ return (@gethostbyname($host_fqdn) == $host_fqdn) ? false : true;
+ }
+
+ // checkdnsrr() is available on Windows since PHP 5.3,
+ // but until 5.3.3 it only works for MX records
+ // See: http://bugs.php.net/bug.php?id=51844
- // Call checkdnsrr() if available. This is also the case on Windows with PHP 5.3 or later.
- if (function_exists('checkdnsrr'))
+ // Call checkdnsrr() if
+ // we're looking for an MX record or
+ // we're not on Windows or
+ // we're running a PHP version where #51844 has been fixed
+
+ // checkdnsrr() supports AAAA since 5.0.0
+ // checkdnsrr() supports TXT since 5.2.4
+ if (
+ ($type == 'MX' || DIRECTORY_SEPARATOR != '\\' || version_compare(PHP_VERSION, '5.3.3', '>=')) &&
+ ($type != 'AAAA' || version_compare(PHP_VERSION, '5.0.0', '>=')) &&
+ ($type != 'TXT' || version_compare(PHP_VERSION, '5.2.4', '>=')) &&
+ function_exists('checkdnsrr')
+ )
{
- // The dot indicates to search the DNS root (helps those having DNS prefixes on the same domain)
- return checkdnsrr($host . '.', $type);
+ return checkdnsrr($host_fqdn, $type);
}
- else if (DIRECTORY_SEPARATOR == '\\' && function_exists('exec'))
+
+ // dns_get_record() is available since PHP 5; since PHP 5.3 also on Windows,
+ // but on Windows it does not work reliable for AAAA records before PHP 5.3.1
+
+ // Call dns_get_record() if
+ // we're not looking for an AAAA record or
+ // we're not on Windows or
+ // we're running a PHP version where AAAA lookups work reliable
+ if (
+ ($type != 'AAAA' || DIRECTORY_SEPARATOR != '\\' || version_compare(PHP_VERSION, '5.3.1', '>=')) &&
+ function_exists('dns_get_record')
+ )
{
- // @exec('nslookup -retry=1 -timout=1 -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host), $output);
- @exec('nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host) . '.', $output);
+ // dns_get_record() expects an integer as second parameter
+ // We have to convert the string $type to the corresponding integer constant.
+ $type_constant = 'DNS_' . $type;
+ $type_param = (defined($type_constant)) ? constant($type_constant) : DNS_ANY;
+
+ // dns_get_record() might throw E_WARNING and return false for records that do not exist
+ $resultset = @dns_get_record($host_fqdn, $type_param);
+
+ if (empty($resultset) || !is_array($resultset))
+ {
+ return false;
+ }
+ else if ($type_param == DNS_ANY)
+ {
+ // $resultset is a non-empty array
+ return true;
+ }
+
+ foreach ($resultset as $result)
+ {
+ if (
+ isset($result['host']) && $result['host'] == $host &&
+ isset($result['type']) && $result['type'] == $type
+ )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // If we're on Windows we can still try to call nslookup via exec() as a last resort
+ if (DIRECTORY_SEPARATOR == '\\' && function_exists('exec'))
+ {
+ @exec('nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host_fqdn), $output);
// If output is empty, the nslookup failed
if (empty($output))
@@ -3469,15 +3575,66 @@ function phpbb_checkdnsrr($host, $type = '')
foreach ($output as $line)
{
- if (!trim($line))
+ $line = trim($line);
+
+ if (empty($line))
{
continue;
}
- // Valid records begin with host name:
- if (strpos($line, $host) === 0)
+ // Squash tabs and multiple whitespaces to a single whitespace.
+ $line = preg_replace('/\s+/', ' ', $line);
+
+ switch ($type)
{
- return true;
+ case 'MX':
+ if (stripos($line, "$host MX") === 0)
+ {
+ return true;
+ }
+ break;
+
+ case 'NS':
+ if (stripos($line, "$host nameserver") === 0)
+ {
+ return true;
+ }
+ break;
+
+ case 'TXT':
+ if (stripos($line, "$host text") === 0)
+ {
+ return true;
+ }
+ break;
+
+ case 'CNAME':
+ if (stripos($line, "$host canonical name") === 0)
+ {
+ return true;
+ }
+
+ default:
+ case 'A':
+ case 'AAAA':
+ if (!empty($host_matches))
+ {
+ // Second line
+ if (stripos($line, "Address: ") === 0)
+ {
+ return true;
+ }
+ else
+ {
+ $host_matches = false;
+ }
+ }
+ else if (stripos($line, "Name: $host") === 0)
+ {
+ // First line
+ $host_matches = true;
+ }
+ break;
}
}
@@ -3596,7 +3753,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
}
// Do not send 200 OK, but service unavailable on errors
- header('HTTP/1.1 503 Service Unavailable');
+ send_status_line(503, 'Service Unavailable');
garbage_collection();
@@ -4066,7 +4223,8 @@ function phpbb_http_login($param)
}
else if ($auth_result['status'] == LOGIN_ERROR_ATTEMPTS)
{
- header('HTTP/1.0 401 Unauthorized');
+ send_status_line(401, 'Unauthorized');
+
trigger_error('NOT_AUTHORISED');
}
}
@@ -4078,7 +4236,7 @@ function phpbb_http_login($param)
$param['auth_message'] = preg_replace('/[\x80-\xFF]/', '?', $param['auth_message']);
header('WWW-Authenticate: Basic realm="' . $param['auth_message'] . '"');
- header('HTTP/1.0 401 Unauthorized');
+ send_status_line(401, 'Unauthorized');
trigger_error('NOT_AUTHORISED');
}
@@ -4308,6 +4466,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'S_ENABLE_FEEDS_TOPICS_ACTIVE' => ($config['feed_topics_active']) ? true : false,
'S_ENABLE_FEEDS_NEWS' => ($s_feed_news) ? true : false,
+ 'S_LOAD_UNREADS' => ($config['load_unreads_search']) ? true : false,
+
'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_admin.php b/phpBB/includes/functions_admin.php
index 89892feb30..3178d35c34 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -1125,53 +1125,65 @@ function delete_attachments($mode, $ids, $resync = true)
}
/**
-* Remove topic shadows
+* Deletes shadow topics pointing to a specified forum.
+*
+* @param int $forum_id The forum id
+* @param string $sql_more Additional WHERE statement, e.g. t.topic_time < (time() - 1234)
+* @param bool $auto_sync Will call sync() if this is true
+*
+* @return array Array with affected forums
+*
+* @author bantu
*/
-function delete_topic_shadows($max_age, $forum_id = '', $auto_sync = true)
+function delete_topic_shadows($forum_id, $sql_more = '', $auto_sync = true)
{
- $where = (is_array($forum_id)) ? 'AND ' . $db->sql_in_set('t.forum_id', array_map('intval', $forum_id)) : (($forum_id) ? 'AND t.forum_id = ' . (int) $forum_id : '');
+ global $db;
- switch ($db->sql_layer)
+ if (!$forum_id)
{
- case 'mysql4':
- case 'mysqli':
- $sql = 'DELETE t.*
- FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
- WHERE t.topic_moved_id = t2.topic_id
- AND t.topic_time < ' . (time() - $max_age)
- . $where;
- $db->sql_query($sql);
- break;
+ // Nothing to do.
+ return;
+ }
- default:
- $sql = 'SELECT t.topic_id
- FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2
- WHERE t.topic_moved_id = t2.topic_id
- AND t.topic_time < ' . (time() - $max_age)
- . $where;
- $result = $db->sql_query($sql);
+ // Set of affected forums we have to resync
+ $sync_forum_ids = array();
- $topic_ids = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $topic_ids[] = $row['topic_id'];
- }
- $db->sql_freeresult($result);
+ // Amount of topics we select and delete at once.
+ $batch_size = 500;
- if (sizeof($topic_ids))
- {
- $sql = 'DELETE FROM ' . TOPICS_TABLE . '
- WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
- $db->sql_query($sql);
- }
- break;
+ do
+ {
+ $sql = 'SELECT t2.forum_id, t2.topic_id
+ FROM ' . TOPICS_TABLE . ' t2, ' . TOPICS_TABLE . ' t
+ WHERE t2.topic_moved_id = t.topic_id
+ AND t.forum_id = ' . (int) $forum_id . '
+ ' . (($sql_more) ? 'AND ' . $sql_more : '');
+ $result = $db->sql_query_limit($sql, $batch_size);
+
+ $topic_ids = array();
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $topic_ids[] = (int) $row['topic_id'];
+
+ $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id'];
+ }
+ $db->sql_freeresult($result);
+
+ if (!empty($topic_ids))
+ {
+ $sql = 'DELETE FROM ' . TOPICS_TABLE . '
+ WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
+ $db->sql_query($sql);
+ }
}
+ while (sizeof($topic_ids) == $batch_size);
if ($auto_sync)
{
- $where_type = ($forum_id) ? 'forum_id' : '';
- sync('forum', $where_type, $forum_id, true, true);
+ sync('forum', 'forum_id', $sync_forum_ids, true, true);
}
+
+ return $sync_forum_ids;
}
/**
diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php
index f422eaa8c1..455debd939 100644
--- a/phpBB/includes/functions_compress.php
+++ b/phpBB/includes/functions_compress.php
@@ -53,13 +53,18 @@ class compress
$filelist = filelist("$phpbb_root_path$src", '', '*');
krsort($filelist);
+ /**
+ * Commented out, as adding the folders produces corrupted archives
if ($src_path)
{
$this->data($src_path, '', true, stat("$phpbb_root_path$src"));
}
+ */
foreach ($filelist as $path => $file_ary)
{
+ /**
+ * Commented out, as adding the folders produces corrupted archives
if ($path)
{
// Same as for src_path
@@ -68,6 +73,7 @@ class compress
$this->data("$src_path$path", '', true, stat("$phpbb_root_path$src$path"));
}
+ */
foreach ($file_ary as $file)
{
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index c035fd3739..9e26043b39 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -2306,7 +2306,7 @@ function copy_file($src, $trg, $overwrite = false, $die_on_failure = true, $sour
}
}
- if (!is_writable($path))
+ if (!phpbb_is_writable($path))
{
@chmod($path, 0777);
}
@@ -2341,7 +2341,7 @@ function copy_dir($src, $trg, $copy_subdirs = true, $overwrite = false, $die_on_
@chmod($trg_path, 0777);
}
- if (!@is_writable($trg_path))
+ if (!phpbb_is_writable($trg_path))
{
$bad_dirs[] = path($config['script_path']) . $trg;
}
@@ -2408,7 +2408,7 @@ function copy_dir($src, $trg, $copy_subdirs = true, $overwrite = false, $die_on_
@chmod($trg_path . $dir, 0777);
}
- if (!@is_writable($trg_path . $dir))
+ if (!phpbb_is_writable($trg_path . $dir))
{
$bad_dirs[] = $trg . $dir;
$bad_dirs[] = $trg_path . $dir;
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index f6f90575d4..6fd87db663 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -2537,7 +2537,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
if ($mode == 'post' || $mode == 'reply' || $mode == 'quote')
{
// Mark this topic as posted to
- markread('post', $data['forum_id'], $data['topic_id'], $data['post_time']);
+ markread('post', $data['forum_id'], $data['topic_id']);
}
// Mark this topic as read
@@ -2583,7 +2583,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
}
// Send Notifications
- if ($mode != 'edit' && $mode != 'delete' && $post_approval)
+ if (($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_approval)
{
user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id']);
}
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index c4cbb7ca1e..4c34bc92ca 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -1380,6 +1380,9 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)
}
}
+ // First of all make sure the subject are having the correct length.
+ $subject = truncate_string($subject);
+
$db->sql_transaction('begin');
$sql = '';
diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php
index fa1cc98e10..3937cf9c21 100644
--- a/phpBB/includes/functions_profile_fields.php
+++ b/phpBB/includes/functions_profile_fields.php
@@ -543,8 +543,9 @@ class custom_profile
else if ($day && $month && $year)
{
global $user;
- // d/m/y 00:00 GMT isn't necessarily on the same d/m/y in the user's timezone, so add the timezone seconds
- return $user->format_date(gmmktime(0, 0, 0, $month, $day, $year) + $user->timezone + $user->dst, $user->lang['DATE_FORMAT'], true);
+ // Date should display as the same date for every user regardless of timezone, so remove offset
+ // to compensate for the offset added by user::format_date()
+ return $user->format_date(gmmktime(0, 0, 0, $month, $day, $year) - ($user->timezone + $user->dst), $user->lang['DATE_FORMAT'], true);
}
return $value;
diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php
index 51fed45ebd..7f09cc1640 100644
--- a/phpBB/includes/functions_upload.php
+++ b/phpBB/includes/functions_upload.php
@@ -58,8 +58,9 @@ class filespec
$this->filename = $upload_ary['tmp_name'];
$this->filesize = $upload_ary['size'];
- $name = trim(utf8_htmlspecialchars(utf8_basename($upload_ary['name'])));
- $this->realname = $this->uploadname = (STRIP) ? stripslashes($name) : $name;
+ $name = (STRIP) ? stripslashes($upload_ary['name']) : $upload_ary['name'];
+ $name = trim(utf8_htmlspecialchars(utf8_basename($name)));
+ $this->realname = $this->uploadname = $name;
$this->mimetype = $upload_ary['type'];
// Opera adds the name to the mime type
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index 0b26f28864..f2c80705ba 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -766,7 +766,8 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas
if (sizeof($ban_other) == 3 && ((int)$ban_other[0] < 9999) &&
(strlen($ban_other[0]) == 4) && (strlen($ban_other[1]) == 2) && (strlen($ban_other[2]) == 2))
{
- $ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0]));
+ $time_offset = (isset($user->timezone) && isset($user->dst)) ? (int) $user->timezone + (int) $user->dst : 0;
+ $ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0]) - $time_offset);
}
else
{
@@ -1229,22 +1230,39 @@ function user_unban($mode, $ban)
}
/**
-* Whois facility
+* Internet Protocol Address Whois
+* RFC3912: WHOIS Protocol Specification
*
-* @link http://tools.ietf.org/html/rfc3912 RFC3912: WHOIS Protocol Specification
+* @param string $ip Ip address, either IPv4 or IPv6.
+*
+* @return string Empty string if not a valid ip address.
+* Otherwise make_clickable()'ed whois result.
*/
function user_ipwhois($ip)
{
- $ipwhois = '';
+ if (empty($ip))
+ {
+ return '';
+ }
- // Check IP
- // Only supporting IPv4 at the moment...
- if (empty($ip) || !preg_match(get_preg_expression('ipv4'), $ip))
+ if (preg_match(get_preg_expression('ipv4'), $ip))
+ {
+ // IPv4 address
+ $whois_host = 'whois.arin.net.';
+ }
+ else if (preg_match(get_preg_expression('ipv6'), $ip))
+ {
+ // IPv6 address
+ $whois_host = 'whois.sixxs.net.';
+ }
+ else
{
return '';
}
- if (($fsk = @fsockopen('whois.arin.net', 43)))
+ $ipwhois = '';
+
+ if (($fsk = @fsockopen($whois_host, 43)))
{
// CRLF as per RFC3912
fputs($fsk, "$ip\r\n");
@@ -1257,7 +1275,7 @@ function user_ipwhois($ip)
$match = array();
- // Test for referrals from ARIN to other whois databases, roll on rwhois
+ // Test for referrals from $whois_host to other whois databases, roll on rwhois
if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match))
{
if (strpos($match[1], ':') !== false)
@@ -1285,7 +1303,7 @@ function user_ipwhois($ip)
@fclose($fsk);
}
- // Use the result from ARIN if we don't get any result here
+ // Use the result from $whois_host if we don't get any result here
$ipwhois = (empty($buffer)) ? $ipwhois : $buffer;
}
@@ -2326,7 +2344,7 @@ function avatar_process_user(&$error, $custom_userdata = false, $can_upload = nu
// Can we upload?
if (is_null($can_upload))
{
- $can_upload = ($config['allow_avatar_upload'] && file_exists($phpbb_root_path . $config['avatar_path']) && @is_writable($phpbb_root_path . $config['avatar_path']) && $change_avatar && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
+ $can_upload = ($config['allow_avatar_upload'] && file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $change_avatar && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
}
if ((!empty($_FILES['uploadfile']['name']) || $data['uploadurl']) && $can_upload)
diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php
index 80c3559649..d5551f5114 100644
--- a/phpBB/includes/mcp/mcp_main.php
+++ b/phpBB/includes/mcp/mcp_main.php
@@ -1048,6 +1048,35 @@ function mcp_fork_topic($topic_ids)
$total_posts = 0;
$new_topic_id_list = array();
+ if ($topic_data['enable_indexing'])
+ {
+ // Select the search method and do some additional checks to ensure it can actually be utilised
+ $search_type = basename($config['search_type']);
+
+ if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
+ {
+ trigger_error('NO_SUCH_SEARCH_MODULE');
+ }
+
+ if (!class_exists($search_type))
+ {
+ include("{$phpbb_root_path}includes/search/$search_type.$phpEx");
+ }
+
+ $error = false;
+ $search = new $search_type($error);
+ $search_mode = 'post';
+
+ if ($error)
+ {
+ trigger_error($error);
+ }
+ }
+ else
+ {
+ $search_type = false;
+ }
+
foreach ($topic_data as $topic_id => $topic_row)
{
$sql_ary = array(
@@ -1158,6 +1187,12 @@ function mcp_fork_topic($topic_ids)
// Copy whether the topic is dotted
markread('post', $to_forum_id, $new_topic_id, 0, $row['poster_id']);
+ if ($search_type)
+ {
+ $search->index($search_mode, $sql_ary['post_id'], $sql_ary['post_text'], $sql_ary['post_subject'], $sql_ary['poster_id'], ($topic_row['topic_type'] == POST_GLOBAL) ? 0 : $to_forum_id);
+ $search_mode = 'reply'; // After one we index replies
+ }
+
// Copy Attachments
if ($row['post_attachment'])
{
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index e43881fab2..c419da5574 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -428,7 +428,7 @@ class mcp_queue
'POST_ID' => $row['post_id'],
'FORUM_NAME' => (!$global_topic) ? $forum_names[$row['forum_id']] : $user->lang['GLOBAL_ANNOUNCEMENT'],
- 'POST_SUBJECT' => $row['post_subject'],
+ 'POST_SUBJECT' => ($row['post_subject'] != '') ? $row['post_subject'] : $user->lang['NO_SUBJECT'],
'TOPIC_TITLE' => $row['topic_title'],
'POST_TIME' => $user->format_date($row['post_time']))
);
diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php
index c89e92711e..727e3aaffb 100644
--- a/phpBB/includes/search/fulltext_native.php
+++ b/phpBB/includes/search/fulltext_native.php
@@ -83,7 +83,9 @@ class fulltext_native extends search_backend
{
global $db, $user, $config;
- $keywords = trim($this->cleanup($keywords, '+-|()*'));
+ $tokens = '+-|()*';
+
+ $keywords = trim($this->cleanup($keywords, $tokens));
// allow word|word|word without brackets
if ((strpos($keywords, ' ') === false) && (strpos($keywords, '|') !== false) && (strpos($keywords, '(') === false))
@@ -114,6 +116,15 @@ class fulltext_native extends search_backend
case ' ':
$keywords[$i] = '|';
break;
+ case '*':
+ if ($i === 0 || ($keywords[$i - 1] !== '*' && strcspn($keywords[$i - 1], $tokens) === 0))
+ {
+ if ($i === $n - 1 || ($keywords[$i + 1] !== '*' && strcspn($keywords[$i + 1], $tokens) === 0))
+ {
+ $keywords = substr($keywords, 0, $i) . substr($keywords, $i + 1);
+ }
+ }
+ break;
}
}
else
diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php
index e157053e61..5f5b39fe27 100644
--- a/phpBB/includes/session.php
+++ b/phpBB/includes/session.php
@@ -285,6 +285,17 @@ class session
break;
}
+ // Quick check for IPv4-mapped address in IPv6
+ if (stripos($ip, '::ffff:') === 0)
+ {
+ $ipv4 = substr($ip, 7);
+
+ if (preg_match(get_preg_expression('ipv4'), $ipv4))
+ {
+ $ip = $ipv4;
+ }
+ }
+
// Use the last in chain
$this->ip = $ip;
}
@@ -748,7 +759,7 @@ class session
if ((int) $row['sessions'] > (int) $config['active_sessions'])
{
- header('HTTP/1.1 503 Service Unavailable');
+ send_status_line(503, 'Service Unavailable');
trigger_error('BOARD_UNAVAILABLE');
}
}
@@ -1821,7 +1832,7 @@ class user extends session
{
if ($this->data['is_bot'])
{
- header('HTTP/1.1 503 Service Unavailable');
+ send_status_line(503, 'Service Unavailable');
}
$message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
@@ -1831,7 +1842,7 @@ class user extends session
// Is load exceeded?
if ($config['limit_load'] && $this->load !== false)
{
- if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN'))
+ if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN') && !defined('IN_ADMIN'))
{
// Set board disabled to true to let the admins/mods get the proper notification
$config['board_disable'] = '1';
@@ -1840,7 +1851,7 @@ class user extends session
{
if ($this->data['is_bot'])
{
- header('HTTP/1.1 503 Service Unavailable');
+ send_status_line(503, 'Service Unavailable');
}
trigger_error('BOARD_UNAVAILABLE');
}
diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php
index 423d9b718a..1c055a4823 100644
--- a/phpBB/includes/ucp/ucp_groups.php
+++ b/phpBB/includes/ucp/ucp_groups.php
@@ -490,7 +490,7 @@ class ucp_groups
$avatar_select = basename(request_var('avatar_select', ''));
$category = basename(request_var('category', ''));
- $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && @is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
+ $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $file_uploads) ? true : false;
// Did we submit?
if ($update)
diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php
index 26968e1382..16700c490c 100644
--- a/phpBB/includes/ucp/ucp_pm_viewmessage.php
+++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php
@@ -309,7 +309,7 @@ function get_user_information($user_id, $user_row)
get_user_rank($user_row['user_rank'], $user_row['user_posts'], $user_row['rank_title'], $user_row['rank_image'], $user_row['rank_image_src']);
- if (!empty($user_row['user_allow_viewemail']) || $auth->acl_get('a_email'))
+ if ((!empty($user_row['user_allow_viewemail']) && $auth->acl_get('u_sendemail')) || $auth->acl_get('a_email'))
{
$user_row['email'] = ($config['board_email_form'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&amp;u=$user_id") : ((($config['board_hide_emails'] && !$auth->acl_get('a_email')) || empty($user_row['user_email'])) ? '' : 'mailto:' . $user_row['user_email']);
}
diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php
index 363a4803b6..c099e3b3fa 100644
--- a/phpBB/includes/ucp/ucp_profile.php
+++ b/phpBB/includes/ucp/ucp_profile.php
@@ -141,10 +141,7 @@ class ucp_profile
$server_url = generate_board_url();
- $user_actkey = gen_rand_string(10);
- $key_len = 54 - (strlen($server_url));
- $key_len = ($key_len > 6) ? $key_len : 6;
- $user_actkey = substr($user_actkey, 0, $key_len);
+ $user_actkey = gen_rand_string(mt_rand(6, 10));
$messenger = new messenger(false);
@@ -564,7 +561,7 @@ class ucp_profile
$avatar_select = basename(request_var('avatar_select', ''));
$category = basename(request_var('category', ''));
- $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && @is_writable($phpbb_root_path . $config['avatar_path']) && $auth->acl_get('u_chgavatar') && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
+ $can_upload = (file_exists($phpbb_root_path . $config['avatar_path']) && phpbb_is_writable($phpbb_root_path . $config['avatar_path']) && $auth->acl_get('u_chgavatar') && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on')) ? true : false;
add_form_key('ucp_avatar');
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 9656a4a3af..7fd99da55a 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -286,11 +286,7 @@ class ucp_register
$config['require_activation'] == USER_ACTIVATION_SELF ||
$config['require_activation'] == USER_ACTIVATION_ADMIN) && $config['email_enable'])
{
- $user_actkey = gen_rand_string(10);
- $key_len = 54 - (strlen($server_url));
- $key_len = ($key_len < 6) ? 6 : $key_len;
- $user_actkey = substr($user_actkey, 0, $key_len);
-
+ $user_actkey = gen_rand_string(mt_rand(6, 10));
$user_type = USER_INACTIVE;
$user_inactive_reason = INACTIVE_REGISTER;
$user_inactive_time = time();
diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php
index f9b792de20..cb89ad99be 100644
--- a/phpBB/includes/ucp/ucp_remind.php
+++ b/phpBB/includes/ucp/ucp_remind.php
@@ -79,10 +79,10 @@ class ucp_remind
// Make password at least 8 characters long, make it longer if admin wants to.
// gen_rand_string() however has a limit of 12 or 13.
- $user_password = gen_rand_string(max(8, rand((int) $config['min_pass_chars'], (int) $config['max_pass_chars'])));
+ $user_password = gen_rand_string_friendly(max(8, mt_rand((int) $config['min_pass_chars'], (int) $config['max_pass_chars'])));
// For the activation key a random length between 6 and 10 will do.
- $user_actkey = gen_rand_string(rand(6, 10));
+ $user_actkey = gen_rand_string(mt_rand(6, 10));
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_newpasswd = '" . $db->sql_escape(phpbb_hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "'
diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php
index b80c7673e3..78224dd5da 100644
--- a/phpBB/install/convertors/functions_phpbb20.php
+++ b/phpBB/install/convertors/functions_phpbb20.php
@@ -1239,9 +1239,9 @@ function phpbb_prepare_message($message)
// Already the new user id ;)
$user_id = $convert->row['poster_id'];
+ $message = str_replace('<br />', "\n", $message);
$message = str_replace('<', '&lt;', $message);
$message = str_replace('>', '&gt;', $message);
- $message = str_replace('<br />', "\n", $message);
// make the post UTF-8
$message = phpbb_set_encoding($message);
diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php
index 83bbbf4577..ca4ef817be 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -119,6 +119,7 @@ $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false);
unset($dbpasswd);
$user->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
+$user->ip = (stripos($user->ip, '::ffff:') === 0) ? substr($user->ip, 7) : $user->ip;
$sql = "SELECT config_value
FROM " . CONFIG_TABLE . "
@@ -880,7 +881,7 @@ function database_update_info()
'pm_id' => array('pm_id'),
),
POSTS_TABLE => array(
- 'post_username' => array('post_username'),
+ 'post_username' => array('post_username:255'),
),
),
),
@@ -1749,6 +1750,55 @@ function change_database_data(&$no_updates, $version)
_sql($sql, $errored, $error_ary);
// end Bing Bot addition
+ // Delete shadow topics pointing to not existing topics
+ $batch_size = 500;
+
+ // Set of affected forums we have to resync
+ $sync_forum_ids = array();
+
+ do
+ {
+ $sql_array = array(
+ 'SELECT' => 't1.topic_id, t1.forum_id',
+ 'FROM' => array(
+ TOPICS_TABLE => 't1',
+ ),
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(TOPICS_TABLE => 't2'),
+ 'ON' => 't1.topic_moved_id = t2.topic_id',
+ ),
+ ),
+ 'WHERE' => 't1.topic_moved_id <> 0
+ AND t2.topic_id IS NULL',
+ );
+ $sql = $db->sql_build_query('SELECT', $sql_array);
+ $result = $db->sql_query_limit($sql, $batch_size);
+
+ $topic_ids = array();
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $topic_ids[] = (int) $row['topic_id'];
+
+ $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id'];
+ }
+ $db->sql_freeresult($result);
+
+ if (!empty($topic_ids))
+ {
+ $sql = 'DELETE FROM ' . TOPICS_TABLE . '
+ WHERE ' . $db->sql_in_set('topic_id', $topic_ids);
+ $db->sql_query($sql);
+ }
+ }
+ while (sizeof($topic_ids) == $batch_size);
+
+ // Sync the forums we have deleted shadow topics from.
+ sync('forum', 'forum_id', $sync_forum_ids, true, true);
+
+ // Unread posts search load switch
+ set_config('load_unreads_search', '1');
+
$no_updates = false;
break;
}
@@ -2095,7 +2145,7 @@ class updater_db_tools
* drop_columns: Removing/Dropping columns
* add_primary_keys: adding primary keys
* add_unique_index: adding an unique index
- * add_index: adding an index
+ * add_index: adding an index (can be column:index_size if you need to provide size)
*
* The values are in this format:
* {TABLE NAME} => array(
@@ -3474,6 +3524,12 @@ class updater_db_tools
{
$statements = array();
+ // remove index length unless MySQL4
+ if ('mysql_40' != $this->sql_layer)
+ {
+ $column = preg_replace('#:.*$#', '', $column);
+ }
+
switch ($this->sql_layer)
{
case 'firebird':
@@ -3484,6 +3540,16 @@ class updater_db_tools
break;
case 'mysql_40':
+ // add index size to definition as required by MySQL4
+ foreach ($column as $i => $col)
+ {
+ if (false !== strpos($col, ':'))
+ {
+ list($col, $index_size) = explode(':', $col);
+ $column[$i] = "$col($index_size)";
+ }
+ }
+ // no break
case 'mysql_41':
$statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
break;
diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php
index 8c3ffd61a8..814b50cf68 100644
--- a/phpBB/install/install_convert.php
+++ b/phpBB/install/install_convert.php
@@ -835,7 +835,7 @@ class install_convert extends module
$this->p_master->error($user->lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__);
}
- if (!$local_path || !@is_writable($phpbb_root_path . $local_path))
+ if (!$local_path || !phpbb_is_writable($phpbb_root_path . $local_path))
{
if (!$local_path)
{
diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php
index 4c22db07b2..2dd58584f4 100644
--- a/phpBB/install/install_install.php
+++ b/phpBB/install/install_install.php
@@ -486,7 +486,7 @@ class install_install extends module
$write = $exists = true;
if (file_exists($phpbb_root_path . $dir))
{
- if (!@is_writable($phpbb_root_path . $dir))
+ if (!phpbb_is_writable($phpbb_root_path . $dir))
{
$write = false;
}
@@ -906,7 +906,7 @@ class install_install extends module
$config_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused!
// Attempt to write out the config file directly. If it works, this is the easiest way to do it ...
- if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && is_writable($phpbb_root_path . 'config.' . $phpEx)) || is_writable($phpbb_root_path))
+ if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx)) || phpbb_is_writable($phpbb_root_path))
{
// Assume it will work ... if nothing goes wrong below
$written = true;
@@ -1236,6 +1236,7 @@ class install_install extends module
$current_time = time();
$user_ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
+ $user_ip = (stripos($user_ip, '::ffff:') === 0) ? substr($user_ip, 7) : $user_ip;
if ($data['script_path'] !== '/')
{
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index e815615eef..a25b68ba39 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -168,6 +168,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_online_time',
INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_onlinetrack', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_search', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_tplcompile', '0');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_unreads_search', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_user_activity', '1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_attachments', '3');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_attachments_pm', '1');
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index 8b12a926b0..77deba6e19 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -177,8 +177,8 @@ $lang = array_merge($lang, array(
'MIN_CHAR_LIMIT_EXPLAIN' => 'The minimum number of characters the user need to enter within a post/private message.',
'POSTING' => 'Posting',
'POSTS_PER_PAGE' => 'Posts per page',
- 'QUOTE_DEPTH_LIMIT' => 'Maximum nested quotes per post',
- 'QUOTE_DEPTH_LIMIT_EXPLAIN' => 'Maximum number of nested quotes in a post. Set to 0 for unlimited depth.',
+ 'QUOTE_DEPTH_LIMIT' => 'Maximum nesting depth for quotes',
+ 'QUOTE_DEPTH_LIMIT_EXPLAIN' => 'Maximum quote nesting depth in a post. Set to 0 for unlimited depth.',
'SMILIES_LIMIT' => 'Maximum smilies per post',
'SMILIES_LIMIT_EXPLAIN' => 'Maximum number of smilies in a post. Set to 0 for unlimited smilies.',
'SMILIES_PER_PAGE' => 'Smilies per page',
@@ -375,6 +375,7 @@ $lang = array_merge($lang, array(
'YES_POST_MARKING_EXPLAIN' => 'Indicates whether user has posted to a topic.',
'YES_READ_MARKING' => 'Enable server-side topic marking',
'YES_READ_MARKING_EXPLAIN' => 'Stores read/unread status information in the database rather than a cookie.',
+ 'YES_UNREAD_SEARCH' => 'Enable search for unread posts',
));
// Auth settings
diff --git a/phpBB/language/en/search.php b/phpBB/language/en/search.php
index be92391a4e..d93fe6b56a 100644
--- a/phpBB/language/en/search.php
+++ b/phpBB/language/en/search.php
@@ -62,6 +62,7 @@ $lang = array_merge($lang, array(
'NO_SEARCH' => 'Sorry but you are not permitted to use the search system.',
'NO_SEARCH_RESULTS' => 'No suitable matches were found.',
'NO_SEARCH_TIME' => 'Sorry but you cannot use search at this time. Please try again in a few minutes.',
+ 'NO_SEARCH_UNREADS' => 'Sorry but searching for unread posts has been disabled on this board.',
'WORD_IN_NO_POST' => 'No posts were found because the word <strong>%s</strong> is not contained in any post.',
'WORDS_IN_NO_POST' => 'No posts were found because the words <strong>%s</strong> are not contained in any post.',
diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php
index b46230b10a..2fa2d11ee1 100644
--- a/phpBB/memberlist.php
+++ b/phpBB/memberlist.php
@@ -1607,7 +1607,7 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f
$rank_title = $rank_img = $rank_img_src = '';
get_user_rank($data['user_rank'], (($user_id == ANONYMOUS) ? false : $data['user_posts']), $rank_title, $rank_img, $rank_img_src);
- if (!empty($data['user_allow_viewemail']) || $auth->acl_get('a_user'))
+ if ((!empty($data['user_allow_viewemail']) && $auth->acl_get('u_sendemail')) || $auth->acl_get('a_user'))
{
$email = ($config['board_email_form'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=email&amp;u=' . $user_id) : (($config['board_hide_emails'] && !$auth->acl_get('a_user')) ? '' : 'mailto:' . $data['user_email']);
}
diff --git a/phpBB/posting.php b/phpBB/posting.php
index df063ef391..f775699cee 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -402,6 +402,19 @@ if ($post_data['poll_start'])
$db->sql_freeresult($result);
}
+if ($mode == 'edit')
+{
+ $original_poll_data = array(
+ 'poll_title' => $post_data['poll_title'],
+ 'poll_length' => $post_data['poll_length'],
+ 'poll_max_options' => $post_data['poll_max_options'],
+ 'poll_option_text' => implode("\n", $post_data['poll_options']),
+ 'poll_start' => $post_data['poll_start'],
+ 'poll_last_vote' => $post_data['poll_last_vote'],
+ 'poll_vote_change' => $post_data['poll_vote_change'],
+ );
+}
+
$orig_poll_options_size = sizeof($post_data['poll_options']);
$message_parser = new parse_message();
@@ -912,6 +925,22 @@ if ($submit || $preview || $refresh)
$message_parser->warn_msg[] = $user->lang['NO_DELETE_POLL_OPTIONS'];
}*/
}
+ else if (!$auth->acl_get('f_poll', $forum_id) && ($mode == 'edit') && ($post_id == $post_data['topic_first_post_id']) && ($original_poll_data['poll_title'] != ''))
+ {
+ // We have a poll but the editing user is not permitted to create/edit it.
+ // So we just keep the original poll-data.
+ $poll = array_merge($original_poll_data, array(
+ 'enable_bbcode' => $post_data['enable_bbcode'],
+ 'enable_urls' => $post_data['enable_urls'],
+ 'enable_smilies' => $post_data['enable_smilies'],
+ 'img_status' => $img_status,
+ ));
+
+ $message_parser->parse_poll($poll);
+
+ $post_data['poll_options'] = (isset($poll['poll_options'])) ? $poll['poll_options'] : '';
+ $post_data['poll_title'] = (isset($poll['poll_title'])) ? $poll['poll_title'] : '';
+ }
else
{
$poll = array();
@@ -1271,7 +1300,7 @@ $attachment_data = $message_parser->attachment_data;
$filename_data = $message_parser->filename_data;
$post_data['post_text'] = $message_parser->message;
-if (sizeof($post_data['poll_options']) && $post_data['poll_title'])
+if (sizeof($post_data['poll_options']) || !empty($post_data['poll_title']))
{
$message_parser->message = $post_data['poll_title'];
$message_parser->bbcode_uid = $post_data['bbcode_uid'];
diff --git a/phpBB/search.php b/phpBB/search.php
index 1e1e42d01f..2a13e20477 100644
--- a/phpBB/search.php
+++ b/phpBB/search.php
@@ -61,10 +61,18 @@ if ($search_id == 'egosearch')
}
}
-// Search for unread posts needs user to be logged in if topics tracking for guests is disabled
-if ($search_id == 'unreadposts' && !$config['load_anon_lastread'] && !$user->data['is_registered'])
+// Search for unread posts needs to be allowed and user to be logged in if topics tracking for guests is disabled
+if ($search_id == 'unreadposts')
{
- login_box('', $user->lang['LOGIN_EXPLAIN_UNREADSEARCH']);
+ if (!$config['load_unreads_search'])
+ {
+ $template->assign_var('S_NO_SEARCH', true);
+ trigger_error('NO_SEARCH_UNREADS');
+ }
+ else if (!$config['load_anon_lastread'] && !$user->data['is_registered'])
+ {
+ login_box('', $user->lang['LOGIN_EXPLAIN_UNREADSEARCH']);
+ }
}
// Is user able to search? Has search been disabled?
@@ -81,9 +89,10 @@ if ($user->load && $config['limit_search_load'] && ($user->load > doubleval($con
trigger_error('NO_SEARCH_TIME');
}
-// Check flood limit ... if applicable
+// It is applicable if the configuration setting is non-zero, and the user cannot
+// ignore the flood setting, and the search is a keyword search.
$interval = ($user->data['user_id'] == ANONYMOUS) ? $config['search_anonymous_interval'] : $config['search_interval'];
-if ($interval && !$auth->acl_get('u_ignoreflood'))
+if ($interval && !in_array($search_id, array('unreadposts', 'unanswered', 'active_topics', 'egosearch')) && !$auth->acl_get('u_ignoreflood'))
{
if ($user->data['user_last_search'] > time() - $interval)
{
@@ -891,7 +900,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
'S_TOPIC_GLOBAL' => (!$forum_id) ? true : false,
'S_TOPIC_TYPE' => $row['topic_type'],
- 'S_USER_POSTED' => (!empty($row['mark_type'])) ? true : false,
+ 'S_USER_POSTED' => (!empty($row['topic_posted'])) ? true : false,
'S_UNREAD_TOPIC' => $unread_topic,
'S_TOPIC_REPORTED' => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $forum_id)) ? true : false,
diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html
index 17790eb78a..af2077141c 100644
--- a/phpBB/styles/prosilver/template/index_body.html
+++ b/phpBB/styles/prosilver/template/index_body.html
@@ -6,7 +6,7 @@
<!-- IF S_DISPLAY_SEARCH or (S_USER_LOGGED_IN and not S_IS_BOT) -->
<ul class="linklist">
<!-- IF S_DISPLAY_SEARCH -->
- <li><a href="{U_SEARCH_UNANSWERED}">{L_SEARCH_UNANSWERED}</a><!-- IF S_USER_LOGGED_IN --> &bull; <a href="{U_SEARCH_UNREAD}">{L_SEARCH_UNREAD}</a> &bull; <a href="{U_SEARCH_NEW}">{L_SEARCH_NEW}</a><!-- ENDIF --> &bull; <a href="{U_SEARCH_ACTIVE_TOPICS}">{L_SEARCH_ACTIVE_TOPICS}</a></li>
+ <li><a href="{U_SEARCH_UNANSWERED}">{L_SEARCH_UNANSWERED}</a><!-- IF S_USER_LOGGED_IN --><!-- IF S_LOAD_UNREADS --> &bull; <a href="{U_SEARCH_UNREAD}">{L_SEARCH_UNREAD}</a><!-- ENDIF --> &bull; <a href="{U_SEARCH_NEW}">{L_SEARCH_NEW}</a><!-- ENDIF --> &bull; <a href="{U_SEARCH_ACTIVE_TOPICS}">{L_SEARCH_ACTIVE_TOPICS}</a></li>
<!-- ENDIF -->
<!-- IF not S_IS_BOT and U_MARK_FORUMS --><li class="rightside"><a href="{U_MARK_FORUMS}" accesskey="m">{L_MARK_FORUMS_READ}</a></li><!-- ENDIF -->
</ul>
diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html
index fe111aaa45..e52ccd6434 100644
--- a/phpBB/styles/prosilver/template/login_body.html
+++ b/phpBB/styles/prosilver/template/login_body.html
@@ -32,11 +32,11 @@
</dl>
<!-- ENDIF -->
+ {S_LOGIN_REDIRECT}
<dl>
<dt>&nbsp;</dt>
<dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" tabindex="6" value="{L_LOGIN}" class="button1" /></dd>
</dl>
- {S_LOGIN_REDIRECT}
</fieldset>
</div>
<span class="corners-bottom"><span></span></span></div>
diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css
index 109312ac1b..f441784d85 100644
--- a/phpBB/styles/prosilver/theme/bidi.css
+++ b/phpBB/styles/prosilver/theme/bidi.css
@@ -236,6 +236,7 @@
}
.rtl a.top2 {
+ background-position: 100% 50%;
padding-left: 0;
padding-right: 15px;
}
diff --git a/phpBB/styles/prosilver/theme/print.css b/phpBB/styles/prosilver/theme/print.css
index 6dfb5c4726..68600b030b 100644
--- a/phpBB/styles/prosilver/theme/print.css
+++ b/phpBB/styles/prosilver/theme/print.css
@@ -140,3 +140,5 @@ div.spacer { clear: both; }
/* Accessibility tweaks: Mozilla.org */
.skip_link { display: none; }
+
+dl.codebox dt { display: none; } \ No newline at end of file
diff --git a/phpBB/styles/subsilver2/template/login_body.html b/phpBB/styles/subsilver2/template/login_body.html
index 51f7068b5f..503de9e69e 100644
--- a/phpBB/styles/subsilver2/template/login_body.html
+++ b/phpBB/styles/subsilver2/template/login_body.html
@@ -72,12 +72,12 @@
<!-- INCLUDE {CAPTCHA_TEMPLATE} -->
<!-- ENDIF -->
+{S_LOGIN_REDIRECT}
<tr>
<td class="cat" <!-- IF not S_ADMIN_AUTH or S_CONFIRM_CODE -->colspan="2"<!-- ENDIF --> align="center">{S_HIDDEN_FIELDS}<input type="submit" name="login" class="btnmain" value="{L_LOGIN}" tabindex="5" /></td>
</tr>
</table>
{S_FORM_TOKEN}
-{S_LOGIN_REDIRECT}
</form>
<br clear="all" />
diff --git a/phpBB/styles/subsilver2/template/overall_header.html b/phpBB/styles/subsilver2/template/overall_header.html
index 963f5160dd..37691d4f1c 100644
--- a/phpBB/styles/subsilver2/template/overall_header.html
+++ b/phpBB/styles/subsilver2/template/overall_header.html
@@ -202,7 +202,7 @@ function marklist(id, name, state)
<p class="searchbar">
<span style="float: {S_CONTENT_FLOW_BEGIN};"><a href="{U_SEARCH_UNANSWERED}">{L_SEARCH_UNANSWERED}</a> | <a href="{U_SEARCH_ACTIVE_TOPICS}">{L_SEARCH_ACTIVE_TOPICS}</a></span>
<!-- IF S_USER_LOGGED_IN -->
- <span style="float: {S_CONTENT_FLOW_END};"><a href="{U_SEARCH_UNREAD}">{L_SEARCH_UNREAD}</a> | <a href="{U_SEARCH_NEW}">{L_SEARCH_NEW}</a> | <a href="{U_SEARCH_SELF}">{L_SEARCH_SELF}</a></span>
+ <span style="float: {S_CONTENT_FLOW_END};"><!-- IF S_LOAD_UNREADS --><a href="{U_SEARCH_UNREAD}">{L_SEARCH_UNREAD}</a> | <!-- ENDIF --><a href="{U_SEARCH_NEW}">{L_SEARCH_NEW}</a> | <a href="{U_SEARCH_SELF}">{L_SEARCH_SELF}</a></span>
<!-- ENDIF -->
</p>
<!-- ENDIF -->
diff --git a/phpBB/ucp.php b/phpBB/ucp.php
index 994fe064a1..f5a2ec9648 100644
--- a/phpBB/ucp.php
+++ b/phpBB/ucp.php
@@ -22,7 +22,7 @@ require($phpbb_root_path . 'includes/functions_module.' . $phpEx);
$id = request_var('i', '');
$mode = request_var('mode', '');
-if ($mode == 'login' || $mode == 'logout' || $mode == 'confirm')
+if (in_array($mode, array('login', 'logout', 'confirm', 'sendpassword', 'activate')))
{
define('IN_LOGIN', true);
}
diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php
index 8926d5a40b..498088c5c8 100644
--- a/phpBB/viewtopic.php
+++ b/phpBB/viewtopic.php
@@ -1146,7 +1146,7 @@ while ($row = $db->sql_fetchrow($result))
get_user_rank($row['user_rank'], $row['user_posts'], $user_cache[$poster_id]['rank_title'], $user_cache[$poster_id]['rank_image'], $user_cache[$poster_id]['rank_image_src']);
- if (!empty($row['user_allow_viewemail']) || $auth->acl_get('a_email'))
+ if ((!empty($row['user_allow_viewemail']) && $auth->acl_get('u_sendemail')) || $auth->acl_get('a_email'))
{
$user_cache[$poster_id]['email'] = ($config['board_email_form'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&amp;u=$poster_id") : (($config['board_hide_emails'] && !$auth->acl_get('a_email')) ? '' : 'mailto:' . $row['user_email']);
}
diff --git a/tests/all_tests.php b/tests/all_tests.php
index 7894d688ee..bae7725ee7 100644
--- a/tests/all_tests.php
+++ b/tests/all_tests.php
@@ -24,6 +24,8 @@ require_once 'template/all_tests.php';
require_once 'text_processing/all_tests.php';
require_once 'dbal/all_tests.php';
require_once 'regex/all_tests.php';
+require_once 'network/all_tests.php';
+require_once 'random/all_tests.php';
// exclude the test directory from code coverage reports
PHPUnit_Util_Filter::addDirectoryToFilter('./');
@@ -46,6 +48,8 @@ class phpbb_all_tests
$suite->addTest(phpbb_text_processing_all_tests::suite());
$suite->addTest(phpbb_dbal_all_tests::suite());
$suite->addTest(phpbb_regex_all_tests::suite());
+ $suite->addTest(phpbb_network_all_tests::suite());
+ $suite->addTest(phpbb_random_all_tests::suite());
return $suite;
}
diff --git a/tests/dbal/dbal.php b/tests/dbal/dbal.php
index 1cce891ca9..663323ad61 100644
--- a/tests/dbal/dbal.php
+++ b/tests/dbal/dbal.php
@@ -244,8 +244,9 @@ class phpbb_dbal_test extends phpbb_database_test_case
array('username_clean' => 'bertie'))),
// These here would throw errors and therefor $result should be false.
- array('user_id', array(), false, false, false, true),
- array('user_id', array(), true, false, false, true),
+ // Removing for now because SQLite accepts empty IN() syntax
+ /*array('user_id', array(), false, false, false, true),
+ array('user_id', array(), true, false, false, true),*/
);
}
diff --git a/tests/network/all_tests.php b/tests/network/all_tests.php
new file mode 100644
index 0000000000..b500647f81
--- /dev/null
+++ b/tests/network/all_tests.php
@@ -0,0 +1,40 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2010 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+if (!defined('PHPUnit_MAIN_METHOD'))
+{
+ define('PHPUnit_MAIN_METHOD', 'phpbb_network_all_tests::main');
+}
+
+require_once 'test_framework/framework.php';
+require_once 'PHPUnit/TextUI/TestRunner.php';
+
+require_once 'network/checkdnsrr.php';
+
+class phpbb_network_all_tests
+{
+ public static function main()
+ {
+ PHPUnit_TextUI_TestRunner::run(self::suite());
+ }
+
+ public static function suite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('phpBB Network Functions');
+
+ $suite->addTestSuite('phpbb_network_checkdnsrr_test');
+
+ return $suite;
+ }
+}
+
+if (PHPUnit_MAIN_METHOD == 'phpbb_network_all_tests::main')
+{
+ phpbb_network_all_tests::main();
+}
diff --git a/tests/network/checkdnsrr.php b/tests/network/checkdnsrr.php
new file mode 100644
index 0000000000..57fe2761cc
--- /dev/null
+++ b/tests/network/checkdnsrr.php
@@ -0,0 +1,63 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2010 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+require_once 'test_framework/framework.php';
+require_once '../phpBB/includes/functions.php';
+
+class phpbb_network_checkdnsrr_test extends phpbb_test_case
+{
+ public function data_provider()
+ {
+ return array(
+ // Existing MX record
+ array('phpbb.com', 'MX', true),
+
+ // Non-existing MX record
+ array('does-not-exist.phpbb.com', 'MX', false),
+
+ // Existing A record
+ array('www.phpbb.com', 'A', true),
+
+ // Non-existing A record
+ array('does-not-exist.phpbb.com', 'A', false),
+
+ // Existing AAAA record
+ array('www.six.heise.de', 'AAAA', true),
+
+ // Non-existing AAAA record
+ array('does-not-exist.phpbb.com', 'AAAA', false),
+
+ // Existing CNAME record
+ array('news.cnet.com', 'CNAME', true),
+
+ // Non-existing CNAME record
+ array('does-not-exist.phpbb.com', 'CNAME', false),
+
+ // Existing NS record
+ array('phpbb.com', 'NS', true),
+
+ // Non-existing NS record
+ array('does-not-exist', 'NS', false),
+
+ // Existing TXT record
+ array('phpbb.com', 'TXT', true),
+
+ // Non-existing TXT record
+ array('does-not-exist', 'TXT', false),
+ );
+ }
+
+ /**
+ * @dataProvider data_provider
+ */
+ public function test_checkdnsrr($host, $type, $expected)
+ {
+ $this->assertEquals($expected, phpbb_checkdnsrr($host, $type));
+ }
+}
diff --git a/tests/random/all_tests.php b/tests/random/all_tests.php
new file mode 100644
index 0000000000..c6ffe78024
--- /dev/null
+++ b/tests/random/all_tests.php
@@ -0,0 +1,40 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2010 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+if (!defined('PHPUnit_MAIN_METHOD'))
+{
+ define('PHPUnit_MAIN_METHOD', 'phpbb_random_all_tests::main');
+}
+
+require_once 'test_framework/framework.php';
+require_once 'PHPUnit/TextUI/TestRunner.php';
+
+require_once 'random/gen_rand_string.php';
+
+class phpbb_random_all_tests
+{
+ public static function main()
+ {
+ PHPUnit_TextUI_TestRunner::run(self::suite());
+ }
+
+ public static function suite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('phpBB Random Functions');
+
+ $suite->addTestSuite('phpbb_random_gen_rand_string_test');
+
+ return $suite;
+ }
+}
+
+if (PHPUnit_MAIN_METHOD == 'phpbb_random_all_tests::main')
+{
+ phpbb_random_all_tests::main();
+}
diff --git a/tests/random/gen_rand_string.php b/tests/random/gen_rand_string.php
new file mode 100644
index 0000000000..cd58d14ed3
--- /dev/null
+++ b/tests/random/gen_rand_string.php
@@ -0,0 +1,63 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2010 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+require_once 'test_framework/framework.php';
+require_once '../phpBB/includes/functions.php';
+
+class phpbb_random_gen_rand_string_test extends phpbb_test_case
+{
+ const TEST_COUNT = 100;
+ const MIN_STRING_LENGTH = 1;
+ const MAX_STRING_LENGTH = 15;
+
+ public function setUp()
+ {
+ global $config;
+
+ if (!is_array($config))
+ {
+ $config = array();
+ }
+
+ $config['rand_seed'] = '';
+ $config['rand_seed_last_update'] = time() + 600;
+ }
+
+ public function test_gen_rand_string()
+ {
+ for ($tests = 0; $tests <= self::TEST_COUNT; ++$tests)
+ {
+ for ($num_chars = self::MIN_STRING_LENGTH; $num_chars <= self::MAX_STRING_LENGTH; ++$num_chars)
+ {
+ $random_string = gen_rand_string($num_chars);
+ $random_string_length = strlen($random_string);
+
+ $this->assertTrue($random_string_length >= self::MIN_STRING_LENGTH);
+ $this->assertTrue($random_string_length <= $num_chars);
+ $this->assertRegExp('#^[A-Z0-9]+$#', $random_string);
+ }
+ }
+ }
+
+ public function test_gen_rand_string_friendly()
+ {
+ for ($tests = 0; $tests <= self::TEST_COUNT; ++$tests)
+ {
+ for ($num_chars = self::MIN_STRING_LENGTH; $num_chars <= self::MAX_STRING_LENGTH; ++$num_chars)
+ {
+ $random_string = gen_rand_string_friendly($num_chars);
+ $random_string_length = strlen($random_string);
+
+ $this->assertTrue($random_string_length >= self::MIN_STRING_LENGTH);
+ $this->assertTrue($random_string_length <= $num_chars);
+ $this->assertRegExp('#^[A-NP-Z1-9]+$#', $random_string);
+ }
+ }
+ }
+}
diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php
index d558874c6f..f6bf420ebc 100644
--- a/tests/test_framework/phpbb_database_test_case.php
+++ b/tests/test_framework/phpbb_database_test_case.php
@@ -19,7 +19,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
}
}
- function get_dbms_data($dbms)
+ public function get_dbms_data($dbms)
{
$available_dbms = array(
'firebird' => array(
@@ -65,7 +65,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
'sqlite' => array(
'SCHEMA' => 'sqlite',
'DELIM' => ';',
- 'PDO' => 'sqlite',
+ 'PDO' => 'sqlite2',
),
);
@@ -79,10 +79,13 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
}
}
- function split_sql_file($sql, $delimiter)
+ // NOTE: This function is not the same as split_sql_file from functions_install
+ public function split_sql_file($sql, $dbms)
{
+ $dbms_data = $this->get_dbms_data($dbms);
+
$sql = str_replace("\r" , '', $sql);
- $data = preg_split('/' . preg_quote($delimiter, '/') . '$/m', $sql);
+ $data = preg_split('/' . preg_quote($dbms_data['DELIM'], '/') . '$/m', $sql);
$data = array_map('trim', $data);
@@ -94,6 +97,15 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
unset($data[key($data)]);
}
+ if ($dbms == 'sqlite')
+ {
+ // trim # off query to satisfy sqlite
+ foreach ($data as $i => $query)
+ {
+ $data[$i] = preg_replace('/^#.*$/m', "\n", $query);
+ }
+ }
+
return $data;
}
@@ -108,21 +120,42 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
if ($already_connected)
{
- $pdo = new PDO($dbms_data['PDO'] . ':host=' . $database_config['dbhost'] . ';dbname=' . $database_config['dbname'], $database_config['dbuser'], $database_config['dbpasswd']);
+ if ($database_config['dbms'] == 'sqlite')
+ {
+ $pdo = new PDO($dbms_data['PDO'] . ':' . $database_config['dbhost']);
+ }
+ else
+ {
+ $pdo = new PDO($dbms_data['PDO'] . ':host=' . $database_config['dbhost'] . ';dbname=' . $database_config['dbname'], $database_config['dbuser'], $database_config['dbpasswd']);
+ }
}
else
{
- $pdo = new PDO($dbms_data['PDO'] . ':host=' . $database_config['dbhost'] . ';', $database_config['dbuser'], $database_config['dbpasswd']);
-
- try
+ if ($database_config['dbms'] == 'sqlite')
{
- $pdo->exec('DROP DATABASE ' . $database_config['dbname']);
+ // delete existing database
+ if (file_exists($database_config['dbhost']))
+ {
+ unlink($database_config['dbhost']);
+ }
+
+ $pdo = new PDO($dbms_data['PDO'] . ':' . $database_config['dbhost']);
}
- catch (PDOException $e){} // ignore non existent db
+ else
+ {
+ $pdo = new PDO($dbms_data['PDO'] . ':host=' . $database_config['dbhost'] . ';', $database_config['dbuser'], $database_config['dbpasswd']);try
+ {
+ $pdo->exec('DROP DATABASE ' . $database_config['dbname']);
+ }
+ catch (PDOException $e){} // ignore non existent db
- $pdo->exec('CREATE DATABASE ' . $database_config['dbname']);
+ $pdo->exec('CREATE DATABASE ' . $database_config['dbname']);
+
+ $pdo = new PDO($dbms_data['PDO'] . ':host=' . $database_config['dbhost'] . ';dbname=' . $database_config['dbname'], $database_config['dbuser'], $database_config['dbpasswd']);
+ }
- $pdo = new PDO($dbms_data['PDO'] . ':host=' . $database_config['dbhost'] . ';dbname=' . $database_config['dbname'], $database_config['dbuser'], $database_config['dbpasswd']);
+ // good for debug
+ // $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($database_config['dbms'] == 'mysql')
{
@@ -141,7 +174,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
unset($row, $sth);
}
- $sql_query = $this->split_sql_file(file_get_contents("../phpBB/install/schemas/{$dbms_data['SCHEMA']}_schema.sql"), $dbms_data['DELIM']);
+ $sql_query = $this->split_sql_file(file_get_contents("../phpBB/install/schemas/{$dbms_data['SCHEMA']}_schema.sql"), $database_config['dbms']);
foreach ($sql_query as $sql)
{
diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php
index 0c5932e1ad..7c026e496e 100644
--- a/tests/test_framework/phpbb_test_case_helpers.php
+++ b/tests/test_framework/phpbb_test_case_helpers.php
@@ -22,7 +22,32 @@ class phpbb_test_case_helpers
{
static $show_error = true;
- if (!file_exists('test_config.php'))
+ if (file_exists('test_config.php'))
+ {
+ include('test_config.php');
+
+ return array(
+ 'dbms' => $dbms,
+ 'dbhost' => $dbhost,
+ 'dbport' => $dbport,
+ 'dbname' => $dbname,
+ 'dbuser' => $dbuser,
+ 'dbpasswd' => $dbpasswd,
+ );
+ }
+ else if (extension_loaded('sqlite') && version_compare(PHPUnit_Runner_Version::id(), '3.4.15', '>='))
+ {
+ // Silently use sqlite
+ return array(
+ 'dbms' => 'sqlite',
+ 'dbhost' => 'phpbb_unit_tests.sqlite2', // filename
+ 'dbport' => '',
+ 'dbname' => '',
+ 'dbuser' => '',
+ 'dbpasswd' => '',
+ );
+ }
+ else
{
if ($show_error)
{
@@ -46,16 +71,6 @@ class phpbb_test_case_helpers
NOTE: The database is dropped and recreated with the phpbb-db-schema! Do NOT specify a database with important data.", E_USER_ERROR);
}
- include('test_config.php');
-
- return array(
- 'dbms' => $dbms,
- 'dbhost' => $dbhost,
- 'dbport' => $dbport,
- 'dbname' => $dbname,
- 'dbuser' => $dbuser,
- 'dbpasswd' => $dbpasswd,
- );
}
public function new_dbal()