diff options
Diffstat (limited to 'phpBB/includes')
57 files changed, 3187 insertions, 1081 deletions
diff --git a/phpBB/includes/acm/acm_file.php b/phpBB/includes/acm/acm_file.php index f58f925506..f9ff92e19d 100644 --- a/phpBB/includes/acm/acm_file.php +++ b/phpBB/includes/acm/acm_file.php @@ -89,7 +89,7 @@ class acm if ($fp = @fopen($this->cache_dir . 'data_global.' . $phpEx, 'wb')) { @flock($fp, LOCK_EX); - fwrite($fp, "<?php\n\$this->vars = " . var_export($this->vars, true) . ";\n\n\$this->var_expires = " . var_export($this->var_expires, true) . "\n?>"); + fwrite($fp, "<?php\nif (!defined('IN_PHPBB')) exit;\n\$this->vars = " . var_export($this->vars, true) . ";\n\n\$this->var_expires = " . var_export($this->var_expires, true) . "\n?>"); @flock($fp, LOCK_UN); fclose($fp); @@ -99,17 +99,20 @@ class acm include($phpbb_root_path . 'includes/functions.' . $phpEx); } - phpbb_chmod($this->cache_dir . 'data_global.' . $phpEx, CHMOD_WRITE); + phpbb_chmod($this->cache_dir . 'data_global.' . $phpEx, CHMOD_READ | CHMOD_WRITE); } else { // Now, this occurred how often? ... phew, just tell the user then... if (!@is_writable($this->cache_dir)) { - trigger_error($this->cache_dir . ' is NOT writable.', E_USER_ERROR); + // 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.'); + exit; } - trigger_error('Not able to open ' . $this->cache_dir . 'data_global.' . $phpEx, E_USER_ERROR); + die('Not able to open ' . $this->cache_dir . 'data_global.' . $phpEx); + exit; } $this->is_modified = false; @@ -199,7 +202,7 @@ class acm if ($fp = @fopen($this->cache_dir . "data{$var_name}.$phpEx", 'wb')) { @flock($fp, LOCK_EX); - fwrite($fp, "<?php\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n\n\$data = " . (sizeof($var) ? "unserialize(" . var_export(serialize($var), true) . ");" : 'array();') . "\n\n?>"); + fwrite($fp, "<?php\nif (!defined('IN_PHPBB')) exit;\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n\n\$data = " . (sizeof($var) ? "unserialize(" . var_export(serialize($var), true) . ");" : 'array();') . "\n\n?>"); @flock($fp, LOCK_UN); fclose($fp); @@ -209,7 +212,7 @@ class acm include($phpbb_root_path . 'includes/functions.' . $phpEx); } - phpbb_chmod($this->cache_dir . "data{$var_name}.$phpEx", CHMOD_WRITE); + phpbb_chmod($this->cache_dir . "data{$var_name}.$phpEx", CHMOD_READ | CHMOD_WRITE); } } else @@ -421,7 +424,7 @@ class acm } $db->sql_freeresult($query_result); - $file = "<?php\n\n/* " . str_replace('*/', '*\/', $query) . " */\n"; + $file = "<?php\nif (!defined('IN_PHPBB')) exit;\n\n/* " . str_replace('*/', '*\/', $query) . " */\n"; $file .= "\n\$expired = (time() > " . (time() + $ttl) . ") ? true : false;\nif (\$expired) { return; }\n"; fwrite($fp, $file . "\n\$this->sql_rowset[\$query_id] = " . (sizeof($this->sql_rowset[$query_id]) ? "unserialize(" . var_export(serialize($this->sql_rowset[$query_id]), true) . ");" : 'array();') . "\n\n?>"); @@ -434,7 +437,7 @@ class acm include($phpbb_root_path . 'includes/functions.' . $phpEx); } - phpbb_chmod($filename, CHMOD_WRITE); + phpbb_chmod($filename, CHMOD_READ | CHMOD_WRITE); $query_result = $query_id; } diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 15e9e6ab62..ef20b48cec 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -1003,8 +1003,8 @@ class acp_attachments if ($files_added) { - set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true); - set_config('num_files', $config['num_files'] + $files_added, true); + set_config_count('upload_dir_size', $space_taken, true); + set_config_count('num_files', $files_added, true); } } } diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php index 90aa4e8683..93505e1590 100644 --- a/phpBB/includes/acp/acp_captcha.php +++ b/phpBB/includes/acp/acp_captcha.php @@ -28,22 +28,26 @@ class acp_captcha global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; $user->add_lang('acp/board'); - - $captcha_vars = array( 'captcha_gd_x_grid' => 'CAPTCHA_GD_X_GRID', 'captcha_gd_y_grid' => 'CAPTCHA_GD_Y_GRID', 'captcha_gd_foreground_noise' => 'CAPTCHA_GD_FOREGROUND_NOISE', - 'captcha_gd' => 'CAPTCHA_GD_PREVIEWED' + 'captcha_gd' => 'CAPTCHA_GD_PREVIEWED', + 'captcha_gd_wave' => 'CAPTCHA_GD_WAVE', + 'captcha_gd_3d_noise' => 'CAPTCHA_GD_3D_NOISE', + 'captcha_gd_fonts' => 'CAPTCHA_GD_FONTS', + ); if (isset($_GET['demo'])) { $captcha_vars = array_keys($captcha_vars); + foreach ($captcha_vars as $captcha_var) { $config[$captcha_var] = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, 0) : $config[$captcha_var]; } + if ($config['captcha_gd']) { include($phpbb_root_path . 'includes/captcha/captcha_gd.' . $phpEx); @@ -52,14 +56,16 @@ class acp_captcha { include($phpbb_root_path . 'includes/captcha/captcha_non_gd.' . $phpEx); } + $captcha = new captcha(); - $captcha->execute(gen_rand_string(mt_rand(5, 8)), time()); + $captcha->execute(gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)), time()); exit; } $config_vars = array( 'enable_confirm' => 'REG_ENABLE', 'enable_post_confirm' => 'POST_ENABLE', + 'confirm_refresh' => 'CONFIRM_REFRESH', 'captcha_gd' => 'CAPTCHA_GD', ); @@ -73,11 +79,14 @@ class acp_captcha if ($submit && check_form_key($form_key)) { $config_vars = array_keys($config_vars); + foreach ($config_vars as $config_var) { set_config($config_var, request_var($config_var, '')); } + $captcha_vars = array_keys($captcha_vars); + foreach ($captcha_vars as $captcha_var) { $value = request_var($captcha_var, 0); @@ -86,35 +95,39 @@ class acp_captcha set_config($captcha_var, $value); } } + + add_log('admin', 'LOG_CONFIG_VISUAL'); trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } else if ($submit) { - trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action)); + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action)); } else { - $preview_image_src = append_sid(append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&demo=demo")); + if (@extension_loaded('gd')) { $template->assign_var('GD', true); } + foreach ($config_vars as $config_var => $template_var) { $template->assign_var($template_var, (isset($_REQUEST[$config_var])) ? request_var($config_var, '') : $config[$config_var]) ; } + foreach ($captcha_vars as $captcha_var => $template_var) { $var = (isset($_REQUEST[$captcha_var])) ? request_var($captcha_var, 0) : $config[$captcha_var]; $template->assign_var($template_var, $var); $preview_image_src .= "&$captcha_var=" . $var; } + $template->assign_vars(array( 'CAPTCHA_PREVIEW' => $preview_image_src, 'PREVIEW' => isset($_POST['preview']), )); - } } } diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index e2ca66b2f3..856b867c9a 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -27,7 +27,7 @@ class acp_database { global $cache, $db, $user, $auth, $template, $table_prefix; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; - + $user->add_lang('acp/database'); $this->tpl_name = 'acp_database'; @@ -82,6 +82,7 @@ class acp_database } @set_time_limit(1200); + @set_time_limit(0); $time = time(); @@ -187,7 +188,7 @@ class acp_database $template->assign_vars(array( 'U_ACTION' => $this->u_action . '&action=download' )); - + $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2'); foreach ($available_methods as $type => $module) @@ -424,27 +425,37 @@ class acp_database $dir = $phpbb_root_path . 'store/'; $dh = @opendir($dir); + $backup_files = array(); + if ($dh) { while (($file = readdir($dh)) !== false) { if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches)) { - $supported = in_array($matches[2], $methods); - - if ($supported == 'true') + if (in_array($matches[2], $methods)) { - $template->assign_block_vars('files', array( - 'FILE' => $file, - 'NAME' => gmdate("d-m-Y H:i:s", $matches[1]), - 'SUPPORTED' => $supported - )); + $backup_files[gmdate("d-m-Y H:i:s", $matches[1])] = $file; } } } closedir($dh); } + if (!empty($backup_files)) + { + krsort($backup_files); + + foreach ($backup_files as $name => $file) + { + $template->assign_block_vars('files', array( + 'FILE' => $file, + 'NAME' => $name, + 'SUPPORTED' => true, + )); + } + } + $template->assign_vars(array( 'U_ACTION' => $this->u_action . '&action=submit' )); @@ -508,7 +519,7 @@ class base_extractor header('Pragma: no-cache'); header("Content-Type: $mimetype; name=\"$name\""); header("Content-disposition: attachment; filename=$name"); - + switch ($format) { case 'bzip2': @@ -527,14 +538,14 @@ class base_extractor break; } } - + if ($store == true) { global $phpbb_root_path; $file = $phpbb_root_path . 'store/' . $filename . $ext; - + $this->fp = $open($file, 'w'); - + if (!$this->fp) { trigger_error('Unable to write temporary file to storage folder', E_USER_ERROR); @@ -545,6 +556,7 @@ class base_extractor function write_end() { static $close; + if ($this->store) { if ($close === null) @@ -662,11 +674,11 @@ class mysql_extractor extends base_extractor if ($result != false) { $fields_cnt = mysqli_num_fields($result); - + // Get field information $field = mysqli_fetch_fields($result); $field_set = array(); - + for ($j = 0; $j < $fields_cnt; $j++) { $field_set[] = $field[$j]->name; @@ -679,7 +691,7 @@ class mysql_extractor extends base_extractor $first_set = true; $query_len = 0; $max_len = get_usable_memory(); - + while ($row = mysqli_fetch_row($result)) { $values = array(); @@ -750,7 +762,7 @@ class mysql_extractor extends base_extractor $field[] = mysql_fetch_field($result, $i); } $field_set = array(); - + for ($j = 0; $j < $fields_cnt; $j++) { $field_set[] = $field[$j]->name; @@ -966,7 +978,7 @@ class sqlite_extractor extends base_extractor $ar[] = $row; } $db->sql_freeresult($result); - + foreach ($ar as $value) { if (strpos($value['name'], 'autoindex') !== false) @@ -1124,7 +1136,7 @@ class postgres_extractor extends base_extractor $sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n"; } $db->sql_freeresult($result); - + $field_query = "SELECT a.attnum, a.attname as field, t.typname as type, a.attlen as length, a.atttypmod as lengthvar, a.attnotnull as notnull FROM pg_class c, pg_attribute a, pg_type t WHERE c.relname = '" . $db->sql_escape($table_name) . "' @@ -1188,7 +1200,7 @@ class postgres_extractor extends base_extractor { $line .= ' NOT NULL'; } - + $lines[] = $line; } $db->sql_freeresult($result); @@ -1388,33 +1400,33 @@ class mssql_extractor extends base_extractor $sql_data .= "GO\n"; $sql_data .= "\nCREATE TABLE [$table_name] (\n"; $rows = array(); - + $text_flag = false; - + $sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$table_name'"; $result = $db->sql_query($sql); - + while ($row = $db->sql_fetchrow($result)) { $line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]"; - + if ($row['DATA_TYPE'] == 'text') { $text_flag = true; } - + if ($row['IS_IDENTITY']) { $line .= ' IDENTITY (1 , 1)'; } - + if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text') { $line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')'; } - + if ($row['IS_NULLABLE'] == 'YES') { $line .= ' NULL'; @@ -1423,27 +1435,27 @@ class mssql_extractor extends base_extractor { $line .= ' NOT NULL'; } - + if ($row['COLUMN_DEFAULT']) { $line .= ' DEFAULT ' . $row['COLUMN_DEFAULT']; } - + $rows[] = $line; } $db->sql_freeresult($result); - + $sql_data .= implode(",\n", $rows); $sql_data .= "\n) ON [PRIMARY]"; - + if ($text_flag) { $sql_data .= " TEXTIMAGE_ON [PRIMARY]"; } - + $sql_data .= "\nGO\n\n"; $rows = array(); - + $sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = '$table_name'"; @@ -1463,7 +1475,7 @@ class mssql_extractor extends base_extractor $sql_data .= "\n\t) ON [PRIMARY] \nGO\n"; } $db->sql_freeresult($result); - + $index = array(); $sql = "EXEC sp_statistics '$table_name'"; $result = $db->sql_query($sql); @@ -1475,12 +1487,12 @@ class mssql_extractor extends base_extractor } } $db->sql_freeresult($result); - + foreach ($index as $index_name => $column_name) { $index[$index_name] = implode(', ', $column_name); } - + foreach ($index as $index_name => $columns) { $sql_data .= "\nCREATE INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n"; @@ -1508,7 +1520,7 @@ class mssql_extractor extends base_extractor $ary_type = $ary_name = array(); $ident_set = false; $sql_data = ''; - + // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; @@ -1602,7 +1614,7 @@ class mssql_extractor extends base_extractor $ary_type = $ary_name = array(); $ident_set = false; $sql_data = ''; - + // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; @@ -1819,7 +1831,7 @@ class oracle_extractor extends base_extractor { global $db; $ary_type = $ary_name = array(); - + // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; @@ -1915,7 +1927,7 @@ class firebird_extractor extends base_extractor { global $db; $ary_type = $ary_name = array(); - + // Grab all of the data from current table. $sql = "SELECT * FROM $table_name"; @@ -2244,7 +2256,7 @@ function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192) { $record = ''; $delim_len = strlen($delim); - + while (!$eof($fp)) { $pos = strpos($record, $delim); diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php index 125908c296..350693a630 100644 --- a/phpBB/includes/acp/acp_email.php +++ b/phpBB/includes/acp/acp_email.php @@ -108,7 +108,7 @@ class acp_email $db->sql_freeresult($result); trigger_error($user->lang['NO_USER'] . adm_back_link($this->u_action), E_USER_WARNING); } - + $i = $j = 0; // Send with BCC, no more than 50 recipients for one mail (to not exceed the limit) @@ -121,7 +121,7 @@ class acp_email { if (($row['user_notify_type'] == NOTIFY_EMAIL && $row['user_email']) || ($row['user_notify_type'] == NOTIFY_IM && $row['user_jabber']) || - ($row['user_notify_type'] == NOTIFY_BOTH && $row['user_email'] && $row['user_jabber'])) + ($row['user_notify_type'] == NOTIFY_BOTH && ($row['user_email'] || $row['user_jabber']))) { if ($i == $max_chunk_size || $row['user_lang'] != $old_lang || $row['user_notify_type'] != $old_notify_type) { @@ -173,7 +173,7 @@ class acp_email $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']); $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']); $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip); - + $messenger->subject(htmlspecialchars_decode($subject)); $messenger->set_mail_priority($priority); @@ -181,7 +181,7 @@ class acp_email 'CONTACT_EMAIL' => $config['board_contact'], 'MESSAGE' => htmlspecialchars_decode($message)) ); - + if (!($messenger->send($used_method))) { $errored = true; @@ -239,7 +239,7 @@ class acp_email $select_list = '<option value="0"' . ((!$group_id) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_USERS'] . '</option>'; $select_list .= group_select_options($group_id, $exclude); - + $s_priority_options = '<option value="' . MAIL_LOW_PRIORITY . '">' . $user->lang['MAIL_LOW_PRIORITY'] . '</option>'; $s_priority_options .= '<option value="' . MAIL_NORMAL_PRIORITY . '" selected="selected">' . $user->lang['MAIL_NORMAL_PRIORITY'] . '</option>'; $s_priority_options .= '<option value="' . MAIL_HIGH_PRIORITY . '">' . $user->lang['MAIL_HIGH_PRIORITY'] . '</option>'; diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index 6095fdd48b..bf5242ace6 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -183,7 +183,7 @@ class acp_forums $forum_perm_from = request_var('forum_perm_from', 0); // Copy permissions? - if ($forum_perm_from && !empty($forum_perm_from) && $forum_perm_from != $forum_data['forum_id'] && + if (!empty($forum_perm_from) && $forum_perm_from != $forum_data['forum_id'] && (($action != 'edit') || empty($forum_id) || ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth')))) { // if we edit a forum delete current permissions first @@ -560,13 +560,12 @@ class acp_forums FROM ' . FORUMS_TABLE . ' WHERE forum_type = ' . FORUM_POST . " AND forum_id <> $forum_id"; - $result = $db->sql_query($sql); + $result = $db->sql_query_limit($sql, 1); + $postable_forum_exists = false; if ($db->sql_fetchrow($result)) { - $template->assign_vars(array( - 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $forum_id, false, true, false)) - ); + $postable_forum_exists = true; } $db->sql_freeresult($result); @@ -583,25 +582,24 @@ class acp_forums $forums_list = make_forum_select($forum_data['parent_id'], $subforums_id); - $sql = 'SELECT forum_id - FROM ' . FORUMS_TABLE . ' - WHERE forum_type = ' . FORUM_POST . " - AND forum_id <> $forum_id"; - $result = $db->sql_query($sql); - - if ($db->sql_fetchrow($result)) + if ($postable_forum_exists) { $template->assign_vars(array( 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $subforums_id)) // , false, true, false??? ); } - $db->sql_freeresult($result); $template->assign_vars(array( 'S_HAS_SUBFORUMS' => ($forum_data['right_id'] - $forum_data['left_id'] > 1) ? true : false, 'S_FORUMS_LIST' => $forums_list) ); } + else if ($postable_forum_exists) + { + $template->assign_vars(array( + 'S_MOVE_FORUM_OPTIONS' => make_forum_select($forum_data['parent_id'], $forum_id, false, true, false)) + ); + } $s_show_display_on_index = false; @@ -714,7 +712,7 @@ class acp_forums FROM ' . FORUMS_TABLE . ' WHERE forum_type = ' . FORUM_POST . " AND forum_id <> $forum_id"; - $result = $db->sql_query($sql); + $result = $db->sql_query_limit($sql, 1); if ($db->sql_fetchrow($result)) { @@ -807,10 +805,6 @@ class acp_forums $url = $this->u_action . "&parent_id=$this->parent_id&f={$row['forum_id']}"; - $forum_title = ($forum_type != FORUM_LINK) ? '<a href="' . $this->u_action . '&parent_id=' . $row['forum_id'] . '">' : ''; - $forum_title .= $row['forum_name']; - $forum_title .= ($forum_type != FORUM_LINK) ? '</a>' : ''; - $template->assign_block_vars('forums', array( 'FOLDER_IMAGE' => $folder_image, 'FORUM_IMAGE' => ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="" />' : '', @@ -888,7 +882,7 @@ class acp_forums */ function update_forum_data(&$forum_data) { - global $db, $user, $cache; + global $db, $user, $cache, $phpbb_root_path; $errors = array(); @@ -926,6 +920,11 @@ class acp_forums array('lang' => 'FORUM_TOPICS_PAGE', 'value' => $forum_data['forum_topics_per_page'], 'column_type' => 'TINT:0'), ); + if (!file_exists($phpbb_root_path . $forum_data['forum_image'])) + { + $errors[] = $user->lang['FORUM_IMAGE_NO_EXIST']; + } + validate_range($range_test_ary, $errors); // Set forum flags diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index 5683ae5dab..a38b47a704 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -111,6 +111,7 @@ class acp_inactive $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']); $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']); $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']); + $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($row['username'])) @@ -161,7 +162,11 @@ class acp_inactive $sql = 'SELECT user_id, username, user_email, user_lang, user_jabber, user_notify_type, user_regdate, user_actkey FROM ' . USERS_TABLE . ' - WHERE ' . $db->sql_in_set('user_id', $mark); + WHERE ' . $db->sql_in_set('user_id', $mark) . ' + AND user_inactive_reason'; + + $sql .= ($config['require_activation'] == USER_ACTIVATION_ADMIN) ? ' = ' . INACTIVE_REMIND : ' <> ' . INACTIVE_MANUAL; + $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) @@ -179,9 +184,14 @@ class acp_inactive $messenger->to($row['user_email'], $row['username']); $messenger->im($row['user_jabber'], $row['username']); + $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']); + $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']); + $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']); + $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip); + $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($row['username']), - 'REGISTER_DATE' => $user->format_date($row['user_regdate']), + 'REGISTER_DATE' => $user->format_date($row['user_regdate'], false, true), 'U_ACTIVATE' => generate_board_url() . "/ucp.$phpEx?mode=activate&u=" . $row['user_id'] . '&k=' . $row['user_actkey']) ); diff --git a/phpBB/includes/acp/acp_jabber.php b/phpBB/includes/acp/acp_jabber.php index 499543cc6c..3ab6eb64ed 100644 --- a/phpBB/includes/acp/acp_jabber.php +++ b/phpBB/includes/acp/acp_jabber.php @@ -88,7 +88,8 @@ class acp_jabber else { // This feature is disabled. - // We update the user table to be sure all users that have IM as notify type are set to both as notify type + // We update the user table to be sure all users that have IM as notify type are set to both as notify type + // We set this to both because users still have their jabber address entered and may want to receive jabber notifications again once it is re-enabled. $sql_ary = array( 'user_notify_type' => NOTIFY_BOTH, ); diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index a558fe6712..8a92c06e04 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -510,6 +510,12 @@ class acp_main $template->assign_var('S_WRITABLE_CONFIG', (bool) (@fileperms($phpbb_root_path . 'config.' . $phpEx) & 0x0002)); } + // Fill dbms version if not yet filled + if (empty($config['dbms_version'])) + { + set_config('dbms_version', $db->sql_server_info(true)); + } + $this->tpl_name = 'acp_main'; $this->page_title = 'ACP_MAIN'; } diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index 727aa0d25d..164970b5d5 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -23,7 +23,7 @@ class acp_permissions { var $u_action; var $permission_dropdown; - + function main($id, $mode) { global $db, $user, $auth, $template, $cache; @@ -94,7 +94,7 @@ class acp_permissions } $db->sql_freeresult($result); } - + // Map usernames to ids and vice versa if ($usernames) { @@ -112,7 +112,7 @@ class acp_permissions } } unset($username); - + // Build forum ids (of all forums are checked or subforum listing used) if ($all_forums) { @@ -528,7 +528,7 @@ class acp_permissions } continue; } - + if ($branch_there) { $s_options .= ' [' . $user->lang['PLUS_SUBFORUMS'] . ']'; @@ -539,14 +539,14 @@ class acp_permissions return $s_options; } - + /** * Build dropdown field for changing permission types */ function build_permission_dropdown($options, $default_option, $permission_scope) { global $user, $auth; - + $s_dropdown_options = ''; foreach ($options as $setting) { @@ -626,7 +626,7 @@ class acp_permissions { trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } - + $ug_id = $forum_id = 0; // We loop through the auth settings defined in our submit @@ -762,7 +762,14 @@ class acp_permissions $this->log_action($mode, 'add', $permission_type, $ug_type, $ug_ids, $forum_ids); - trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); + if ($mode == 'setting_forum_local' || $mode == 'setting_mod_local') + { + trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action . '&forum_id[]=' . implode('&forum_id[]=', $forum_ids))); + } + else + { + trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); + } } /** @@ -809,7 +816,7 @@ class acp_permissions function remove_permissions($mode, $permission_type, &$auth_admin, &$user_id, &$group_id, &$forum_id) { global $user, $db, $auth; - + // User or group to be set? $ug_type = (sizeof($user_id)) ? 'user' : 'group'; @@ -829,7 +836,14 @@ class acp_permissions $this->log_action($mode, 'del', $permission_type, $ug_type, (($ug_type == 'user') ? $user_id : $group_id), (sizeof($forum_id) ? $forum_id : array(0 => 0))); - trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); + if ($mode == 'setting_forum_local' || $mode == 'setting_mod_local') + { + trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action . '&forum_id[]=' . implode('&forum_id[]=', $forum_id))); + } + else + { + trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action)); + } } /** @@ -1150,7 +1164,11 @@ class acp_permissions { $sql_where = 'AND (' . $db->sql_in_set('a.auth_option_id', $option_ids) . ' OR ' . $db->sql_in_set('a.auth_role_id', $role_ids) . ')'; } - else + else if (sizeof($role_ids)) + { + $sql_where = 'AND ' . $db->sql_in_set('a.auth_role_id', $role_ids); + } + else if (sizeof($option_ids)) { $sql_where = 'AND ' . $db->sql_in_set('a.auth_option_id', $option_ids); } diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 7ab6ff7cd6..2b5ec88e5b 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -1539,7 +1539,7 @@ class acp_profile case 'firebird': // We are defining the biggest common value, because of the possibility to edit the min/max values of each field. - $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . " ADD \"$field_ident\" "; + $sql = 'ALTER TABLE ' . PROFILE_FIELDS_DATA_TABLE . ' ADD "' . strtoupper($field_ident) . '" '; switch ($field_type) { diff --git a/phpBB/includes/acp/acp_search.php b/phpBB/includes/acp/acp_search.php index dc6f3d1c44..930c8d2a26 100644 --- a/phpBB/includes/acp/acp_search.php +++ b/phpBB/includes/acp/acp_search.php @@ -63,6 +63,7 @@ class acp_search 'load_search' => 'bool', 'limit_search_load' => 'float', 'min_search_author_chars' => 'integer', + 'max_num_search_keywords' => 'integer', 'search_store_results' => 'integer', ); @@ -216,6 +217,7 @@ class acp_search 'SEARCH_INTERVAL' => (float) $config['search_interval'], 'SEARCH_GUEST_INTERVAL' => (float) $config['search_anonymous_interval'], 'SEARCH_STORE_RESULTS' => (int) $config['search_store_results'], + 'MAX_NUM_SEARCH_KEYWORDS' => (int) $config['max_num_search_keywords'], 'S_SEARCH_TYPES' => $search_options, 'S_YES_SEARCH' => (bool) $config['load_search'], @@ -591,7 +593,7 @@ class acp_search ksort($this->state); - set_config('search_indexing_state', implode(',', $this->state)); + set_config('search_indexing_state', implode(',', $this->state), true); } /** diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 3a021bb4cf..184b71cec3 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -37,7 +37,10 @@ class acp_styles // Hardcoded template bitfield to add for new templates $bitfield = new bitfield(); $bitfield->set(0); + $bitfield->set(1); + $bitfield->set(2); $bitfield->set(3); + $bitfield->set(4); $bitfield->set(8); $bitfield->set(9); $bitfield->set(11); @@ -743,7 +746,7 @@ parse_css_file = {PARSE_CSS_FILE} // If it's not stored in the db yet, then update the template setting and store all template files in the db if (!$template_info['template_storedb']) { - if ($this->get_super('template', $template_id)) + if ($super = $this->get_super('template', $template_id)) { $this->store_in_db('template', $super['template_id']); } @@ -1275,139 +1278,143 @@ parse_css_file = {PARSE_CSS_FILE} $this->page_title = 'EDIT_IMAGESET'; - $update = (isset($_POST['update'])) ? true : false; + if (!$imageset_id) + { + trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING); + } - $imgname = request_var('imgname', ''); - $imgpath = request_var('imgpath', ''); - $imgsize = request_var('imgsize', false); - $imgwidth = request_var('imgwidth', 0); - $imgheight = request_var('imgheight', 0); + $update = (isset($_POST['update'])) ? true : false; + $imgname = request_var('imgname', 'site_logo'); $imgname = preg_replace('#[^a-z0-9\-+_]#i', '', $imgname); - $imgpath = str_replace('..', '.', $imgpath); + $sql_extra = $imgnamelang = ''; + + $sql = 'SELECT imageset_path, imageset_name + FROM ' . STYLES_IMAGESET_TABLE . " + WHERE imageset_id = $imageset_id"; + $result = $db->sql_query($sql); + $imageset_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); - if ($imageset_id) + if (!$imageset_row) { - $sql = 'SELECT imageset_path, imageset_name - FROM ' . STYLES_IMAGESET_TABLE . " - WHERE imageset_id = $imageset_id"; - $result = $db->sql_query($sql); - $imageset_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING); + } - $imageset_path = $imageset_row['imageset_path']; - $imageset_name = $imageset_row['imageset_name']; + $imageset_path = $imageset_row['imageset_path']; + $imageset_name = $imageset_row['imageset_name']; - $sql_extra = ''; - if (strpos($imgname, '-') !== false) + if (strpos($imgname, '-') !== false) + { + list($imgname, $imgnamelang) = explode('-', $imgname); + $sql_extra = " AND image_lang IN ('" . $db->sql_escape($imgnamelang) . "', '')"; + } + + $sql = 'SELECT image_filename, image_width, image_height, image_lang, image_id + FROM ' . STYLES_IMAGESET_DATA_TABLE . " + WHERE imageset_id = $imageset_id + AND image_name = '" . $db->sql_escape($imgname) . "'$sql_extra"; + $result = $db->sql_query($sql); + $imageset_data_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $image_filename = $imageset_data_row['image_filename']; + $image_width = $imageset_data_row['image_width']; + $image_height = $imageset_data_row['image_height']; + $image_lang = $imageset_data_row['image_lang']; + $image_id = $imageset_data_row['image_id']; + $imgsize = ($imageset_data_row['image_width'] && $imageset_data_row['image_height']) ? 1 : 0; + + // Check to see whether the selected image exists in the table + $valid_name = ($update) ? false : true; + + foreach ($this->imageset_keys as $category => $img_ary) + { + if (in_array($imgname, $img_ary)) { - list($imgname, $imgnamelang) = explode('-', $imgname); - $sql_extra = " AND image_lang IN ('" . $db->sql_escape($imgnamelang) . "', '')"; + $valid_name = true; + break; } + } - $sql = 'SELECT image_filename, image_width, image_height, image_lang, image_id - FROM ' . STYLES_IMAGESET_DATA_TABLE . " - WHERE imageset_id = $imageset_id - AND image_name = '" . $db->sql_escape($imgname) . "'$sql_extra"; - $result = $db->sql_query($sql); - $imageset_data_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - $image_filename = $imageset_data_row['image_filename']; - $image_width = $imageset_data_row['image_width']; - $image_height = $imageset_data_row['image_height']; - $image_lang = $imageset_data_row['image_lang']; - $image_id = $imageset_data_row['image_id']; + if ($update && isset($_POST['imgpath']) && $valid_name) + { + // If imgwidth and imgheight are non-zero grab the actual size + // from the image itself ... we ignore width settings for the poll center image + $imgwidth = request_var('imgwidth', 0); + $imgheight = request_var('imgheight', 0); + $imgsize = request_var('imgsize', 0); + $imgpath = request_var('imgpath', ''); + $imgpath = str_replace('..', '.', $imgpath); - if (!$imageset_row) + // If no dimensions selected, we reset width and height to 0 ;) + if (!$imgsize) { - trigger_error($user->lang['NO_IMAGESET'] . adm_back_link($this->u_action), E_USER_WARNING); + $imgwidth = $imgheight = 0; } - // Check to see whether the selected image exists in the table - $valid_name = ($update) ? false : true; + $imglang = ''; - foreach ($this->imageset_keys as $category => $img_ary) + if ($imgpath && !file_exists("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath")) { - if (in_array($imgname, $img_ary)) - { - $valid_name = true; - break; - } + trigger_error($user->lang['NO_IMAGE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING); } - if ($update && isset($_POST['imgpath'])) + // Determine width/height. If dimensions included and no width/height given, we detect them automatically... + if ($imgsize && $imgpath) { - if ($valid_name) + if (!$imgwidth || !$imgheight) { - // If imgwidth and imgheight are non-zero grab the actual size - // from the image itself ... we ignore width settings for the poll center image - $imgwidth = request_var('imgwidth', 0); - $imgheight = request_var('imgheight', 0); - $imglang = ''; - - if ($imgpath && !file_exists("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath")) - { - trigger_error($user->lang['NO_IMAGE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING); - } - - if ($imgsize && $imgpath) - { - if (!$imgwidth || !$imgheight) - { - list($imgwidth_file, $imgheight_file) = getimagesize("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath"); - $imgwidth = ($imgwidth) ? $imgwidth : $imgwidth_file; - $imgheight = ($imgheight) ? $imgheight : $imgheight_file; - } - $imgwidth = ($imgname != 'poll_center') ? (int) $imgwidth : 0; - $imgheight = (int) $imgheight; - } - + list($imgwidth_file, $imgheight_file) = getimagesize("{$phpbb_root_path}styles/$imageset_path/imageset/$imgpath"); + $imgwidth = ($imgwidth) ? $imgwidth : $imgwidth_file; + $imgheight = ($imgheight) ? $imgheight : $imgheight_file; + } + $imgwidth = ($imgname != 'poll_center') ? (int) $imgwidth : 0; + $imgheight = (int) $imgheight; + } - if (strpos($imgpath, '/') !== false) - { - list($imglang, $imgfilename) = explode('/', $imgpath); - } - else - { - $imgfilename = $imgpath; - } + if (strpos($imgpath, '/') !== false) + { + list($imglang, $imgfilename) = explode('/', $imgpath); + } + else + { + $imgfilename = $imgpath; + } - $sql_ary = array( - 'image_filename' => (string) $imgfilename, - 'image_width' => (int) $imgwidth, - 'image_height' => (int) $imgheight, - 'image_lang' => (string) $imglang, - ); + $sql_ary = array( + 'image_filename' => (string) $imgfilename, + 'image_width' => (int) $imgwidth, + 'image_height' => (int) $imgheight, + 'image_lang' => (string) $imglang, + ); - // already exists - if ($imageset_data_row) - { - $sql = 'UPDATE ' . STYLES_IMAGESET_DATA_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE image_id = $image_id"; - $db->sql_query($sql); - } - // does not exist - else if (!$imageset_data_row) - { - $sql_ary['image_name'] = $imgname; - $sql_ary['imageset_id'] = (int) $imageset_id; - $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); - } + // already exists + if ($imageset_data_row) + { + $sql = 'UPDATE ' . STYLES_IMAGESET_DATA_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE image_id = $image_id"; + $db->sql_query($sql); + } + // does not exist + else if (!$imageset_data_row) + { + $sql_ary['image_name'] = $imgname; + $sql_ary['imageset_id'] = (int) $imageset_id; + $db->sql_query('INSERT INTO ' . STYLES_IMAGESET_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); + } - $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); + $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); - add_log('admin', 'LOG_IMAGESET_EDIT', $imageset_name); + add_log('admin', 'LOG_IMAGESET_EDIT', $imageset_name); - $template->assign_var('SUCCESS', true); + $template->assign_var('SUCCESS', true); - $image_filename = $imgfilename; - $image_width = $imgwidth; - $image_height = $imgheight; - $image_lang = $imglang; - } - } + $image_filename = $imgfilename; + $image_width = $imgwidth; + $image_height = $imgheight; + $image_lang = $imglang; } $imglang = ''; @@ -1529,6 +1536,8 @@ parse_css_file = {PARSE_CSS_FILE} 'U_BACK' => $this->u_action, 'NAME' => $imageset_name, 'A_NAME' => addslashes($imageset_name), + 'PATH' => $imageset_path, + 'A_PATH' => addslashes($imageset_path), 'ERROR' => !$valid_name, 'IMG_SRC' => ($image_found) ? '../styles/' . $imageset_path . '/imageset/' . $img_val : 'images/no_image.png', 'IMAGE_SELECT' => $image_found @@ -3210,7 +3219,16 @@ parse_css_file = {PARSE_CSS_FILE} if (isset($cfg_data['inherit_from']) && $cfg_data['inherit_from']) { - $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path, {$mode}_storedb + if ($mode === 'template') + { + $select_bf = ', template_bitfield'; + } + else + { + $select_bf = ''; + } + + $sql = "SELECT {$mode}_id, {$mode}_name, {$mode}_path, {$mode}_storedb $select_bf FROM $sql_from WHERE {$mode}_name = '" . $db->sql_escape($cfg_data['inherit_from']) . "' AND {$mode}_inherits_id = 0"; @@ -3225,6 +3243,7 @@ parse_css_file = {PARSE_CSS_FILE} { $inherit_id = $row["{$mode}_id"]; $inherit_path = $row["{$mode}_path"]; + $inherit_bf = ($mode === 'template') ? $row["{$mode}_bitfield"] : false; $cfg_data['store_db'] = $row["{$mode}_storedb"]; $store_db = $row["{$mode}_storedb"]; } @@ -3233,6 +3252,7 @@ parse_css_file = {PARSE_CSS_FILE} { $inherit_id = 0; $inherit_path = ''; + $inherit_bf = false; } @@ -3255,6 +3275,10 @@ parse_css_file = {PARSE_CSS_FILE} { $sql_ary['bbcode_bitfield'] = $cfg_data['template_bitfield']; } + else if ($inherit_bf) + { + $sql_ary['bbcode_bitfield'] = $inherit_bf; + } else { $sql_ary['bbcode_bitfield'] = TEMPLATE_BITFIELD; diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 05a087f4c3..e5f83faec3 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -972,6 +972,7 @@ class acp_users { $sql = 'DELETE FROM ' . LOG_TABLE . ' WHERE log_type = ' . LOG_USERS . " + AND reportee_id = $user_id $where_sql"; $db->sql_query($sql); @@ -1161,7 +1162,8 @@ class acp_users foreach ($cp_data as $key => $value) { - $cp_data[$left_delim . $key . $right_delim] = $value; + // Firebird is case sensitive with delimiter + $cp_data[$left_delim . (($db->sql_layer == 'firebird') ? strtoupper($key) : $key) . $right_delim] = $value; unset($cp_data[$key]); } @@ -1846,6 +1848,16 @@ class acp_users } $error = array(); + + // The delete action was successful - therefore update the user row... + $sql = 'SELECT u.*, s.* + FROM ' . USERS_TABLE . ' u + LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id) + WHERE u.user_id = ' . $user_id . ' + ORDER BY s.session_time DESC'; + $result = $db->sql_query($sql); + $user_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); } else { diff --git a/phpBB/includes/acp/auth.php b/phpBB/includes/acp/auth.php index 6943f5ada1..10d7973da6 100644 --- a/phpBB/includes/acp/auth.php +++ b/phpBB/includes/acp/auth.php @@ -58,7 +58,7 @@ class auth_admin extends auth $cache->put('_acl_options', $this->acl_options); } } - + /** * Get permission mask * This function only supports getting permissions of one type (for example a_) @@ -140,7 +140,7 @@ class auth_admin extends auth $auth2 = &$auth; } - + $hold_ary[$userdata['user_id']] = array(); foreach ($forum_ids as $f_id) { @@ -345,7 +345,7 @@ class auth_admin extends auth // Build js roles array (role data assignments) $s_role_js_array = ''; - + if (sizeof($roles)) { $s_role_js_array = array(); @@ -696,6 +696,7 @@ class auth_admin extends auth $cur_options = array(); + // Determine current options $sql = 'SELECT auth_option, is_global, is_local FROM ' . ACL_OPTIONS_TABLE . ' ORDER BY auth_option_id'; @@ -703,15 +704,7 @@ class auth_admin extends auth while ($row = $db->sql_fetchrow($result)) { - if ($row['is_global']) - { - $cur_options['global'][] = $row['auth_option']; - } - - if ($row['is_local']) - { - $cur_options['local'][] = $row['auth_option']; - } + $cur_options[$row['auth_option']] = ($row['is_global'] && $row['is_local']) ? 'both' : (($row['is_global']) ? 'global' : 'local'); } $db->sql_freeresult($result); @@ -726,14 +719,11 @@ class auth_admin extends auth foreach ($option_ary as $option_value) { - if (!in_array($option_value, $cur_options[$type])) - { - $new_options[$type][] = $option_value; - } + $new_options[$type][] = $option_value; $flag = substr($option_value, 0, strpos($option_value, '_') + 1); - if (!in_array($flag, $cur_options[$type]) && !in_array($flag, $new_options[$type])) + if (!in_array($flag, $new_options[$type])) { $new_options[$type][] = $flag; } @@ -744,23 +734,53 @@ class auth_admin extends auth $options = array(); $options['local'] = array_diff($new_options['local'], $new_options['global']); $options['global'] = array_diff($new_options['global'], $new_options['local']); - $options['local_global'] = array_intersect($new_options['local'], $new_options['global']); + $options['both'] = array_intersect($new_options['local'], $new_options['global']); - $sql_ary = array(); + // Now check which options to add/update + $add_options = $update_options = array(); + // First local ones... foreach ($options as $type => $option_ary) { foreach ($option_ary as $option) { - $sql_ary[] = array( - 'auth_option' => (string) $option, - 'is_global' => ($type == 'global' || $type == 'local_global') ? 1 : 0, - 'is_local' => ($type == 'local' || $type == 'local_global') ? 1 : 0 - ); + if (!isset($cur_options[$option])) + { + $add_options[] = array( + 'auth_option' => (string) $option, + 'is_global' => ($type == 'global' || $type == 'both') ? 1 : 0, + 'is_local' => ($type == 'local' || $type == 'both') ? 1 : 0 + ); + + continue; + } + + // Else, update existing entry if it is changed... + if ($type === $cur_options[$option]) + { + continue; + } + + // New type is always both: + // If is now both, we set both. + // If it was global the new one is local and we need to set it to both + // If it was local the new one is global and we need to set it to both + $update_options[] = $option; } } - $db->sql_multi_insert(ACL_OPTIONS_TABLE, $sql_ary); + if (!empty($add_options)) + { + $db->sql_multi_insert(ACL_OPTIONS_TABLE, $add_options); + } + + if (!empty($update_options)) + { + $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' + SET is_global = 1, is_local = 1 + WHERE ' . $db->sql_in_set('auth_option', $update_options); + $db->sql_query($sql); + } $cache->destroy('_acl_options'); $this->acl_clear_prefetch(); @@ -802,7 +822,7 @@ class auth_admin extends auth reset($auth); $flag = key($auth); $flag = substr($flag, 0, strpos($flag, '_') + 1); - + // This ID (the any-flag) is set if one or more permissions are true... $any_option_id = (int) $this->acl_options['id'][$flag]; @@ -916,7 +936,7 @@ class auth_admin extends auth reset($auth); $flag = key($auth); $flag = substr($flag, 0, strpos($flag, '_') + 1); - + // Remove any-flag from auth ary if (isset($auth[$flag])) { @@ -1067,7 +1087,7 @@ class auth_admin extends auth { $where_sql[] = $db->sql_in_set('auth_option_id', array_map('intval', $option_id_ary)); } - + $sql = "DELETE FROM $table WHERE " . implode(' AND ', $where_sql); $db->sql_query($sql); @@ -1090,7 +1110,7 @@ class auth_admin extends auth 'S_YES' => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false, 'S_NEVER' => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false, 'S_NO' => ($cat_array['S_NO'] && !$cat_array['S_NEVER'] && !$cat_array['S_YES']) ? true : false, - + 'CAT_NAME' => $user->lang['permission_cat'][$cat]) ); @@ -1179,9 +1199,9 @@ class auth_admin extends auth 'lang' => '{ acl_' . $permission . ' }' ); } - + $cat = $user->lang['acl_' . $permission]['cat']; - + // Build our categories array if (!isset($categories[$cat])) { diff --git a/phpBB/includes/auth/auth_apache.php b/phpBB/includes/auth/auth_apache.php index 80ac81ed46..930f5a0632 100644 --- a/phpBB/includes/auth/auth_apache.php +++ b/phpBB/includes/auth/auth_apache.php @@ -104,7 +104,7 @@ function login_apache(&$username, &$password) 'user_row' => $row, ); } - + // Successful login... return array( 'status' => LOGIN_SUCCESS, @@ -227,15 +227,22 @@ function user_row_apache($username, $password) */ function validate_session_apache(&$user) { - if (!isset($_SERVER['PHP_AUTH_USER'])) + // Check if PHP_AUTH_USER is set and handle this case + if (isset($_SERVER['PHP_AUTH_USER'])) { - return false; + $php_auth_user = ''; + set_var($php_auth_user, $_SERVER['PHP_AUTH_USER'], 'string', true); + + return ($php_auth_user === $user['username']) ? true : false; } - $php_auth_user = ''; - set_var($php_auth_user, $_SERVER['PHP_AUTH_USER'], 'string', true); + // PHP_AUTH_USER is not set. A valid session is now determined by the user type (anonymous/bot or not) + if ($user['user_type'] == USER_IGNORE) + { + return true; + } - return ($php_auth_user === $user['username']) ? true : false; + return false; } ?>
\ No newline at end of file diff --git a/phpBB/includes/auth/auth_db.php b/phpBB/includes/auth/auth_db.php index 1a5fd9e418..24d4c56614 100644 --- a/phpBB/includes/auth/auth_db.php +++ b/phpBB/includes/auth/auth_db.php @@ -141,7 +141,9 @@ function login_db(&$username, &$password) } // cp1252 is phpBB2's default encoding, characters outside ASCII range might work when converted into that encoding - if (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password']) + // plain md5 support left in for conversions from other systems. + if ((strlen($row['user_password']) == 34 && (phpbb_check_hash(md5($password_old_format), $row['user_password']) || phpbb_check_hash(md5(utf8_to_cp1252($password_old_format)), $row['user_password']))) + || (strlen($row['user_password']) == 32 && (md5($password_old_format) == $row['user_password'] || md5(utf8_to_cp1252($password_old_format)) == $row['user_password']))) { $hash = phpbb_hash($password_new_format); @@ -155,7 +157,7 @@ function login_db(&$username, &$password) $row['user_pass_convert'] = 0; $row['user_password'] = $hash; } - else + else { // Although we weren't able to convert this password we have to // increase login attempt count to make sure this cannot be exploited diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index fd8fadf3a7..562488db70 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -134,7 +134,7 @@ class bbcode { $this->template_bitfield = new bitfield($user->theme['bbcode_bitfield']); $this->template_filename = $phpbb_root_path . 'styles/' . $user->theme['template_path'] . '/template/bbcode.html'; - + if (!@file_exists($this->template_filename)) { if (isset($user->theme['template_inherits_id']) && $user->theme['template_inherits_id']) @@ -410,7 +410,7 @@ class bbcode if (empty($bbcode_hardtpl)) { global $user; - + $bbcode_hardtpl = array( 'b_open' => '<span style="font-weight: bold">', 'b_close' => '</span>', @@ -528,12 +528,12 @@ class bbcode else if (is_numeric($type)) { $tpl = 'olist_open'; - $type = 'arabic-numbers'; + $type = 'decimal'; } else { $tpl = 'olist_open'; - $type = 'arabic-numbers'; + $type = 'decimal'; } return str_replace('{LIST_TYPE}', $type, $this->bbcode_tpl($tpl)); diff --git a/phpBB/includes/captcha/captcha_gd.php b/phpBB/includes/captcha/captcha_gd.php index 9c9eb5eda7..9734a63c1b 100644 --- a/phpBB/includes/captcha/captcha_gd.php +++ b/phpBB/includes/captcha/captcha_gd.php @@ -27,6 +27,7 @@ class captcha var $width = 360; var $height = 96; + /** * Create the image containing $code with a seed of $seed */ @@ -34,7 +35,7 @@ class captcha { global $config; srand($seed); - mt_srand($seed); + //mt_srand($seed); // Create image $img = imagecreatetruecolor($this->width, $this->height); @@ -52,11 +53,11 @@ class captcha $bg_colours = array_splice($scheme, mt_rand(6, 12)); // Generate code characters - $characters = $sizes = $bounding_boxes = array(); + $characters = $sizes = $bounding_boxes = $noise = array(); $width_avail = $this->width - 15; $code_len = strlen($code); - $captcha_bitmaps = $this->captcha_bitmaps(); + for ($i = 0; $i < $code_len; ++$i) { $characters[$i] = new char_cube3d($captcha_bitmaps, $code[$i]); @@ -69,6 +70,7 @@ class captcha $bounding_boxes[$i] = $box; } + // Redistribute leftover x-space $offset = array(); for ($i = 0; $i < $code_len; ++$i) @@ -98,7 +100,34 @@ class captcha imagedashedline($img, mt_rand($x -3, $x + 3), mt_rand(0, 4), mt_rand($x -3, $x + 3), mt_rand($this->height - 5, $this->height), $current_colour); } } + if ($config['captcha_gd_wave'] && ($config['captcha_gd_y_grid'] || $config['captcha_gd_y_grid'])) + { + $this->wave($img); + } + + + if ($config['captcha_gd_3d_noise']) + { + $xoffset = rand(0,9); + $noise_bitmaps = $this->captcha_noise_bg_bitmaps(); + for ($i = 0; $i < $code_len; ++$i) + { + $noise[$i] = new char_cube3d($noise_bitmaps, mt_rand(1, count($noise_bitmaps['data']))); + list($min, $max) = $noise[$i]->range(); + //$box = $noise[$i]->dimensions($sizes[$i]); + } + $xoffset = 0; + for ($i = 0; $i < $code_len; ++$i) + { + $dimm = $bounding_boxes[$i]; + $xoffset += ($offset[$i] - $dimm[0]); + $yoffset = mt_rand(-$dimm[1], $this->height - $dimm[3]); + + $noise[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $colour->get_resource('background'), $scheme); + $xoffset += $dimm[2]; + } + } $xoffset = 5; for ($i = 0; $i < $code_len; ++$i) { @@ -109,12 +138,14 @@ class captcha $characters[$i]->drawchar($sizes[$i], $xoffset, $yoffset, $img, $colour->get_resource('background'), $scheme); $xoffset += $dimm[2]; } - + if ($config['captcha_gd_wave']) + { + $this->wave($img); + } if ($config['captcha_gd_foreground_noise']) { $this->noise_line($img, 0, 0, $this->width, $this->height, $colour->get_resource('background'), $scheme, $bg_colours); } - // Send image header('Content-Type: image/png'); header('Cache-control: no-cache, no-store'); @@ -123,6 +154,38 @@ class captcha } /** + * Sinus + */ + function wave($img) + { + global $config; + + $period_x = mt_rand(12,18); + $period_y = mt_rand(7,14); + $amp_x = mt_rand(5,10); + $amp_y = mt_rand(2,4); + $socket = mt_rand(0,100); + + $dampen_x = mt_rand($this->width/5, $this->width/2); + $dampen_y = mt_rand($this->height/5, $this->height/2); + $direction_x = (mt_rand (0, 1)); + $direction_y = (mt_rand (0, 1)); + + for ($i = 0; $i < $this->width; $i++) + { + $dir = ($direction_x) ? $i : ($this->width - $i); + imagecopy($img, $img, $i-1, sin($socket+ $i/($period_x + $dir/$dampen_x)) * $amp_x, $i, 0, 1, $this->height); + } + $socket = mt_rand(0,100); + for ($i = 0; $i < $this->height; $i++) + { + $dir = ($direction_y) ? $i : ($this->height - $i); + imagecopy($img, $img ,sin($socket + $i/($period_y + ($dir)/$dampen_y)) * $amp_y, $i-1, 0, $i, $this->width, 1); + } + return $img; + } + + /** * Noise line */ function noise_line($img, $min_x, $min_y, $max_x, $max_y, $bg, $font, $non_font) @@ -171,458 +234,1468 @@ class captcha imagesetthickness($img, 1); } - /** - * Return bitmaps - */ - function captcha_bitmaps() - { + + function captcha_noise_bg_bitmaps() + { return array( - 'width' => 9, - 'height' => 15, + 'width' => 15, + 'height' => 5, 'data' => array( - 'A' => array( - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,1,0,0,0,1,0,0), - array(0,1,0,0,0,0,0,1,0), - array(0,1,0,0,0,0,0,1,0), - array(0,1,1,1,1,1,1,1,0), - array(0,1,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - ), - 'B' => array( - array(1,1,1,1,1,1,1,0,0), - array(1,0,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,1,0), - array(1,1,1,1,1,1,1,0,0), - array(1,0,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,1,0), - array(1,1,1,1,1,1,1,0,0), - ), - 'C' => array( - array(0,0,1,1,1,1,1,0,0), - array(0,1,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,1,1,1,1,0,0), - ), - 'D' => array( - array(1,1,1,1,1,1,1,0,0), - array(1,0,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,1,0), - array(1,1,1,1,1,1,1,0,0), - ), - 'E' => array( - array(1,1,1,1,1,1,1,1,1), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,1,1,1,1,1,1,1,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,1,1,1,1,1,1,1,1), - ), - 'F' => array( - array(1,1,1,1,1,1,1,1,1), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,1,1,1,1,1,1,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - ), - 'G' => array( - array(0,0,1,1,1,1,1,0,0), - array(0,1,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,1,1,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,1,1,1,1,0,0), - ), - 'H' => array( - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,1,1,1,1,1,1,1,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - ), - 'I' => array( - array(1,1,1,1,1,1,1,1,1), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(1,1,1,1,1,1,1,1,1), - ), - 'J' => array( - array(1,1,1,1,1,1,1,1,1), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(1,0,0,0,0,1,0,0,0), - array(1,0,0,0,0,1,0,0,0), - array(0,1,0,0,1,0,0,0,0), - array(0,0,1,1,0,0,0,0,0), - ), - 'K' => array( // New 'K', supplied by NeoThermic - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,1,0,0), - array(1,0,0,0,0,1,0,0,0), - array(1,0,0,0,1,0,0,0,0), - array(1,0,0,1,0,0,0,0,0), - array(1,0,1,0,0,0,0,0,0), - array(1,1,0,0,0,0,0,0,0), - array(1,0,1,0,0,0,0,0,0), - array(1,0,0,1,0,0,0,0,0), - array(1,0,0,0,1,0,0,0,0), - array(1,0,0,0,0,1,0,0,0), - array(1,0,0,0,0,0,1,0,0), - array(1,0,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - ), - 'L' => array( - array(0,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,1,1,1,1,1,1,1,1), - ), - 'M' => array( - array(1,1,0,0,0,0,0,1,1), - array(1,1,0,0,0,0,0,1,1), - array(1,0,1,0,0,0,1,0,1), - array(1,0,1,0,0,0,1,0,1), - array(1,0,1,0,0,0,1,0,1), - array(1,0,0,1,0,1,0,0,1), - array(1,0,0,1,0,1,0,0,1), - array(1,0,0,1,0,1,0,0,1), - array(1,0,0,0,1,0,0,0,1), - array(1,0,0,0,1,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - ), - 'N' => array( - array(1,1,0,0,0,0,0,0,1), - array(1,1,0,0,0,0,0,0,1), - array(1,0,1,0,0,0,0,0,1), - array(1,0,1,0,0,0,0,0,1), - array(1,0,0,1,0,0,0,0,1), - array(1,0,0,1,0,0,0,0,1), - array(1,0,0,0,1,0,0,0,1), - array(1,0,0,0,1,0,0,0,1), - array(1,0,0,0,1,0,0,0,1), - array(1,0,0,0,0,1,0,0,1), - array(1,0,0,0,0,1,0,0,1), - array(1,0,0,0,0,0,1,0,1), - array(1,0,0,0,0,0,1,0,1), - array(1,0,0,0,0,0,0,1,1), - array(1,0,0,0,0,0,0,1,1), - ), - 'O' => array( - array(0,0,1,1,1,1,1,0,0), - array(0,1,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,1,1,1,1,0,0), - ), - 'P' => array( - array(1,1,1,1,1,1,1,0,0), - array(1,0,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,1,0), - array(1,1,1,1,1,1,1,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - ), - 'Q' => array( - array(0,0,1,1,1,1,1,0,0), - array(0,1,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,1,0,0,1), - array(1,0,0,0,0,0,1,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,1,1,1,1,0,1), - ), - 'R' => array( - array(1,1,1,1,1,1,1,0,0), - array(1,0,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,1,0), - array(1,1,1,1,1,1,1,0,0), - array(1,1,1,0,0,0,0,0,0), - array(1,0,0,1,0,0,0,0,0), - array(1,0,0,0,1,0,0,0,0), - array(1,0,0,0,0,1,0,0,0), - array(1,0,0,0,0,0,1,0,0), - array(1,0,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - ), - 'S' => array( - array(0,0,1,1,1,1,1,0,0), - array(0,1,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(0,1,0,0,0,0,0,0,0), - array(0,0,1,1,1,1,1,0,0), - array(0,0,0,0,0,0,0,1,0), - array(0,0,0,0,0,0,0,0,1), - array(0,0,0,0,0,0,0,0,1), - array(0,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,1,1,1,1,0,0), - ), - 'T' => array( - array(1,1,1,1,1,1,1,1,1), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), + 1 => array( + array(1,0,0,0,1,0,0,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,1,0,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,1,0,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0,0,0,1,0,0,0), ), - 'U' => array( - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,1,1,1,1,0,0), + 2 => array( + array(1,1,mt_rand(0,1),1,0,1,1,1,1,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,1,1,0,1,1,1), ), - 'V' => array( - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,1,0,0,0,0,0,1,0), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), + 3 => array( + array(1,0,0,0,0,0,0,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0,0,0,0,0,1,0), + array(0,0,0,0,1,0,0,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,0,0,0,0,0,0,1), ), - 'W' => array( // New 'W', supplied by MHobbit - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,1,0,0,0,1), - array(1,0,0,0,1,0,0,0,1), - array(1,0,0,1,0,1,0,0,1), - array(1,0,0,1,0,1,0,0,1), - array(1,0,0,1,0,1,0,0,1), - array(1,0,1,0,0,0,1,0,1), - array(1,0,1,0,0,0,1,0,1), - array(1,0,1,0,0,0,1,0,1), - array(1,1,0,0,0,0,0,1,1), - array(1,1,0,0,0,0,0,1,1), + 4 => array( + array(1,0,1,0,1,0,0,1,1,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(1,0,1,0,0,0,0,0,0,0,0,0,0,0,0), ), - 'X' => array( - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,1,0,0,0,1,0,0), - array(0,1,0,0,0,0,1,0,0), - array(0,1,0,0,0,0,0,1,0), - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), + 5 => array( + array(1,1,1,1,0,0,0,1,1,1,0,0,1,0,1), + array(0,0,0,0,0,0,0,1,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(1,0,1,0,0,0,0,0,0,0,0,0,0,0,0), ), - 'Y' => array( - array(1,0,0,0,0,0,0,0,1), - array(1,0,0,0,0,0,0,0,1), - array(0,1,0,0,0,0,0,1,0), - array(0,1,0,0,0,0,0,1,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,1,0,0,0,1,0,0), - array(0,0,0,1,0,1,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,0,1,0,0,0,0), + 6 => array( + array(mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),0,mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),mt_rand(0,1),0,mt_rand(0,1),mt_rand(0,1),mt_rand(0,1)), + array(0,0,0,0,0,0,0,mt_rand(0,1),0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(mt_rand(0,1),0,mt_rand(0,1),0,0,0,0,0,0,0,0,0,0,0,0), ), - 'Z' => array( // New 'Z' supplied by Anon - array(1,1,1,1,1,1,1,1,1), - array(1,0,0,0,0,0,0,0,1), - array(0,0,0,0,0,0,0,0,1), - array(0,0,0,0,0,0,0,1,0), - array(0,0,0,0,0,0,1,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,0,1,0,0,0), - array(0,0,0,0,1,0,0,0,0), - array(0,0,0,1,0,0,0,0,0), - array(0,0,0,1,0,0,0,0,0), - array(0,0,1,0,0,0,0,0,0), - array(0,1,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,0), - array(1,0,0,0,0,0,0,0,1), - array(1,1,1,1,1,1,1,1,1), + 7 => array( + array(0,0,0,0,0,0,0,0,0,0,1,1,0,1,1), + array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + array(0,0,1,1,0,0,0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,1,0,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0), ), + )); + } + + /** + * Return bitmaps + */ + function captcha_bitmaps() + { + global $config; + + $chars = array( + 'A' => array( + array( + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,1,1,1,1,1,0), + array(0,1,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,1,1,0,1,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,1,1,1,1,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,0,0,0,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,1,1,1,1,1,0,0), + array(0,1,1,0,0,0,1,1,0), + array(1,1,0,0,0,0,0,1,1), + array(1,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,1,1), + array(0,0,0,0,0,1,1,1,1), + array(0,0,0,1,1,1,0,0,1), + array(0,1,1,1,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,1,0,0,0,0,1,1,1), + array(0,1,1,1,1,1,1,0,1), + ), + ), + 'B' => array( + array( + array(1,1,1,1,1,1,1,0,0), + array(1,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + array(1,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + ), + array( + array(1,1,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + ), + array( + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,1,1,1,1,0,0), + ), + ), + 'C' => array( + array( + array(0,0,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,1,1,1,1,0,0), + ), + array( + array(0,0,1,1,1,1,1,0,1), + array(0,1,0,0,0,0,0,1,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,1), + array(0,0,1,1,1,1,1,0,1), + ), + ), + 'D' => array( + array( + array(1,1,1,1,1,1,1,0,0), + array(1,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + ), + array( + array(1,1,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,1,1,1,1,1,0,1), + array(0,1,1,0,0,0,1,1,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,1,0,0,0,1,1,1), + array(0,0,1,1,1,1,1,0,1), + ), + ), + 'E' => array( + array( + array(1,1,1,1,1,1,1,1,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,1,1,1,1,1,1,1,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,1,1,1,1,1,1,1,1), + ), + array( + array(1,1,1,1,1,1,1,1,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,1,1,1,1,1,1,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,1), + array(1,1,1,1,1,1,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,1,1,1,1,1,0,0), + array(0,1,1,0,0,0,1,1,0), + array(1,1,0,0,0,0,0,1,1), + array(1,1,1,1,1,1,1,1,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,1), + array(1,1,0,0,0,0,0,1,1), + array(0,1,1,1,1,1,1,1,0), + ), + ), + 'F' => array( + array( + array(1,1,1,1,1,1,1,1,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,1,1,1,1,1,1,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + ), + array( + array(0,1,1,1,1,1,1,1,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(1,1,1,0,0,0,0,0,0), + ), + array( + array(0,0,0,1,1,0,0,0,0), + array(0,0,1,1,0,0,0,0,0), + array(0,1,1,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(1,1,1,1,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + ), + ), + 'G' => array( + array( + array(0,0,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,1,1,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,1,1,1,1,0,0), + ), + array( + array(0,0,1,1,1,1,1,0,1), + array(0,1,0,0,0,0,0,1,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,1,1,1,1,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,1), + array(0,0,1,1,1,1,1,0,1), + ), + array( + array(0,0,1,1,1,1,1,0,1), + array(0,1,1,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,1,1,0,0,0,0,0,1), + array(0,0,1,1,1,1,1,1,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,1,1), + array(1,1,1,1,1,1,1,1,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + ), + ), + 'H' => array( + array( + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,1,1,1,1,1,1,1,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + ), + array( + array(1,1,1,0,0,0,1,1,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,1,1,1,1,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,0,0,0,1,1,1), + ), + array( + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,1,1,1,0,0,0), + array(1,1,1,1,0,1,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + ), + ), + 'I' => array( + array( + array(1,1,1,1,1,1,1,1,1), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(1,1,1,1,1,1,1,1,1), + ), + array( + array(0,0,0,1,1,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,1,1,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,1,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,1,1,0,0,0), + ), + ), + 'J' => array( + array( + array(1,1,1,1,1,1,1,1,1), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(0,1,0,0,1,0,0,0,0), + array(0,0,1,1,0,0,0,0,0), + ), + array( + array(1,1,1,1,1,1,1,1,1), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(1,1,0,0,1,0,0,0,0), + array(1,0,1,1,0,0,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(0,1,0,0,1,0,0,0,0), + array(0,0,1,1,0,0,0,0,0), + ), + ), + 'K' => array( + array( // New 'K', supplied by NeoThermic + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,1,0,0,0), + array(1,0,0,0,1,0,0,0,0), + array(1,0,0,1,0,0,0,0,0), + array(1,0,1,0,0,0,0,0,0), + array(1,1,0,0,0,0,0,0,0), + array(1,0,1,0,0,0,0,0,0), + array(1,0,0,1,0,0,0,0,0), + array(1,0,0,0,1,0,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + ), + array( + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,1,0,0), + array(0,1,0,0,0,1,0,0,0), + array(0,1,0,0,1,0,0,0,0), + array(0,1,0,1,0,0,0,0,0), + array(0,1,1,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,1,0,0,0,0,0,0), + array(0,1,0,1,0,0,0,0,0), + array(0,1,0,0,1,0,0,0,0), + array(0,1,0,0,0,1,0,0,0), + array(0,1,0,0,0,0,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,0,0,0,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,1,0,0,0), + array(0,1,0,0,1,0,0,0,0), + array(0,1,0,1,0,0,0,0,0), + array(0,1,1,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,1,0,0,0,0,0,0), + array(0,1,0,1,0,0,0,0,0), + array(0,1,0,0,1,0,0,0,0), + array(0,1,0,0,0,1,0,0,0), + array(0,1,0,0,0,0,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + ), + ), + 'L' => array( + array( + array(0,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,1,1,1,1,1,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,1), + array(1,1,1,1,1,1,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,1,0,0,0,0,0,0), + array(0,0,1,1,1,0,0,0,0), + ), + ), + 'M' => array( + array( + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,0,1,0,0,0,1,0,1), + array(1,0,1,0,0,0,1,0,1), + array(1,0,1,0,0,0,1,0,1), + array(1,0,0,1,0,1,0,0,1), + array(1,0,0,1,0,1,0,0,1), + array(1,0,0,1,0,1,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,0,0,0,1,1,0), + array(0,1,1,0,0,0,1,1,0), + array(0,1,1,0,0,0,1,1,0), + array(0,1,0,1,0,1,0,1,0), + array(0,1,0,1,0,1,0,1,0), + array(0,1,0,1,0,1,0,1,0), + array(0,1,0,0,1,0,0,1,0), + array(0,1,0,0,1,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,0,0,0,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,1,1,1,0,1,1,1,0), + array(1,1,0,1,1,1,0,1,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + ), + ), + 'N' => array( + array( + array(1,1,0,0,0,0,0,0,1), + array(1,1,0,0,0,0,0,0,1), + array(1,0,1,0,0,0,0,0,1), + array(1,0,1,0,0,0,0,0,1), + array(1,0,0,1,0,0,0,0,1), + array(1,0,0,1,0,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,0,1,0,0,1), + array(1,0,0,0,0,1,0,0,1), + array(1,0,0,0,0,0,1,0,1), + array(1,0,0,0,0,0,1,0,1), + array(1,0,0,0,0,0,0,1,1), + array(1,0,0,0,0,0,0,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,0,0,0,0,1,0), + array(0,1,1,0,0,0,0,1,0), + array(0,1,1,0,0,0,0,1,0), + array(0,1,0,1,0,0,0,1,0), + array(0,1,0,1,0,0,0,1,0), + array(0,1,0,1,0,0,0,1,0), + array(0,1,0,0,1,0,0,1,0), + array(0,1,0,0,1,1,0,1,0), + array(0,1,0,0,0,1,0,1,0), + array(0,1,0,0,0,1,1,1,0), + array(0,1,0,0,0,0,1,1,0), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,0,0,0,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(1,0,1,1,1,1,0,0,0), + array(1,1,1,0,0,1,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + ), + ), + 'O' => array( + array( + array(0,0,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,1,1,1,1,0,0), + ), + array( + array(0,0,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,1,1,1,1,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,1,1,1,1,1,0,0,0), + array(1,1,1,0,0,1,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,1,0,0,0,1,1,0,0), + array(0,1,1,1,1,1,0,0,0), + ), + ), + 'P' => array( + array( + array(1,1,1,1,1,1,1,0,0), + array(1,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + ), + array( + array(1,1,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(1,1,1,0,0,0,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,1,1,0,0,0,0,0), + array(1,1,0,1,1,0,0,0,0), + array(1,0,0,0,1,0,0,0,0), + array(1,0,0,0,1,0,0,0,0), + array(1,0,0,1,1,0,0,0,0), + array(1,1,1,1,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + ), + ), + 'Q' => array( + array( + array(0,0,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,1,0,0,1), + array(1,0,0,0,0,0,1,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,1,1,1,1,0,1), + ), + array( + array(0,0,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,1,0,0,1,1,0,1,1), + array(0,1,1,1,1,1,1,1,0), + array(0,0,0,0,0,0,1,1,0), + array(0,0,0,0,0,0,0,1,1), + array(0,0,0,0,0,0,0,0,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,1,1,1,1), + array(0,0,0,0,1,1,0,0,1), + array(0,0,0,0,1,0,0,0,1), + array(0,0,0,0,1,0,0,0,1), + array(0,0,0,0,1,1,0,1,1), + array(0,0,0,0,0,1,1,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + ), + ), + 'R' => array( + array( + array(1,1,1,1,1,1,1,0,0), + array(1,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + array(1,1,1,0,0,0,0,0,0), + array(1,0,0,1,0,0,0,0,0), + array(1,0,0,0,1,0,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,0,1,0,0), + array(1,0,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + ), + array( + array(1,1,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,1,1,1,1,0,0), + array(0,1,1,0,0,0,0,0,0), + array(0,1,1,1,0,0,0,0,0), + array(0,1,0,1,1,0,0,0,0), + array(0,1,0,0,1,1,0,0,0), + array(0,1,0,0,0,1,1,0,0), + array(0,1,0,0,0,0,1,1,0), + array(1,1,1,0,0,0,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,1,1,1,1,0,0,0,0), + array(1,1,0,0,1,1,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + ), + ), + 'S' => array( + array( + array(0,0,1,1,1,1,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,0,1,1,1,1,1,0,0), + array(0,0,0,0,0,0,0,1,0), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,1,1,1,1,0,0), + ), + array( + array(0,0,1,1,1,1,1,0,1), + array(0,1,0,0,0,0,0,1,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(0,0,1,1,1,1,1,0,0), + array(0,0,0,0,0,0,0,1,0), + array(0,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,1,0,0,0,0,0,1,0), + array(1,0,1,1,1,1,1,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,1,1,1,1,0,0,0,0), + array(1,0,0,0,0,1,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,1,0,0,0,0,0,0,0), + array(0,1,1,1,1,0,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(1,0,0,0,1,1,0,0,0), + array(0,1,1,1,1,0,0,0,0), + ), + ), + 'T' => array( + array( + array(1,1,1,1,1,1,1,1,1), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + ), + array( + array(1,1,1,1,1,1,1,1,1), + array(1,0,0,0,1,0,0,0,1), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,1,1,0,0,0), + ), + array( + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,1,1,1,1,1,1,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,1,0,0,0), + array(0,0,0,0,0,1,1,1,0), + ), + ), + 'U' => array( + array( + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,1,1,1,1,0,0), + ), + array( + array(1,0,0,0,0,0,0,0,0), + array(1,1,1,0,0,0,1,1,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,0,0,0,1,1,0), + array(0,0,1,1,1,1,1,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,1,0,0,0,0,0,1), + array(0,0,1,0,0,0,0,0,1), + array(0,0,1,0,0,0,0,0,1), + array(0,0,1,0,0,0,0,0,1), + array(0,0,1,0,0,0,0,0,1), + array(0,0,1,0,0,0,0,1,1), + array(0,0,1,1,0,0,1,1,1), + array(0,0,0,1,1,1,1,0,1), + ), + ), + 'V' => array( + array( + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(1,1,1,0,0,0,1,1,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + ), + ), + 'W' => array( + array( + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,0,1,0,0,0,1), + array(1,0,0,1,0,1,0,0,1), + array(1,0,0,1,0,1,0,0,1), + array(1,0,0,1,0,1,0,0,1), + array(1,0,1,0,0,0,1,0,1), + array(1,0,1,0,0,0,1,0,1), + array(1,0,1,0,0,0,1,0,1), + array(1,1,0,0,0,0,0,1,1), + array(1,1,0,0,0,0,0,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(1,1,1,0,0,0,1,1,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,1,0,0,1,0), + array(0,1,0,0,1,0,0,1,0), + array(0,1,0,1,1,1,0,1,0), + array(0,1,0,1,0,1,0,1,0), + array(0,1,1,1,0,1,1,1,0), + array(0,1,1,0,0,0,1,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,0,0,0,0,0,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,1,0,0,1,0), + array(0,1,0,0,1,0,0,1,0), + array(0,1,0,1,1,1,0,1,0), + array(0,1,0,1,0,1,0,1,0), + array(0,1,1,1,0,1,1,1,0), + array(0,1,1,0,0,0,1,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,0,0,0,0,0,0,0,0), + ), + ), + 'X' => array( + array( + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,1,0,0,0,0,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(1,1,1,0,0,0,1,1,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,1,0,0,0,0,1,0,0), + array(0,1,0,0,0,0,0,1,0), + array(1,1,1,0,0,0,1,1,1), + array(0,0,0,0,0,0,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,1,0), + array(0,1,1,0,0,0,1,1,0), + array(0,0,1,1,0,1,1,0,0), + array(0,0,0,1,1,1,0,0,0), + array(0,0,0,1,1,1,0,0,0), + array(0,0,1,1,0,1,1,0,0), + array(0,1,1,0,0,0,1,1,0), + array(0,0,0,0,0,0,0,0,0), + ), + ), + 'Y' => array( + array( + array(1,0,0,0,0,0,0,0,1), + array(1,0,0,0,0,0,0,0,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(1,1,1,0,0,0,1,1,1), + array(0,1,0,0,0,0,0,1,0), + array(0,1,0,0,0,0,0,1,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,1,0,0,0,1,0,0), + array(0,0,0,1,0,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,1,1,0,0,0), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,1,0,0,0,0,1), + array(0,0,0,1,1,0,0,0,1), + array(0,0,0,0,1,0,0,1,1), + array(0,0,0,0,1,1,0,1,0), + array(0,0,0,0,0,1,1,1,0), + array(0,0,0,0,0,0,1,0,0), + array(0,0,0,0,0,1,1,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,1,1,0,0,0), + array(0,0,1,1,1,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + ), + ), + 'Z' => array( + array( + array(1,1,1,1,1,1,1,1,1), + array(1,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,1,0), + array(0,0,0,0,0,0,1,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,1,0,0,0,0), + array(0,0,0,1,0,0,0,0,0), + array(0,0,0,1,0,0,0,0,0), + array(0,0,1,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,1), + array(1,1,1,1,1,1,1,1,1), + ), + array( + array(1,1,1,1,1,1,1,1,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,0,1), + array(0,0,0,0,0,0,0,1,0), + array(0,0,0,0,0,0,1,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,0,0,0,1,0,0,0), + array(0,0,1,1,1,1,1,0,0), + array(0,0,0,1,0,0,0,0,0), + array(0,0,0,1,0,0,0,0,0), + array(0,0,1,0,0,0,0,0,0), + array(0,1,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,0,0,0,0,0,0,0,0), + array(1,1,1,1,1,1,1,1,1), + ), + array( + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,0,0,0,0,0,0,0,0), + array(0,1,1,1,1,1,1,1,0), + array(0,0,0,0,0,1,1,0,0), + array(0,0,0,0,1,1,0,0,0), + array(0,0,0,1,1,0,0,0,0), + array(0,0,1,1,0,0,0,0,0), + array(0,0,1,0,0,0,0,0,0), + array(0,1,1,1,1,1,1,1,0), + ), + ), + ); + return array( + 'width' => 9, + 'height' => 15, + 'data' => array( + + 'A' => $chars['A'][mt_rand(0, min(count($chars['A']), $config['captcha_gd_fonts']) -1)], + 'B' => $chars['B'][mt_rand(0, min(count($chars['B']), $config['captcha_gd_fonts']) -1)], + 'C' => $chars['C'][mt_rand(0, min(count($chars['C']), $config['captcha_gd_fonts']) -1)], + 'D' => $chars['D'][mt_rand(0, min(count($chars['D']), $config['captcha_gd_fonts']) -1)], + 'E' => $chars['E'][mt_rand(0, min(count($chars['E']), $config['captcha_gd_fonts']) -1)], + 'F' => $chars['F'][mt_rand(0, min(count($chars['F']), $config['captcha_gd_fonts']) -1)], + 'G' => $chars['G'][mt_rand(0, min(count($chars['G']), $config['captcha_gd_fonts']) -1)], + 'H' => $chars['H'][mt_rand(0, min(count($chars['H']), $config['captcha_gd_fonts']) -1)], + 'I' => $chars['I'][mt_rand(0, min(count($chars['I']), $config['captcha_gd_fonts']) -1)], + 'J' => $chars['J'][mt_rand(0, min(count($chars['J']), $config['captcha_gd_fonts']) -1)], + 'K' => $chars['K'][mt_rand(0, min(count($chars['K']), $config['captcha_gd_fonts']) -1)], + 'L' => $chars['L'][mt_rand(0, min(count($chars['L']), $config['captcha_gd_fonts']) -1)], + 'M' => $chars['M'][mt_rand(0, min(count($chars['M']), $config['captcha_gd_fonts']) -1)], + 'N' => $chars['N'][mt_rand(0, min(count($chars['N']), $config['captcha_gd_fonts']) -1)], + 'O' => $chars['O'][mt_rand(0, min(count($chars['O']), $config['captcha_gd_fonts']) -1)], + 'P' => $chars['P'][mt_rand(0, min(count($chars['P']), $config['captcha_gd_fonts']) -1)], + 'Q' => $chars['Q'][mt_rand(0, min(count($chars['Q']), $config['captcha_gd_fonts']) -1)], + 'R' => $chars['R'][mt_rand(0, min(count($chars['R']), $config['captcha_gd_fonts']) -1)], + 'S' => $chars['S'][mt_rand(0, min(count($chars['S']), $config['captcha_gd_fonts']) -1)], + 'T' => $chars['T'][mt_rand(0, min(count($chars['T']), $config['captcha_gd_fonts']) -1)], + 'U' => $chars['U'][mt_rand(0, min(count($chars['U']), $config['captcha_gd_fonts']) -1)], + 'V' => $chars['V'][mt_rand(0, min(count($chars['V']), $config['captcha_gd_fonts']) -1)], + 'W' => $chars['W'][mt_rand(0, min(count($chars['W']), $config['captcha_gd_fonts']) -1)], + 'X' => $chars['X'][mt_rand(0, min(count($chars['X']), $config['captcha_gd_fonts']) -1)], + 'Y' => $chars['Y'][mt_rand(0, min(count($chars['Y']), $config['captcha_gd_fonts']) -1)], + 'Z' => $chars['Z'][mt_rand(0, min(count($chars['Z']), $config['captcha_gd_fonts']) -1)], + '1' => array( array(0,0,0,1,1,0,0,0,0), array(0,0,1,0,1,0,0,0,0), diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 2210b6f8a5..ff0e46974f 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -25,7 +25,7 @@ if (!defined('IN_PHPBB')) */ // phpBB Version -define('PHPBB_VERSION', '3.0.4'); +define('PHPBB_VERSION', '3.0.5-RC1'); // QA-related // define('PHPBB_QA', 1); @@ -185,6 +185,10 @@ define('REFERER_VALIDATE_PATH', 2); @define('CHMOD_WRITE', 2); @define('CHMOD_EXECUTE', 1); +// Captcha code length +define('CAPTCHA_MIN_CHARS', 4); +define('CAPTCHA_MAX_CHARS', 7); + // Additional constants define('VOTE_CONVERTED', 127); diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index 703af25086..bc6b027b1f 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -30,6 +30,15 @@ class phpbb_db_tools */ var $sql_layer = ''; + /** + * @var object DB object + */ + var $db = NULL; + + /** + * The Column types for every database we support + * @var array + */ var $dbms_type_map = array( 'mysql_41' => array( 'INT:' => 'int(%d)', @@ -242,20 +251,34 @@ class phpbb_db_tools ), ); - // A list of types being unsigned for better reference in some db's + /** + * A list of types being unsigned for better reference in some db's + * @var array + */ var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); + + /** + * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. + * @var array + */ var $supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); /** - * Set this to true if you only want to return the 'to-be-executed' SQL statement(s) (as an array). + * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). + * This mode has no effect on some methods (inserting of data for example). This is expressed within the methods command. */ var $return_statements = false; /** + * Constructor. Set DB Object and set {@link $return_statements return_statements}. + * + * @param phpbb_dbal $db DBAL object + * @param bool $return_statements True if only statements should be returned and no SQL being executed */ - function phpbb_db_tools(&$db) + function phpbb_db_tools(&$db, $return_statements = false) { $this->db = $db; + $this->return_statements = $return_statements; // Determine mapping database type switch ($this->db->sql_layer) @@ -291,6 +314,245 @@ class phpbb_db_tools } /** + * Check if table exists + * + * + * @param string $table_name The table name to check for + * @return bool true if table exists, else false + */ + function sql_table_exists($table_name) + { + $this->db->sql_return_on_error(true); + $result = $this->db->sql_query_limit('SELECT * FROM ' . $table_name, 1); + $this->db->sql_return_on_error(false); + + if ($result) + { + $this->db->sql_freeresult($result); + return true; + } + + return false; + } + + /** + * Create SQL Table + * + * @param string $table_name The table name to create + * @param array $table_data Array containing table data. + * @return array Statements if $return_statements is true. + */ + function sql_create_table($table_name, $table_data) + { + // holds the DDL for a column + $columns = $statements = array(); + + // Begin transaction + $statements[] = 'begin'; + + // Determine if we have created a PRIMARY KEY in the earliest + $primary_key_gen = false; + + // Determine if the table must be created with TEXTIMAGE + $create_textimage = false; + + // Determine if the table requires a sequence + $create_sequence = false; + + // Begin table sql statement + switch ($this->sql_layer) + { + case 'mssql': + $table_sql = 'CREATE TABLE [' . $table_name . '] (' . "\n"; + break; + + default: + $table_sql = 'CREATE TABLE ' . $table_name . ' (' . "\n"; + break; + } + + // Iterate through the columns to create a table + foreach ($table_data['COLUMNS'] as $column_name => $column_data) + { + // here lies an array, filled with information compiled on the column's data + $prepared_column = $this->sql_prepare_column_data($table_name, $column_name, $column_data); + + // here we add the definition of the new column to the list of columns + switch ($this->sql_layer) + { + case 'mssql': + $columns[] = "\t [{$column_name}] " . $prepared_column['column_type_sql_default']; + break; + + default: + $columns[] = "\t {$column_name} " . $prepared_column['column_type_sql']; + break; + } + + // see if we have found a primary key set due to a column definition if we have found it, we can stop looking + if (!$primary_key_gen) + { + $primary_key_gen = isset($prepared_column['primary_key_set']) && $prepared_column['primary_key_set']; + } + + // create textimage DDL based off of the existance of certain column types + if (!$create_textimage) + { + $create_textimage = isset($prepared_column['textimage']) && $prepared_column['textimage']; + } + + // create sequence DDL based off of the existance of auto incrementing columns + if (!$create_sequence && isset($prepared_column['auto_increment']) && $prepared_column['auto_increment']) + { + $create_sequence = $column_name; + } + } + + // this makes up all the columns in the create table statement + $table_sql .= implode(",\n", $columns); + + // Close the table for two DBMS and add to the statements + switch ($this->sql_layer) + { + case 'firebird': + $table_sql .= "\n);"; + $statements[] = $table_sql; + break; + + case 'mssql': + $table_sql .= "\n) ON [PRIMARY]" . (($create_textimage) ? ' TEXTIMAGE_ON [PRIMARY]' : ''); + $statements[] = $table_sql; + break; + } + + // we have yet to create a primary key for this table, + // this means that we can add the one we really wanted instead + if (!$primary_key_gen) + { + // Write primary key + if (isset($table_data['PRIMARY_KEY'])) + { + if (!is_array($table_data['PRIMARY_KEY'])) + { + $table_data['PRIMARY_KEY'] = array($table_data['PRIMARY_KEY']); + } + + switch ($this->sql_layer) + { + case 'mysql_40': + case 'mysql_41': + case 'postgres': + case 'sqlite': + $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; + break; + + case 'firebird': + case 'mssql': + $primary_key_stmts = $this->sql_create_primary_key($table_name, $table_data['PRIMARY_KEY']); + foreach ($primary_key_stmts as $pk_stmt) + { + $statements[] = $pk_stmt; + } + break; + + case 'oracle': + $table_sql .= ",\n\t CONSTRAINT pk_{$table_name} PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; + break; + } + } + } + + // close the table + switch ($this->sql_layer) + { + case 'mysql_41': + // make sure the table is in UTF-8 mode + $table_sql .= "\n) CHARACTER SET `utf8` COLLATE `utf8_bin`;"; + $statements[] = $table_sql; + break; + + case 'mysql_40': + case 'sqlite': + $table_sql .= "\n);"; + $statements[] = $table_sql; + break; + + case 'postgres': + // do we need to add a sequence for auto incrementing columns? + if ($create_sequence) + { + $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; + } + + $table_sql .= "\n);"; + $statements[] = $table_sql; + break; + + case 'oracle': + $table_sql .= "\n);"; + $statements[] = $table_sql; + + // do we need to add a sequence and a tigger for auto incrementing columns? + if ($create_sequence) + { + // create the actual sequence + $statements[] = "CREATE SEQUENCE {$table_name}_seq"; + + // the trigger is the mechanism by which we increment the counter + $trigger = "CREATE OR REPLACE TRIGGER t_{$table_name}\n"; + $trigger .= "BEFORE INSERT ON {$table_name}\n"; + $trigger .= "FOR EACH ROW WHEN (\n"; + $trigger .= "\tnew.{$create_sequence} IS NULL OR new.{$create_sequence} = 0\n"; + $trigger .= ")\n"; + $trigger .= "BEGIN\n"; + $trigger .= "\tSELECT {$table_name}_seq.nextval\n"; + $trigger .= "\tINTO :new.{$create_sequence}\n"; + $trigger .= "\tFROM dual\n"; + $trigger .= "END;"; + + $statements[] = $trigger; + } + break; + + case 'firebird': + if ($create_sequence) + { + $statements[] = "CREATE SEQUENCE {$table_name}_seq;"; + } + break; + } + + // Write Keys + if (isset($table_data['KEYS'])) + { + foreach ($table_data['KEYS'] as $key_name => $key_data) + { + if (!is_array($key_data[1])) + { + $key_data[1] = array($key_data[1]); + } + + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $key_stmts = ($key_data[0] == 'UNIQUE') ? $this->sql_create_unique_index($table_name, $key_name, $key_data[1]) : $this->sql_create_index($table_name, $key_name, $key_data[1]); + + foreach ($key_stmts as $key_stmt) + { + $statements[] = $key_stmt; + } + + $this->return_statements = $old_return_statements; + } + } + + // Commit Transaction + $statements[] = 'commit'; + + return $this->_sql_run_sql($statements); + } + + /** * Handle passed database update array. * Expected structure... * Key being one of the following @@ -308,7 +570,7 @@ class phpbb_db_tools * {KEY/INDEX NAME} => array({COLUMN NAMES}), * ) * - * For more information have a look at /develop/create_schema_files.php (only available through CVS) + * For more information have a look at /develop/create_schema_files.php (only available through SVN) */ function perform_schema_changes($schema_changes) { @@ -326,7 +588,15 @@ class phpbb_db_tools { foreach ($columns as $column_name => $column_data) { - $result = $this->sql_column_change($table, $column_name, $column_data); + // If the column exists we change it, else we add it ;) + if ($this->sql_column_exists($table, $column_name)) + { + $result = $this->sql_column_change($table, $column_name, $column_data); + } + else + { + $result = $this->sql_column_add($table, $column_name, $column_data); + } if ($this->return_statements) { @@ -343,15 +613,19 @@ class phpbb_db_tools { foreach ($columns as $column_name => $column_data) { - // Only add the column if it does not exist yet - if (!$this->sql_column_exists($table, $column_name)) + // Only add the column if it does not exist yet, else change it (to be consistent) + if ($this->sql_column_exists($table, $column_name)) + { + $result = $this->sql_column_change($table, $column_name, $column_data); + } + else { $result = $this->sql_column_add($table, $column_name, $column_data); + } - if ($this->return_statements) - { - $statements = array_merge($statements, $result); - } + if ($this->return_statements) + { + $statements = array_merge($statements, $result); } } } @@ -381,11 +655,15 @@ class phpbb_db_tools { foreach ($columns as $column) { - $result = $this->sql_column_remove($table, $column); - - if ($this->return_statements) + // Only remove the column if it exists... + if ($this->sql_column_exists($table, $column)) { - $statements = array_merge($statements, $result); + $result = $this->sql_column_remove($table, $column); + + if ($this->return_statements) + { + $statements = array_merge($statements, $result); + } } } } @@ -447,6 +725,10 @@ class phpbb_db_tools /** * Check if a specified column exist + * + * @param string $table Table to check the column at + * @param string $column_name The column to check + * * @return bool True if column exists, else false */ function sql_column_exists($table, $column_name) @@ -632,7 +914,6 @@ class phpbb_db_tools if (strpos($column_data[0], ':') !== false) { list($orig_column_type, $column_length) = explode(':', $column_data[0]); - if (!is_array($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'])) { $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length); @@ -705,6 +986,12 @@ class phpbb_db_tools $sql .= ' COLLATE UNICODE'; } + $return_array['auto_increment'] = false; + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $return_array['auto_increment'] = true; + } + break; case 'mssql': @@ -725,10 +1012,19 @@ class phpbb_db_tools } } + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { +// $sql .= 'IDENTITY (1, 1) '; + $sql_default .= 'IDENTITY (1, 1) '; + } + + $return_array['textimage'] = $column_type === '[text]'; + $sql .= 'NOT NULL'; $sql_default .= 'NOT NULL'; $return_array['column_type_sql_default'] = $sql_default; + break; case 'mysql_40': @@ -763,10 +1059,17 @@ class phpbb_db_tools // In Oracle empty strings ('') are treated as NULL. // Therefore in oracle we allow NULL's for all DEFAULT '' entries // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields) - if (preg_match('/number/i', $column_type)) + if (!preg_match('/number/i', $column_type)) { $sql .= ($column_data[1] === '') ? '' : 'NOT NULL'; } + + $return_array['auto_increment'] = false; + if (isset($column_data[2]) && $column_data[2] == 'auto_increment') + { + $return_array['auto_increment'] = true; + } + break; case 'postgres': @@ -774,9 +1077,11 @@ class phpbb_db_tools $sql .= " {$column_type} "; + $return_array['auto_increment'] = false; if (isset($column_data[2]) && $column_data[2] == 'auto_increment') { $default_val = "nextval('{$table_name}_seq')"; + $return_array['auto_increment'] = true; } else if (!is_null($column_data[1])) { @@ -795,12 +1100,15 @@ class phpbb_db_tools $return_array['constraint'] = "CHECK ({$column_name} >= 0)"; $sql .= " CHECK ({$column_name} >= 0)"; } + break; case 'sqlite': + $return_array['primary_key_set'] = false; if (isset($column_data[2]) && $column_data[2] == 'auto_increment') { $sql .= ' INTEGER PRIMARY KEY'; + $return_array['primary_key_set'] = true; } else { @@ -809,6 +1117,7 @@ class phpbb_db_tools $sql .= ' NOT NULL '; $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : ''; + break; } @@ -828,7 +1137,7 @@ class phpbb_db_tools switch ($this->sql_layer) { case 'firebird': - $statements[] = 'ALTER TABLE "' . $table_name . '" ADD "' . $column_name . '" ' . $column_data['column_type_sql']; + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD "' . strtoupper($column_name) . '" ' . $column_data['column_type_sql']; break; case 'mssql': @@ -920,7 +1229,7 @@ class phpbb_db_tools switch ($this->sql_layer) { case 'firebird': - $statements[] = 'ALTER TABLE "' . $table_name . '" DROP "' . $column_name . '"'; + $statements[] = 'ALTER TABLE ' . $table_name . ' DROP "' . strtoupper($column_name) . '"'; break; case 'mssql': @@ -1032,6 +1341,68 @@ class phpbb_db_tools } /** + * Drop Table + */ + function sql_table_drop($table_name) + { + $statements = array(); + + // the most basic operation, get rid of the table + $statements[] = 'DROP TABLE ' . $table_name; + + switch ($this->sql_layer) + { + case 'firebird': + $sql = 'SELECT RDB$GENERATOR_NAME as gen + FROM RDB$GENERATORS + WHERE RDB$SYSTEM_FLAG = 0 + AND RDB$GENERATOR_NAME = \'' . strtoupper($table_name) . "_GEN'"; + $result = $this->db->sql_query($sql); + + // does a generator exist? + if ($row = $this->db->sql_fetchrow($result)) + { + $statements[] = "DROP GENERATOR {$row['gen']};"; + } + $this->db->sql_freeresult($result); + break; + + case 'oracle': + $sql = 'SELECT A.REFERENCED_NAME + FROM USER_DEPENDENCIES A, USER_TRIGGERS B + WHERE A.REFERENCED_TYPE = \'SEQUENCE\' + AND A.NAME = B.TRIGGER_NAME + AND B.TABLE_NAME = \'' . strtoupper($table_name) . "'"; + $result = $this->db->sql_query($sql); + + // any sequences ref'd to this table's triggers? + while ($row = $this->db->sql_fetchrow($result)) + { + $statements[] = "DROP SEQUENCE {$row['referenced_name']}"; + } + $this->db->sql_freeresult($result); + + case 'postgres': + // PGSQL does not "tightly" bind sequences and tables, we must guess... + $sql = "SELECT relname + FROM pg_class + WHERE relkind = 'S' + AND relname = '{$table_name}_seq'"; + $result = $this->db->sql_query($sql); + + // We don't even care about storing the results. We already know the answer if we get rows back. + if ($this->db->sql_fetchrow($result)) + { + $statements[] = "DROP SEQUENCE {$table_name}_seq;\n"; + } + $this->db->sql_freeresult($result); + break; + } + + return $this->_sql_run_sql($statements); + } + + /** * Add primary key */ function sql_create_primary_key($table_name, $column) @@ -1042,6 +1413,8 @@ class phpbb_db_tools { case 'firebird': case 'postgres': + case 'mysql_40': + case 'mysql_41': $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; break; @@ -1054,11 +1427,6 @@ class phpbb_db_tools $statements[] = $sql; break; - case 'mysql_40': - case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; - break; - case 'oracle': $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; break; @@ -1233,6 +1601,7 @@ class phpbb_db_tools FROM user_indexes WHERE table_name = '" . $table_name . "' AND generated = 'N'"; + $col = 'index_name'; break; case 'sqlite': @@ -1279,7 +1648,7 @@ class phpbb_db_tools { case 'firebird': // Change type... - $statements[] = 'ALTER TABLE "' . $table_name . '" ALTER COLUMN "' . $column_name . '" TYPE ' . ' ' . $column_data['column_type_sql']; + $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql']; break; case 'mssql': diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php index 080f3d541a..c03b38708c 100644 --- a/phpBB/includes/db/mysql.php +++ b/phpBB/includes/db/mysql.php @@ -51,7 +51,7 @@ class dbal_mysql extends dbal if (@mysql_select_db($this->dbname, $this->db_connect_id)) { // Determine what version we are using and if it natively supports UNICODE - if (version_compare($this->sql_server_info(true), '4.1.3', '>=')) + if (version_compare($this->sql_server_info(true), '4.1.0', '>=')) { @mysql_query("SET NAMES 'utf8'", $this->db_connect_id); @@ -341,7 +341,7 @@ class dbal_mysql extends dbal return $data; } - + /** * return sql error array * @access private diff --git a/phpBB/includes/db/postgres.php b/phpBB/includes/db/postgres.php index 83678e2904..d117e8c948 100644 --- a/phpBB/includes/db/postgres.php +++ b/phpBB/includes/db/postgres.php @@ -26,7 +26,7 @@ include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx); class dbal_postgres extends dbal { var $last_query_text = ''; - + /** * Connect to server */ @@ -55,7 +55,7 @@ class dbal_postgres extends dbal { $connect_string .= "host=$sqlserver "; } - + if ($port) { $connect_string .= "port=$port "; @@ -224,7 +224,7 @@ class dbal_postgres extends dbal // if $total is set to 0 we do not want to limit the number of rows if ($total == 0) { - $total = -1; + $total = 'ALL'; } $query .= "\n LIMIT $total OFFSET $offset"; diff --git a/phpBB/includes/diff/diff.php b/phpBB/includes/diff/diff.php index ef018b2d9a..2adc3a3e6e 100644 --- a/phpBB/includes/diff/diff.php +++ b/phpBB/includes/diff/diff.php @@ -17,7 +17,7 @@ if (!defined('IN_PHPBB')) } /** -* Code from pear.php.net, Text_Diff-1.0.0 package +* Code from pear.php.net, Text_Diff-1.1.0 package * http://pear.php.net/package/Text_Diff/ * * Modified by phpBB Group to meet our coding standards @@ -61,6 +61,48 @@ class diff } /** + * returns the number of new (added) lines in a given diff. + * + * @since Text_Diff 1.1.0 + * + * @return integer The number of new lines + */ + function count_added_lines() + { + $count = 0; + + foreach ($this->_edits as $edit) + { + if (is_a($edit, 'diff_op_add') || is_a($edit, 'diff_op_change')) + { + $count += $edit->nfinal(); + } + } + return $count; + } + + /** + * Returns the number of deleted (removed) lines in a given diff. + * + * @since Text_Diff 1.1.0 + * + * @return integer The number of deleted lines + */ + function count_deleted_lines() + { + $count = 0; + + foreach ($this->_edits as $edit) + { + if (is_a($edit, 'diff_op_delete') || is_a($edit, 'diff_op_change')) + { + $count += $edit->norig(); + } + } + return $count; + } + + /** * Computes a reversed diff. * * Example: @@ -427,33 +469,37 @@ class diff3 extends diff } /** - * Return merged output + * Return number of conflicts + */ + function get_num_conflicts() + { + $conflicts = 0; + + foreach ($this->_edits as $edit) + { + if ($edit->is_conflict()) + { + $conflicts++; + } + } + + return $conflicts; + } + + /** + * Get conflicts content for download. This is generally a merged file, but preserving conflicts and adding explanations to it. + * A user could then go through this file, search for the conflicts and changes the code accordingly. * * @param string $label1 the cvs file version/label from the original set of lines * @param string $label2 the cvs file version/label from the new set of lines * @param string $label_sep the explanation between label1 and label2 - more of a helper for the user - * @param bool $get_conflicts if set to true only the number of conflicts is returned - * @param bool $merge_new if set to true the merged output will have the new file contents on a conflicting merge * * @return mixed the merged output */ - function merged_output($label1 = 'CURRENT_FILE', $label2 = 'NEW_FILE', $label_sep = 'DIFF_SEP_EXPLAIN', $get_conflicts = false, $merge_new = false) + function get_conflicts_content($label1 = 'CURRENT_FILE', $label2 = 'NEW_FILE', $label_sep = 'DIFF_SEP_EXPLAIN') { global $user; - if ($get_conflicts) - { - foreach ($this->_edits as $edit) - { - if ($edit->is_conflict()) - { - $this->_conflicting_blocks++; - } - } - - return $this->_conflicting_blocks; - } - $label1 = (!empty($user->lang[$label1])) ? $user->lang[$label1] : $label1; $label2 = (!empty($user->lang[$label2])) ? $user->lang[$label2] : $label2; $label_sep = (!empty($user->lang[$label_sep])) ? $user->lang[$label_sep] : $label_sep; @@ -464,14 +510,12 @@ class diff3 extends diff { if ($edit->is_conflict()) { - if (!$merge_new) - { - $lines = array_merge($lines, array('<<<<<<<' . ($label1 ? ' ' . $label1 : '')), $edit->final1, array('=======' . ($label_sep ? ' ' . $label_sep : '')), $edit->final2, array('>>>>>>>' . ($label2 ? ' ' . $label2 : ''))); - } - else - { - $lines = array_merge($lines, $edit->final1); - } + // Start conflict label + $label_start = array('<<<<<<< ' . $label1); + $label_mid = array('======= ' . $label_sep); + $label_end = array('>>>>>>> ' . $label2); + + $lines = array_merge($lines, $label_start, $edit->final1, $label_mid, $edit->final2, $label_end); $this->_conflicting_blocks++; } else @@ -484,6 +528,16 @@ class diff3 extends diff } /** + * Return merged output (used by the renderer) + * + * @return mixed the merged output + */ + function merged_output() + { + return $this->get_conflicts_content(); + } + + /** * Merge the output and use the new file code for conflicts */ function merged_new_output() diff --git a/phpBB/includes/diff/engine.php b/phpBB/includes/diff/engine.php index d82afb048a..eb0dcce395 100644 --- a/phpBB/includes/diff/engine.php +++ b/phpBB/includes/diff/engine.php @@ -17,7 +17,7 @@ if (!defined('IN_PHPBB')) } /** -* Code from pear.php.net, Text_Diff-1.0.0 package +* Code from pear.php.net, Text_Diff-1.1.0 package * http://pear.php.net/package/Text_Diff/ (native engine) * * Modified by phpBB Group to meet our coding standards diff --git a/phpBB/includes/diff/renderer.php b/phpBB/includes/diff/renderer.php index 2e0ec86e75..02fb6ccc37 100644 --- a/phpBB/includes/diff/renderer.php +++ b/phpBB/includes/diff/renderer.php @@ -17,7 +17,7 @@ if (!defined('IN_PHPBB')) } /** -* Code from pear.php.net, Text_Diff-1.0.0 package +* Code from pear.php.net, Text_Diff-1.1.0 package * http://pear.php.net/package/Text_Diff/ * * Modified by phpBB Group to meet our coding standards diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 55c4cc5b51..be5e661d44 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -165,6 +165,37 @@ function set_config($config_name, $config_value, $is_dynamic = false) } /** +* Set dynamic config value with arithmetic operation. +*/ +function set_config_count($config_name, $increment, $is_dynamic = false) +{ + global $db, $cache; + + switch ($db->sql_layer) + { + case 'firebird': + $sql_update = 'CAST(CAST(config_value as integer) + ' . (int) $increment . ' as CHAR)'; + break; + + case 'postgres': + $sql_update = 'int4(config_value) + ' . (int) $increment; + break; + + // MySQL, SQlite, mssql, mssql_odbc, oracle + default: + $sql_update = 'config_value + ' . (int) $increment; + break; + } + + $db->sql_query('UPDATE ' . CONFIG_TABLE . ' SET config_value = ' . $sql_update . " WHERE config_name = '" . $db->sql_escape($config_name) . "'"); + + if (!$is_dynamic) + { + $cache->destroy('config'); + } +} + +/** * Generates an alphanumeric random string of given length */ function gen_rand_string($num_chars = 8) @@ -205,6 +236,11 @@ function get_formatted_filesize($bytes, $add_size_lang = true) { global $user; + if ($bytes >= pow(2, 30)) + { + return ($add_size_lang) ? round($bytes / 1024 / 1024 / 1024, 2) . ' ' . $user->lang['GIB'] : round($bytes / 1024 / 1024 / 1024, 2); + } + if ($bytes >= pow(2, 20)) { return ($add_size_lang) ? round($bytes / 1024 / 1024, 2) . ' ' . $user->lang['MIB'] : round($bytes / 1024 / 1024, 2); @@ -461,8 +497,9 @@ function _hash_crypt_private($password, $setting, &$itoa64) /** * Global function for chmodding directories and files for internal use +* * This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions. -* The function determines owner and group from common.php file and sets the same to the provided file. Permissions are mapped to the group, user always has rw(x) permission. +* The function determines owner and group from common.php file and sets the same to the provided file. * The function uses bit fields to build the permissions. * The function sets the appropiate execute bit on directories. * @@ -475,76 +512,106 @@ function _hash_crypt_private($password, $setting, &$itoa64) * * NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions. * -* @param $filename The file/directory to be chmodded -* @param $perms Permissions to set -* @return true on success, otherwise false +* @param string $filename The file/directory to be chmodded +* @param int $perms Permissions to set * +* @return bool true on success, otherwise false * @author faw, phpBB Group */ function phpbb_chmod($filename, $perms = CHMOD_READ) { + static $_chmod_info; + // Return if the file no longer exists. if (!file_exists($filename)) { return false; } - if (!function_exists('fileowner') || !function_exists('filegroup')) + // Determine some common vars + if (empty($_chmod_info)) { - $file_uid = $file_gid = false; - $common_php_owner = $common_php_group = false; - } - else - { - global $phpbb_root_path, $phpEx; + if (!function_exists('fileowner') || !function_exists('filegroup')) + { + // No need to further determine owner/group - it is unknown + $_chmod_info['process'] = false; + } + else + { + global $phpbb_root_path, $phpEx; - // Determine owner/group of common.php file and the filename we want to change here - $common_php_owner = fileowner($phpbb_root_path . 'common.' . $phpEx); - $common_php_group = filegroup($phpbb_root_path . 'common.' . $phpEx); + // Determine owner/group of common.php file and the filename we want to change here + $common_php_owner = fileowner($phpbb_root_path . 'common.' . $phpEx); + $common_php_group = filegroup($phpbb_root_path . 'common.' . $phpEx); - $file_uid = fileowner($filename); - $file_gid = filegroup($filename); + // And the owner and the groups PHP is running under. + $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false; + $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false; - // Try to set the owner to the same common.php has - if ($common_php_owner !== $file_uid && $common_php_owner !== false && $file_uid !== false) - { - // Will most likely not work - if (@chown($filename, $common_php_owner)); + // If we are unable to get owner/group, then do not try to set them by guessing + if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group) { - clearstatcache(); - $file_uid = fileowner($filename); + $_chmod_info['process'] = false; } - } - - // Try to set the group to the same common.php has - if ($common_php_group !== $file_gid && $common_php_group !== false && $file_gid !== false) - { - if (@chgrp($filename, $common_php_group)); + else { - clearstatcache(); - $file_gid = filegroup($filename); + $_chmod_info = array( + 'process' => true, + 'common_owner' => $common_php_owner, + 'common_group' => $common_php_group, + 'php_uid' => $php_uid, + 'php_gids' => $php_gids, + ); } } } - // And the owner and the groups PHP is running under. - $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false; - $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false; - - // Who is PHP? - if ($file_uid === false || $file_gid === false || $php_uid === false || $php_gids === false) - { - $php = NULL; - } - else if ($file_uid == $php_uid /* && $common_php_owner !== false && $common_php_owner === $file_uid*/) + if ($_chmod_info['process']) { - $php = 'owner'; + $file_uid = fileowner($filename); + $file_gid = filegroup($filename); + + // Change owner + if (@chown($filename, $_chmod_info['common_owner'])) + { + clearstatcache(); + $file_uid = fileowner($filename); + } + + // Change group + if (@chgrp($filename, $_chmod_info['common_group'])) + { + clearstatcache(); + $file_gid = filegroup($filename); + } + + // If the file_uid/gid now match the one from common.php we can process further, else we are not able to change something + if ($file_uid != $_chmod_info['common_owner'] || $file_gid != $_chmod_info['common_group']) + { + $_chmod_info['process'] = false; + } } - else if (in_array($file_gid, $php_gids)) + + // Still able to process? + if ($_chmod_info['process']) { - $php = 'group'; + if ($file_uid == $_chmod_info['php_uid']) + { + $php = 'owner'; + } + else if (in_array($file_gid, $_chmod_info['php_gids'])) + { + $php = 'group'; + } + else + { + // Since we are setting the everyone bit anyway, no need to do expensive operations + $_chmod_info['process'] = false; + } } - else + + // We are not able to determine or change something + if (!$_chmod_info['process']) { $php = 'other'; } @@ -564,26 +631,22 @@ function phpbb_chmod($filename, $perms = CHMOD_READ) switch ($php) { - case null: case 'owner': - /* ATTENTION: if php is owner or NULL we set it to group here. This is the most failsafe combination for the vast majority of server setups. - $result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0)); clearstatcache(); - if (!is_null($php) || (is_readable($filename) && is_writable($filename))) + if (is_readable($filename) && is_writable($filename)) { break; } - */ case 'group': $result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0)); clearstatcache(); - if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))) + if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))) { break; } @@ -593,7 +656,7 @@ function phpbb_chmod($filename, $perms = CHMOD_READ) clearstatcache(); - if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename)))) + if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))) { break; } @@ -703,7 +766,7 @@ if (!function_exists('stripos')) */ function is_absolute($path) { - return ($path[0] == '/' || (DIRECTORY_SEPARATOR == '\\' && preg_match('#^[a-z]:/#i', $path))) ? true : false; + return ($path[0] == '/' || (DIRECTORY_SEPARATOR == '\\' && preg_match('#^[a-z]:[/\\\]#i', $path))) ? true : false; } /** @@ -1065,7 +1128,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ $sql_update = array(); while ($row = $db->sql_fetchrow($result)) { - $sql_update[] = $row['forum_id']; + $sql_update[] = (int) $row['forum_id']; } $db->sql_freeresult($result); @@ -2574,7 +2637,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa $db->sql_query($sql); // Generate code - $code = gen_rand_string(mt_rand(5, 8)); + $code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); $confirm_id = md5(unique_id($user->ip)); $seed = hexdec(substr(unique_id(), 4, 10)); @@ -3182,6 +3245,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline) $msg_text = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $msg_text); echo '<b>[phpBB Debug] PHP Notice</b>: in file <b>' . $errfile . '</b> on line <b>' . $errline . '</b>: <b>' . $msg_text . '</b><br />' . "\n"; + // echo '<br /><br />BACKTRACE<br />' . get_backtrace() . '<br />' . "\n"; } return; @@ -3369,7 +3433,7 @@ function obtain_guest_count($forum_id = 0) AND s.session_time >= ' . ($time - ((int) ($time % 60))) . $reading_sql; } - $result = $db->sql_query($sql, 60); + $result = $db->sql_query($sql); $guests_online = (int) $db->sql_fetchfield('num_guests'); $db->sql_freeresult($result); diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 5ec51e44cf..79282c0358 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -619,7 +619,7 @@ function delete_topics($where_type, $where_ids, $auto_sync = true, $post_count_s if ($approved_topics) { - set_config('num_topics', $config['num_topics'] - $approved_topics, true); + set_config_count('num_topics', $approved_topics * (-1), true); } return $return; @@ -652,7 +652,23 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = return false; } - $where_clause = $db->sql_in_set($where_type, array_map('intval', $where_ids)); + $where_ids = array_map('intval', $where_ids); + +/* Possible code for splitting post deletion + if (sizeof($where_ids) >= 1001) + { + // Split into chunks of 1000 + $chunks = array_chunk($where_ids, 1000); + + foreach ($chunks as $_where_ids) + { + delete_posts($where_type, $_where_ids, $auto_sync, $posted_sync, $post_count_sync, $call_delete_topics); + } + + return; + }*/ + + $where_clause = $db->sql_in_set($where_type, $where_ids); } $approved_posts = 0; @@ -665,10 +681,10 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = while ($row = $db->sql_fetchrow($result)) { - $post_ids[] = $row['post_id']; - $poster_ids[] = $row['poster_id']; - $topic_ids[] = $row['topic_id']; - $forum_ids[] = $row['forum_id']; + $post_ids[] = (int) $row['post_id']; + $poster_ids[] = (int) $row['poster_id']; + $topic_ids[] = (int) $row['topic_id']; + $forum_ids[] = (int) $row['forum_id']; if ($row['post_postcount'] && $post_count_sync && $row['post_approved']) { @@ -776,7 +792,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = if ($approved_posts) { - set_config('num_posts', $config['num_posts'] - $approved_posts, true); + set_config_count('num_posts', $approved_posts * (-1), true); } // We actually remove topics now to not be inconsistent (the delete_topics function calls this function too) @@ -814,11 +830,14 @@ function delete_attachments($mode, $ids, $resync = true) return false; } + $sql_where = ''; + switch ($mode) { case 'post': case 'message': $sql_id = 'post_msg_id'; + $sql_where = ' AND in_message = ' . ($mode == 'message' ? 1 : 0); break; case 'topic': @@ -842,6 +861,9 @@ function delete_attachments($mode, $ids, $resync = true) $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); + + $sql .= $sql_where; + $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) @@ -867,6 +889,9 @@ function delete_attachments($mode, $ids, $resync = true) // Delete attachments $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); + + $sql .= $sql_where; + $db->sql_query($sql); $num_deleted = $db->sql_affectedrows(); @@ -894,8 +919,8 @@ function delete_attachments($mode, $ids, $resync = true) if ($space_removed || $files_removed) { - set_config('upload_dir_size', $config['upload_dir_size'] - $space_removed, true); - set_config('num_files', $config['num_files'] - $files_removed, true); + set_config_count('upload_dir_size', $space_removed * (-1), true); + set_config_count('num_files', $files_removed * (-1), true); } // If we do not resync, we do not need to adjust any message, post, topic or user entries diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index f5c0786fed..23cbff7e8f 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -950,6 +950,8 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count, 'S_THUMBNAIL' => true, 'THUMB_IMAGE' => $thumbnail_link, ); + + $update_count[] = $attachment['attach_id']; break; // Windows Media Streams @@ -996,6 +998,7 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count, 'S_FLASH_FILE' => true, 'WIDTH' => $width, 'HEIGHT' => $height, + 'U_VIEW_LINK' => $download_link . '&view=1', ); // Viewed/Heared File ... update the download count @@ -1126,7 +1129,7 @@ function truncate_string($string, $max_length = 60, $max_store_length = 255, $al array_pop($chars); $string = implode('', $chars); } - while (utf8_strlen($string) > $max_store_length || !sizeof($chars)); + while (!empty($chars) && utf8_strlen($string) > $max_store_length); } if ($strip_reply) @@ -1159,72 +1162,87 @@ function truncate_string($string, $max_length = 60, $max_store_length = 255, $al function get_username_string($mode, $user_id, $username, $username_colour = '', $guest_username = false, $custom_profile_url = false) { static $_profile_cache; - static $_base_profile_url; - - $cache_key = $user_id; - // If the get_username_string() function had been executed once with an (to us) unkown mode, all modes are pre-filled and we can just grab it. - if ($user_id && $user_id != ANONYMOUS && isset($_profile_cache[$cache_key][$mode])) + // We cache some common variables we need within this function + if (empty($_profile_cache)) { - // If the mode is 'no_profile', we simply construct the TPL code due to calls to this mode being very very rare - if ($mode == 'no_profile') - { - $tpl = (!$_profile_cache[$cache_key]['colour']) ? '{USERNAME}' : '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>'; - return str_replace(array('{USERNAME_COLOUR}', '{USERNAME}'), array($_profile_cache[$cache_key]['colour'], $_profile_cache[$cache_key]['username']), $tpl); - } + global $phpbb_root_path, $phpEx; - return $_profile_cache[$cache_key][$mode]; + $_profile_cache['base_url'] = append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u={USER_ID}'); + $_profile_cache['tpl_noprofile'] = '{USERNAME}'; + $_profile_cache['tpl_noprofile_colour'] = '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>'; + $_profile_cache['tpl_profile'] = '<a href="{PROFILE_URL}">{USERNAME}</a>'; + $_profile_cache['tpl_profile_colour'] = '<a href="{PROFILE_URL}" style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</a>'; } - global $phpbb_root_path, $phpEx, $user, $auth; - - $username_colour = ($username_colour) ? '#' . $username_colour : ''; + global $user, $auth; - if ($guest_username === false) + // This switch makes sure we only run code required for the mode + switch ($mode) { - $username = ($username) ? $username : $user->lang['GUEST']; - } - else - { - $username = ($user_id && $user_id != ANONYMOUS) ? $username : ((!empty($guest_username)) ? $guest_username : $user->lang['GUEST']); - } + case 'full': + case 'no_profile': + case 'colour': - // Build cache for all modes - $_profile_cache[$cache_key]['colour'] = $username_colour; - $_profile_cache[$cache_key]['username'] = $username; - $_profile_cache[$cache_key]['no_profile'] = true; + // Build correct username colour + $username_colour = ($username_colour) ? '#' . $username_colour : ''; - // Profile url - only show if not anonymous and permission to view profile if registered user - // For anonymous the link leads to a login page. - if ($user_id && $user_id != ANONYMOUS && ($user->data['user_id'] == ANONYMOUS || $auth->acl_get('u_viewprofile'))) - { - if (empty($_base_profile_url)) - { - $_base_profile_url = append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=viewprofile&u={USER_ID}'); - } + // Return colour + if ($mode == 'colour') + { + return $username_colour; + } - $profile_url = ($custom_profile_url !== false) ? $custom_profile_url . '&u=' . (int) $user_id : str_replace('={USER_ID}', '=' . (int) $user_id, $_base_profile_url); - $tpl = (!$username_colour) ? '<a href="{PROFILE_URL}">{USERNAME}</a>' : '<a href="{PROFILE_URL}" style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</a>'; - $_profile_cache[$cache_key]['full'] = str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), $tpl); - } - else - { - $tpl = (!$username_colour) ? '{USERNAME}' : '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>'; - $_profile_cache[$cache_key]['full'] = str_replace(array('{USERNAME_COLOUR}', '{USERNAME}'), array($username_colour, $username), $tpl); - $profile_url = ''; - } + // no break; - // Use the profile url from above - $_profile_cache[$cache_key]['profile'] = $profile_url; + case 'username': + + // Build correct username + if ($guest_username === false) + { + $username = ($username) ? $username : $user->lang['GUEST']; + } + else + { + $username = ($user_id && $user_id != ANONYMOUS) ? $username : ((!empty($guest_username)) ? $guest_username : $user->lang['GUEST']); + } + + // Return username + if ($mode == 'username') + { + return $username; + } + + // no break; + + case 'profile': + + // Build correct profile url - only show if not anonymous and permission to view profile if registered user + // For anonymous the link leads to a login page. + if ($user_id && $user_id != ANONYMOUS && ($user->data['user_id'] == ANONYMOUS || $auth->acl_get('u_viewprofile'))) + { + $profile_url = ($custom_profile_url !== false) ? $custom_profile_url . '&u=' . (int) $user_id : str_replace(array('={USER_ID}', '=%7BUSER_ID%7D'), '=' . (int) $user_id, $_profile_cache['base_url']); + } + else + { + $profile_url = ''; + } + + // Return profile + if ($mode == 'profile') + { + return $profile_url; + } + + // no break; + } - // If - by any chance - no_profile is called before any other mode, we need to do the calculation here - if ($mode == 'no_profile') + if (($mode == 'full' && !$profile_url) || $mode == 'no_profile') { - $tpl = (!$_profile_cache[$cache_key]['colour']) ? '{USERNAME}' : '<span style="color: {USERNAME_COLOUR};" class="username-coloured">{USERNAME}</span>'; - return str_replace(array('{USERNAME_COLOUR}', '{USERNAME}'), array($_profile_cache[$cache_key]['colour'], $_profile_cache[$cache_key]['username']), $tpl); + return str_replace(array('{USERNAME_COLOUR}', '{USERNAME}'), array($username_colour, $username), (!$username_colour) ? $_profile_cache['tpl_noprofile'] : $_profile_cache['tpl_noprofile_colour']); } - return $_profile_cache[$cache_key][$mode]; + return str_replace(array('{PROFILE_URL}', '{USERNAME_COLOUR}', '{USERNAME}'), array($profile_url, $username_colour, $username), (!$username_colour) ? $_profile_cache['tpl_profile'] : $_profile_cache['tpl_profile_colour']); } /** diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 14ab079202..fdcc118269 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -237,7 +237,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod // Handle marking posts if ($mark_read == 'forums' || $mark_read == 'all') { - $redirect = build_url('mark', 'hash'); + $redirect = build_url(array('mark', 'hash')); $token = request_var('hash', ''); if (check_link_hash($token, 'global')) { @@ -846,7 +846,7 @@ function topic_status(&$topic_row, $replies, $unread_topic, &$folder_img, &$fold */ function display_custom_bbcodes() { - global $db, $template; + global $db, $template, $user; // Start counting from 22 for the bbcode ids (every bbcode takes two ids - opening/closing) $num_predefined_bbcodes = 22; @@ -860,6 +860,12 @@ function display_custom_bbcodes() $i = 0; while ($row = $db->sql_fetchrow($result)) { + // If the helpline is defined within the language file, we will use the localised version, else just use the database entry... + if (isset($user->lang[strtoupper($row['bbcode_helpline'])])) + { + $row['bbcode_helpline'] = $user->lang[strtoupper($row['bbcode_helpline'])]; + } + $template->assign_block_vars('custom_tags', array( 'BBCODE_NAME' => "'[{$row['bbcode_tag']}]', '[/" . str_replace('=', '', $row['bbcode_tag']) . "]'", 'BBCODE_ID' => $num_predefined_bbcodes + ($i * 2), diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index cbec2582a9..4fd5fd19e0 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -28,6 +28,7 @@ class messenger var $mail_priority = MAIL_NORMAL_PRIORITY; var $use_queue = true; var $tpl_msg = array(); + var $eol = "\n"; /** * Constructor @@ -38,6 +39,10 @@ class messenger $this->use_queue = (!$config['email_package_size']) ? false : $use_queue; $this->subject = ''; + + // Determine EOL character (\n for UNIX, \r\n for Windows and \r for Mac) + $this->eol = (!defined('PHP_EOL')) ? (($eol = strtolower(substr(PHP_OS, 0, 3))) == 'win') ? "\r\n" : (($eol == 'mac') ? "\r" : "\n") : PHP_EOL; + $this->eol = (!$this->eol) ? "\n" : $this->eol; } /** @@ -57,6 +62,11 @@ class messenger { global $config; + if (!trim($address)) + { + return; + } + $pos = isset($this->addresses['to']) ? sizeof($this->addresses['to']) : 0; $this->addresses['to'][$pos]['email'] = trim($address); @@ -77,6 +87,11 @@ class messenger */ function cc($address, $realname = '') { + if (!trim($address)) + { + return; + } + $pos = isset($this->addresses['cc']) ? sizeof($this->addresses['cc']) : 0; $this->addresses['cc'][$pos]['email'] = trim($address); $this->addresses['cc'][$pos]['name'] = trim($realname); @@ -87,6 +102,11 @@ class messenger */ function bcc($address, $realname = '') { + if (!trim($address)) + { + return; + } + $pos = isset($this->addresses['bcc']) ? sizeof($this->addresses['bcc']) : 0; $this->addresses['bcc'][$pos]['email'] = trim($address); $this->addresses['bcc'][$pos]['name'] = trim($realname); @@ -98,7 +118,7 @@ class messenger function im($address, $realname = '') { // IM-Addresses could be empty - if (!$address) + if (!trim($address)) { return; } @@ -153,7 +173,7 @@ class messenger */ function template($template_file, $template_lang = '') { - global $config, $phpbb_root_path; + global $config, $phpbb_root_path, $user; if (!trim($template_file)) { @@ -167,7 +187,8 @@ class messenger if (empty($this->tpl_msg[$template_lang . $template_file])) { - $tpl_file = "{$phpbb_root_path}language/$template_lang/email/$template_file.txt"; + $tpl_file = (!empty($user->lang_path)) ? $user->lang_path : $phpbb_root_path . 'language/'; + $tpl_file .= $template_lang . "/email/$template_file.txt"; if (!file_exists($tpl_file)) { @@ -309,6 +330,7 @@ class messenger { global $config; + // We could use keys here, but we won't do this for 3.0.x to retain backwards compatibility $headers = array(); $headers[] = 'From: ' . $this->from; @@ -338,15 +360,12 @@ class messenger $headers[] = 'X-MimeOLE: phpBB3'; $headers[] = 'X-phpBB-Origin: phpbb://' . str_replace(array('http://', 'https://'), array('', ''), generate_board_url()); - // We use \n here instead of \r\n because our smtp mailer is adjusting it to \r\n automatically, whereby the php mail function only works - // if using \n. - if (sizeof($this->extra_headers)) { - $headers[] = implode("\n", $this->extra_headers); + $headers = array_merge($headers, $this->extra_headers); } - return implode("\n", $headers); + return $headers; } /** @@ -361,6 +380,13 @@ class messenger return false; } + // Addresses to send to? + if (empty($this->addresses) || (empty($this->addresses['to']) && empty($this->addresses['cc']) && empty($this->addresses['bcc']))) + { + // Send was successful. ;) + return true; + } + $use_queue = false; if ($config['email_package_size'] && $this->use_queue) { @@ -412,6 +438,10 @@ class messenger } else { + // We use the EOL character for the OS here because the PHP mail function does not correctly transform line endings. On Windows SMTP is used (SMTP is \r\n), on UNIX a command is used... + // Reference: http://bugs.php.net/bug.php?id=15841 + $headers = implode($this->eol, $headers); + ob_start(); $result = $config['email_function_name']($mail_to, mail_encode($this->subject), wordwrap(utf8_wordwrap($this->msg), 997, "\n", true), $headers); $err_msg = ob_get_clean(); @@ -451,7 +481,8 @@ class messenger if (empty($this->addresses['im'])) { - return false; + // Send was successful. ;) + return true; } $use_queue = false; @@ -519,6 +550,7 @@ class queue var $queue_data = array(); var $package_size = 0; var $cache_file = ''; + var $eol = "\n"; /** * constructor @@ -529,6 +561,10 @@ class queue $this->data = array(); $this->cache_file = "{$phpbb_root_path}cache/queue.$phpEx"; + + // Determine EOL character (\n for UNIX, \r\n for Windows and \r for Mac) + $this->eol = (!defined('PHP_EOL')) ? (($eol = strtolower(substr(PHP_OS, 0, 3))) == 'win') ? "\r\n" : (($eol == 'mac') ? "\r" : "\n") : PHP_EOL; + $this->eol = (!$this->eol) ? "\n" : $this->eol; } /** @@ -652,7 +688,7 @@ class queue else { ob_start(); - $result = $config['email_function_name']($to, mail_encode($subject), wordwrap(utf8_wordwrap($msg), 997, "\n", true), $headers); + $result = $config['email_function_name']($to, mail_encode($subject), wordwrap(utf8_wordwrap($msg), 997, "\n", true), implode($this->eol, $headers)); $err_msg = ob_get_clean(); } @@ -704,11 +740,11 @@ class queue if ($fp = @fopen($this->cache_file, 'wb')) { @flock($fp, LOCK_EX); - fwrite($fp, "<?php\n\$this->queue_data = unserialize(" . var_export(serialize($this->queue_data), true) . ");\n\n?>"); + fwrite($fp, "<?php\nif (!defined('IN_PHPBB')) exit;\n\$this->queue_data = unserialize(" . var_export(serialize($this->queue_data), true) . ");\n\n?>"); @flock($fp, LOCK_UN); fclose($fp); - phpbb_chmod($this->cache_file, CHMOD_WRITE); + phpbb_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE); } } @@ -745,11 +781,11 @@ class queue if ($fp = @fopen($this->cache_file, 'w')) { @flock($fp, LOCK_EX); - fwrite($fp, "<?php\n\$this->queue_data = unserialize(" . var_export(serialize($this->data), true) . ");\n\n?>"); + fwrite($fp, "<?php\nif (!defined('IN_PHPBB')) exit;\n\$this->queue_data = unserialize(" . var_export(serialize($this->data), true) . ");\n\n?>"); @flock($fp, LOCK_UN); fclose($fp); - phpbb_chmod($this->cache_file, CHMOD_WRITE); + phpbb_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE); } } } @@ -757,40 +793,37 @@ class queue /** * Replacement or substitute for PHP's mail command */ -function smtpmail($addresses, $subject, $message, &$err_msg, $headers = '') +function smtpmail($addresses, $subject, $message, &$err_msg, $headers = false) { global $config, $user; // Fix any bare linefeeds in the message to make it RFC821 Compliant. $message = preg_replace("#(?<!\r)\n#si", "\r\n", $message); - if ($headers != '') + if ($headers !== false) { - if (is_array($headers)) + if (!is_array($headers)) { - $headers = (sizeof($headers) > 1) ? join("\n", $headers) : $headers[0]; + // Make sure there are no bare linefeeds in the headers + $headers = preg_replace('#(?<!\r)\n#si', "\n", $headers); + $headers = explode("\n", $headers); } - $headers = chop($headers); - - // Make sure there are no bare linefeeds in the headers - $headers = preg_replace('#(?<!\r)\n#si', "\r\n", $headers); // Ok this is rather confusing all things considered, // but we have to grab bcc and cc headers and treat them differently // Something we really didn't take into consideration originally - $header_array = explode("\r\n", $headers); - $headers = ''; + $headers_used = array(); - foreach ($header_array as $header) + foreach ($headers as $header) { if (strpos(strtolower($header), 'cc:') === 0 || strpos(strtolower($header), 'bcc:') === 0) { - $header = ''; + continue; } - $headers .= ($header != '') ? $header . "\r\n" : ''; + $headers_used[] = trim($header); } - $headers = chop($headers); + $headers = chop(implode("\r\n", $headers_used)); } if (trim($subject) == '') @@ -946,7 +979,10 @@ function smtpmail($addresses, $subject, $message, &$err_msg, $headers = '') } // Now any custom headers.... - $smtp->server_send("$headers\r\n"); + if ($headers !== false) + { + $smtp->server_send("$headers\r\n"); + } // Ok now we are ready for the message... $smtp->server_send($message); @@ -1067,7 +1103,7 @@ class smtp_class global $user; $err_msg = ''; - $local_host = (function_exists('php_uname')) ? php_uname('n') : $user->host; + $local_host = (function_exists('php_uname')) ? gethostbyaddr(gethostbyname(php_uname('n'))) : $user->host; // If we are authenticating through pop-before-smtp, we // have to login ones before we get authenticated @@ -1411,9 +1447,10 @@ function mail_encode($str) // define start delimimter, end delimiter and spacer $start = "=?UTF-8?B?"; $end = "?="; - $spacer = $end . ' ' . $start; - $split_length = 64; + $delimiter = "\r\n "; + // Maximum length is 75. $split_length *must* be a multiple of 4, but <= 75 - strlen($start . $delimiter . $end)!!! + $split_length = 60; $encoded_str = base64_encode($str); // If encoded string meets the limits, we just return with the correct data. @@ -1425,7 +1462,7 @@ function mail_encode($str) // If there is only ASCII data, we just return what we want, correctly splitting the lines. if (strlen($str) === utf8_strlen($str)) { - return $start . implode($spacer, str_split($encoded_str, $split_length)) . $end; + return $start . implode($end . $delimiter . $start, str_split($encoded_str, $split_length)) . $end; } // UTF-8 data, compose encoded lines @@ -1441,10 +1478,10 @@ function mail_encode($str) $text .= array_shift($array); } - $str .= $start . base64_encode($text) . $end . ' '; + $str .= $start . base64_encode($text) . $end . $delimiter; } - return substr($str, 0, -1); + return substr($str, 0, -strlen($delimiter)); } ?>
\ No newline at end of file diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 4d96fb9537..07c8944992 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -614,7 +614,7 @@ function create_thumbnail($source, $destination, $mimetype) list($new_width, $new_height) = get_img_size_format($width, $height); // Do not create a thumbnail if the resulting width/height is bigger than the original one - if ($new_width > $width && $new_height > $height) + if ($new_width >= $width && $new_height >= $height) { return false; } @@ -629,7 +629,7 @@ function create_thumbnail($source, $destination, $mimetype) $config['img_imagick'] .= '/'; } - @passthru(escapeshellcmd($config['img_imagick']) . 'convert' . ((defined('PHP_OS') && preg_match('#^win#i', PHP_OS)) ? '.exe' : '') . ' -quality 85 -antialias -sample ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" +profile "*" "' . str_replace('\\', '/', $destination) . '"'); + @passthru(escapeshellcmd($config['img_imagick']) . 'convert' . ((defined('PHP_OS') && preg_match('#^win#i', PHP_OS)) ? '.exe' : '') . ' -quality 85 -geometry ' . $new_width . 'x' . $new_height . ' "' . str_replace('\\', '/', $source) . '" "' . str_replace('\\', '/', $destination) . '"'); if (file_exists($destination)) { @@ -963,13 +963,20 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id } $sql = $db->sql_build_query('SELECT', array( - 'SELECT' => 'u.username, u.user_id, u.user_colour, p.*', + 'SELECT' => 'u.username, u.user_id, u.user_colour, p.*, z.friend, z.foe', 'FROM' => array( USERS_TABLE => 'u', POSTS_TABLE => 'p', ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(ZEBRA_TABLE => 'z'), + 'ON' => 'z.user_id = ' . $user->data['user_id'] . ' AND z.zebra_id = p.poster_id' + ) + ), + 'WHERE' => $db->sql_in_set('p.post_id', $post_list) . ' AND u.user_id = p.poster_id' )); @@ -1060,6 +1067,9 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id $post_subject = censor_text($post_subject); + $post_anchor = ($mode == 'post_review') ? 'ppr' . $row['post_id'] : 'pr' . $row['post_id']; + $u_show_post = append_sid($phpbb_root_path . 'viewtopic.' . $phpEx, "f=$forum_id&t=$topic_id&p={$row['post_id']}&view=show#p{$row['post_id']}"); + $template->assign_block_vars($mode . '_row', array( 'POST_AUTHOR_FULL' => get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), 'POST_AUTHOR_COLOUR' => get_username_string('colour', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), @@ -1067,6 +1077,9 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id 'U_POST_AUTHOR' => get_username_string('profile', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), 'S_HAS_ATTACHMENTS' => (!empty($attachments[$row['post_id']])) ? true : false, + 'S_FRIEND' => ($row['friend']) ? true : false, + 'S_IGNORE_POST' => ($row['foe']) ? true : false, + 'L_IGNORE_POST' => ($row['foe']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), "<a href=\"{$u_show_post}\" onclick=\"dE('{$post_anchor}', 1); return false;\">", '</a>') : '', 'POST_SUBJECT' => $post_subject, 'MINI_POST_IMG' => $user->img('icon_post_target', $user->lang['POST']), @@ -1113,7 +1126,7 @@ function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id if (!$topic_notification && !$forum_notification) { - trigger_error('WRONG_NOTIFICATION_MODE'); + trigger_error('NO_MODE'); } if (($topic_notification && !$config['allow_topic_notify']) || ($forum_notification && !$config['allow_forum_notify'])) @@ -1725,6 +1738,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $sql_data[TOPICS_TABLE]['sql'] = array( 'topic_poster' => (int) $user->data['user_id'], 'topic_time' => $current_time, + 'topic_last_view_time' => $current_time, 'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'], 'icon_id' => $data['icon_id'], 'topic_approved' => $post_approval, @@ -1738,11 +1752,23 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u if (isset($poll['poll_options']) && !empty($poll['poll_options'])) { + $poll_start = ($poll['poll_start']) ? $poll['poll_start'] : $current_time; + $poll_length = $poll['poll_length'] * 86400; + if ($poll_length < 0) + { + $poll_start = $poll_start + $poll_length; + if ($poll_start < 0) + { + $poll_start = 0; + } + $poll_length = 1; + } + $sql_data[TOPICS_TABLE]['sql'] = array_merge($sql_data[TOPICS_TABLE]['sql'], array( 'poll_title' => $poll['poll_title'], - 'poll_start' => ($poll['poll_start']) ? $poll['poll_start'] : $current_time, + 'poll_start' => $poll_start, 'poll_max_options' => $poll['poll_max_options'], - 'poll_length' => ($poll['poll_length'] * 86400), + 'poll_length' => $poll_length, 'poll_vote_change' => $poll['poll_vote_change']) ); } @@ -1760,7 +1786,13 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u break; case 'reply': - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies_real = topic_replies_real + 1, topic_bumped = 0, topic_bumper = 0' . (($post_approval) ? ', topic_replies = topic_replies + 1' : '') . ((!empty($data['attachment_data']) || (isset($data['topic_attachment']) && $data['topic_attachment'])) ? ', topic_attachment = 1' : ''); + $sql_data[TOPICS_TABLE]['stat'][] = 'topic_last_view_time = ' . $current_time . ', + topic_replies_real = topic_replies_real + 1, + topic_bumped = 0, + topic_bumper = 0' . + (($post_approval) ? ', topic_replies = topic_replies + 1' : '') . + ((!empty($data['attachment_data']) || (isset($data['topic_attachment']) && $data['topic_attachment'])) ? ', topic_attachment = 1' : ''); + $sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_approval) ? ', user_posts = user_posts + 1' : ''); if ($post_approval && $topic_type != POST_GLOBAL) @@ -1771,6 +1803,20 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u case 'edit_topic': case 'edit_first_post': + if (isset($poll['poll_options']) && !empty($poll['poll_options'])) + { + $poll_start = ($poll['poll_start']) ? $poll['poll_start'] : $current_time; + $poll_length = $poll['poll_length'] * 86400; + if ($poll_length < 0) + { + $poll_start = $poll_start + $poll_length; + if ($poll_start < 0) + { + $poll_start = 0; + } + $poll_length = 1; + } + } $sql_data[TOPICS_TABLE]['sql'] = array( 'forum_id' => ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'], @@ -1781,10 +1827,11 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u 'topic_type' => $topic_type, 'topic_time_limit' => ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0, 'poll_title' => (isset($poll['poll_options'])) ? $poll['poll_title'] : '', - 'poll_start' => (isset($poll['poll_options'])) ? (($poll['poll_start']) ? $poll['poll_start'] : $current_time) : 0, + 'poll_start' => (isset($poll['poll_options'])) ? $poll_start : 0, 'poll_max_options' => (isset($poll['poll_options'])) ? $poll['poll_max_options'] : 1, - 'poll_length' => (isset($poll['poll_options'])) ? ($poll['poll_length'] * 86400) : 0, + 'poll_length' => (isset($poll['poll_options'])) ? $poll_length : 0, 'poll_vote_change' => (isset($poll['poll_vote_change'])) ? $poll['poll_vote_change'] : 0, + 'topic_last_view_time' => $current_time, 'topic_attachment' => (!empty($data['attachment_data'])) ? 1 : (isset($data['topic_attachment']) ? $data['topic_attachment'] : 0), ); @@ -1810,8 +1857,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u $sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics = forum_topics - 1'; $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - ' . ($topic_row['topic_replies'] + 1); - set_config('num_topics', $config['num_topics'] - 1, true); - set_config('num_posts', $config['num_posts'] - ($topic_row['topic_replies'] + 1), true); + set_config_count('num_topics', -1, true); + set_config_count('num_posts', ($topic_row['topic_replies'] + 1) * (-1), true); // Only decrement this post, since this is the one non-approved now if ($auth->acl_get('f_postcount', $data['forum_id'])) @@ -1828,10 +1875,10 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u // Correctly set back the topic replies and forum posts... but only if the post was approved before. if (!$post_approval && $data['post_approved']) { - $sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies = topic_replies - 1'; + $sql_data[TOPICS_TABLE]['stat'][] = 'topic_replies = topic_replies - 1, topic_last_view_time = ' . $current_time; $sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts - 1'; - set_config('num_posts', $config['num_posts'] - 1, true); + set_config_count('num_posts', -1, true); if ($auth->acl_get('f_postcount', $data['forum_id'])) { @@ -2098,8 +2145,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u if ($space_taken && $files_added) { - set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true); - set_config('num_files', $config['num_files'] + $files_added, true); + set_config_count('upload_dir_size', $space_taken, true); + set_config_count('num_files', $files_added, true); } } @@ -2332,13 +2379,13 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u { if ($post_mode == 'post') { - set_config('num_topics', $config['num_topics'] + 1, true); - set_config('num_posts', $config['num_posts'] + 1, true); + set_config_count('num_topics', 1, true); + set_config_count('num_posts', 1, true); } if ($post_mode == 'reply') { - set_config('num_posts', $config['num_posts'] + 1, true); + set_config_count('num_posts', 1, true); } } diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 4926cabf2c..05653f7e3b 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1350,7 +1350,7 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) WHERE ' . $db->sql_in_set('ug.group_id', array_keys($data['address_list']['g'])) . ' AND ug.user_pending = 0 AND u.user_id = ug.user_id - AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')' . + AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')' . $sql_allow_pm; $result = $db->sql_query($sql); @@ -1571,8 +1571,8 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) if ($space_taken && $files_added) { - set_config('upload_dir_size', $config['upload_dir_size'] + $space_taken, true); - set_config('num_files', $config['num_files'] + $files_added, true); + set_config_count('upload_dir_size', $space_taken, true); + set_config_count('num_files', $files_added, true); } } @@ -1763,8 +1763,14 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode $url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm'); $next_history_pm = $previous_history_pm = $prev_id = 0; - foreach ($rowset as $id => $row) + // Re-order rowset to be able to get the next/prev message rows... + $rowset = array_values($rowset); + + for ($i = 0, $size = sizeof($rowset); $i < $size; $i++) { + $row = &$rowset[$i]; + $id = (int) $row['msg_id']; + $author_id = $row['author_id']; $folder_id = (int) $row['folder_id']; @@ -1795,8 +1801,7 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode if ($id == $msg_id) { - $next_history_pm = next($rowset); - $next_history_pm = (sizeof($next_history_pm)) ? (int) $next_history_pm['msg_id'] : 0; + $next_history_pm = (isset($rowset[$i + 1])) ? (int) $rowset[$i + 1]['msg_id'] : 0; $previous_history_pm = $prev_id; } diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php index cc59648e54..26a1feb126 100644 --- a/phpBB/includes/functions_profile_fields.php +++ b/phpBB/includes/functions_profile_fields.php @@ -39,8 +39,8 @@ class custom_profile switch ($mode) { case 'register': - // If the field is required we show it on the registration page and do not show hidden fields - $sql_where .= ' AND f.field_show_on_reg = 1 AND f.field_no_view = 0'; + // If the field is required we show it on the registration page + $sql_where .= ' AND f.field_show_on_reg = 1'; break; case 'profile': @@ -270,8 +270,8 @@ class custom_profile switch ($mode) { case 'register': - // If the field is required we show it on the registration page and do not show hidden fields - $sql_where .= ' AND f.field_show_on_reg = 1 AND f.field_no_view = 0'; + // If the field is required we show it on the registration page + $sql_where .= ' AND f.field_show_on_reg = 1'; break; case 'profile': @@ -1086,4 +1086,4 @@ class custom_profile_admin extends custom_profile } } -?> +?>
\ No newline at end of file diff --git a/phpBB/includes/functions_template.php b/phpBB/includes/functions_template.php index 15efc7ec00..42a5eb3248 100644 --- a/phpBB/includes/functions_template.php +++ b/phpBB/includes/functions_template.php @@ -223,9 +223,12 @@ class template_compile // There will be a number of occasions where we switch into and out of // PHP mode instantaneously. Rather than "burden" the parser with this // we'll strip out such occurences, minimising such switching - $template_php = str_replace(' ?><?php ', ' ', $template_php); + if ($no_echo) + { + return "\$$echo_var .= '" . str_replace(' ?><?php ', ' ', $template_php) . "'"; + } - return (!$no_echo) ? $template_php : "\$$echo_var .= '" . $template_php . "'"; + return str_replace(' ?><?php ', ' ', $template_php); } /** @@ -253,19 +256,19 @@ class template_compile // transform vars prefixed by L_ into their language variable pendant if nothing is set within the tpldata array if (strpos($text_blocks, '{L_') !== false) { - $text_blocks = preg_replace('#\{L_([a-z0-9\-_]*)\}#is', "<?php echo ((isset(\$this->_rootref['L_\\1'])) ? \$this->_rootref['L_\\1'] : ((isset(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '{ \\1 }')); ?>", $text_blocks); + $text_blocks = preg_replace('#\{L_([A-Z0-9\-_]+)\}#', "<?php echo ((isset(\$this->_rootref['L_\\1'])) ? \$this->_rootref['L_\\1'] : ((isset(\$user->lang['\\1'])) ? \$user->lang['\\1'] : '{ \\1 }')); ?>", $text_blocks); } // Handle addslashed language variables prefixed with LA_ // If a template variable already exist, it will be used in favor of it... if (strpos($text_blocks, '{LA_') !== false) { - $text_blocks = preg_replace('#\{LA_([a-z0-9\-_]*)\}#is', "<?php echo ((isset(\$this->_rootref['LA_\\1'])) ? \$this->_rootref['LA_\\1'] : ((isset(\$this->_rootref['L_\\1'])) ? addslashes(\$this->_rootref['L_\\1']) : ((isset(\$user->lang['\\1'])) ? addslashes(\$user->lang['\\1']) : '{ \\1 }'))); ?>", $text_blocks); + $text_blocks = preg_replace('#\{LA_([A-Z0-9\-_]+)\}#', "<?php echo ((isset(\$this->_rootref['LA_\\1'])) ? \$this->_rootref['LA_\\1'] : ((isset(\$this->_rootref['L_\\1'])) ? addslashes(\$this->_rootref['L_\\1']) : ((isset(\$user->lang['\\1'])) ? addslashes(\$user->lang['\\1']) : '{ \\1 }'))); ?>", $text_blocks); } // Handle remaining varrefs - $text_blocks = preg_replace('#\{([a-z0-9\-_]+)\}#is', "<?php echo (isset(\$this->_rootref['\\1'])) ? \$this->_rootref['\\1'] : ''; ?>", $text_blocks); - $text_blocks = preg_replace('#\{\$([a-z0-9\-_]+)\}#is', "<?php echo (isset(\$this->_tpldata['DEFINE']['.']['\\1'])) ? \$this->_tpldata['DEFINE']['.']['\\1'] : ''; ?>", $text_blocks); + $text_blocks = preg_replace('#\{([A-Z0-9\-_]+)\}#', "<?php echo (isset(\$this->_rootref['\\1'])) ? \$this->_rootref['\\1'] : ''; ?>", $text_blocks); + $text_blocks = preg_replace('#\{\$([A-Z0-9\-_]+)\}#', "<?php echo (isset(\$this->_tpldata['DEFINE']['.']['\\1'])) ? \$this->_tpldata['DEFINE']['.']['\\1'] : ''; ?>", $text_blocks); return; } @@ -748,6 +751,8 @@ class template_compile $filename = $this->template->cachepath . str_replace('/', '.', $this->template->filename[$handle]) . '.' . $phpEx; + $data = "<?php if (!defined('IN_PHPBB')) exit;" . ((strpos($data, '<?php') === 0) ? substr($data, 5) : ' ?>' . $data); + if ($fp = @fopen($filename, 'wb')) { @flock($fp, LOCK_EX); @@ -755,7 +760,7 @@ class template_compile @flock($fp, LOCK_UN); @fclose($fp); - phpbb_chmod($filename, CHMOD_WRITE); + phpbb_chmod($filename, CHMOD_READ | CHMOD_WRITE); } return; diff --git a/phpBB/includes/functions_transfer.php b/phpBB/includes/functions_transfer.php index 2925a2df77..c345f81e1d 100644 --- a/phpBB/includes/functions_transfer.php +++ b/phpBB/includes/functions_transfer.php @@ -206,7 +206,7 @@ class transfer $directory = $this->root_path . str_replace($phpbb_root_path, '', $directory); $this->_chdir($directory); - $result = $this->_ls(''); + $result = $this->_ls(); if ($result !== false && is_array($result)) { @@ -460,7 +460,24 @@ class ftp extends transfer */ function _ls($dir = './') { - return @ftp_nlist($this->connection, $dir); + $list = @ftp_nlist($this->connection, $dir); + + // Remove path if prepended + foreach ($list as $key => $item) + { + // Use same separator for item and dir + $item = str_replace('\\', '/', $item); + $dir = str_replace('\\', '/', $dir); + + if (strpos($item, $dir) === 0) + { + $item = substr($item, strlen($dir)); + } + + $list[$key] = $item; + } + + return $list; } /** @@ -710,6 +727,24 @@ class ftp_fsock extends transfer } $this->_close_data_connection(); + // Clear buffer + $this->_check_command(); + + // Remove path if prepended + foreach ($list as $key => $item) + { + // Use same separator for item and dir + $item = str_replace('\\', '/', $item); + $dir = str_replace('\\', '/', $dir); + + if (strpos($item, $dir) === 0) + { + $item = substr($item, strlen($dir)); + } + + $list[$key] = $item; + } + return $list; } diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index e3a9363d62..1ad6223aa1 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -594,7 +594,18 @@ class fileupload // PHP Upload filesize exceeded if ($file->get('filename') == 'none') { - $file->error[] = (@ini_get('upload_max_filesize') == '') ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], @ini_get('upload_max_filesize')); + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); return $file; } @@ -670,7 +681,18 @@ class fileupload // PHP Upload filesize exceeded if ($file->get('filename') == 'none') { - $file->error[] = (@ini_get('upload_max_filesize') == '') ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], @ini_get('upload_max_filesize')); + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); return $file; } @@ -818,7 +840,18 @@ class fileupload switch ($errorcode) { case 1: - $error = (@ini_get('upload_max_filesize') == '') ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], @ini_get('upload_max_filesize')); + $max_filesize = @ini_get('upload_max_filesize'); + $unit = 'MB'; + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $max_filesize = (int) $max_filesize; + + $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB'); + } + + $error = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]); break; case 2: diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index ea62a75306..027db39751 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -280,7 +280,7 @@ function user_add($user_row, $cp_data = false) { set_config('newest_user_id', $user_id, true); set_config('newest_username', $user_row['username'], true); - set_config('num_users', $config['num_users'] + 1, true); + set_config_count('num_users', 1, true); $sql = 'SELECT group_colour FROM ' . GROUPS_TABLE . ' @@ -490,7 +490,7 @@ function user_delete($mode, $user_id, $post_username = false) $db->sql_transaction('begin'); - $table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE, DRAFTS_TABLE, BOOKMARKS_TABLE); + $table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE, DRAFTS_TABLE, BOOKMARKS_TABLE, SESSIONS_KEYS_TABLE); foreach ($table_ary as $table) { @@ -501,6 +501,16 @@ function user_delete($mode, $user_id, $post_username = false) $cache->destroy('sql', MODERATOR_CACHE_TABLE); + // Delete the user_id from the banlist + $sql = 'DELETE FROM ' . BANLIST_TABLE . ' + WHERE ban_userid = ' . $user_id; + $db->sql_query($sql); + + // Delete the user_id from the session table + $sql = 'DELETE FROM ' . SESSIONS_TABLE . ' + WHERE session_user_id = ' . $user_id; + $db->sql_query($sql); + // Remove any undelivered mails... $sql = 'SELECT msg_id, user_id FROM ' . PRIVMSGS_TO_TABLE . ' @@ -569,7 +579,7 @@ function user_delete($mode, $user_id, $post_username = false) // Decrement number of users if this user is active if ($user_row['user_type'] != USER_INACTIVE && $user_row['user_type'] != USER_IGNORE) { - set_config('num_users', $config['num_users'] - 1, true); + set_config_count('num_users', -1, true); } return false; @@ -650,12 +660,12 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL) if ($deactivated) { - set_config('num_users', $config['num_users'] - $deactivated, true); + set_config_count('num_users', $deactivated * (-1), true); } if ($activated) { - set_config('num_users', $config['num_users'] + $activated, true); + set_config_count('num_users', $activated, true); } // Update latest username @@ -1134,6 +1144,8 @@ function user_unban($mode, $ban) /** * Whois facility +* +* @link http://tools.ietf.org/html/rfc3912 RFC3912: WHOIS Protocol Specification */ function user_ipwhois($ip) { @@ -1146,16 +1158,10 @@ function user_ipwhois($ip) return ''; } - $match = array( - '#RIPE\.NET#is' => 'whois.ripe.net', - '#whois\.apnic\.net#is' => 'whois.apnic.net', - '#nic\.ad\.jp#is' => 'whois.nic.ad.jp', - '#whois\.registro\.br#is' => 'whois.registro.br' - ); - if (($fsk = @fsockopen('whois.arin.net', 43))) { - fputs($fsk, "$ip\n"); + // CRLF as per RFC3912 + fputs($fsk, "$ip\r\n"); while (!feof($fsk)) { $ipwhois .= fgets($fsk, 1024); @@ -1163,22 +1169,38 @@ function user_ipwhois($ip) @fclose($fsk); } - foreach (array_keys($match) as $server) + $match = array(); + + // Test for referrals from ARIN to other whois databases, roll on rwhois + if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match)) { - if (preg_match($server, $ipwhois)) + if (strpos($match[1], ':') !== false) + { + $pos = strrpos($match[1], ':'); + $server = substr($match[1], 0, $pos); + $port = (int) substr($match[1], $pos + 1); + unset($pos); + } + else + { + $server = $match[1]; + $port = 43; + } + + $buffer = ''; + + if (($fsk = @fsockopen($server, $port))) { - $ipwhois = ''; - if (($fsk = @fsockopen($match[$server], 43))) + fputs($fsk, "$ip\r\n"); + while (!feof($fsk)) { - fputs($fsk, "$ip\n"); - while (!feof($fsk)) - { - $ipwhois .= fgets($fsk, 1024); - } - @fclose($fsk); + $buffer .= fgets($fsk, 1024); } - break; + @fclose($fsk); } + + // Use the result from ARIN if we don't get any result here + $ipwhois = (empty($buffer)) ? $ipwhois : $buffer; } $ipwhois = htmlspecialchars($ipwhois); @@ -1414,7 +1436,7 @@ function validate_username($username, $allowed_username = false) } else if ($mbstring) { - $regex = '[-\]_+ [[:upper:][:lower:][:digit:]]+'; + $regex = '[-\]_+ \[[:upper:][:lower:][:digit:]]+'; } else { @@ -1439,8 +1461,7 @@ function validate_username($username, $allowed_username = false) } else if ($mbstring) { - $matches = array(); - mb_ereg_search_init('^' . $username . '$', $regex, $matches); + mb_ereg_search_init($username, '^' . $regex . '$'); if (!mb_ereg_search()) { return 'INVALID_CHARS'; @@ -2713,9 +2734,16 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false, */ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, $group_name = false) { - global $db, $auth; + global $db, $auth, $config; - $group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'REGISTERED_COPPA', 'REGISTERED', 'BOTS', 'GUESTS'); + if ($config['coppa_enable']) + { + $group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'REGISTERED_COPPA', 'REGISTERED', 'BOTS', 'GUESTS'); + } + else + { + $group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'REGISTERED', 'BOTS', 'GUESTS'); + } // We need both username and user_id info $result = user_get_id_name($user_id_ary, $username_ary); @@ -2779,13 +2807,14 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, $temp_ary = array(); while ($row = $db->sql_fetchrow($result)) { - if ($default_groups[$row['user_id']] == $group_id && (!isset($temp_ary[$row['user_id']]) || array_search($row['group_name'], $group_order) < $temp_ary[$row['user_id']])) + if ($default_groups[$row['user_id']] == $group_id && (!isset($temp_ary[$row['user_id']]) || $group_order_id[$row['group_name']] < $temp_ary[$row['user_id']])) { $temp_ary[$row['user_id']] = $row['group_id']; } } $db->sql_freeresult($result); + // sql_where_ary holds the new default groups and their users $sql_where_ary = array(); foreach ($temp_ary as $uid => $gid) { @@ -2797,7 +2826,7 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, { if (isset($sql_where_ary[$gid]) && sizeof($sql_where_ary[$gid])) { - remove_default_rank($group_id, $sql_where_ary[$gid]); + remove_default_rank($gid, $sql_where_ary[$gid]); remove_default_avatar($group_id, $sql_where_ary[$gid]); group_set_user_default($gid, $sql_where_ary[$gid], $default_data_ary); } diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 8fafb232cc..0dfe3b0086 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -594,44 +594,67 @@ function mcp_move_topic($topic_ids) $topic_data = get_topic_data($topic_ids); $leave_shadow = (isset($_POST['move_leave_shadow'])) ? true : false; - $topics_moved = sizeof($topic_ids); - $topics_authed_moved = 0; $forum_sync_data = array(); $forum_sync_data[$forum_id] = current($topic_data); $forum_sync_data[$to_forum_id] = $forum_data; + // Real topics added to target forum + $topics_moved = sizeof($topic_data); + + // Approved topics added to target forum + $topics_authed_moved = 0; + + // Posts (topic replies + topic post if approved) added to target forum + $topic_posts_added = 0; + + // Posts (topic replies + topic post if approved and not global announcement) removed from source forum + $topic_posts_removed = 0; + + // Real topics removed from source forum (all topics without global announcements) + $topics_removed = 0; + + // Approved topics removed from source forum (except global announcements) + $topics_authed_removed = 0; + foreach ($topic_data as $topic_id => $topic_info) { - if ($topic_info['topic_approved'] == '1') + if ($topic_info['topic_approved']) { $topics_authed_moved++; + $topic_posts_added++; + } + + $topic_posts_added += $topic_info['topic_replies']; + + if ($topic_info['topic_type'] != POST_GLOBAL) + { + $topics_removed++; + $topic_posts_removed += $topic_info['topic_replies']; + + if ($topic_info['topic_approved']) + { + $topics_authed_removed++; + $topic_posts_removed++; + } } } $db->sql_transaction('begin'); - $sql = 'SELECT SUM(t.topic_replies + t.topic_approved) as topic_posts - FROM ' . TOPICS_TABLE . ' t - WHERE ' . $db->sql_in_set('t.topic_id', $topic_ids); - $result = $db->sql_query($sql); - $row_data = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - $sync_sql = array(); - if ($row_data['topic_posts']) + if ($topic_posts_added) { - $sync_sql[$forum_id][] = 'forum_posts = forum_posts - ' . (int) $row_data['topic_posts']; - $sync_sql[$to_forum_id][] = 'forum_posts = forum_posts + ' . (int) $row_data['topic_posts']; + $sync_sql[$to_forum_id][] = 'forum_posts = forum_posts + ' . $topic_posts_added; } if ($topics_authed_moved) { - $sync_sql[$to_forum_id][] = 'forum_topics = forum_topics + ' . (int) $topics_authed_moved; + $sync_sql[$to_forum_id][] = 'forum_topics = forum_topics + ' . (int) $topics_authed_moved; } - $sync_sql[$to_forum_id][] = 'forum_topics_real = forum_topics_real + ' . (int) $topics_moved; + $sync_sql[$to_forum_id][] = 'forum_topics_real = forum_topics_real + ' . (int) $topics_moved; // Move topics, but do not resync yet move_topics($topic_ids, $to_forum_id, false); @@ -692,17 +715,26 @@ function mcp_move_topic($topic_ids) $db->sql_query('INSERT INTO ' . TOPICS_TABLE . $db->sql_build_array('INSERT', $shadow)); - $topics_authed_moved--; - $topics_moved--; + // Shadow topics only count on new "topics" and not posts... a shadow topic alone has 0 posts + $topics_removed--; + $topics_authed_removed--; } } unset($topic_data); - $sync_sql[$forum_id][] = 'forum_topics_real = forum_topics_real - ' . (int) $topics_moved; + if ($topic_posts_removed) + { + $sync_sql[$forum_id][] = 'forum_posts = forum_posts - ' . $topic_posts_removed; + } - if ($topics_authed_moved) + if ($topics_removed) { - $sync_sql[$forum_id][] = 'forum_topics = forum_topics - ' . (int) $topics_authed_moved; + $sync_sql[$forum_id][] = 'forum_topics_real = forum_topics_real - ' . (int) $topics_removed; + } + + if ($topics_authed_removed) + { + $sync_sql[$forum_id][] = 'forum_topics = forum_topics - ' . (int) $topics_authed_removed; } $success_msg = (sizeof($topic_ids) == 1) ? 'TOPIC_MOVED_SUCCESS' : 'TOPICS_MOVED_SUCCESS'; @@ -929,6 +961,11 @@ function mcp_delete_post($post_ids) } else { + if ($affected_topics != 1 || $deleted_topics || !$topic_id) + { + $redirect = append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&i=main&mode=forum_view", false); + } + meta_refresh(3, $redirect); trigger_error($success_msg . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>') . '<br /><br />' . implode('<br /><br />', $return_link)); } @@ -1189,8 +1226,8 @@ function mcp_fork_topic($topic_ids) } sync('forum', 'forum_id', $to_forum_id); - set_config('num_topics', $config['num_topics'] + sizeof($new_topic_id_list), true); - set_config('num_posts', $config['num_posts'] + $total_posts, true); + set_config_count('num_topics', sizeof($new_topic_id_list), true); + set_config_count('num_posts', $total_posts, true); foreach ($new_topic_id_list as $topic_id => $new_topic_id) { diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php index 42a64055ce..7480b24a46 100644 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -226,13 +226,16 @@ class mcp_notes 'PAGINATION' => generate_pagination($this->u_action . "&st=$st&sk=$sk&sd=$sd", $log_count, $config['posts_per_page'], $start), 'TOTAL_REPORTS' => ($log_count == 1) ? $user->lang['LIST_REPORT'] : sprintf($user->lang['LIST_REPORTS'], $log_count), - 'USERNAME' => $userrow['username'], - 'USER_COLOR' => (!empty($userrow['user_colour'])) ? $userrow['user_colour'] : '', 'RANK_TITLE' => $rank_title, 'JOINED' => $user->format_date($userrow['user_regdate']), 'POSTS' => ($userrow['user_posts']) ? $userrow['user_posts'] : 0, 'WARNINGS' => ($userrow['user_warnings']) ? $userrow['user_warnings'] : 0, + 'USERNAME_FULL' => get_username_string('full', $userrow['user_id'], $userrow['username'], $userrow['user_colour']), + 'USERNAME_COLOUR' => get_username_string('colour', $userrow['user_id'], $userrow['username'], $userrow['user_colour']), + 'USERNAME' => get_username_string('username', $userrow['user_id'], $userrow['username'], $userrow['user_colour']), + 'U_PROFILE' => get_username_string('profile', $userrow['user_id'], $userrow['username'], $userrow['user_colour']), + 'AVATAR_IMG' => $avatar_img, 'RANK_IMG' => $rank_img, ) diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index aa77dbdf16..6209a27bf7 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -492,12 +492,18 @@ function approve_post($post_id_list, $id, $mode) $total_topics = $total_posts = 0; $forum_topics_posts = $topic_approve_sql = $topic_replies_sql = $post_approve_sql = $topic_id_list = $forum_id_list = $approve_log = array(); - $user_posts_sql = array(); + $user_posts_sql = $post_approved_list = array(); $update_forum_information = false; foreach ($post_info as $post_id => $post_data) { + if ($post_data['post_approved']) + { + $post_approved_list[] = $post_id; + continue; + } + $topic_id_list[$post_data['topic_id']] = 1; if ($post_data['forum_id']) @@ -539,12 +545,6 @@ function approve_post($post_id_list, $id, $mode) } else { - if (!isset($topic_replies_sql[$post_data['topic_id']])) - { - $topic_replies_sql[$post_data['topic_id']] = 0; - } - $topic_replies_sql[$post_data['topic_id']]++; - $approve_log[] = array( 'type' => 'post', 'post_subject' => $post_data['post_subject'], @@ -553,6 +553,15 @@ function approve_post($post_id_list, $id, $mode) ); } + if ($post_data['topic_replies_real'] > 0) + { + if (!isset($topic_replies_sql[$post_data['topic_id']])) + { + $topic_replies_sql[$post_data['topic_id']] = 0; + } + $topic_replies_sql[$post_data['topic_id']]++; + } + if ($post_data['forum_id']) { if (!isset($forum_topics_posts[$post_data['forum_id']])) @@ -583,6 +592,11 @@ function approve_post($post_id_list, $id, $mode) $update_forum_information = true; } } + $post_id_list = array_values(array_diff($post_id_list, $post_approved_list)); + for ($i = 0, $size = sizeof($post_approved_list); $i < $size; $i++) + { + unset($post_info[$post_approved_list[$i]]); + } if (sizeof($topic_approve_sql)) { @@ -652,12 +666,12 @@ function approve_post($post_id_list, $id, $mode) if ($total_topics) { - set_config('num_topics', $config['num_topics'] + $total_topics, true); + set_config_count('num_topics', $total_topics, true); } if ($total_posts) { - set_config('num_posts', $config['num_posts'] + $total_posts, true); + set_config_count('num_posts', $total_posts, true); } unset($topic_approve_sql, $topic_replies_sql, $post_approve_sql); @@ -733,7 +747,7 @@ function approve_post($post_id_list, $id, $mode) } else { - $success_msg = (sizeof($post_id_list) == 1) ? 'POST_APPROVED_SUCCESS' : 'POSTS_APPROVED_SUCCESS'; + $success_msg = (sizeof($post_id_list) + sizeof($post_approved_list) == 1) ? 'POST_APPROVED_SUCCESS' : 'POSTS_APPROVED_SUCCESS'; } } else diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 931300897e..576d20b466 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -501,7 +501,7 @@ function split_topic($action, $topic_id, $to_forum_id, $subject) $success_msg = 'TOPIC_SPLIT_SUCCESS'; // Update forum statistics - set_config('num_topics', $config['num_topics'] + 1, true); + set_config_count('num_topics', 1, true); // Link back to both topics $return_link = sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&t=' . $post_info['topic_id']) . '">', '</a>') . '<br /><br />' . sprintf($user->lang['RETURN_NEW_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $to_forum_id . '&t=' . $to_topic_id) . '">', '</a>'); diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php index bf0e66dc67..4ce67e5f9b 100644 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -420,13 +420,16 @@ class mcp_warn $template->assign_vars(array( 'U_POST_ACTION' => $this->u_action, - 'USERNAME' => $user_row['username'], - 'USER_COLOR' => (!empty($user_row['user_colour'])) ? $user_row['user_colour'] : '', 'RANK_TITLE' => $rank_title, 'JOINED' => $user->format_date($user_row['user_regdate']), 'POSTS' => ($user_row['user_posts']) ? $user_row['user_posts'] : 0, 'WARNINGS' => ($user_row['user_warnings']) ? $user_row['user_warnings'] : 0, + 'USERNAME_FULL' => get_username_string('full', $user_row['user_id'], $user_row['username'], $user_row['user_colour']), + 'USERNAME_COLOUR' => get_username_string('colour', $user_row['user_id'], $user_row['username'], $user_row['user_colour']), + 'USERNAME' => get_username_string('username', $user_row['user_id'], $user_row['username'], $user_row['user_colour']), + 'U_PROFILE' => get_username_string('profile', $user_row['user_id'], $user_row['username'], $user_row['user_colour']), + 'AVATAR_IMG' => $avatar_img, 'RANK_IMG' => $rank_img, diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index 4e350bce99..ab6fc3f4f3 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -695,6 +695,7 @@ class bbcode_firstpass extends bbcode * [quote="[i]test[/i]"]test[/quote] (correct: parsed) * [quote="[quote]test[/quote]"]test[/quote] (correct: parsed - Username displayed as [quote]test[/quote]) * #20735 - [quote]test[/[/b]quote] test [/quote][/quote] test - (correct: quoted: "test[/[/b]quote] test" / non-quoted: "[/quote] test" - also failed if layout distorted) + * #40565 - [quote="a"]a[/quote][quote="a]a[/quote] (correct: first quote tag parsed, second quote tag unparsed) */ $in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in))); @@ -705,7 +706,7 @@ class bbcode_firstpass extends bbcode } // To let the parser not catch tokens within quote_username quotes we encode them before we start this... - $in = preg_replace('#quote="(.*?)"\]#ie', "'quote="' . str_replace(array('[', ']'), array('[', ']'), '\$1') . '"]'", $in); + $in = preg_replace('#quote="(.*?)"\]#ie', "'quote="' . str_replace(array('[', ']', '\\\"'), array('[', ']', '\"'), '\$1') . '"]'", $in); $tok = ']'; $out = '['; @@ -858,6 +859,8 @@ class bbcode_firstpass extends bbcode } while ($in); + $out .= $buffer; + if (sizeof($close_tags)) { $out .= '[' . implode('][', $close_tags) . ']'; @@ -1049,11 +1052,7 @@ class parse_message extends bbcode_firstpass { // Init BBCode UID $this->bbcode_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN); - - if ($message) - { - $this->message = $message; - } + $this->message = $message; } /** @@ -1102,13 +1101,6 @@ class parse_message extends bbcode_firstpass } } - // Check for "empty" message - if ($mode !== 'sig' && utf8_clean_string($this->message) === '') - { - $this->warn_msg[] = $user->lang['TOO_FEW_CHARS']; - return (!$update_this_message) ? $return_message : $this->warn_msg; - } - // Prepare BBcode (just prepares some tags for better parsing) if ($allow_bbcode && strpos($this->message, '[') !== false) { @@ -1151,6 +1143,14 @@ class parse_message extends bbcode_firstpass } } + // Check for "empty" message. We do not check here for maximum length, because bbcode, smilies, etc. can add to the length. + // The maximum length check happened before any parsings. + if ($mode !== 'sig' && utf8_clean_string($this->message) === '') + { + $this->warn_msg[] = $user->lang['TOO_FEW_CHARS']; + return (!$update_this_message) ? $return_message : $this->warn_msg; + } + // Check number of links if ($config['max_' . $mode . '_urls'] && $num_urls > $config['max_' . $mode . '_urls']) { diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 2a67b58246..e1e7951367 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -118,7 +118,7 @@ class fulltext_mysql extends search_backend */ function split_keywords(&$keywords, $terms) { - global $config; + global $config, $user; if ($terms == 'all') { @@ -167,6 +167,12 @@ class fulltext_mysql extends search_backend $this->split_words = $matches[1]; } + // We limit the number of allowed keywords to minimize load on the database + if ($config['max_num_search_keywords'] && sizeof($this->split_words) > $config['max_num_search_keywords']) + { + trigger_error($user->lang('MAX_NUM_SEARCH_KEYWORDS_REFINE', $config['max_num_search_keywords'], sizeof($this->split_words))); + } + // to allow phrase search, we need to concatenate quoted words $tmp_split_words = array(); $phrase = ''; diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index 1c6a64d07c..8df5ddfbae 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -81,7 +81,7 @@ class fulltext_native extends search_backend */ function split_keywords($keywords, $terms) { - global $db, $user; + global $db, $user, $config; $keywords = trim($this->cleanup($keywords, '+-|()*')); @@ -167,6 +167,13 @@ class fulltext_native extends search_backend ); $keywords = preg_replace($match, $replace, $keywords); + $num_keywords = sizeof(explode(' ', $keywords)); + + // We limit the number of allowed keywords to minimize load on the database + if ($config['max_num_search_keywords'] && $num_keywords > $config['max_num_search_keywords']) + { + trigger_error($user->lang('MAX_NUM_SEARCH_KEYWORDS_REFINE', $config['max_num_search_keywords'], $num_keywords)); + } // $keywords input format: each word separated by a space, words in a bracket are not separated @@ -638,13 +645,21 @@ class fulltext_native extends search_backend $sql = ''; $sql_array_count = $sql_array; + if ($left_join_topics) + { + $sql_array_count['LEFT_JOIN'][] = array( + 'FROM' => array(TOPICS_TABLE => 't'), + 'ON' => 'p.topic_id = t.topic_id' + ); + } + switch ($db->sql_layer) { case 'mysql4': case 'mysqli': // 3.x does not support SQL_CALC_FOUND_ROWS - $sql_array['SELECT'] = 'SQL_CALC_FOUND_ROWS ' . $sql_array['SELECT']; + // $sql_array['SELECT'] = 'SQL_CALC_FOUND_ROWS ' . $sql_array['SELECT']; $is_mysql = true; break; @@ -693,10 +708,10 @@ class fulltext_native extends search_backend $sql_where[] = 'f.forum_id = p.forum_id'; break; } - + if ($left_join_topics) { - $sql_array['LEFT_JOIN'][$left_join_topics] = array( + $sql_array['LEFT_JOIN'][] = array( 'FROM' => array(TOPICS_TABLE => 't'), 'ON' => 'p.topic_id = t.topic_id' ); @@ -725,6 +740,16 @@ class fulltext_native extends search_backend // if we use mysql and the total result count is not cached yet, retrieve it from the db if (!$total_results && $is_mysql) { + // Count rows for the executed queries. Replace $select within $sql with SQL_CALC_FOUND_ROWS, and run it. + $sql_array_copy = $sql_array; + $sql_array_copy['SELECT'] = 'SQL_CALC_FOUND_ROWS p.post_id '; + + $sql = $db->sql_build_query('SELECT', $sql_array_copy); + unset($sql_array_copy); + + $db->sql_query($sql); + $db->sql_freeresult($result); + $sql = 'SELECT FOUND_ROWS() as total_results'; $result = $db->sql_query($sql); $total_results = (int) $db->sql_fetchfield('total_results'); @@ -848,7 +873,7 @@ class fulltext_native extends search_backend { case 'mysql4': case 'mysqli': - $select = 'SQL_CALC_FOUND_ROWS ' . $select; +// $select = 'SQL_CALC_FOUND_ROWS ' . $select; $is_mysql = true; break; @@ -941,6 +966,12 @@ class fulltext_native extends search_backend if (!$total_results && $is_mysql) { + // Count rows for the executed queries. Replace $select within $sql with SQL_CALC_FOUND_ROWS, and run it. + $sql = str_replace('SELECT ' . $select, 'SELECT DISTINCT SQL_CALC_FOUND_ROWS p.post_id', $sql); + + $db->sql_query($sql); + $db->sql_freeresult($result); + $sql = 'SELECT FOUND_ROWS() as total_results'; $result = $db->sql_query($sql); $total_results = (int) $db->sql_fetchfield('total_results'); @@ -1110,7 +1141,7 @@ class fulltext_native extends search_backend // Get unique words from the above arrays $unique_add_words = array_unique(array_merge($words['add']['post'], $words['add']['title'])); - + // We now have unique arrays of all words to be added and removed and // individual arrays of added and removed words for text and title. What // we need to do now is add the new words (if they don't already exist) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index c7d287181b..043a637584 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -182,7 +182,7 @@ class session else { // Set to OS hostname or localhost - $host = (function_exists('php_uname')) ? php_uname('n') : 'localhost'; + $host = (function_exists('php_uname')) ? gethostbyaddr(gethostbyname(php_uname('n'))) : 'localhost'; } } @@ -480,6 +480,13 @@ class session foreach (explode(',', $row['bot_ip']) as $bot_ip) { + $bot_ip = trim($bot_ip); + + if (!$bot_ip) + { + continue; + } + if (strpos($this->ip, $bot_ip) === 0) { $bot = (int) $row['user_id']; @@ -719,6 +726,15 @@ class session // Commented out because it will not allow forums to update correctly // $db->sql_return_on_error(false); + // Something quite important: session_page always holds the *last* page visited, except for the *first* visit. + // We are not able to simply have an empty session_page btw, therefore we need to tell phpBB how to detect this special case. + // If the session id is empty, we have a completely new one and will set an "identifier" here. This identifier is able to be checked later. + if (empty($this->data['session_id'])) + { + // This is a temporary variable, only set for the very first visit + $this->data['session_created'] = true; + } + $this->session_id = $this->data['session_id'] = md5(unique_id()); $sql_ary['session_id'] = (string) $this->session_id; @@ -1204,7 +1220,7 @@ class session } $dnsbl_check = array( - 'sbl-xbl.spamhaus.org' => 'http://www.spamhaus.org/query/bl?ip=', + 'sbl.spamhaus.org' => 'http://www.spamhaus.org/query/bl?ip=', ); if ($mode == 'register') @@ -1377,7 +1393,7 @@ class session $host = htmlspecialchars($this->host); $ref = substr($this->referer, strpos($this->referer, '://') + 3); - if (!(stripos($ref, $host) === 0)) + if (!(stripos($ref, $host) === 0) && (!$config['force_server'] || !(stripos($ref, $config['server_name']) === 0))) { return false; } @@ -1527,7 +1543,10 @@ class user extends session // We include common language file here to not load it every time a custom language file is included $lang = &$this->lang; - if ((@include $this->lang_path . $this->lang_name . "/common.$phpEx") === false) + // Do not suppress error if in DEBUG_EXTRA mode + $include_result = (defined('DEBUG_EXTRA')) ? (include $this->lang_path . $this->lang_name . "/common.$phpEx") : (@include $this->lang_path . $this->lang_name . "/common.$phpEx"); + + if ($include_result === false) { die('Language file ' . $this->lang_path . $this->lang_name . "/common.$phpEx" . " couldn't be opened."); } @@ -1657,7 +1676,8 @@ class user extends session $this->img_lang = (file_exists($phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . $this->lang_name)) ? $this->lang_name : $config['default_lang']; - $sql = 'SELECT image_name, image_filename, image_lang, image_height, image_width + // Same query in style.php + $sql = 'SELECT * FROM ' . STYLES_IMAGESET_DATA_TABLE . ' WHERE imageset_id = ' . $this->theme['imageset_id'] . " AND image_filename <> '' @@ -1773,7 +1793,10 @@ class user extends session // Is board disabled and user not an admin or moderator? if ($config['board_disable'] && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) { - header('HTTP/1.1 503 Service Unavailable'); + if ($this->data['is_bot']) + { + header('HTTP/1.1 503 Service Unavailable'); + } $message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE'; trigger_error($message); @@ -1789,7 +1812,10 @@ class user extends session if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) { - header('HTTP/1.1 503 Service Unavailable'); + if ($this->data['is_bot']) + { + header('HTTP/1.1 503 Service Unavailable'); + } trigger_error('BOARD_UNAVAILABLE'); } } @@ -2000,7 +2026,10 @@ class user extends session $language_filename = $this->lang_path . $this->lang_name . '/' . (($use_help) ? 'help_' : '') . $lang_file . '.' . $phpEx; } - if ((@include $language_filename) === false) + // Do not suppress error if in DEBUG_EXTRA mode + $include_result = (defined('DEBUG_EXTRA')) ? (include $language_filename) : (@include $language_filename); + + if ($include_result === false) { trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR); } @@ -2036,7 +2065,6 @@ class user extends session // Is the user requesting a friendly date format (i.e. 'Today 12:42')? $date_cache[$format] = array( 'is_short' => strpos($format, '|'), - 'zone_offset' => $this->timezone + $this->dst, 'format_short' => substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1), 'format_long' => str_replace('|', '', $format), 'lang' => $this->lang['datetime'], @@ -2049,8 +2077,11 @@ class user extends session } } + // Zone offset + $zone_offset = $this->timezone + $this->dst; + // Show date <= 1 hour ago as 'xx min ago' - // A small tolerence is given for times in the future and times in the future but in the same minute are displayed as '< than a minute ago' + // A small tolerence is given for times in the future but in the same minute are displayed as '< than a minute ago' if ($delta <= 3600 && ($delta >= -5 || (($now / 60) % 60) == (($gmepoch / 60) % 60)) && $date_cache[$format]['is_short'] !== false && !$forcedate && isset($this->lang['datetime']['AGO'])) { return $this->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60))); @@ -2058,11 +2089,11 @@ class user extends session if (!$midnight) { - list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $date_cache[$format]['zone_offset'])); - $midnight = gmmktime(0, 0, 0, $m, $d, $y) - $date_cache[$format]['zone_offset']; + list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $zone_offset)); + $midnight = gmmktime(0, 0, 0, $m, $d, $y) - $zone_offset; } - if ($date_cache[$format]['is_short'] !== false && !$forcedate) + if ($date_cache[$format]['is_short'] !== false && !$forcedate && !($gmepoch < $midnight - 86400 || $gmepoch > $midnight + 172800)) { $day = false; @@ -2081,11 +2112,11 @@ class user extends session if ($day !== false) { - return str_replace('||', $this->lang['datetime'][$day], strtr(@gmdate($date_cache[$format]['format_short'], $gmepoch + $date_cache[$format]['zone_offset']), $date_cache[$format]['lang'])); + return str_replace('||', $this->lang['datetime'][$day], strtr(@gmdate($date_cache[$format]['format_short'], $gmepoch + $zone_offset), $date_cache[$format]['lang'])); } } - return strtr(@gmdate($date_cache[$format]['format_long'], $gmepoch + $date_cache[$format]['zone_offset']), $date_cache[$format]['lang']); + return strtr(@gmdate($date_cache[$format]['format_long'], $gmepoch + $zone_offset), $date_cache[$format]['lang']); } /** @@ -2155,7 +2186,7 @@ class user extends session return $img_data; } - $img_data['src'] = $phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename']; + $img_data['src'] = $phpbb_root_path . 'styles/' . rawurlencode($this->theme['imageset_path']) . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename']; $img_data['width'] = $this->img_array[$img]['image_width']; $img_data['height'] = $this->img_array[$img]['image_height']; } diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php index ad9dcc3659..36ab8a0e9b 100644 --- a/phpBB/includes/ucp/ucp_activate.php +++ b/phpBB/includes/ucp/ucp_activate.php @@ -56,6 +56,17 @@ class ucp_activate trigger_error('WRONG_ACTIVATION'); } + // Do not allow activating by non administrators when admin activation is on + // Only activation type the user should be able to do is INACTIVE_REMIND + if ($user_row['user_inactive_reason'] != INACTIVE_REMIND && $config['require_activation'] == USER_ACTIVATION_ADMIN && !$auth->acl_get('a_user')) + { + if (!$user->data['is_registered']) + { + login_box('', $user->lang['NO_AUTH_OPERATION']); + } + trigger_error('NO_AUTH_OPERATION'); + } + $update_password = ($user_row['user_newpasswd']) ? true : false; if ($update_password) @@ -72,6 +83,8 @@ class ucp_activate SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $user_row['user_id']; $db->sql_query($sql); + + add_log('user', $user_row['user_id'], 'LOG_USER_NEW_PASSWORD', $user_row['username']); } if (!$update_password) diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php index 5685702de2..b011b4f75d 100644 --- a/phpBB/includes/ucp/ucp_attachments.php +++ b/phpBB/includes/ucp/ucp_attachments.php @@ -184,7 +184,7 @@ class ucp_attachments 'U_SORT_FILESIZE' => $this->u_action . "&sk=d&sd=" . (($sort_key == 'd' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_DOWNLOADS' => $this->u_action . "&sk=e&sd=" . (($sort_key == 'e' && $sort_dir == 'a') ? 'd' : 'a'), 'U_SORT_POST_TIME' => $this->u_action . "&sk=f&sd=" . (($sort_key == 'f' && $sort_dir == 'a') ? 'd' : 'a'), - 'U_SORT_TOPIC_TITLE' => $this->u_action . "&sk=g&sd=" . (($sort_key == 'f' && $sort_dir == 'a') ? 'd' : 'a'), + 'U_SORT_TOPIC_TITLE' => $this->u_action . "&sk=g&sd=" . (($sort_key == 'g' && $sort_dir == 'a') ? 'd' : 'a'), 'S_DISPLAY_MARK_ALL' => ($num_attachments) ? true : false, 'S_DISPLAY_PAGINATION' => ($num_attachments) ? true : false, diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index db3dbc5cac..4e40f0a2a3 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -340,7 +340,7 @@ class ucp_groups 'S_ROW_COUNT' => ${$block . '_count'}++) ); - $group_id_ary[] = $row['group_id']; + $group_id_ary[] = (int) $row['group_id']; } $db->sql_freeresult($result); diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php index 6f4e525b2f..6ac2412ef0 100644 --- a/phpBB/includes/ucp/ucp_main.php +++ b/phpBB/includes/ucp/ucp_main.php @@ -633,11 +633,14 @@ class ucp_main */ function assign_topiclist($mode = 'subscribed', $forbidden_forum_ary = array()) { - global $user, $db, $template, $config, $auth, $phpbb_root_path, $phpEx; + global $user, $db, $template, $config, $cache, $auth, $phpbb_root_path, $phpEx; $table = ($mode == 'subscribed') ? TOPICS_WATCH_TABLE : BOOKMARKS_TABLE; $start = request_var('start', 0); + // Grab icons + $icons = $cache->obtain_icons(); + $sql_array = array( 'SELECT' => 'COUNT(t.topic_id) as topics_count', @@ -776,7 +779,8 @@ class ucp_main $folder_img = $folder_alt = $topic_type = ''; topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type); - $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id"); + $view_topic_url_params = "f=$forum_id&t=$topic_id"; + $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params); // Send vars to template $template->assign_block_vars('topicrow', array( @@ -809,6 +813,7 @@ class ucp_main 'TOPIC_FOLDER_IMG' => $user->img($folder_img, $folder_alt), 'TOPIC_FOLDER_IMG_SRC' => $user->img($folder_img, $folder_alt, false, '', 'src'), + 'TOPIC_FOLDER_IMG_ALT' => $user->lang[$folder_alt], 'TOPIC_ICON_IMG' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '', 'TOPIC_ICON_IMG_WIDTH' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '', 'TOPIC_ICON_IMG_HEIGHT' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '', @@ -818,8 +823,8 @@ class ucp_main 'S_USER_POSTED' => (!empty($row['topic_posted'])) ? true : false, 'S_UNREAD_TOPIC' => $unread_topic, - 'U_NEWEST_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&view=unread") . '#unread', - 'U_LAST_POST' => $view_topic_url . '&p=' . $row['topic_last_post_id'] . '#p' . $row['topic_last_post_id'], + 'U_NEWEST_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&view=unread') . '#unread', + 'U_LAST_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'], 'U_VIEW_TOPIC' => $view_topic_url, 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id), )); diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index d451e25be4..008d8d6c88 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -850,7 +850,7 @@ function compose_pm($id, $mode, $action) $forward_text = array(); $forward_text[] = $user->lang['FWD_ORIGINAL_MESSAGE']; $forward_text[] = sprintf($user->lang['FWD_SUBJECT'], censor_text($message_subject)); - $forward_text[] = sprintf($user->lang['FWD_DATE'], $user->format_date($message_time)); + $forward_text[] = sprintf($user->lang['FWD_DATE'], $user->format_date($message_time, false, true)); $forward_text[] = sprintf($user->lang['FWD_FROM'], $quote_username_text); $forward_text[] = sprintf($user->lang['FWD_TO'], implode(', ', $fwd_to_field['to'])); @@ -1039,6 +1039,7 @@ function compose_pm($id, $mode, $action) 'FLASH_STATUS' => ($flash_status) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'], 'SMILIES_STATUS' => ($smilies_status) ? $user->lang['SMILIES_ARE_ON'] : $user->lang['SMILIES_ARE_OFF'], 'URL_STATUS' => ($url_status) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'], + 'MAX_FONT_SIZE' => (int) $config['max_post_font_size'], 'MINI_POST_IMG' => $user->img('icon_post_target', $user->lang['PM']), 'ERROR' => (sizeof($error)) ? implode('<br />', $error) : '', 'MAX_RECIPIENTS' => ($config['allow_mass_pm'] && ($auth->acl_get('u_masspm') || $auth->acl_get('u_masspm_group'))) ? $max_recipients : 0, @@ -1124,7 +1125,9 @@ function handle_message_list_actions(&$address_list, &$error, $remove_u, $remove $group_list = request_var('group_list', array(0)); // Build usernames to add - $usernames = (isset($_REQUEST['username'])) ? array(request_var('username', '', true)) : array(); + $usernames = request_var('username', '', true); + $usernames = (empty($usernames)) ? array() : array($usernames); + $username_list = request_var('username_list', '', true); if ($username_list) { diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 360912ae49..cb96b77754 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -328,7 +328,8 @@ function view_folder($id, $mode, $folder_id, $folder) $data[] = array( 'subject' => censor_text($row['message_subject']), 'sender' => $row['username'], - 'date' => $user->format_date($row['message_time']), + // ISO 8601 date. For PHP4 we are able to hardcode the timezone because $user->format_date() does not set it. + 'date' => $user->format_date($row['message_time'], (PHP_VERSION >= 5) ? 'c' : "Y-m-d\TH:i:s+00:00", true), 'to' => ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX) ? $address[$message_id] : '', 'message' => $message_row['message_text'] ); @@ -502,7 +503,7 @@ function get_pm_from($folder_id, $folder, $user_id) 'PAGE_NUMBER' => on_page($pm_count, $config['topics_per_page'], $start), 'TOTAL_MESSAGES' => (($pm_count == 1) ? $user->lang['VIEW_PM_MESSAGE'] : sprintf($user->lang['VIEW_PM_MESSAGES'], $pm_count)), - 'POST_IMG' => (!$auth->acl_get('u_sendpm')) ? $user->img('button_topic_locked', 'PM_LOCKED') : $user->img('button_pm_new', 'POST_PM'), + 'POST_IMG' => (!$auth->acl_get('u_sendpm')) ? $user->img('button_topic_locked', 'POST_PM_LOCKED') : $user->img('button_pm_new', 'POST_NEW_PM'), 'L_NO_MESSAGES' => (!$auth->acl_get('u_sendpm')) ? $user->lang['POST_PM_LOCKED'] : $user->lang['NO_MESSAGES'], @@ -511,7 +512,7 @@ function get_pm_from($folder_id, $folder, $user_id) 'S_SELECT_SORT_DAYS' => $s_limit_days, 'S_TOPIC_ICONS' => ($config['enable_pm_icons']) ? true : false, - 'U_POST_NEW_TOPIC' => ($auth->acl_get('u_sendpm')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose') : '', + 'U_POST_NEW_TOPIC' => ($auth->acl_get('u_sendpm')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose') : '', 'S_PM_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id" . (($start !== 0) ? "&start=$start" : '')), )); diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index bdd0e44ea8..5fef30056f 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -286,7 +286,7 @@ function get_user_information($user_id, $user_row) $update_time = $config['load_online_time'] * 60; if ($row) { - $user_row['online'] = (time() - $update_time < $row['online_time'] && ($row['viewonline'])) ? true : false; + $user_row['online'] = (time() - $update_time < $row['online_time'] && ($row['viewonline'] || $auth->acl_get('u_viewonline'))) ? true : false; } } diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 328d374e9a..30752d8c8a 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -349,11 +349,11 @@ class ucp_profile { $data['notify'] = $user->data['user_notify_type']; - if (!$config['jab_enable'] || !$data['jabber'] || !@extension_loaded('xml')) + if ($data['notify'] == NOTIFY_IM && (!$config['jab_enable'] || !$data['jabber'] || !@extension_loaded('xml'))) { // User has not filled in a jabber address (Or one of the modules is disabled or jabber is disabled) // Disable notify by Jabber now for this user. - $data['notify'] = NOTIFY_BOTH; + $data['notify'] = NOTIFY_EMAIL; } $sql_ary = array( @@ -549,6 +549,7 @@ class ucp_profile 'IMG_STATUS' => ($config['allow_sig_img']) ? $user->lang['IMAGES_ARE_ON'] : $user->lang['IMAGES_ARE_OFF'], 'FLASH_STATUS' => ($config['allow_sig_flash']) ? $user->lang['FLASH_IS_ON'] : $user->lang['FLASH_IS_OFF'], 'URL_STATUS' => ($config['allow_sig_links']) ? $user->lang['URL_IS_ON'] : $user->lang['URL_IS_OFF'], + 'MAX_FONT_SIZE' => (int) $config['max_sig_font_size'], 'L_SIGNATURE_EXPLAIN' => sprintf($user->lang['SIGNATURE_EXPLAIN'], $config['max_sig_chars']), diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 315d24d47f..549f96c42d 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -37,12 +37,13 @@ class ucp_register include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); - $confirm_id = request_var('confirm_id', ''); - $coppa = (isset($_REQUEST['coppa'])) ? ((!empty($_REQUEST['coppa'])) ? 1 : 0) : false; - $agreed = (!empty($_POST['agreed'])) ? 1 : 0; - $submit = (isset($_POST['submit'])) ? true : false; - $change_lang = request_var('change_lang', ''); - $user_lang = request_var('lang', $user->lang_name); + $confirm_id = request_var('confirm_id', ''); + $confirm_refresh = (isset($_POST['confirm_refresh']) && $config['confirm_refresh']) ? ((!empty($_POST['confirm_refresh'])) ? 1 : 0) : false; + $coppa = (isset($_REQUEST['coppa'])) ? ((!empty($_REQUEST['coppa'])) ? 1 : 0) : false; + $agreed = (!empty($_POST['agreed'])) ? 1 : 0; + $submit = (isset($_POST['submit'])) ? true : false; + $change_lang = request_var('change_lang', ''); + $user_lang = request_var('lang', $user->lang_name); if ($agreed) { @@ -187,7 +188,7 @@ class ucp_register array('string', false, 6, 60), array('email')), 'email_confirm' => array('string', false, 6, 60), - 'confirm_code' => array('string', !$config['enable_confirm'], 5, 8), + 'confirm_code' => array('string', !$config['enable_confirm'], CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS), 'tz' => array('num', false, -14, 14), 'lang' => array('match', false, '#^[a-z_\-]{2,}$#i'), )); @@ -448,7 +449,7 @@ class ucp_register if ($config['enable_confirm']) { - if ($change_lang) + if ($change_lang || $confirm_refresh) { $str = '&change_lang=' . $change_lang; $sql = 'SELECT code @@ -467,7 +468,7 @@ class ucp_register { $str = ''; } - if (!$change_lang || !$confirm_id) + if (!$change_lang || !$confirm_id || !$confirm_refresh) { $user->confirm_gc(CONFIRM_REG); @@ -484,7 +485,7 @@ class ucp_register trigger_error('TOO_MANY_REGISTERS'); } - $code = gen_rand_string(mt_rand(5, 8)); + $code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); $confirm_id = md5(unique_id($user->ip)); $seed = hexdec(substr(unique_id(), 4, 10)); @@ -500,6 +501,24 @@ class ucp_register ); $db->sql_query($sql); } + else if ($confirm_refresh) + { + $code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); + $confirm_id = md5(unique_id($user->ip)); + $seed = hexdec(substr(unique_id(), 4, 10)); + // compute $seed % 0x7fffffff + $seed -= 0x7fffffff * floor($seed / 0x7fffffff); + $sql = 'UPDATE ' . CONFIRM_TABLE . ' SET ' . $db->sql_build_array('UPDATE', array( + 'confirm_type' => (int) CONFIRM_REG, + 'code' => (string) $code, + 'seed' => (int) $seed) . " + WHERE + confirm_id = '" . $db->sql_escape($confirm_id) . "' AND + session_id = '" . $db->sql_escape($session_id) . "' AND + confirm_type = " . (int) CONFIRM_REG + ); + $db->sql_query($sql); + } $confirm_image = '<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=confirm&id=' . $confirm_id . '&type=' . CONFIRM_REG . $str) . '" alt="" title="" />'; $s_hidden_fields .= '<input type="hidden" name="confirm_id" value="' . $confirm_id . '" />'; } @@ -534,6 +553,7 @@ class ucp_register 'S_LANG_OPTIONS' => language_select($data['lang']), 'S_TZ_OPTIONS' => tz_select($data['tz']), 'S_CONFIRM_CODE' => ($config['enable_confirm']) ? true : false, + 'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false, 'S_COPPA' => $coppa, 'S_HIDDEN_FIELDS' => $s_hidden_fields, 'S_UCP_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'), diff --git a/phpBB/includes/ucp/ucp_resend.php b/phpBB/includes/ucp/ucp_resend.php index 48176a3989..cad494541b 100644 --- a/phpBB/includes/ucp/ucp_resend.php +++ b/phpBB/includes/ucp/ucp_resend.php @@ -133,6 +133,11 @@ class ucp_resend $messenger->to($row['user_email'], $row['username']); $messenger->im($row['user_jabber'], $row['username']); + $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']); + $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']); + $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']); + $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip); + $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($user_row['username']), 'U_USER_DETAILS' => generate_board_url() . "/memberlist.$phpEx?mode=viewprofile&u={$user_row['user_id']}", @@ -146,7 +151,7 @@ class ucp_resend meta_refresh(3, append_sid("{$phpbb_root_path}index.$phpEx")); - $message = ($config['require_activation'] == USER_ACTIVATION_ADMIN) ? $user->lang['ACIVATION_EMAIL_SENT_ADMIN'] : $user->lang['ACTIVATION_EMAIL_SENT']; + $message = ($config['require_activation'] == USER_ACTIVATION_ADMIN) ? $user->lang['ACTIVATION_EMAIL_SENT_ADMIN'] : $user->lang['ACTIVATION_EMAIL_SENT']; $message .= '<br /><br />' . sprintf($user->lang['RETURN_INDEX'], '<a href="' . append_sid("{$phpbb_root_path}index.$phpEx") . '">', '</a>'); trigger_error($message); } |
