/
PhpIniUtils.php
271 lines (240 loc) · 8.43 KB
/
PhpIniUtils.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
<?php
/**
***********************************************************************************************
* Class manages PHP-Ini stuff
*
* @copyright 2004-2018 The Admidio Team
* @see https://www.admidio.org/
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2.0 only
***********************************************************************************************
*/
final class PhpIniUtils
{
const BYTES_UNIT_FACTOR_1024 = 1024;
const BYTES_UNIT_FACTOR_1000 = 1000;
/**
* @var array<int,string> The disabled function names
*/
private static $disabledFunctions;
/**
* Returns the disabled function names
* @return array<int,string> Returns the disabled function names
* @see https://secure.php.net/manual/en/ini.core.php#ini.disable-functions
*/
public static function getDisabledFunctions()
{
if (self::$disabledFunctions === null)
{
self::$disabledFunctions = explode(',', ini_get('disable_functions'));
}
return self::$disabledFunctions;
}
/**
* Checks if the size limits have valid values because they depend on each other
* @return bool
*/
public static function checkSizeLimits()
{
return (is_infinite(self::getMemoryLimit()) || self::getMemoryLimit() >= self::getPostMaxSize())
&& (is_infinite(self::getPostMaxSize()) || self::getPostMaxSize() >= self::getFileUploadMaxFileSize());
}
/**
* Returns the calculated bytes of a string or INF if unlimited.
* @param string $data Could be empty string (not set), "-1" (no limit) or a float with a unit.
* Units could be K for Kilobyte, M for Megabyte, G for Gigabyte or T for Terabyte.
* @param int $multi Factor to multiply. Default: 1024
* @return int Returns the bytes of the data string.
*/
private static function getBytesFromSize($data, $multi = self::BYTES_UNIT_FACTOR_1024)
{
if ($data === '' || $data === '-1')
{
return INF;
}
$value = (float) substr($data, 0, -1);
$unit = strtoupper(substr($data, -1));
switch ($unit)
{
case 'T':
$value *= $multi;
case 'G':
$value *= $multi;
case 'M':
$value *= $multi;
case 'K':
$value *= $multi;
}
return (int) $value;
}
/**
* Returns the allowed base-dirs
* @return array<string,string>
* @see https://secure.php.net/manual/en/ini.core.php#ini.open-basedir
*/
public static function getBaseDirs()
{
return explode(PATH_SEPARATOR, ini_get('open_basedir'));
}
/**
* Returns the memory limit
* @return int
* @see https://secure.php.net/manual/en/ini.core.php#ini.memory-limit
*/
public static function getMemoryLimit()
{
return self::getBytesFromSize(ini_get('memory_limit'));
}
/**
* Returns the maximum post size
* @return int
* @see https://secure.php.net/manual/en/ini.core.php#ini.post-max-size
*/
public static function getPostMaxSize()
{
return self::getBytesFromSize(ini_get('post_max_size'));
}
/**
* Returns the file upload temporary directory
* @return string
* @see https://secure.php.net/manual/en/ini.core.php#ini.upload-tmp-dir
*/
public static function getFileUploadTmpDir()
{
return ini_get('upload_tmp_dir');
}
/**
* Returns the maximum upload filesize
* @return int
* @see https://secure.php.net/manual/en/ini.core.php#ini.upload-max-filesize
*/
public static function getFileUploadMaxFileSize()
{
return self::getBytesFromSize(ini_get('upload_max_filesize'));
}
/**
* Returns the maximum file upload count
* @return int
* @see https://secure.php.net/manual/en/ini.core.php#ini.max-file-uploads
*/
public static function getFileUploadMaxFileCount()
{
return (int) ini_get('max_file_uploads');
}
/**
* Returns the maximum upload size out of memory-limit, max-post-size and max-file-size
* @return int
*/
public static function getUploadMaxSize()
{
return min(self::getMemoryLimit(), self::getPostMaxSize(), self::getFileUploadMaxFileSize());
}
/**
* Returns if file-upload is enabled
* @return bool
* @see https://secure.php.net/manual/en/ini.core.php#ini.file-uploads
*/
public static function isFileUploadEnabled()
{
return (bool) ini_get('file_uploads');
}
/**
* Returns if safe-mode is enabled
* @deprecated 3.3.0:4.0.0 This function will be removed if PHP 5.3 support gets dropped
* @return bool
* @see https://secure.php.net/manual/en/features.safe-mode.php
*/
public static function isSafeModeEnabled()
{
return (bool) ini_get('safe_mode');
}
/**
* Checks if a given directory path is in the allowed base-directories
* @param string $directoryPath The directory path to check
* @return bool
*/
private static function isInBaseDirs($directoryPath)
{
$baseDirs = self::getBaseDirs();
if ($baseDirs[0] === '')
{
return true;
}
foreach ($baseDirs as $baseDir)
{
if (strpos($directoryPath, $baseDir) === 0)
{
return true;
}
}
return false;
}
/**
* Checks if a given directory path exists and is in the base-directories
* @param string $directoryPath The directory path to check
* @throws \UnexpectedValueException Throws if a given directory does not exist
* @throws \RuntimeException Throws if a given directory is not in the base-directories
*/
private static function checkIsValidDir(&$directoryPath)
{
$directoryPath = FileSystemUtils::getNormalizedPath($directoryPath);
if (!is_dir($directoryPath))
{
throw new \UnexpectedValueException('Directory "' . $directoryPath . '" does not exist!');
}
if (!self::isInBaseDirs($directoryPath))
{
throw new \RuntimeException('Directory "' . $directoryPath . '" is not in base-directories!');
}
}
/**
* Sets the allowed base-directories
* @param array<int,string> $directoryPaths The directory paths to set as allowed base-dirs
* @throws \UnexpectedValueException Throws if a given directory does not exist
* @throws \RuntimeException Throws if a given directory is not in the base-directories
* @return bool|string
* @see https://secure.php.net/manual/en/ini.core.php#ini.open-basedir
*/
public static function setBaseDirs(array $directoryPaths = array())
{
foreach ($directoryPaths as &$directoryPath)
{
self::checkIsValidDir($directoryPath);
}
unset($directoryPath);
return ini_set('open_basedir', implode(PATH_SEPARATOR, $directoryPaths));
}
/**
* Sets the file upload temporary directory
* @param string $directoryPath The directory path to set the file upload temporary directory
* @throws \UnexpectedValueException Throws if a given directory does not exist
* @throws \RuntimeException Throws if a given directory is not in the base-directories
* @return bool|string
* @see https://secure.php.net/manual/en/ini.core.php#ini.upload-tmp-dir
*/
public static function setUploadTmpDir($directoryPath)
{
self::checkIsValidDir($directoryPath);
return ini_set('upload_tmp_dir', $directoryPath);
}
/**
* Starts a new execution time limit
* @param int $seconds Execution time limit in seconds
* @throws \RuntimeException Throws if starting a new execution time limit failed
* @see https://secure.php.net/manual/en/function.set-time-limit.php
* @see https://secure.php.net/manual/en/info.configuration.php#ini.max-execution-time
*/
public static function startNewExecutionTimeLimit($seconds)
{
global $gDebug, $gLogger;
if (in_array('set_time_limit', self::getDisabledFunctions(), true))
{
return;
}
// @ prevents error output in safe-mode
$result = @set_time_limit($seconds);
if (!$result && $gDebug)
{
$gLogger->warning('Function set_time_limit failed');
}
}
}