Yoshi2889 /
SMF2.1
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * Simple Machines Forum (SMF) |
||
| 5 | * |
||
| 6 | * @package SMF |
||
| 7 | * @author Simple Machines http://www.simplemachines.org |
||
| 8 | * @copyright 2017 Simple Machines and individual contributors |
||
| 9 | * @license http://www.simplemachines.org/about/smf/license.php BSD |
||
| 10 | * |
||
| 11 | * @version 2.1 Beta 4 |
||
| 12 | * |
||
| 13 | * This file contains helper functions for upgrade.php |
||
| 14 | */ |
||
| 15 | |||
| 16 | if (!defined('SMF_VERSION')) |
||
| 17 | die('No direct access!'); |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Clean the cache using the SMF 2.1 CacheAPI. |
||
| 21 | * If coming from SMF 2.0 and below it should wipe the cache using the SMF backend. |
||
| 22 | */ |
||
| 23 | function upgrade_clean_cache() |
||
| 24 | { |
||
| 25 | global $cacheAPI, $sourcedir; |
||
| 26 | |||
| 27 | // Initialize the cache API if it does not have an instance yet. |
||
| 28 | require_once($sourcedir . '/Load.php'); |
||
| 29 | if (empty($cacheAPI)) |
||
| 30 | { |
||
| 31 | loadCacheAccelerator(); |
||
| 32 | } |
||
| 33 | |||
| 34 | // Just through back to Load.php's clean_cache function. |
||
| 35 | clean_cache(); |
||
| 36 | } |
||
| 37 | |||
| 38 | /** |
||
| 39 | * Returns a list of member groups. Used to upgrade 1.0 and 1.1. |
||
| 40 | * |
||
| 41 | * @return array |
||
| 42 | */ |
||
| 43 | function getMemberGroups() |
||
| 44 | { |
||
| 45 | global $smcFunc; |
||
| 46 | static $member_groups = array(); |
||
| 47 | |||
| 48 | if (!empty($member_groups)) |
||
| 49 | return $member_groups; |
||
| 50 | |||
| 51 | $request = $smcFunc['db_query']('', ' |
||
| 52 | SELECT group_name, id_group |
||
| 53 | FROM {db_prefix}membergroups |
||
| 54 | WHERE id_group = {int:admin_group} OR id_group > {int:old_group}', |
||
| 55 | array( |
||
| 56 | 'admin_group' => 1, |
||
| 57 | 'old_group' => 7, |
||
| 58 | 'db_error_skip' => true, |
||
| 59 | ) |
||
| 60 | ); |
||
| 61 | if ($request === false) |
||
| 62 | { |
||
| 63 | $request = $smcFunc['db_query']('', ' |
||
| 64 | SELECT membergroup, id_group |
||
| 65 | FROM {db_prefix}membergroups |
||
| 66 | WHERE id_group = {int:admin_group} OR id_group > {int:old_group}', |
||
| 67 | array( |
||
| 68 | 'admin_group' => 1, |
||
| 69 | 'old_group' => 7, |
||
| 70 | 'db_error_skip' => true, |
||
| 71 | ) |
||
| 72 | ); |
||
| 73 | } |
||
| 74 | while ($row = $smcFunc['db_fetch_row']($request)) |
||
| 75 | $member_groups[trim($row[0])] = $row[1]; |
||
| 76 | $smcFunc['db_free_result']($request); |
||
| 77 | |||
| 78 | return $member_groups; |
||
| 79 | } |
||
| 80 | |||
| 81 | /** |
||
| 82 | * Make files writable. First try to use regular chmod, but if that fails, try to use FTP. |
||
| 83 | * |
||
| 84 | * @param $files |
||
| 85 | * @return bool |
||
| 86 | */ |
||
| 87 | function makeFilesWritable(&$files) |
||
| 88 | { |
||
| 89 | global $upcontext, $boarddir, $sourcedir; |
||
| 90 | |||
| 91 | if (empty($files)) |
||
| 92 | return true; |
||
| 93 | |||
| 94 | $failure = false; |
||
| 95 | // On linux, it's easy - just use is_writable! |
||
| 96 | if (substr(__FILE__, 1, 2) != ':\\') |
||
| 97 | { |
||
| 98 | $upcontext['systemos'] = 'linux'; |
||
| 99 | |||
| 100 | foreach ($files as $k => $file) |
||
| 101 | { |
||
| 102 | // Some files won't exist, try to address up front |
||
| 103 | if (!file_exists($file)) |
||
| 104 | @touch($file); |
||
|
0 ignored issues
–
show
|
|||
| 105 | // NOW do the writable check... |
||
| 106 | if (!is_writable($file)) |
||
| 107 | { |
||
| 108 | @chmod($file, 0755); |
||
|
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
| 109 | |||
| 110 | // Well, 755 hopefully worked... if not, try 777. |
||
| 111 | if (!is_writable($file) && !@chmod($file, 0777)) |
||
| 112 | $failure = true; |
||
| 113 | // Otherwise remove it as it's good! |
||
| 114 | else |
||
| 115 | unset($files[$k]); |
||
| 116 | } |
||
| 117 | else |
||
| 118 | unset($files[$k]); |
||
| 119 | } |
||
| 120 | } |
||
| 121 | // Windows is trickier. Let's try opening for r+... |
||
| 122 | else |
||
| 123 | { |
||
| 124 | $upcontext['systemos'] = 'windows'; |
||
| 125 | |||
| 126 | foreach ($files as $k => $file) |
||
| 127 | { |
||
| 128 | // Folders can't be opened for write... but the index.php in them can ;). |
||
| 129 | if (is_dir($file)) |
||
| 130 | $file .= '/index.php'; |
||
| 131 | |||
| 132 | // Funny enough, chmod actually does do something on windows - it removes the read only attribute. |
||
| 133 | @chmod($file, 0777); |
||
|
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
| 134 | $fp = @fopen($file, 'r+'); |
||
| 135 | |||
| 136 | // Hmm, okay, try just for write in that case... |
||
| 137 | if (!$fp) |
||
| 138 | $fp = @fopen($file, 'w'); |
||
| 139 | |||
| 140 | if (!$fp) |
||
| 141 | $failure = true; |
||
| 142 | else |
||
| 143 | unset($files[$k]); |
||
| 144 | @fclose($fp); |
||
|
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
| 145 | } |
||
| 146 | } |
||
| 147 | |||
| 148 | if (empty($files)) |
||
| 149 | return true; |
||
| 150 | |||
| 151 | if (!isset($_SERVER)) |
||
| 152 | return !$failure; |
||
| 153 | |||
| 154 | // What still needs to be done? |
||
| 155 | $upcontext['chmod']['files'] = $files; |
||
| 156 | |||
| 157 | // If it's windows it's a mess... |
||
| 158 | if ($failure && substr(__FILE__, 1, 2) == ':\\') |
||
| 159 | { |
||
| 160 | $upcontext['chmod']['ftp_error'] = 'total_mess'; |
||
| 161 | |||
| 162 | return false; |
||
| 163 | } |
||
| 164 | // We're going to have to use... FTP! |
||
| 165 | elseif ($failure) |
||
| 166 | { |
||
| 167 | // Load any session data we might have... |
||
| 168 | if (!isset($_POST['ftp_username']) && isset($_SESSION['installer_temp_ftp'])) |
||
| 169 | { |
||
| 170 | $upcontext['chmod']['server'] = $_SESSION['installer_temp_ftp']['server']; |
||
| 171 | $upcontext['chmod']['port'] = $_SESSION['installer_temp_ftp']['port']; |
||
| 172 | $upcontext['chmod']['username'] = $_SESSION['installer_temp_ftp']['username']; |
||
| 173 | $upcontext['chmod']['password'] = $_SESSION['installer_temp_ftp']['password']; |
||
| 174 | $upcontext['chmod']['path'] = $_SESSION['installer_temp_ftp']['path']; |
||
| 175 | } |
||
| 176 | // Or have we submitted? |
||
| 177 | View Code Duplication | elseif (isset($_POST['ftp_username'])) |
|
| 178 | { |
||
| 179 | $upcontext['chmod']['server'] = $_POST['ftp_server']; |
||
| 180 | $upcontext['chmod']['port'] = $_POST['ftp_port']; |
||
| 181 | $upcontext['chmod']['username'] = $_POST['ftp_username']; |
||
| 182 | $upcontext['chmod']['password'] = $_POST['ftp_password']; |
||
| 183 | $upcontext['chmod']['path'] = $_POST['ftp_path']; |
||
| 184 | } |
||
| 185 | |||
| 186 | require_once($sourcedir . '/Class-Package.php'); |
||
| 187 | if (isset($upcontext['chmod']['username'])) |
||
| 188 | { |
||
| 189 | $ftp = new ftp_connection($upcontext['chmod']['server'], $upcontext['chmod']['port'], $upcontext['chmod']['username'], $upcontext['chmod']['password']); |
||
| 190 | |||
| 191 | if ($ftp->error === false) |
||
| 192 | { |
||
| 193 | // Try it without /home/abc just in case they messed up. |
||
| 194 | if (!$ftp->chdir($upcontext['chmod']['path'])) |
||
| 195 | { |
||
| 196 | $upcontext['chmod']['ftp_error'] = $ftp->last_message; |
||
| 197 | $ftp->chdir(preg_replace('~^/home[2]?/[^/]+?~', '', $upcontext['chmod']['path'])); |
||
| 198 | } |
||
| 199 | } |
||
| 200 | } |
||
| 201 | |||
| 202 | if (!isset($ftp) || $ftp->error !== false) |
||
| 203 | { |
||
| 204 | if (!isset($ftp)) |
||
| 205 | $ftp = new ftp_connection(null); |
||
| 206 | // Save the error so we can mess with listing... |
||
| 207 | elseif ($ftp->error !== false && !isset($upcontext['chmod']['ftp_error'])) |
||
| 208 | $upcontext['chmod']['ftp_error'] = $ftp->last_message === null ? '' : $ftp->last_message; |
||
| 209 | |||
| 210 | list ($username, $detect_path, $found_path) = $ftp->detect_path(dirname(__FILE__)); |
||
| 211 | |||
| 212 | if ($found_path || !isset($upcontext['chmod']['path'])) |
||
| 213 | $upcontext['chmod']['path'] = $detect_path; |
||
| 214 | |||
| 215 | if (!isset($upcontext['chmod']['username'])) |
||
| 216 | $upcontext['chmod']['username'] = $username; |
||
| 217 | |||
| 218 | // Don't forget the login token. |
||
| 219 | $upcontext += createToken('login'); |
||
| 220 | |||
| 221 | return false; |
||
| 222 | } |
||
| 223 | else |
||
| 224 | { |
||
| 225 | // We want to do a relative path for FTP. |
||
| 226 | if (!in_array($upcontext['chmod']['path'], array('', '/'))) |
||
| 227 | { |
||
| 228 | $ftp_root = strtr($boarddir, array($upcontext['chmod']['path'] => '')); |
||
| 229 | if (substr($ftp_root, -1) == '/' && ($upcontext['chmod']['path'] == '' || $upcontext['chmod']['path'][0] === '/')) |
||
| 230 | $ftp_root = substr($ftp_root, 0, -1); |
||
| 231 | } |
||
| 232 | else |
||
| 233 | $ftp_root = $boarddir; |
||
| 234 | |||
| 235 | // Save the info for next time! |
||
| 236 | $_SESSION['installer_temp_ftp'] = array( |
||
| 237 | 'server' => $upcontext['chmod']['server'], |
||
| 238 | 'port' => $upcontext['chmod']['port'], |
||
| 239 | 'username' => $upcontext['chmod']['username'], |
||
| 240 | 'password' => $upcontext['chmod']['password'], |
||
| 241 | 'path' => $upcontext['chmod']['path'], |
||
| 242 | 'root' => $ftp_root, |
||
| 243 | ); |
||
| 244 | |||
| 245 | foreach ($files as $k => $file) |
||
| 246 | { |
||
| 247 | if (!is_writable($file)) |
||
| 248 | $ftp->chmod($file, 0755); |
||
| 249 | if (!is_writable($file)) |
||
| 250 | $ftp->chmod($file, 0777); |
||
| 251 | |||
| 252 | // Assuming that didn't work calculate the path without the boarddir. |
||
| 253 | if (!is_writable($file)) |
||
| 254 | { |
||
| 255 | if (strpos($file, $boarddir) === 0) |
||
| 256 | { |
||
| 257 | $ftp_file = strtr($file, array($_SESSION['installer_temp_ftp']['root'] => '')); |
||
| 258 | $ftp->chmod($ftp_file, 0755); |
||
| 259 | if (!is_writable($file)) |
||
| 260 | $ftp->chmod($ftp_file, 0777); |
||
| 261 | // Sometimes an extra slash can help... |
||
| 262 | $ftp_file = '/' . $ftp_file; |
||
| 263 | if (!is_writable($file)) |
||
| 264 | $ftp->chmod($ftp_file, 0755); |
||
| 265 | if (!is_writable($file)) |
||
| 266 | $ftp->chmod($ftp_file, 0777); |
||
| 267 | } |
||
| 268 | } |
||
| 269 | |||
| 270 | if (is_writable($file)) |
||
| 271 | unset($files[$k]); |
||
| 272 | } |
||
| 273 | |||
| 274 | $ftp->close(); |
||
| 275 | } |
||
| 276 | } |
||
| 277 | |||
| 278 | // What remains? |
||
| 279 | $upcontext['chmod']['files'] = $files; |
||
| 280 | |||
| 281 | if (empty($files)) |
||
| 282 | return true; |
||
| 283 | |||
| 284 | return false; |
||
| 285 | } |
||
| 286 | |||
| 287 | /** |
||
| 288 | * The quick version of makeFilesWritable, which does not support FTP. |
||
| 289 | * |
||
| 290 | * @param string $file |
||
| 291 | * @return bool |
||
| 292 | */ |
||
| 293 | function quickFileWritable($file) |
||
| 294 | { |
||
| 295 | |||
| 296 | // Some files won't exist, try to address up front |
||
| 297 | if (!file_exists($file)) |
||
| 298 | @touch($file); |
||
|
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
| 299 | |||
| 300 | // NOW do the writable check... |
||
| 301 | if (is_writable($file)) |
||
| 302 | return true; |
||
| 303 | |||
| 304 | @chmod($file, 0755); |
||
|
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
| 305 | |||
| 306 | // Try 755 and 775 first since 777 doesn't always work and could be a risk... |
||
| 307 | $chmod_values = array(0755, 0775, 0777); |
||
| 308 | |||
| 309 | foreach ($chmod_values as $val) |
||
| 310 | { |
||
| 311 | // If it's writable, break out of the loop |
||
| 312 | if (is_writable($file)) |
||
| 313 | break; |
||
| 314 | else |
||
| 315 | @chmod($file, $val); |
||
|
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
| 316 | } |
||
| 317 | |||
| 318 | return is_writable($file); |
||
| 319 | } |
||
| 320 | |||
| 321 | /** |
||
| 322 | * UTF-8 aware strtolower function. |
||
| 323 | * |
||
| 324 | * @param $string |
||
| 325 | * @return string |
||
| 326 | */ |
||
| 327 | function smf_strtolower($string) |
||
| 328 | { |
||
| 329 | return mb_strtolower($string, 'UTF-8'); |
||
| 330 | } |
||
| 331 | |||
| 332 | /** |
||
| 333 | * Prints an error to stderr. |
||
| 334 | * |
||
| 335 | * @param $message |
||
| 336 | * @param bool $fatal |
||
| 337 | */ |
||
| 338 | function print_error($message, $fatal = false) |
||
| 339 | { |
||
| 340 | static $fp = null; |
||
| 341 | |||
| 342 | if ($fp === null) |
||
| 343 | $fp = fopen('php://stderr', 'wb'); |
||
| 344 | |||
| 345 | fwrite($fp, $message . "\n"); |
||
| 346 | |||
| 347 | if ($fatal) |
||
| 348 | exit; |
||
| 349 | } |
||
| 350 | |||
| 351 | /** |
||
| 352 | * Throws a graphical error message. |
||
| 353 | * |
||
| 354 | * @param $message |
||
| 355 | * @return bool |
||
| 356 | */ |
||
| 357 | function throw_error($message) |
||
| 358 | { |
||
| 359 | global $upcontext; |
||
| 360 | |||
| 361 | $upcontext['error_msg'] = $message; |
||
| 362 | $upcontext['sub_template'] = 'error_message'; |
||
| 363 | |||
| 364 | return false; |
||
| 365 | } |
||
| 366 | |||
| 367 | /** |
||
| 368 | * Database functions below here. |
||
| 369 | */ |
||
| 370 | /** |
||
| 371 | * @param $rs |
||
| 372 | * @return array|null |
||
| 373 | */ |
||
| 374 | function smf_mysql_fetch_assoc($rs) |
||
| 375 | { |
||
| 376 | return mysqli_fetch_assoc($rs); |
||
| 377 | } |
||
| 378 | |||
| 379 | /** |
||
| 380 | * @param $rs |
||
| 381 | * @return array|null |
||
| 382 | */ |
||
| 383 | function smf_mysql_fetch_row($rs) |
||
| 384 | { |
||
| 385 | return mysqli_fetch_row($rs); |
||
| 386 | } |
||
| 387 | |||
| 388 | /** |
||
| 389 | * @param $rs |
||
| 390 | */ |
||
| 391 | function smf_mysql_free_result($rs) |
||
| 392 | { |
||
| 393 | mysqli_free_result($rs); |
||
| 394 | } |
||
| 395 | |||
| 396 | /** |
||
| 397 | * @param $rs |
||
| 398 | * @return int|string |
||
| 399 | */ |
||
| 400 | function smf_mysql_insert_id($rs) |
||
| 401 | { |
||
| 402 | return mysqli_insert_id($rs); |
||
| 403 | } |
||
| 404 | |||
| 405 | /** |
||
| 406 | * @param $rs |
||
| 407 | * @return int |
||
| 408 | */ |
||
| 409 | function smf_mysql_num_rows($rs) |
||
| 410 | { |
||
| 411 | return mysqli_num_rows($rs); |
||
| 412 | } |
||
| 413 | |||
| 414 | /** |
||
| 415 | * @param $string |
||
| 416 | */ |
||
| 417 | function smf_mysql_real_escape_string($string) |
||
| 418 | { |
||
| 419 | global $db_connection; |
||
| 420 | mysqli_real_escape_string($db_connection, $string); |
||
| 421 | } |
If you suppress an error, we recommend checking for the error condition explicitly: