albertlast /
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 | if (!is_writable($file)) |
||
| 103 | { |
||
| 104 | @chmod($file, 0755); |
||
|
0 ignored issues
–
show
|
|||
| 105 | |||
| 106 | // Well, 755 hopefully worked... if not, try 777. |
||
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
37% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. Loading history...
|
|||
| 107 | if (!is_writable($file) && !@chmod($file, 0777)) |
||
| 108 | $failure = true; |
||
| 109 | // Otherwise remove it as it's good! |
||
| 110 | else |
||
| 111 | unset($files[$k]); |
||
| 112 | } |
||
| 113 | else |
||
| 114 | unset($files[$k]); |
||
| 115 | } |
||
| 116 | } |
||
| 117 | // Windows is trickier. Let's try opening for r+... |
||
| 118 | else |
||
| 119 | { |
||
| 120 | $upcontext['systemos'] = 'windows'; |
||
| 121 | |||
| 122 | foreach ($files as $k => $file) |
||
| 123 | { |
||
| 124 | // Folders can't be opened for write... but the index.php in them can ;). |
||
| 125 | if (is_dir($file)) |
||
| 126 | $file .= '/index.php'; |
||
| 127 | |||
| 128 | // Funny enough, chmod actually does do something on windows - it removes the read only attribute. |
||
| 129 | @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...
|
|||
| 130 | $fp = @fopen($file, 'r+'); |
||
| 131 | |||
| 132 | // Hmm, okay, try just for write in that case... |
||
| 133 | if (!$fp) |
||
| 134 | $fp = @fopen($file, 'w'); |
||
| 135 | |||
| 136 | if (!$fp) |
||
| 137 | $failure = true; |
||
| 138 | else |
||
| 139 | unset($files[$k]); |
||
| 140 | @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...
|
|||
| 141 | } |
||
| 142 | } |
||
| 143 | |||
| 144 | if (empty($files)) |
||
| 145 | return true; |
||
| 146 | |||
| 147 | if (!isset($_SERVER)) |
||
| 148 | return !$failure; |
||
| 149 | |||
| 150 | // What still needs to be done? |
||
| 151 | $upcontext['chmod']['files'] = $files; |
||
| 152 | |||
| 153 | // If it's windows it's a mess... |
||
| 154 | if ($failure && substr(__FILE__, 1, 2) == ':\\') |
||
| 155 | { |
||
| 156 | $upcontext['chmod']['ftp_error'] = 'total_mess'; |
||
| 157 | |||
| 158 | return false; |
||
| 159 | } |
||
| 160 | // We're going to have to use... FTP! |
||
| 161 | elseif ($failure) |
||
| 162 | { |
||
| 163 | // Load any session data we might have... |
||
| 164 | if (!isset($_POST['ftp_username']) && isset($_SESSION['installer_temp_ftp'])) |
||
| 165 | { |
||
| 166 | $upcontext['chmod']['server'] = $_SESSION['installer_temp_ftp']['server']; |
||
| 167 | $upcontext['chmod']['port'] = $_SESSION['installer_temp_ftp']['port']; |
||
| 168 | $upcontext['chmod']['username'] = $_SESSION['installer_temp_ftp']['username']; |
||
| 169 | $upcontext['chmod']['password'] = $_SESSION['installer_temp_ftp']['password']; |
||
| 170 | $upcontext['chmod']['path'] = $_SESSION['installer_temp_ftp']['path']; |
||
| 171 | } |
||
| 172 | // Or have we submitted? |
||
| 173 | View Code Duplication | elseif (isset($_POST['ftp_username'])) |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 174 | { |
||
| 175 | $upcontext['chmod']['server'] = $_POST['ftp_server']; |
||
| 176 | $upcontext['chmod']['port'] = $_POST['ftp_port']; |
||
| 177 | $upcontext['chmod']['username'] = $_POST['ftp_username']; |
||
| 178 | $upcontext['chmod']['password'] = $_POST['ftp_password']; |
||
| 179 | $upcontext['chmod']['path'] = $_POST['ftp_path']; |
||
| 180 | } |
||
| 181 | |||
| 182 | require_once($sourcedir . '/Class-Package.php'); |
||
| 183 | if (isset($upcontext['chmod']['username'])) |
||
| 184 | { |
||
| 185 | $ftp = new ftp_connection($upcontext['chmod']['server'], $upcontext['chmod']['port'], $upcontext['chmod']['username'], $upcontext['chmod']['password']); |
||
| 186 | |||
| 187 | if ($ftp->error === false) |
||
| 188 | { |
||
| 189 | // Try it without /home/abc just in case they messed up. |
||
| 190 | if (!$ftp->chdir($upcontext['chmod']['path'])) |
||
| 191 | { |
||
| 192 | $upcontext['chmod']['ftp_error'] = $ftp->last_message; |
||
| 193 | $ftp->chdir(preg_replace('~^/home[2]?/[^/]+?~', '', $upcontext['chmod']['path'])); |
||
| 194 | } |
||
| 195 | } |
||
| 196 | } |
||
| 197 | |||
| 198 | if (!isset($ftp) || $ftp->error !== false) |
||
| 199 | { |
||
| 200 | if (!isset($ftp)) |
||
| 201 | $ftp = new ftp_connection(null); |
||
| 202 | // Save the error so we can mess with listing... |
||
| 203 | elseif ($ftp->error !== false && !isset($upcontext['chmod']['ftp_error'])) |
||
| 204 | $upcontext['chmod']['ftp_error'] = $ftp->last_message === null ? '' : $ftp->last_message; |
||
| 205 | |||
| 206 | list ($username, $detect_path, $found_path) = $ftp->detect_path(dirname(__FILE__)); |
||
| 207 | |||
| 208 | if ($found_path || !isset($upcontext['chmod']['path'])) |
||
| 209 | $upcontext['chmod']['path'] = $detect_path; |
||
| 210 | |||
| 211 | if (!isset($upcontext['chmod']['username'])) |
||
| 212 | $upcontext['chmod']['username'] = $username; |
||
| 213 | |||
| 214 | // Don't forget the login token. |
||
| 215 | $upcontext += createToken('login'); |
||
| 216 | |||
| 217 | return false; |
||
| 218 | } |
||
| 219 | else |
||
| 220 | { |
||
| 221 | // We want to do a relative path for FTP. |
||
| 222 | if (!in_array($upcontext['chmod']['path'], array('', '/'))) |
||
| 223 | { |
||
| 224 | $ftp_root = strtr($boarddir, array($upcontext['chmod']['path'] => '')); |
||
| 225 | if (substr($ftp_root, -1) == '/' && ($upcontext['chmod']['path'] == '' || $upcontext['chmod']['path'][0] === '/')) |
||
| 226 | $ftp_root = substr($ftp_root, 0, -1); |
||
| 227 | } |
||
| 228 | else |
||
| 229 | $ftp_root = $boarddir; |
||
| 230 | |||
| 231 | // Save the info for next time! |
||
| 232 | $_SESSION['installer_temp_ftp'] = array( |
||
| 233 | 'server' => $upcontext['chmod']['server'], |
||
| 234 | 'port' => $upcontext['chmod']['port'], |
||
| 235 | 'username' => $upcontext['chmod']['username'], |
||
| 236 | 'password' => $upcontext['chmod']['password'], |
||
| 237 | 'path' => $upcontext['chmod']['path'], |
||
| 238 | 'root' => $ftp_root, |
||
| 239 | ); |
||
| 240 | |||
| 241 | foreach ($files as $k => $file) |
||
| 242 | { |
||
| 243 | if (!is_writable($file)) |
||
| 244 | $ftp->chmod($file, 0755); |
||
| 245 | if (!is_writable($file)) |
||
| 246 | $ftp->chmod($file, 0777); |
||
| 247 | |||
| 248 | // Assuming that didn't work calculate the path without the boarddir. |
||
| 249 | if (!is_writable($file)) |
||
| 250 | { |
||
| 251 | if (strpos($file, $boarddir) === 0) |
||
| 252 | { |
||
| 253 | $ftp_file = strtr($file, array($_SESSION['installer_temp_ftp']['root'] => '')); |
||
| 254 | $ftp->chmod($ftp_file, 0755); |
||
| 255 | if (!is_writable($file)) |
||
| 256 | $ftp->chmod($ftp_file, 0777); |
||
| 257 | // Sometimes an extra slash can help... |
||
| 258 | $ftp_file = '/' . $ftp_file; |
||
| 259 | if (!is_writable($file)) |
||
| 260 | $ftp->chmod($ftp_file, 0755); |
||
| 261 | if (!is_writable($file)) |
||
| 262 | $ftp->chmod($ftp_file, 0777); |
||
| 263 | } |
||
| 264 | } |
||
| 265 | |||
| 266 | if (is_writable($file)) |
||
| 267 | unset($files[$k]); |
||
| 268 | } |
||
| 269 | |||
| 270 | $ftp->close(); |
||
| 271 | } |
||
| 272 | } |
||
| 273 | |||
| 274 | // What remains? |
||
| 275 | $upcontext['chmod']['files'] = $files; |
||
| 276 | |||
| 277 | if (empty($files)) |
||
| 278 | return true; |
||
| 279 | |||
| 280 | return false; |
||
| 281 | } |
||
| 282 | |||
| 283 | /** |
||
| 284 | * The quick version of makeFilesWritable, which does not support FTP. |
||
| 285 | * |
||
| 286 | * @param string $file |
||
| 287 | * @return bool |
||
| 288 | */ |
||
| 289 | function quickFileWritable($file) |
||
| 290 | { |
||
| 291 | if (is_writable($file)) |
||
| 292 | return true; |
||
| 293 | |||
| 294 | @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...
|
|||
| 295 | |||
| 296 | // Try 755 and 775 first since 777 doesn't always work and could be a risk... |
||
| 297 | $chmod_values = array(0755, 0775, 0777); |
||
| 298 | |||
| 299 | foreach ($chmod_values as $val) |
||
| 300 | { |
||
| 301 | // If it's writable, break out of the loop |
||
| 302 | if (is_writable($file)) |
||
| 303 | break; |
||
| 304 | else |
||
| 305 | @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...
|
|||
| 306 | } |
||
| 307 | |||
| 308 | return is_writable($file); |
||
| 309 | } |
||
| 310 | |||
| 311 | /** |
||
| 312 | * UTF-8 aware strtolower function. |
||
| 313 | * |
||
| 314 | * @param $string |
||
| 315 | * @return string |
||
| 316 | */ |
||
| 317 | function smf_strtolower($string) |
||
| 318 | { |
||
| 319 | return mb_strtolower($string, 'UTF-8'); |
||
| 320 | } |
||
| 321 | |||
| 322 | /** |
||
| 323 | * Prints an error to stderr. |
||
| 324 | * |
||
| 325 | * @param $message |
||
| 326 | * @param bool $fatal |
||
| 327 | */ |
||
| 328 | function print_error($message, $fatal = false) |
||
| 329 | { |
||
| 330 | static $fp = null; |
||
| 331 | |||
| 332 | if ($fp === null) |
||
| 333 | $fp = fopen('php://stderr', 'wb'); |
||
| 334 | |||
| 335 | fwrite($fp, $message . "\n"); |
||
| 336 | |||
| 337 | if ($fatal) |
||
| 338 | exit; |
||
| 339 | } |
||
| 340 | |||
| 341 | /** |
||
| 342 | * Throws a graphical error message. |
||
| 343 | * |
||
| 344 | * @param $message |
||
| 345 | * @return bool |
||
| 346 | */ |
||
| 347 | function throw_error($message) |
||
| 348 | { |
||
| 349 | global $upcontext; |
||
| 350 | |||
| 351 | $upcontext['error_msg'] = $message; |
||
| 352 | $upcontext['sub_template'] = 'error_message'; |
||
| 353 | |||
| 354 | return false; |
||
| 355 | } |
||
| 356 | |||
| 357 | /** |
||
| 358 | * Database functions below here. |
||
| 359 | */ |
||
| 360 | /** |
||
| 361 | * @param $rs |
||
| 362 | * @return array|null |
||
| 363 | */ |
||
| 364 | function smf_mysql_fetch_assoc($rs) |
||
| 365 | { |
||
| 366 | return mysqli_fetch_assoc($rs); |
||
| 367 | } |
||
| 368 | |||
| 369 | /** |
||
| 370 | * @param $rs |
||
| 371 | * @return array|null |
||
| 372 | */ |
||
| 373 | function smf_mysql_fetch_row($rs) |
||
| 374 | { |
||
| 375 | return mysqli_fetch_row($rs); |
||
| 376 | } |
||
| 377 | |||
| 378 | /** |
||
| 379 | * @param $rs |
||
| 380 | */ |
||
| 381 | function smf_mysql_free_result($rs) |
||
| 382 | { |
||
| 383 | mysqli_free_result($rs); |
||
| 384 | } |
||
| 385 | |||
| 386 | /** |
||
| 387 | * @param $rs |
||
| 388 | * @return int|string |
||
| 389 | */ |
||
| 390 | function smf_mysql_insert_id($rs) |
||
| 391 | { |
||
| 392 | return mysqli_insert_id($rs); |
||
| 393 | } |
||
| 394 | |||
| 395 | /** |
||
| 396 | * @param $rs |
||
| 397 | * @return int |
||
| 398 | */ |
||
| 399 | function smf_mysql_num_rows($rs) |
||
| 400 | { |
||
| 401 | return mysqli_num_rows($rs); |
||
| 402 | } |
||
| 403 | |||
| 404 | /** |
||
| 405 | * @param $string |
||
| 406 | */ |
||
| 407 | function smf_mysql_real_escape_string($string) |
||
| 408 | { |
||
| 409 | global $db_connection; |
||
| 410 | mysqli_real_escape_string($db_connection, $string); |
||
| 411 | } |
If you suppress an error, we recommend checking for the error condition explicitly: