Completed
Branch development (176841)
by Elk
06:59
created

File::_cleanSettings()   C

Complexity

Conditions 11
Paths 108

Size

Total Lines 93

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 11

Importance

Changes 0
Metric Value
cc 11
nc 108
nop 0
dl 0
loc 93
ccs 23
cts 23
cp 1
crap 11
rs 5.9527
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This class handles display, edit, save, of forum settings.
5
 *
6
 * @package   ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
9
 *
10
 * This file contains code covered by:
11
 * copyright:    2011 Simple Machines (http://www.simplemachines.org)
12
 *
13
 * @version 2.0 dev
14
 *
15
 */
16
17
namespace ElkArte\SettingsForm\SettingsFormAdapter;
18
19
/**
20
 * Class File
21
 *
22
 * @package ElkArte\SettingsForm\SettingsFormAdapter
23
 */
24
class File extends Db
25
{
26
	/**
27
	 * @var int
28
	 */
29
	private $last_settings_change;
30
31
	/**
32
	 * @var array
33
	 */
34
	private $settingsArray = array();
35
36
	/**
37
	 * @var array
38
	 */
39
	private $new_settings = array();
40
41
	/**
42
	 * Helper method, it sets up the context for the settings which will be saved
43
	 * to the settings.php file
44
	 *
45
	 * What it does:
46
	 *
47
	 * - The basic usage of the six numbered key fields are
48
	 * - array(0 ,1, 2, 3, 4, 5
49
	 *    0 variable name - the name of the saved variable
50
	 *    1 label - the text to show on the settings page
51
	 *    2 saveto - file or db, where to save the variable name - value pair
52
	 *    3 type - type of data to display int, float, text, check, select, password
53
	 *    4 size - false or field size, if type is select, this needs to be an array of
54
	 *                select options
55
	 *    5 help - '' or helptxt variable name
56
	 *  )
57
	 * - The following named keys are also permitted
58
	 *    'disabled' =>
59
	 *    'postinput' =>
60
	 *    'preinput' =>
61
	 *    'subtext' =>
62
	 */
63 4
	public function prepare()
64
	{
65 4
		global $modSettings;
66
67
		$defines = array(
68 4
			'boarddir',
69
			'sourcedir',
70
			'cachedir',
71
		);
72
73
		$safe_strings = array(
74 4
			'mtitle',
75
			'mmessage',
76
			'mbname',
77
		);
78
79 4
		foreach ($this->configVars as $identifier => $configVar)
80
		{
81 4
			$new_setting = $configVar;
82
83 4
			if (is_array($configVar) && isset($configVar[1]))
84
			{
85 4
				$varname = $configVar[0];
86 4
				global ${$varname};
87
88
				// Rewrite the definition a bit.
89 4
				$new_setting[0] = $configVar[3];
90 4
				$new_setting[1] = $configVar[0];
91 4
				$new_setting['text_label'] = $configVar[1];
92
93 4
				if (isset($configVar[4]))
94
				{
95 4
					$new_setting[2] = $configVar[4];
96
				}
97
98 4
				if (isset($configVar[5]))
99
				{
100 4
					$new_setting['helptext'] = $configVar[5];
101
				}
102
103
				// Special value needed from the settings file?
104 4
				if ($configVar[2] === 'file')
105
				{
106 4
					$value = in_array($varname, $defines) ? constant(strtoupper($varname)) : $$varname;
0 ignored issues
show
Security Other Vulnerability introduced by
$varname can contain request data and is used in security-relevant context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and (array) $_POST is passed to SettingsForm::setConfigValues() in sources/ElkArte/AdminController/AdminLog.php on line 167
  1. Read from $_POST, and (array) $_POST is passed to SettingsForm::setConfigValues()
    in sources/ElkArte/AdminController/AdminLog.php on line 167
  2. $configValues is passed to Adapter::setConfigValues()
    in sources/ElkArte/SettingsForm/SettingsForm.php on line 108
  3. Adapter::$configValues is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/Adapter.php on line 74
  4. Tainted property Adapter::$configValues is read, and $this->configValues[$configVar][0] is passed through addcslashes(), and File::$new_settings is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 291
  5. Tainted property File::$new_settings is read, and $this->new_settings is passed to Adapter::setConfigVars()
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 118
  6. Adapter::$configVars is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/Adapter.php on line 58
  7. Tainted property Adapter::$configVars is read, and $configVar is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 79
  8. $varname is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 85
  2. Path: Read from $_POST, and $configValues is assigned in sources/ElkArte/EmailSettings.php on line 45
  1. Read from $_POST, and $configValues is assigned
    in sources/ElkArte/EmailSettings.php on line 45
  2. $configValues is passed to SettingsForm::setConfigValues()
    in sources/ElkArte/EmailSettings.php on line 60
  3. $configValues is passed to Adapter::setConfigValues()
    in sources/ElkArte/SettingsForm/SettingsForm.php on line 108
  4. Adapter::$configValues is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/Adapter.php on line 74
  5. Tainted property Adapter::$configValues is read, and $this->configValues[$configVar][0] is passed through addcslashes(), and File::$new_settings is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 291
  6. Tainted property File::$new_settings is read, and $this->new_settings is passed to Adapter::setConfigVars()
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 118
  7. Adapter::$configVars is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/Adapter.php on line 58
  8. Tainted property Adapter::$configVars is read, and $configVar is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 79
  9. $varname is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 85

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
107
108 4
					if (in_array($varname, $safe_strings))
109
					{
110 4
						$new_setting['mask'] = 'nohtml';
111 4
						$value = strtr($value, array(\ElkArte\Util::htmlspecialchars('<br />') => "\n"));
112
					}
113 4
					$modSettings[$configVar[0]] = $value;
114
				}
115
			}
116 4
			$this->new_settings[] = $new_setting;
117
		}
118 4
		$this->setConfigVars($this->new_settings);
119 4
		parent::prepare();
120 4
	}
121
122
	/**
123
	 * Update the Settings.php file.
124
	 *
125
	 * Typically this method is used from admin screens, just like this entire class.
126
	 * They're also available for addons and integrations.
127
	 *
128
	 * What it does:
129
	 *
130
	 * - updates the Settings.php file with the changes supplied in new_settings.
131
	 * - expects new_settings to be an associative array, with the keys as the
132
	 *   variable names in Settings.php, and the values the variable values.
133
	 * - does not escape or quote values.
134
	 * - preserves case, formatting, and additional options in file.
135
	 * - writes nothing if the resulting file would be less than 10 lines
136
	 *   in length (sanity check for read lock.)
137
	 * - check for changes to db_last_error and passes those off to a separate handler
138
	 * - attempts to create a backup file and will use it should the writing of the
139
	 *   new settings file fail
140
	 */
141 2
	public function save()
142
	{
143 2
		$this->_cleanSettings();
144
145
		// When was Settings.php last changed?
146 2
		$this->last_settings_change = filemtime(BOARDDIR . '/Settings.php');
147
148
		// Load the settings file.
149 2
		$settingsFile = trim(file_get_contents(BOARDDIR . '/Settings.php'));
150
151
		// Break it up based on \r or \n, and then clean out extra characters.
152 2
		if (strpos($settingsFile, "\n") !== false)
153
		{
154 2
			$this->settingsArray = explode("\n", $settingsFile);
155
		}
156
		elseif (strpos($settingsFile, "\r") !== false)
157
		{
158
			$this->settingsArray = explode("\r", $settingsFile);
159
		}
160
		else
161
		{
162
			return;
163
		}
164
165 2
		$this->_prepareSettings();
166 2
		$this->_updateSettingsFile();
167 2
		$this->_extractDbVars();
168 2
	}
169
170
	/**
171
	 * Find and save the new database-based settings, if any
172
	 */
173 2
	private function _extractDbVars()
174
	{
175
		// Now loop through the remaining (database-based) settings.
176 2
		$this->configVars = array_map(
177
			function ($configVar)
178
			{
179
				// We just saved the file-based settings, so skip their definitions.
180 2
				if (!is_array($configVar) || $configVar[2] === 'file')
181
				{
182 2
					return '';
183
				}
184
185
				// Rewrite the definition a bit.
186 2
				if (is_array($configVar) && $configVar[2] === 'db')
187
				{
188 2
					return array($configVar[3], $configVar[0]);
189
				}
190
				else
191
				{
192
					// This is a regular config var requiring no special treatment.
193
					return $configVar;
194
				}
195 2
			}, $this->configVars
196
		);
197
198
		// Save the new database-based settings, if any.
199 2
		parent::save();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (save() instead of _extractDbVars()). Are you sure this is correct? If so, you might want to change this to $this->save().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
200 2
	}
201
202
	/**
203
	 * Fix the cookie name by removing invalid characters
204
	 */
205 2
	private function _fixCookieName()
206
	{
207
		// Fix the darn stupid cookiename! (more may not be allowed, but these for sure!)
208 2
		if (isset($this->configValues['cookiename']))
209
		{
210
			$this->configValues['cookiename'] = preg_replace('~[,;\s\.$]+~u', '', $this->configValues['cookiename']);
211
		}
212 2
	}
213
214
	/**
215
	 * Fix the forum's URL if necessary so that it is a valid root url
216
	 */
217 2
	private function _fixBoardUrl()
218
	{
219 2
		if (isset($this->configValues['boardurl']))
220
		{
221
			if (substr($this->configValues['boardurl'], -10) === '/index.php')
222
			{
223
				$this->configValues['boardurl'] = substr($this->configValues['boardurl'], 0, -10);
224
			}
225
			elseif (substr($this->configValues['boardurl'], -1) === '/')
226
			{
227
				$this->configValues['boardurl'] = substr($this->configValues['boardurl'], 0, -1);
228
			}
229
230
			$this->configValues['boardurl'] = addProtocol($this->configValues['boardurl'], array('http://', 'https://', 'file://'));
231
		}
232 2
	}
233
234
	/**
235
	 * For all known configuration values, ensures they are properly cast / escaped
236
	 */
237 2
	private function _cleanSettings()
238
	{
239 2
		$this->_fixCookieName();
240 2
		$this->_fixBoardUrl();
241
242
		// Any passwords?
243
		$config_passwords = array(
244 2
			'db_passwd',
245
			'ssi_db_passwd',
246
		);
247
248
		// All the strings to write.
249
		$config_strs = array(
250 2
			'mtitle',
251
			'mmessage',
252
			'language',
253
			'mbname',
254
			'boardurl',
255
			'cookiename',
256
			'webmaster_email',
257
			'db_name',
258
			'db_user',
259
			'db_server',
260
			'db_prefix',
261
			'ssi_db_user',
262
			'cache_accelerator',
263
			'cache_memcached',
264
			'url_format',
265
		);
266
267
		// These need HTML encoded. Be sure they all exist in $config_strs!
268
		$safe_strings = array(
269 2
			'mtitle',
270
			'mmessage',
271
			'mbname',
272
		);
273
274
		// All the numeric variables.
275
		$config_ints = array(
276 2
			'cache_enable',
277
		);
278
279
		// All the checkboxes.
280
		$config_bools = array(
281 2
			'db_persist',
282
			'db_error_send',
283
			'maintenance',
284
		);
285
286
		// Now sort everything into a big array, and figure out arrays and etc.
287 2
		foreach ($config_passwords as $configVar)
288
		{
289 2
			if (isset($this->configValues[$configVar][1]) && $this->configValues[$configVar][0] == $this->configValues[$configVar][1])
290
			{
291 1
				$this->new_settings[$configVar] = '\'' . addcslashes($this->configValues[$configVar][0], '\'\\') . '\'';
292
			}
293
		}
294
295
		// Escape and update Setting strings
296 2
		foreach ($config_strs as $configVar)
297
		{
298 2
			if (isset($this->configValues[$configVar]))
299
			{
300 2
				if (in_array($configVar, $safe_strings))
301
				{
302 2
					$this->new_settings[$configVar] = '\'' . addcslashes(\ElkArte\Util::htmlspecialchars(strtr($this->configValues[$configVar], array("\n" => '<br />', "\r" => '')), ENT_QUOTES), '\'\\') . '\'';
303
				}
304
				else
305
				{
306 1
					$this->new_settings[$configVar] = '\'' . addcslashes($this->configValues[$configVar], '\'\\') . '\'';
307
				}
308
			}
309
		}
310
311
		// Ints are saved as integers
312 2
		foreach ($config_ints as $configVar)
313
		{
314 2
			if (isset($this->configValues[$configVar]))
315
			{
316 1
				$this->new_settings[$configVar] = (int) $this->configValues[$configVar];
317
			}
318
		}
319
320
		// Convert checkbox selections to 0 / 1
321 2
		foreach ($config_bools as $key)
322
		{
323
			// Check boxes need to be part of this settings form
324 2
			if ($this->_array_value_exists__recursive($key, $this->getConfigVars()))
325
			{
326 1
				$this->new_settings[$key] = (int) !empty($this->configValues[$key]);
327
			}
328
		}
329 2
	}
330
331
	/**
332
	 * Recursively checks if a value exists in an array
333
	 *
334
	 * @param string  $needle
335
	 * @param mixed[] $haystack
336
	 *
337
	 * @return boolean
338
	 */
339 2
	private function _array_value_exists__recursive($needle, $haystack)
340
	{
341 2
		foreach ($haystack as $item)
342
		{
343 2
			if ($item == $needle || (is_array($item) && $this->_array_value_exists__recursive($needle, $item)))
344
			{
345 1
				return true;
346
			}
347
		}
348
349 2
		return false;
350
	}
351
352
	/**
353
	 * Updates / Validates the Settings array for later output.
354
	 *
355
	 * - Updates any values that have been changed.
356
	 * - Key/value pairs that did not exists are added at the end of the array.
357
	 * - Ensures the completed array is valid for later output
358
	 */
359 2
	private function _prepareSettings()
360
	{
361
		// Presumably, the file has to have stuff in it for this function to be called :P.
362 2
		if (count($this->settingsArray) < 10)
363
		{
364
			return;
365
		}
366
367
		// remove any /r's that made there way in here
368 2
		foreach ($this->settingsArray as $k => $dummy)
369
		{
370 2
			$this->settingsArray[$k] = strtr($dummy, array("\r" => '')) . "\n";
371
		}
372
373
		// go line by line and see whats changing
374 2
		for ($i = 0, $n = count($this->settingsArray); $i < $n; $i++)
375
		{
376
			// Don't trim or bother with it if it's not a variable.
377 2
			if (substr($this->settingsArray[$i], 0, 1) !== '$')
378
			{
379 2
				continue;
380
			}
381
382 2
			$this->settingsArray[$i] = trim($this->settingsArray[$i]) . "\n";
383
384
			// Look through the variables to set....
385 2
			foreach ($this->new_settings as $var => $val)
386
			{
387 2
				if (strncasecmp($this->settingsArray[$i], '$' . $var, 1 + strlen($var)) == 0)
388
				{
389 2
					$comment = strstr(substr(un_htmlspecialchars($this->settingsArray[$i]), strpos(un_htmlspecialchars($this->settingsArray[$i]), ';')), '#');
390 2
					$this->settingsArray[$i] = '$' . $var . ' = ' . $val . ';' . ($comment == '' ? '' : "\t\t" . rtrim($comment)) . "\n";
391
392
					// This one's been 'used', so to speak.
393 2
					unset($this->new_settings[$var]);
394
				}
395
			}
396
397
			// End of the file ... maybe
398 2
			if (substr(trim($this->settingsArray[$i]), 0, 2) === '?' . '>')
399
			{
400
				$end = $i;
401
			}
402
		}
403
404
		// This should never happen, but apparently it is happening.
405 2
		if (empty($end) || $end < 10)
406
		{
407 2
			$end = count($this->settingsArray) - 1;
408
		}
409
410
		// Still more variables to go?  Then lets add them at the end.
411 2
		if (!empty($this->new_settings))
412
		{
413
			if (trim($this->settingsArray[$end]) === '?' . '>')
414
			{
415
				$this->settingsArray[$end++] = '';
416
			}
417
			else
418
			{
419
				$end++;
420
			}
421
422
			// Add in any newly defined vars that were passed
423
			foreach ($this->new_settings as $var => $val)
424
			{
425
				$this->settingsArray[$end++] = '$' . $var . ' = ' . $val . ';' . "\n";
426
			}
427
		}
428
		else
429
		{
430 2
			$this->settingsArray[$end] = trim($this->settingsArray[$end]);
431
		}
432 2
	}
433
434
	/**
435
	 * Write out the contents of Settings.php file.
436
	 *
437
	 * This function will add the variables passed to it in $this->new_settings,
438
	 * to the Settings.php file.
439
	 */
440 2
	private function _updateSettingsFile()
441
	{
442 2
		global $context;
443
444
		// Sanity error checking: the file needs to be at least 12 lines.
445 2
		if (count($this->settingsArray) < 12)
446
		{
447
			return;
448
		}
449
450
		// Try to avoid a few pitfalls:
451
		//  - like a possible race condition,
452
		//  - or a failure to write at low diskspace
453
		//
454
		// Check before you act: if cache is enabled, we can do a simple write test
455
		// to validate that we even write things on this filesystem.
456 2
		if ((!defined('CACHEDIR') || !file_exists(CACHEDIR)) && file_exists(BOARDDIR . '/cache'))
457
		{
458
			$tmp_cache = BOARDDIR . '/cache';
459
		}
460
		else
461
		{
462 2
			$tmp_cache = CACHEDIR;
463
		}
464
465 2
		$test_fp = @fopen($tmp_cache . '/settings_update.tmp', 'w+');
466 2
		if ($test_fp)
467
		{
468 2
			fclose($test_fp);
469 2
			$written_bytes = file_put_contents($tmp_cache . '/settings_update.tmp', 'test', LOCK_EX);
470 2
			@unlink($tmp_cache . '/settings_update.tmp');
0 ignored issues
show
Security Best Practice introduced by
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...
471
472 2
			if ($written_bytes !== 4)
473
			{
474
				// Oops. Low disk space, perhaps. Don't mess with Settings.php then.
475
				// No means no. :P
476
				return;
477
			}
478
		}
479
480
		// Protect me from what I want! :P
481 2
		clearstatcache();
482 2
		if (filemtime(BOARDDIR . '/Settings.php') === $this->last_settings_change)
483
		{
484
			// Save the old before we do anything
485 2
			$settings_backup_fail = !@is_writable(BOARDDIR . '/Settings_bak.php') || !@copy(BOARDDIR . '/Settings.php', BOARDDIR . '/Settings_bak.php');
486 2
			$settings_backup_fail = !$settings_backup_fail ? (!file_exists(BOARDDIR . '/Settings_bak.php') || filesize(BOARDDIR . '/Settings_bak.php') === 0) : $settings_backup_fail;
487
488
			// Write out the new
489 2
			$write_settings = implode('', $this->settingsArray);
490 2
			$written_bytes = file_put_contents(BOARDDIR . '/Settings.php', $write_settings, LOCK_EX);
0 ignored issues
show
Security File Manipulation introduced by
$write_settings can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

2 paths for user data to reach this point

  1. Path: Read from $_POST, and (array) $_POST is passed to SettingsForm::setConfigValues() in sources/ElkArte/AdminController/AdminLog.php on line 167
  1. Read from $_POST, and (array) $_POST is passed to SettingsForm::setConfigValues()
    in sources/ElkArte/AdminController/AdminLog.php on line 167
  2. $configValues is passed to Adapter::setConfigValues()
    in sources/ElkArte/SettingsForm/SettingsForm.php on line 108
  3. Adapter::$configValues is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/Adapter.php on line 74
  4. Tainted property Adapter::$configValues is read, and $this->configValues[$configVar][0] is passed through addcslashes(), and File::$new_settings is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 291
  5. Tainted property File::$new_settings is read, and $var is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 385
  6. File::$settingsArray is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 390
  7. Tainted property File::$settingsArray is read, and $this->settingsArray is passed through implode(), and $write_settings is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 489
  2. Path: Read from $_POST, and $configValues is assigned in sources/ElkArte/EmailSettings.php on line 45
  1. Read from $_POST, and $configValues is assigned
    in sources/ElkArte/EmailSettings.php on line 45
  2. $configValues is passed to SettingsForm::setConfigValues()
    in sources/ElkArte/EmailSettings.php on line 60
  3. $configValues is passed to Adapter::setConfigValues()
    in sources/ElkArte/SettingsForm/SettingsForm.php on line 108
  4. Adapter::$configValues is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/Adapter.php on line 74
  5. Tainted property Adapter::$configValues is read, and $this->configValues[$configVar][0] is passed through addcslashes(), and File::$new_settings is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 291
  6. Tainted property File::$new_settings is read, and $var is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 385
  7. File::$settingsArray is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 390
  8. Tainted property File::$settingsArray is read, and $this->settingsArray is passed through implode(), and $write_settings is assigned
    in sources/ElkArte/SettingsForm/SettingsFormAdapter/File.php on line 489

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
491
492
			// Survey says ...
493 2
			if ($written_bytes !== strlen($write_settings) && !$settings_backup_fail)
494
			{
495
				// Well this is not good at all, lets see if we can save this
496
				$context['settings_message'] = 'settings_error';
497
498
				if (file_exists(BOARDDIR . '/Settings_bak.php'))
499
				{
500
					@copy(BOARDDIR . '/Settings_bak.php', BOARDDIR . '/Settings.php');
0 ignored issues
show
Security Best Practice introduced by
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...
501
				}
502
			}
503
504 2
			if (extension_loaded('Zend OPcache') && ini_get('opcache.enable') && stripos(BOARDDIR, ini_get('opcache.restrict_api')) !== 0)
505
			{
506
				opcache_invalidate(BOARDDIR . '/Settings.php');
507
			}
508
		}
509 2
	}
510
}
511