Bored? Looking to kill some time? Want to chat with other SMF users? Join us in IRC chat or Discord
* @version 2.0.16
* @version 2.0.19
if (empty($_GET['hash']) || empty($_GET['request']) || ($_GET['request'] === 'http:') || ($_GET['request'] === 'https:'))
// Basic sanity check
$_GET['request'] = filter_var($_GET['request'], FILTER_VALIDATE_URL);
// We aren't going anywhere without these
if (empty($_GET['hash']) || empty($_GET['request']))
if ($response === null)
{
// Throw a 404
header('HTTP/1.1 404 Not Found');
exit;
}
// Right, image not cached? Simply redirect, then.
if ($response === false)
header('Location: ' . $request, false, 301);
if (!$response)
{
// Throw a 404
header('HTTP/1.1 404 Not Found');
exit;
}
if (empty($response) || $responseCode != 200)
return null;
if (empty($response) || $responseCode != 200)
$this->redirectexit($request_url);
// Make sure the url is returning an image
// What kind of file did they give us?
if (function_exists('finfo_open'))
{
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$headers['content-type'] = finfo_buffer($finfo, $response['body']);
finfo_close($finfo);
}
// SVG needs a little extra care
if (in_array($headers['content-type'], array('text/plain', 'text/xml')) && strtolower(pathinfo(parse_url($request_url, PHP_URL_PATH), PATHINFO_EXTENSION)) == 'svg' && strpos($response['body'], '<svg') !== false && strpos($response['body'], '</svg>') !== false)
$headers['content-type'] = 'image/svg+xml';
if ($contentParts[0] != 'image')
return null;
if ($contentParts[0] != 'image')
$this->redirectexit($request_url);
* @version 2.0.16
* @version 2.0.19
if (strpos($file, 'eval()') !== false && !empty($settings['current_include_filename']))
// Also ignore these deprecation warnings introduced in PHP 8.1.
if (defined('PHP_VERSION_ID') && PHP_VERSION_ID >= 80100 && strpos($error_string, 'strftime()') !== false)
return true;
* @version 2.0.18
* @version 2.0.19
$ent_list = empty($modSettings['disableEntityCheck']) ? '&(#\d{1,7}|quot|amp|lt|gt|nbsp);' : '&(#021|quot|amp|lt|gt|nbsp);';
$ent_list = empty($modSettings['disableEntityCheck']) ? '&(?>#\d{1,7}|quot|amp|lt|gt|nbsp);' : '&(?>#021|quot|amp|lt|gt|nbsp);';
$ent_check = empty($modSettings['disableEntityCheck']) ? function($string)
{
$string = preg_replace_callback('~(&#(\d{1,7}|x[0-9a-fA-F]{1,6});)~', 'entity_fix__callback', $string);
$ent_check = empty($modSettings['disableEntityCheck']) ? function($string, $double = false)
{
$string = preg_replace_callback('~(&' . (!empty($double) ? '(?:amp;)?' : '') . '#(\d{1,7}|x[0-9a-fA-F]{1,6});)~', 'entity_fix__callback', $string);
* @version 2.0.16
* @version 2.0.19
// Get the maximum value for the primary key.
$request = $smcFunc['db_query']('', '
SELECT MAX(' . $primary_key . ')
FROM {db_prefix}' . $cur_table,
array(
)
);
list($max_value) = $smcFunc['db_fetch_row']($request);
$smcFunc['db_free_result']($request);
if (empty($max_value))
continue;
while ($context['start'] <= $max_value)
// Get the count of records.
$request = $smcFunc['db_query']('', '
SELECT COUNT(*)
FROM {db_prefix}' . $cur_table,
array(
)
);
list($rec_count) = $smcFunc['db_fetch_row']($request);
$smcFunc['db_free_result']($request);
if (empty($rec_count))
continue;
while ($context['start'] <= $rec_count)
* @version 2.0.18
* @version 2.0.19
function loadProfileFields($force_reload = false)
{
global $context, $profile_fields, $txt, $scripturl, $modSettings, $user_info, $old_profile, $smcFunc, $cur_profile, $language
, $profile_vars
list ($uyear, $umonth, $uday) = explode('-', empty($cur_profile['birthdate']) || $cur_profile['birthdate'] === '1004-01-01' ? '--' : $cur_profile['birthdate']);
list ($uyear, $umonth, $uday) = explode('-', empty($cur_profile['birthdate']) || $cur_profile['birthdate'] === '0001-01-01' ? '0000-00-00' : $cur_profile['birthdate']);
'input_validate' => function(&$value) use (&$cur_profile, &$profile_vars)
{
if (isset($_POST['bday2'], $_POST['bday3']) && $value > 0 && $_POST['bday2'] > 0)
{
// Set to blank?
if ((int) $_POST['bday3'] == 1 && (int) $_POST['bday2'] == 1 && (int) $value == 1)
$value = '1004-01-01';
else
$value = checkdate($value, $_POST['bday2'], $_POST['bday3'] < 1004 ? 1004 : $_POST['bday3']) ? sprintf('%04d-%02d-%02d', $_POST['bday3'] < 1004 ? 1004 : $_POST['bday3'], $_POST['bday1'], $_POST['bday2']) : '1004-01-01';
}
else
$value = '1004-01-01';
'input_validate' => function(&$value)
{
global $cur_profile, $profile_vars;
if (isset($_POST['bday2'], $_POST['bday3']) && $value > 0 && $_POST['bday2'] > 0)
{
// Set to blank?
if ((int) $_POST['bday3'] == 1 && (int) $_POST['bday2'] == 1 && (int) $value == 1)
$value = '0001-01-01';
else
$value = checkdate($value, $_POST['bday2'], $_POST['bday3'] < 4 ? 4 : $_POST['bday3']) ? sprintf('%04d-%02d-%02d', $_POST['bday3'] < 4 ? 4 : $_POST['bday3'], $_POST['bday1'], $_POST['bday2']) : '0001-01-01';
}
else
$value = '0001-01-01';
$value = checkdate($dates[2], $dates[3], $dates[1] < 4 ? 4 : $dates[1]) ? sprintf('%04d-%02d-%02d', $dates[1] < 4 ? 4 : $dates[1], $dates[2], $dates[3]) : '1004-01-01';
$value = checkdate($dates[2], $dates[3], $dates[1] < 4 ? 4 : $dates[1]) ? sprintf('%04d-%02d-%02d', $dates[1] < 4 ? 4 : $dates[1], $dates[2], $dates[3]) : '0001-01-01';
$value = empty($cur_profile['birthdate']) ? '1004-01-01' : $cur_profile['birthdate'];
$value = empty($cur_profile['birthdate']) ? '0001-01-01' : $cur_profile['birthdate'];
if ($value == 'external' && allowedTo('profile_remote_avatar') && strtolower(substr($_POST['userpicpersonal'], 0, 7)) == 'http://' && strlen($_POST['userpicpersonal']) > 7 && !empty($modSettings['avatar_download_external']))
if ($value == 'external' && allowedTo('profile_remote_avatar') && (strtolower(substr($_POST['userpicpersonal'], 0, 7)) == 'http://' || strtolower(substr($_POST['userpicpersonal'], 0, 8)) == 'https://') && strlen($_POST['userpicpersonal']) > 7 && !empty($modSettings['avatar_download_external']))
* @version 2.0.18
* @version 2.0.19
// Check loadLanguage actually exists!
if (!function_exists('loadLanguage'))
{
require_once($sourcedir . '/Load.php');
require_once($sourcedir . '/Subs.php');
}
loadLanguage('index+Modifications');
// Also load up some context that is used by routines throughout ScheduledTasks.
// These may not be set when AutoTask is called very early in index.php.
// When scheduled tasks throw undefined errors, address them here.
if (!isset($context['server']))
{
// Copied over from Load.php...
// This determines the server... not used in many places, except for login fixing.
$context['server'] = array(
'is_iis' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false,
'is_apache' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false,
'is_lighttpd' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'lighttpd') !== false,
'is_nginx' => isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'nginx') !== false,
'is_cgi' => isset($_SERVER['SERVER_SOFTWARE']) && strpos(php_sapi_name(), 'cgi') !== false,
'is_windows' => strpos(PHP_OS, 'WIN') === 0,
'iso_case_folding' => ord(strtolower(chr(138))) === 154,
'complex_preg_chars' => @version_compare(PHP_VERSION, '4.3.3') != -1,
);
}
if (!isset($context['utf8']))
{
// Copied over from Load.php...
// Set the character set from the template.
$context['character_set'] = empty($modSettings['global_character_set']) ? (empty($txt['lang_character_set']) ? 'ISO-8859-1' : $txt['lang_character_set']) : $modSettings['global_character_set'];
$context['utf8'] = $context['character_set'] === 'UTF-8' && (strpos(strtolower(PHP_OS), 'win') === false || @version_compare(PHP_VERSION, '4.2.3') != -1);
$context['right_to_left'] = !empty($txt['lang_rtl']);
}
* @version 2.0.18
* @version 2.0.19
// Try to avoid a few pitfalls:
// like a possible race condition,
// or a failure to write at low diskspace
// Check before you act: if cache is enabled, we can do a simple test
// Can we even write things on this filesystem?
if ((empty($cachedir) || !file_exists($cachedir)) && file_exists($boarddir . '/cache'))
$cachedir = $boarddir . '/cache';
$test_fp = @fopen($cachedir . '/settings_update.tmp', "w+");
if ($test_fp)
{
fclose($test_fp);
$test_fp = @fopen($cachedir . '/settings_update.tmp', 'r+');
$written_bytes = fwrite($test_fp, "test");
fclose($test_fp);
@unlink($cachedir . '/settings_update.tmp');
if ($written_bytes !== strlen("test"))
{
// Oops. Low disk space, perhaps. Don't mess with Settings.php then.
// No means no. :P
return;
}
}
// Protect me from what I want! :P
clearstatcache();
if (filemtime($boarddir . '/Settings.php') === $last_settings_change)
{
// You asked for it...
$fp = @fopen($boarddir . '/Settings.php', 'c');
// Is it even writable, though?
if ($fp)
{
flock($fp, LOCK_EX);
ftruncate($fp, 0);
rewind($fp);
foreach ($settingsArray as $line)
fwrite($fp, strtr($line, "\r", ''));
flock($fp, LOCK_UN);
fclose($fp);
}
}
// Even though on normal installations the filemtime should prevent this being used by the installer incorrectly
// it seems that there are times it might not. So let's MAKE it dump the cache.
if (function_exists('opcache_invalidate'))
opcache_invalidate(dirname(__FILE__) . '/Settings.php', true);
safe_file_write($boarddir . '/Settings.php', strtr(implode('', $settingsArray), "\r", ''), $boarddir . '/Settings_bak.php', $last_settings_change);
?>
/**
* Writes data to a file, optionally making a backup, while avoiding race conditions.
*
* @param string $file The filepath of the file where the data should be written.
* @param string $data The data to be written to $file.
* @param string $backup_file The filepath where the backup should be saved. Default null.
* @param int $mtime If modification time of $file is more recent than this Unix timestamp, the write operation will abort. Defaults to time that the script started execution.
* @param bool $append If true, the data will be appended instead of overwriting the existing content of the file. Default false.
* @return bool Whether the write operation succeeded or not.
*/
function safe_file_write($file, $data, $backup_file = null, $mtime = null, $append = false)
{
// Sanity checks.
if (!file_exists($file) && !is_dir(dirname($file)))
return false;
if (!is_int($mtime))
$mtime = $_SERVER['REQUEST_TIME'];
$temp_dir = sm_temp_dir();
// Our temp files.
$temp_sfile = tempnam($temp_dir, pathinfo($file, PATHINFO_FILENAME) . '.');
if (!empty($backup_file))
$temp_bfile = tempnam($temp_dir, pathinfo($backup_file, PATHINFO_FILENAME) . '.');
// We need write permissions.
$failed = false;
foreach (array($file, $backup_file) as $sf)
{
if (empty($sf))
continue;
if (!file_exists($sf))
touch($sf);
elseif (!is_file($sf))
$failed = true;
if (!$failed && !is_writable($sf))
{
foreach (array(0644, 0664, 0666) as $mode)
{
$failed = !@chmod($sf, $mode);
if (!$failed)
break;
}
}
}
// Now let's see if writing to a temp file succeeds.
if (!$failed && file_put_contents($temp_sfile, $data, LOCK_EX) !== strlen($data))
$failed = true;
// Tests passed, so it's time to do the job.
if (!$failed)
{
// Back up the backup, just in case.
if (file_exists($backup_file))
$temp_bfile_saved = @copy($backup_file, $temp_bfile);
// Make sure no one changed the file while we weren't looking.
clearstatcache();
if (filemtime($file) <= $mtime)
{
// Attempt to open the file.
$sfhandle = @fopen($file, 'c');
// Let's do this thing!
if ($sfhandle !== false)
{
// Immediately get a lock.
flock($sfhandle, LOCK_EX);
// Make sure the backup works before we do anything more.
$temp_sfile_saved = @copy($file, $temp_sfile);
// Now write our data to the file.
if ($temp_sfile_saved)
{
if (empty($append))
{
ftruncate($sfhandle, 0);
rewind($sfhandle);
}
$failed = fwrite($sfhandle, $data) !== strlen($data);
}
else
$failed = true;
// If writing failed, put everything back the way it was.
if ($failed)
{
if (!empty($temp_sfile_saved))
@rename($temp_sfile, $file);
if (!empty($temp_bfile_saved))
@rename($temp_bfile, $backup_file);
}
// It worked, so make our temp backup the new permanent backup.
elseif (!empty($backup_file))
@rename($temp_sfile, $backup_file);
// And we're done.
flock($sfhandle, LOCK_UN);
fclose($sfhandle);
}
}
}
// We're done with these.
@unlink($temp_sfile);
@unlink($temp_bfile);
if ($failed)
return false;
// Even though on normal installations the filemtime should invalidate any cached version
// it seems that there are times it might not. So let's MAKE it dump the cache.
if (function_exists('opcache_invalidate'))
opcache_invalidate($file, true);
return true;
}
/**
* Locates the most appropriate temp directory.
*
* Systems using `open_basedir` restrictions may receive errors with
* `sys_get_temp_dir()` due to misconfigurations on servers. Other
* cases sys_temp_dir may not be set to a safe value. Additionally
* `sys_get_temp_dir` may use a readonly directory. This attempts to
* find a working temp directory that is accessible under the
* restrictions and is writable to the web service account.
*
* Directories checked against `open_basedir`:
*
* - `sys_get_temp_dir()`
* - `upload_tmp_dir`
* - `session.save_path`
* - `cachedir`
*
* @return string
*/
function sm_temp_dir()
{
global $cachedir;
static $temp_dir = null;
// Already did this.
if (!empty($temp_dir))
return $temp_dir;
// Temp Directory options order.
$temp_dir_options = array(
0 => 'sys_get_temp_dir',
1 => 'upload_tmp_dir',
2 => 'session.save_path',
3 => 'cachedir'
);
// Determine if we should detect a restriction and what restrictions that may be.
$open_base_dir = ini_get('open_basedir');
$restriction = !empty($open_base_dir) ? explode(':', $open_base_dir) : false;
// Prevent any errors as we search.
$old_error_reporting = error_reporting(0);
// Search for a working temp directory.
foreach ($temp_dir_options as $id_temp => $temp_option)
{
switch ($temp_option) {
case 'cachedir':
$possible_temp = rtrim($cachedir, '/');
break;
case 'session.save_path':
$possible_temp = rtrim(ini_get('session.save_path'), '/');
break;
case 'upload_tmp_dir':
$possible_temp = rtrim(ini_get('upload_tmp_dir'), '/');
break;
default:
$possible_temp = sys_get_temp_dir();
break;
}
// Check if we have a restriction preventing this from working.
if ($restriction)
{
foreach ($restriction as $dir)
{
if (strpos($possible_temp, $dir) !== false && is_writable($possible_temp))
{
$temp_dir = $possible_temp;
break;
}
}
}
// No restrictions, but need to check for writable status.
elseif (is_writable($possible_temp))
{
$temp_dir = $possible_temp;
break;
}
}
// Fall back to sys_get_temp_dir even though it won't work, so we have something.
if (empty($temp_dir))
$temp_dir = sys_get_temp_dir();
// Fix the path.
$temp_dir = substr($temp_dir, -1) === '/' ? $temp_dir : $temp_dir . '/';
// Put things back.
error_reporting($old_error_reporting);
return $temp_dir;
}
* @version 2.0.16
* @version 2.0.19
'db_escape_wildcard_string' => 'smf_db_escape_wildcard_string',
'db_connect_error' => 'mysql_connect_error',
'db_connect_errno' => 'mysql_connect_errno',
'db_escape_wildcard_string' => array($this, 'escape_wildcard_string'),
'db_connect_error' => 'mysqli_connect_error',
'db_connect_errno' => 'mysqli_connect_errno',
* @version 2.0.4
* @version 2.0.19
'db_escape_wildcard_string' => 'smf_db_escape_wildcard_string',
'db_connect_error' => 'smf_db_connect_error',
'db_connect_errno' => 'smf_db_connect_errno',
?>
/**
* Function to emulate mysqli_connect_error.
* Since pg doesn't have such a function, just return an empty string.
*
* @return string connection error message
*/
function smf_db_connect_error()
{
return '';
}
/**
* Function to emulate mysqli_connect_errno.
* Since pg doesn't have such a function, just return an empty string.
*
* @return string connection error number
*/
function smf_db_connect_errno()
{
return '';
}
* @version 2.0.18
* @version 2.0.19
* @version 2.0.16
* @version 2.0.19
'Michele "Illori" Davis',
// Former Project Managers
'Aleksi "Lex" Kilpinen',
// Former Project Managers
'Michele "Illori" Davis',
// Developers
'John "live627" Rayes',
'Jeremy "SleePy" Darwood',
// Developers
'Jessica "Suki" González',
'John "live627" Rayes',
'Oscar "Ozp" Rydhé',
'Hendrik Jan "Compuart" Visser',
'Jeremy "SleePy" Darwood',
// Lead Support Specialist
'Aleksi "Lex" Kilpinen',
// Support Specialists
'br360',
'GigaWatt',
'Will "Kindred" Wagner',
'Steve',
'ziycon',
// Lead Support Specialist
'Will "Kindred" Wagner',
// Support Specialists
'lurkalot',
'shadav',
'Steve',
// Lead Customizer
'Sami "SychO" Mazouz',
// Customizers
'Diego Andrés',
'Gary M. Gadsdon',
'Jonathan "vbgamer45" Valentin',
// Lead Customizer
'Gary M. Gadsdon',
// Customizers
'Diego Andrés',
'Jonathan "vbgamer45" Valentin',
'Mick.',
'Matthew "Labradoodle-360" Kerle',
'Mick.',
'Matthew "Labradoodle-360" Kerle',
* @version 2.0.14
* @version 2.0.19
// If we're viewing a topic, these should be the previous and next topics, respectively.
if (!empty($context['current_topic']))
echo '
<link rel="prev" href="', $scripturl, '?topic=', $context['current_topic'], '.0;prev_next=prev" />
<link rel="next" href="', $scripturl, '?topic=', $context['current_topic'], '.0;prev_next=next" />';
// If we're in a board, or a topic for that matter, the index will be the board's index.
// If we're in a board, or a topic for that matter, the index will be the board's index.
// Version: 2.0.16; Help
// Version: 2.0.19; Help
https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en
https://ec.europa.eu/info/law/law-topic/data-protection_en
https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en
https://ec.europa.eu/info/law/law-topic/data-protection_en
https://ec.europa.eu/commission/priorities/justice-and-fundamental-rights/data-protection/2018-reform-eu-data-protection-rules_en
https://ec.europa.eu/info/law/law-topic/data-protection_en