This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Include most things that are needed to make %MediaWiki work. |
||
4 | * |
||
5 | * This file is included by WebStart.php and doMaintenance.php so that both |
||
6 | * web and maintenance scripts share a final set up phase to include necessary |
||
7 | * files and create global object variables. |
||
8 | * |
||
9 | * This program is free software; you can redistribute it and/or modify |
||
10 | * it under the terms of the GNU General Public License as published by |
||
11 | * the Free Software Foundation; either version 2 of the License, or |
||
12 | * (at your option) any later version. |
||
13 | * |
||
14 | * This program is distributed in the hope that it will be useful, |
||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
17 | * GNU General Public License for more details. |
||
18 | * |
||
19 | * You should have received a copy of the GNU General Public License along |
||
20 | * with this program; if not, write to the Free Software Foundation, Inc., |
||
21 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||
22 | * http://www.gnu.org/copyleft/gpl.html |
||
23 | * |
||
24 | * @file |
||
25 | */ |
||
26 | use MediaWiki\MediaWikiServices; |
||
27 | |||
28 | /** |
||
29 | * This file is not a valid entry point, perform no further processing unless |
||
30 | * MEDIAWIKI is defined |
||
31 | */ |
||
32 | if ( !defined( 'MEDIAWIKI' ) ) { |
||
33 | exit( 1 ); |
||
34 | } |
||
35 | |||
36 | $fname = 'Setup.php'; |
||
37 | $ps_setup = Profiler::instance()->scopedProfileIn( $fname ); |
||
38 | |||
39 | // If any extensions are still queued, force load them |
||
40 | ExtensionRegistry::getInstance()->loadFromQueue(); |
||
41 | |||
42 | // Check to see if we are at the file scope |
||
43 | if ( !isset( $wgVersion ) ) { |
||
44 | echo "Error, Setup.php must be included from the file scope, after DefaultSettings.php\n"; |
||
45 | die( 1 ); |
||
46 | } |
||
47 | |||
48 | mb_internal_encoding( 'UTF-8' ); |
||
49 | |||
50 | // Set various default paths sensibly... |
||
51 | $ps_default = Profiler::instance()->scopedProfileIn( $fname . '-defaults' ); |
||
52 | |||
53 | if ( $wgScript === false ) { |
||
54 | $wgScript = "$wgScriptPath/index.php"; |
||
55 | } |
||
56 | if ( $wgLoadScript === false ) { |
||
57 | $wgLoadScript = "$wgScriptPath/load.php"; |
||
58 | } |
||
59 | |||
60 | if ( $wgArticlePath === false ) { |
||
61 | if ( $wgUsePathInfo ) { |
||
62 | $wgArticlePath = "$wgScript/$1"; |
||
63 | } else { |
||
64 | $wgArticlePath = "$wgScript?title=$1"; |
||
65 | } |
||
66 | } |
||
67 | |||
68 | if ( !empty( $wgActionPaths ) && !isset( $wgActionPaths['view'] ) ) { |
||
69 | // 'view' is assumed the default action path everywhere in the code |
||
70 | // but is rarely filled in $wgActionPaths |
||
71 | $wgActionPaths['view'] = $wgArticlePath; |
||
72 | } |
||
73 | |||
74 | if ( $wgResourceBasePath === null ) { |
||
75 | $wgResourceBasePath = $wgScriptPath; |
||
76 | } |
||
77 | if ( $wgStylePath === false ) { |
||
78 | $wgStylePath = "$wgResourceBasePath/skins"; |
||
79 | } |
||
80 | if ( $wgLocalStylePath === false ) { |
||
81 | // Avoid wgResourceBasePath here since that may point to a different domain (e.g. CDN) |
||
82 | $wgLocalStylePath = "$wgScriptPath/skins"; |
||
83 | } |
||
84 | if ( $wgExtensionAssetsPath === false ) { |
||
85 | $wgExtensionAssetsPath = "$wgResourceBasePath/extensions"; |
||
86 | } |
||
87 | |||
88 | if ( $wgLogo === false ) { |
||
89 | $wgLogo = "$wgResourceBasePath/resources/assets/wiki.png"; |
||
90 | } |
||
91 | |||
92 | if ( $wgUploadPath === false ) { |
||
93 | $wgUploadPath = "$wgScriptPath/images"; |
||
94 | } |
||
95 | if ( $wgUploadDirectory === false ) { |
||
96 | $wgUploadDirectory = "$IP/images"; |
||
97 | } |
||
98 | if ( $wgReadOnlyFile === false ) { |
||
99 | $wgReadOnlyFile = "{$wgUploadDirectory}/lock_yBgMBwiR"; |
||
100 | } |
||
101 | if ( $wgFileCacheDirectory === false ) { |
||
102 | $wgFileCacheDirectory = "{$wgUploadDirectory}/cache"; |
||
103 | } |
||
104 | if ( $wgDeletedDirectory === false ) { |
||
105 | $wgDeletedDirectory = "{$wgUploadDirectory}/deleted"; |
||
106 | } |
||
107 | |||
108 | if ( $wgGitInfoCacheDirectory === false && $wgCacheDirectory !== false ) { |
||
109 | $wgGitInfoCacheDirectory = "{$wgCacheDirectory}/gitinfo"; |
||
110 | } |
||
111 | |||
112 | if ( $wgEnableParserCache === false ) { |
||
113 | $wgParserCacheType = CACHE_NONE; |
||
114 | } |
||
115 | |||
116 | // Fix path to icon images after they were moved in 1.24 |
||
117 | if ( $wgRightsIcon ) { |
||
118 | $wgRightsIcon = str_replace( |
||
119 | "{$wgStylePath}/common/images/", |
||
120 | "{$wgResourceBasePath}/resources/assets/licenses/", |
||
121 | $wgRightsIcon |
||
122 | ); |
||
123 | } |
||
124 | |||
125 | if ( isset( $wgFooterIcons['copyright']['copyright'] ) |
||
126 | && $wgFooterIcons['copyright']['copyright'] === [] |
||
127 | ) { |
||
128 | if ( $wgRightsIcon || $wgRightsText ) { |
||
129 | $wgFooterIcons['copyright']['copyright'] = [ |
||
130 | 'url' => $wgRightsUrl, |
||
131 | 'src' => $wgRightsIcon, |
||
132 | 'alt' => $wgRightsText, |
||
133 | ]; |
||
134 | } |
||
135 | } |
||
136 | |||
137 | if ( isset( $wgFooterIcons['poweredby'] ) |
||
138 | && isset( $wgFooterIcons['poweredby']['mediawiki'] ) |
||
139 | && $wgFooterIcons['poweredby']['mediawiki']['src'] === null |
||
140 | ) { |
||
141 | $wgFooterIcons['poweredby']['mediawiki']['src'] = |
||
142 | "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png"; |
||
143 | $wgFooterIcons['poweredby']['mediawiki']['srcset'] = |
||
144 | "$wgResourceBasePath/resources/assets/poweredby_mediawiki_132x47.png 1.5x, " . |
||
145 | "$wgResourceBasePath/resources/assets/poweredby_mediawiki_176x62.png 2x"; |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * Unconditional protection for NS_MEDIAWIKI since otherwise it's too easy for a |
||
150 | * sysadmin to set $wgNamespaceProtection incorrectly and leave the wiki insecure. |
||
151 | * |
||
152 | * Note that this is the definition of editinterface and it can be granted to |
||
153 | * all users if desired. |
||
154 | */ |
||
155 | $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; |
||
156 | |||
157 | /** |
||
158 | * The canonical names of namespaces 6 and 7 are, as of v1.14, "File" |
||
159 | * and "File_talk". The old names "Image" and "Image_talk" are |
||
160 | * retained as aliases for backwards compatibility. |
||
161 | */ |
||
162 | $wgNamespaceAliases['Image'] = NS_FILE; |
||
163 | $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; |
||
164 | |||
165 | /** |
||
166 | * Initialise $wgLockManagers to include basic FS version |
||
167 | */ |
||
168 | $wgLockManagers[] = [ |
||
169 | 'name' => 'fsLockManager', |
||
170 | 'class' => 'FSLockManager', |
||
171 | 'lockDirectory' => "{$wgUploadDirectory}/lockdir", |
||
172 | ]; |
||
173 | $wgLockManagers[] = [ |
||
174 | 'name' => 'nullLockManager', |
||
175 | 'class' => 'NullLockManager', |
||
176 | ]; |
||
177 | |||
178 | /** |
||
179 | * Initialise $wgLocalFileRepo from backwards-compatible settings |
||
180 | */ |
||
181 | if ( !$wgLocalFileRepo ) { |
||
182 | $wgLocalFileRepo = [ |
||
183 | 'class' => 'LocalRepo', |
||
184 | 'name' => 'local', |
||
185 | 'directory' => $wgUploadDirectory, |
||
186 | 'scriptDirUrl' => $wgScriptPath, |
||
187 | 'scriptExtension' => '.php', |
||
188 | 'url' => $wgUploadBaseUrl ? $wgUploadBaseUrl . $wgUploadPath : $wgUploadPath, |
||
189 | 'hashLevels' => $wgHashedUploadDirectory ? 2 : 0, |
||
190 | 'thumbScriptUrl' => $wgThumbnailScriptPath, |
||
191 | 'transformVia404' => !$wgGenerateThumbnailOnParse, |
||
192 | 'deletedDir' => $wgDeletedDirectory, |
||
193 | 'deletedHashLevels' => $wgHashedUploadDirectory ? 3 : 0 |
||
194 | ]; |
||
195 | } |
||
196 | /** |
||
197 | * Initialise shared repo from backwards-compatible settings |
||
198 | */ |
||
199 | if ( $wgUseSharedUploads ) { |
||
200 | if ( $wgSharedUploadDBname ) { |
||
201 | $wgForeignFileRepos[] = [ |
||
202 | 'class' => 'ForeignDBRepo', |
||
203 | 'name' => 'shared', |
||
204 | 'directory' => $wgSharedUploadDirectory, |
||
205 | 'url' => $wgSharedUploadPath, |
||
206 | 'hashLevels' => $wgHashedSharedUploadDirectory ? 2 : 0, |
||
207 | 'thumbScriptUrl' => $wgSharedThumbnailScriptPath, |
||
208 | 'transformVia404' => !$wgGenerateThumbnailOnParse, |
||
209 | 'dbType' => $wgDBtype, |
||
210 | 'dbServer' => $wgDBserver, |
||
211 | 'dbUser' => $wgDBuser, |
||
212 | 'dbPassword' => $wgDBpassword, |
||
213 | 'dbName' => $wgSharedUploadDBname, |
||
214 | 'dbFlags' => ( $wgDebugDumpSql ? DBO_DEBUG : 0 ) | DBO_DEFAULT, |
||
215 | 'tablePrefix' => $wgSharedUploadDBprefix, |
||
216 | 'hasSharedCache' => $wgCacheSharedUploads, |
||
217 | 'descBaseUrl' => $wgRepositoryBaseUrl, |
||
218 | 'fetchDescription' => $wgFetchCommonsDescriptions, |
||
219 | ]; |
||
220 | } else { |
||
221 | $wgForeignFileRepos[] = [ |
||
222 | 'class' => 'FileRepo', |
||
223 | 'name' => 'shared', |
||
224 | 'directory' => $wgSharedUploadDirectory, |
||
225 | 'url' => $wgSharedUploadPath, |
||
226 | 'hashLevels' => $wgHashedSharedUploadDirectory ? 2 : 0, |
||
227 | 'thumbScriptUrl' => $wgSharedThumbnailScriptPath, |
||
228 | 'transformVia404' => !$wgGenerateThumbnailOnParse, |
||
229 | 'descBaseUrl' => $wgRepositoryBaseUrl, |
||
230 | 'fetchDescription' => $wgFetchCommonsDescriptions, |
||
231 | ]; |
||
232 | } |
||
233 | } |
||
234 | if ( $wgUseInstantCommons ) { |
||
235 | $wgForeignFileRepos[] = [ |
||
236 | 'class' => 'ForeignAPIRepo', |
||
237 | 'name' => 'wikimediacommons', |
||
238 | 'apibase' => 'https://commons.wikimedia.org/w/api.php', |
||
239 | 'url' => 'https://upload.wikimedia.org/wikipedia/commons', |
||
240 | 'thumbUrl' => 'https://upload.wikimedia.org/wikipedia/commons/thumb', |
||
241 | 'hashLevels' => 2, |
||
242 | 'transformVia404' => true, |
||
243 | 'fetchDescription' => true, |
||
244 | 'descriptionCacheExpiry' => 43200, |
||
245 | 'apiThumbCacheExpiry' => 86400, |
||
246 | ]; |
||
247 | } |
||
248 | /* |
||
249 | * Add on default file backend config for file repos. |
||
250 | * FileBackendGroup will handle initializing the backends. |
||
251 | */ |
||
252 | if ( !isset( $wgLocalFileRepo['backend'] ) ) { |
||
253 | $wgLocalFileRepo['backend'] = $wgLocalFileRepo['name'] . '-backend'; |
||
254 | } |
||
255 | foreach ( $wgForeignFileRepos as &$repo ) { |
||
256 | if ( !isset( $repo['directory'] ) && $repo['class'] === 'ForeignAPIRepo' ) { |
||
257 | $repo['directory'] = $wgUploadDirectory; // b/c |
||
258 | } |
||
259 | if ( !isset( $repo['backend'] ) ) { |
||
260 | $repo['backend'] = $repo['name'] . '-backend'; |
||
261 | } |
||
262 | } |
||
263 | unset( $repo ); // no global pollution; destroy reference |
||
264 | |||
265 | $rcMaxAgeDays = $wgRCMaxAge / ( 3600 * 24 ); |
||
266 | if ( $wgRCFilterByAge ) { |
||
267 | // Trim down $wgRCLinkDays so that it only lists links which are valid |
||
268 | // as determined by $wgRCMaxAge. |
||
269 | // Note that we allow 1 link higher than the max for things like 56 days but a 60 day link. |
||
270 | sort( $wgRCLinkDays ); |
||
271 | |||
272 | // @codingStandardsIgnoreStart Generic.CodeAnalysis.ForLoopWithTestFunctionCall.NotAllowed |
||
273 | for ( $i = 0; $i < count( $wgRCLinkDays ); $i++ ) { |
||
274 | // @codingStandardsIgnoreEnd |
||
275 | if ( $wgRCLinkDays[$i] >= $rcMaxAgeDays ) { |
||
276 | $wgRCLinkDays = array_slice( $wgRCLinkDays, 0, $i + 1, false ); |
||
277 | break; |
||
278 | } |
||
279 | } |
||
280 | } |
||
281 | // Ensure that default user options are not invalid, since that breaks Special:Preferences |
||
282 | $wgDefaultUserOptions['rcdays'] = min( |
||
283 | $wgDefaultUserOptions['rcdays'], |
||
284 | ceil( $rcMaxAgeDays ) |
||
285 | ); |
||
286 | $wgDefaultUserOptions['watchlistdays'] = min( |
||
287 | $wgDefaultUserOptions['watchlistdays'], |
||
288 | ceil( $rcMaxAgeDays ) |
||
289 | ); |
||
290 | unset( $rcMaxAgeDays ); |
||
291 | |||
292 | if ( $wgSkipSkin ) { |
||
293 | $wgSkipSkins[] = $wgSkipSkin; |
||
294 | } |
||
295 | |||
296 | $wgSkipSkins[] = 'fallback'; |
||
297 | $wgSkipSkins[] = 'apioutput'; |
||
298 | |||
299 | if ( $wgLocalInterwiki ) { |
||
300 | array_unshift( $wgLocalInterwikis, $wgLocalInterwiki ); |
||
301 | } |
||
302 | |||
303 | // Set default shared prefix |
||
304 | if ( $wgSharedPrefix === false ) { |
||
305 | $wgSharedPrefix = $wgDBprefix; |
||
306 | } |
||
307 | |||
308 | // Set default shared schema |
||
309 | if ( $wgSharedSchema === false ) { |
||
310 | $wgSharedSchema = $wgDBmwschema; |
||
311 | } |
||
312 | |||
313 | if ( !$wgCookiePrefix ) { |
||
314 | if ( $wgSharedDB && $wgSharedPrefix && in_array( 'user', $wgSharedTables ) ) { |
||
315 | $wgCookiePrefix = $wgSharedDB . '_' . $wgSharedPrefix; |
||
316 | } elseif ( $wgSharedDB && in_array( 'user', $wgSharedTables ) ) { |
||
317 | $wgCookiePrefix = $wgSharedDB; |
||
318 | } elseif ( $wgDBprefix ) { |
||
319 | $wgCookiePrefix = $wgDBname . '_' . $wgDBprefix; |
||
320 | } else { |
||
321 | $wgCookiePrefix = $wgDBname; |
||
322 | } |
||
323 | } |
||
324 | $wgCookiePrefix = strtr( $wgCookiePrefix, '=,; +."\'\\[', '__________' ); |
||
325 | |||
326 | if ( $wgEnableEmail ) { |
||
327 | $wgUseEnotif = $wgEnotifUserTalk || $wgEnotifWatchlist; |
||
328 | } else { |
||
329 | // Disable all other email settings automatically if $wgEnableEmail |
||
330 | // is set to false. - bug 63678 |
||
331 | $wgAllowHTMLEmail = false; |
||
332 | $wgEmailAuthentication = false; // do not require auth if you're not sending email anyway |
||
333 | $wgEnableUserEmail = false; |
||
334 | $wgEnotifFromEditor = false; |
||
335 | $wgEnotifImpersonal = false; |
||
336 | $wgEnotifMaxRecips = 0; |
||
337 | $wgEnotifMinorEdits = false; |
||
338 | $wgEnotifRevealEditorAddress = false; |
||
339 | $wgEnotifUseRealName = false; |
||
340 | $wgEnotifUserTalk = false; |
||
341 | $wgEnotifWatchlist = false; |
||
342 | unset( $wgGroupPermissions['user']['sendemail'] ); |
||
343 | $wgUseEnotif = false; |
||
344 | $wgUserEmailUseReplyTo = false; |
||
345 | $wgUsersNotifiedOnAllChanges = []; |
||
346 | } |
||
347 | |||
348 | if ( $wgMetaNamespace === false ) { |
||
349 | $wgMetaNamespace = str_replace( ' ', '_', $wgSitename ); |
||
350 | } |
||
351 | |||
352 | // Default value is 2000 or the suhosin limit if it is between 1 and 2000 |
||
353 | if ( $wgResourceLoaderMaxQueryLength === false ) { |
||
354 | $suhosinMaxValueLength = (int)ini_get( 'suhosin.get.max_value_length' ); |
||
355 | if ( $suhosinMaxValueLength > 0 && $suhosinMaxValueLength < 2000 ) { |
||
356 | $wgResourceLoaderMaxQueryLength = $suhosinMaxValueLength; |
||
357 | } else { |
||
358 | $wgResourceLoaderMaxQueryLength = 2000; |
||
359 | } |
||
360 | unset( $suhosinMaxValueLength ); |
||
361 | } |
||
362 | |||
363 | // Ensure the minimum chunk size is less than PHP upload limits or the maximum |
||
364 | // upload size. |
||
365 | $wgMinUploadChunkSize = min( |
||
366 | $wgMinUploadChunkSize, |
||
367 | UploadBase::getMaxUploadSize( 'file' ), |
||
368 | UploadBase::getMaxPhpUploadSize(), |
||
369 | ( wfShorthandToInteger( |
||
370 | ini_get( 'post_max_size' ) ?: ini_get( 'hhvm.server.max_post_size' ), |
||
371 | PHP_INT_MAX |
||
372 | ) ?: PHP_INT_MAX ) - 1024 // Leave some room for other POST parameters |
||
373 | ); |
||
374 | |||
375 | /** |
||
376 | * Definitions of the NS_ constants are in Defines.php |
||
377 | * @private |
||
378 | */ |
||
379 | $wgCanonicalNamespaceNames = [ |
||
380 | NS_MEDIA => 'Media', |
||
381 | NS_SPECIAL => 'Special', |
||
382 | NS_TALK => 'Talk', |
||
383 | NS_USER => 'User', |
||
384 | NS_USER_TALK => 'User_talk', |
||
385 | NS_PROJECT => 'Project', |
||
386 | NS_PROJECT_TALK => 'Project_talk', |
||
387 | NS_FILE => 'File', |
||
388 | NS_FILE_TALK => 'File_talk', |
||
389 | NS_MEDIAWIKI => 'MediaWiki', |
||
390 | NS_MEDIAWIKI_TALK => 'MediaWiki_talk', |
||
391 | NS_TEMPLATE => 'Template', |
||
392 | NS_TEMPLATE_TALK => 'Template_talk', |
||
393 | NS_HELP => 'Help', |
||
394 | NS_HELP_TALK => 'Help_talk', |
||
395 | NS_CATEGORY => 'Category', |
||
396 | NS_CATEGORY_TALK => 'Category_talk', |
||
397 | ]; |
||
398 | |||
399 | /// @todo UGLY UGLY |
||
400 | if ( is_array( $wgExtraNamespaces ) ) { |
||
401 | $wgCanonicalNamespaceNames = $wgCanonicalNamespaceNames + $wgExtraNamespaces; |
||
402 | } |
||
403 | |||
404 | // These are now the same, always |
||
405 | // To determine the user language, use $wgLang->getCode() |
||
406 | $wgContLanguageCode = $wgLanguageCode; |
||
407 | |||
408 | // Easy to forget to falsify $wgDebugToolbar for static caches. |
||
409 | // If file cache or CDN cache is on, just disable this (DWIMD). |
||
410 | if ( $wgUseFileCache || $wgUseSquid ) { |
||
411 | $wgDebugToolbar = false; |
||
412 | } |
||
413 | |||
414 | // We always output HTML5 since 1.22, overriding these is no longer supported |
||
415 | // we set them here for extensions that depend on its value. |
||
416 | $wgHtml5 = true; |
||
417 | $wgXhtmlDefaultNamespace = 'http://www.w3.org/1999/xhtml'; |
||
418 | $wgJsMimeType = 'text/javascript'; |
||
419 | |||
420 | // Blacklisted file extensions shouldn't appear on the "allowed" list |
||
421 | $wgFileExtensions = array_values( array_diff( $wgFileExtensions, $wgFileBlacklist ) ); |
||
422 | |||
423 | if ( $wgInvalidateCacheOnLocalSettingsChange ) { |
||
424 | MediaWiki\suppressWarnings(); |
||
425 | $wgCacheEpoch = max( $wgCacheEpoch, gmdate( 'YmdHis', filemtime( "$IP/LocalSettings.php" ) ) ); |
||
426 | MediaWiki\restoreWarnings(); |
||
427 | } |
||
428 | |||
429 | if ( $wgNewUserLog ) { |
||
430 | // Add a new log type |
||
431 | $wgLogTypes[] = 'newusers'; |
||
432 | $wgLogNames['newusers'] = 'newuserlogpage'; |
||
433 | $wgLogHeaders['newusers'] = 'newuserlogpagetext'; |
||
434 | $wgLogActionsHandlers['newusers/newusers'] = 'NewUsersLogFormatter'; |
||
435 | $wgLogActionsHandlers['newusers/create'] = 'NewUsersLogFormatter'; |
||
436 | $wgLogActionsHandlers['newusers/create2'] = 'NewUsersLogFormatter'; |
||
437 | $wgLogActionsHandlers['newusers/byemail'] = 'NewUsersLogFormatter'; |
||
438 | $wgLogActionsHandlers['newusers/autocreate'] = 'NewUsersLogFormatter'; |
||
439 | } |
||
440 | |||
441 | if ( $wgPageLanguageUseDB ) { |
||
442 | $wgLogTypes[] = 'pagelang'; |
||
443 | $wgLogActionsHandlers['pagelang/pagelang'] = 'PageLangLogFormatter'; |
||
444 | } |
||
445 | |||
446 | if ( $wgCookieSecure === 'detect' ) { |
||
447 | $wgCookieSecure = ( WebRequest::detectProtocol() === 'https' ); |
||
448 | } |
||
449 | |||
450 | if ( $wgProfileOnly ) { |
||
451 | $wgDebugLogGroups['profileoutput'] = $wgDebugLogFile; |
||
452 | $wgDebugLogFile = ''; |
||
453 | } |
||
454 | |||
455 | // Backwards compatibility with old password limits |
||
456 | if ( $wgMinimalPasswordLength !== false ) { |
||
457 | $wgPasswordPolicy['policies']['default']['MinimalPasswordLength'] = $wgMinimalPasswordLength; |
||
458 | } |
||
459 | |||
460 | if ( $wgMaximalPasswordLength !== false ) { |
||
461 | $wgPasswordPolicy['policies']['default']['MaximalPasswordLength'] = $wgMaximalPasswordLength; |
||
462 | } |
||
463 | |||
464 | // Backwards compatibility warning |
||
465 | if ( !$wgSessionsInObjectCache && !$wgSessionsInMemcached ) { |
||
466 | wfDeprecated( '$wgSessionsInObjectCache = false', '1.27' ); |
||
467 | if ( $wgSessionHandler ) { |
||
468 | wfDeprecated( '$wgSessionsHandler', '1.27' ); |
||
469 | } |
||
470 | $cacheType = get_class( ObjectCache::getInstance( $wgSessionCacheType ) ); |
||
471 | wfDebugLog( |
||
472 | 'caches', |
||
473 | "Session data will be stored in \"$cacheType\" cache with " . |
||
474 | "expiry $wgObjectCacheSessionExpiry seconds" |
||
475 | ); |
||
476 | } |
||
477 | $wgSessionsInObjectCache = true; |
||
478 | |||
479 | if ( $wgPHPSessionHandling !== 'enable' && |
||
480 | $wgPHPSessionHandling !== 'warn' && |
||
481 | $wgPHPSessionHandling !== 'disable' |
||
482 | ) { |
||
483 | $wgPHPSessionHandling = 'warn'; |
||
484 | } |
||
485 | if ( defined( 'MW_NO_SESSION' ) ) { |
||
486 | // If the entry point wants no session, force 'disable' here unless they |
||
487 | // specifically set it to the (undocumented) 'warn'. |
||
488 | $wgPHPSessionHandling = MW_NO_SESSION === 'warn' ? 'warn' : 'disable'; |
||
489 | } |
||
490 | |||
491 | Profiler::instance()->scopedProfileOut( $ps_default ); |
||
492 | |||
493 | // Disable MWDebug for command line mode, this prevents MWDebug from eating up |
||
494 | // all the memory from logging SQL queries on maintenance scripts |
||
495 | global $wgCommandLineMode; |
||
496 | if ( $wgDebugToolbar && !$wgCommandLineMode ) { |
||
497 | MWDebug::init(); |
||
498 | } |
||
499 | |||
500 | if ( !class_exists( 'AutoLoader' ) ) { |
||
501 | require_once "$IP/includes/AutoLoader.php"; |
||
502 | } |
||
503 | |||
504 | // Reset the global service locator, so any services that have already been created will be |
||
505 | // re-created while taking into account any custom settings and extensions. |
||
506 | MediaWikiServices::resetGlobalInstance( new GlobalVarConfig(), 'quick' ); |
||
507 | |||
508 | if ( $wgSharedDB && $wgSharedTables ) { |
||
509 | // Apply $wgSharedDB table aliases for the local LB (all non-foreign DB connections) |
||
510 | MediaWikiServices::getInstance()->getDBLoadBalancer()->setTableAliases( |
||
511 | array_fill_keys( |
||
512 | $wgSharedTables, |
||
513 | [ |
||
514 | 'dbname' => $wgSharedDB, |
||
515 | 'schema' => $wgSharedSchema, |
||
516 | 'prefix' => $wgSharedPrefix |
||
517 | ] |
||
518 | ) |
||
519 | ); |
||
520 | } |
||
521 | |||
522 | // Define a constant that indicates that the bootstrapping of the service locator |
||
523 | // is complete. |
||
524 | define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 ); |
||
525 | |||
526 | // Install a header callback to prevent caching of responses with cookies (T127993) |
||
527 | if ( !$wgCommandLineMode ) { |
||
528 | header_register_callback( function () { |
||
529 | $headers = []; |
||
530 | foreach ( headers_list() as $header ) { |
||
531 | list( $name, $value ) = explode( ':', $header, 2 ); |
||
532 | $headers[strtolower( trim( $name ) )][] = trim( $value ); |
||
533 | } |
||
534 | |||
535 | if ( isset( $headers['set-cookie'] ) ) { |
||
536 | $cacheControl = isset( $headers['cache-control'] ) |
||
537 | ? implode( ', ', $headers['cache-control'] ) |
||
538 | : ''; |
||
539 | |||
540 | if ( !preg_match( '/(?:^|,)\s*(?:private|no-cache|no-store)\s*(?:$|,)/i', $cacheControl ) ) { |
||
541 | header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' ); |
||
542 | header( 'Cache-Control: private, max-age=0, s-maxage=0' ); |
||
543 | MediaWiki\Logger\LoggerFactory::getInstance( 'cache-cookies' )->warning( |
||
544 | 'Cookies set on {url} with Cache-Control "{cache-control}"', [ |
||
545 | 'url' => WebRequest::getGlobalRequestURL(), |
||
546 | 'cookies' => $headers['set-cookie'], |
||
547 | 'cache-control' => $cacheControl ?: '<not set>', |
||
548 | ] |
||
549 | ); |
||
550 | } |
||
551 | } |
||
552 | } ); |
||
553 | } |
||
554 | |||
555 | MWExceptionHandler::installHandler(); |
||
556 | |||
557 | require_once "$IP/includes/compat/normal/UtfNormalUtil.php"; |
||
558 | |||
559 | $ps_validation = Profiler::instance()->scopedProfileIn( $fname . '-validation' ); |
||
560 | |||
561 | // T48998: Bail out early if $wgArticlePath is non-absolute |
||
562 | foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) { |
||
563 | if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) { |
||
564 | throw new FatalError( |
||
565 | "If you use a relative URL for \$$varName, it must start " . |
||
566 | 'with a slash (<code>/</code>).<br><br>See ' . |
||
567 | "<a href=\"https://www.mediawiki.org/wiki/Manual:\$$varName\">" . |
||
568 | "https://www.mediawiki.org/wiki/Manual:\$$varName</a>." |
||
569 | ); |
||
570 | } |
||
571 | } |
||
572 | |||
573 | Profiler::instance()->scopedProfileOut( $ps_validation ); |
||
0 ignored issues
–
show
|
|||
574 | |||
575 | $ps_default2 = Profiler::instance()->scopedProfileIn( $fname . '-defaults2' ); |
||
576 | |||
577 | if ( $wgCanonicalServer === false ) { |
||
578 | $wgCanonicalServer = wfExpandUrl( $wgServer, PROTO_HTTP ); |
||
579 | } |
||
580 | |||
581 | // Set server name |
||
582 | $serverParts = wfParseUrl( $wgCanonicalServer ); |
||
583 | if ( $wgServerName !== false ) { |
||
584 | wfWarn( '$wgServerName should be derived from $wgCanonicalServer, ' |
||
585 | . 'not customized. Overwriting $wgServerName.' ); |
||
586 | } |
||
587 | $wgServerName = $serverParts['host']; |
||
588 | unset( $serverParts ); |
||
589 | |||
590 | // Set defaults for configuration variables |
||
591 | // that are derived from the server name by default |
||
592 | // Note: $wgEmergencyContact and $wgPasswordSender may be false or empty string (T104142) |
||
593 | if ( !$wgEmergencyContact ) { |
||
594 | $wgEmergencyContact = 'wikiadmin@' . $wgServerName; |
||
595 | } |
||
596 | if ( !$wgPasswordSender ) { |
||
597 | $wgPasswordSender = 'apache@' . $wgServerName; |
||
598 | } |
||
599 | if ( !$wgNoReplyAddress ) { |
||
600 | $wgNoReplyAddress = $wgPasswordSender; |
||
601 | } |
||
602 | |||
603 | if ( $wgSecureLogin && substr( $wgServer, 0, 2 ) !== '//' ) { |
||
604 | $wgSecureLogin = false; |
||
605 | wfWarn( 'Secure login was enabled on a server that only supports ' |
||
606 | . 'HTTP or HTTPS. Disabling secure login.' ); |
||
607 | } |
||
608 | |||
609 | $wgVirtualRestConfig['global']['domain'] = $wgCanonicalServer; |
||
610 | |||
611 | // Now that GlobalFunctions is loaded, set defaults that depend on it. |
||
612 | if ( $wgTmpDirectory === false ) { |
||
613 | $wgTmpDirectory = wfTempDir(); |
||
614 | } |
||
615 | |||
616 | // We don't use counters anymore. Left here for extensions still |
||
617 | // expecting this to exist. Should be removed sometime 1.26 or later. |
||
618 | if ( !isset( $wgDisableCounters ) ) { |
||
619 | $wgDisableCounters = true; |
||
620 | } |
||
621 | |||
622 | if ( $wgMainWANCache === false ) { |
||
623 | // Setup a WAN cache from $wgMainCacheType with no relayer. |
||
624 | // Sites using multiple datacenters can configure a relayer. |
||
625 | $wgMainWANCache = 'mediawiki-main-default'; |
||
626 | $wgWANObjectCaches[$wgMainWANCache] = [ |
||
627 | 'class' => 'WANObjectCache', |
||
628 | 'cacheId' => $wgMainCacheType, |
||
629 | 'channels' => [ 'purge' => 'wancache-main-default-purge' ] |
||
630 | ]; |
||
631 | } |
||
632 | |||
633 | Profiler::instance()->scopedProfileOut( $ps_default2 ); |
||
634 | |||
635 | $ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc1' ); |
||
636 | |||
637 | // Raise the memory limit if it's too low |
||
638 | wfMemoryLimit(); |
||
639 | |||
640 | /** |
||
641 | * Set up the timezone, suppressing the pseudo-security warning in PHP 5.1+ |
||
642 | * that happens whenever you use a date function without the timezone being |
||
643 | * explicitly set. Inspired by phpMyAdmin's treatment of the problem. |
||
644 | */ |
||
645 | if ( is_null( $wgLocaltimezone ) ) { |
||
646 | MediaWiki\suppressWarnings(); |
||
647 | $wgLocaltimezone = date_default_timezone_get(); |
||
648 | MediaWiki\restoreWarnings(); |
||
649 | } |
||
650 | |||
651 | date_default_timezone_set( $wgLocaltimezone ); |
||
652 | if ( is_null( $wgLocalTZoffset ) ) { |
||
653 | $wgLocalTZoffset = date( 'Z' ) / 60; |
||
654 | } |
||
655 | // The part after the System| is ignored, but rest of MW fills it |
||
656 | // out as the local offset. |
||
657 | $wgDefaultUserOptions['timecorrection'] = "System|$wgLocalTZoffset"; |
||
658 | |||
659 | if ( !$wgDBerrorLogTZ ) { |
||
660 | $wgDBerrorLogTZ = $wgLocaltimezone; |
||
661 | } |
||
662 | |||
663 | // initialize the request object in $wgRequest |
||
664 | $wgRequest = RequestContext::getMain()->getRequest(); // BackCompat |
||
665 | // Set user IP/agent information for causal consistency purposes |
||
666 | MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->setRequestInfo( [ |
||
667 | 'IPAddress' => $wgRequest->getIP(), |
||
668 | 'UserAgent' => $wgRequest->getHeader( 'User-Agent' ), |
||
669 | 'ChronologyProtection' => $wgRequest->getHeader( 'ChronologyProtection' ) |
||
670 | ] ); |
||
671 | |||
672 | // Useful debug output |
||
673 | if ( $wgCommandLineMode ) { |
||
674 | wfDebug( "\n\nStart command line script $self\n" ); |
||
675 | } else { |
||
676 | $debug = "\n\nStart request {$wgRequest->getMethod()} {$wgRequest->getRequestURL()}\n"; |
||
677 | |||
678 | if ( $wgDebugPrintHttpHeaders ) { |
||
679 | $debug .= "HTTP HEADERS:\n"; |
||
680 | |||
681 | foreach ( $wgRequest->getAllHeaders() as $name => $value ) { |
||
682 | $debug .= "$name: $value\n"; |
||
683 | } |
||
684 | } |
||
685 | wfDebug( $debug ); |
||
686 | } |
||
687 | |||
688 | Profiler::instance()->scopedProfileOut( $ps_misc ); |
||
689 | $ps_memcached = Profiler::instance()->scopedProfileIn( $fname . '-memcached' ); |
||
690 | |||
691 | $wgMemc = wfGetMainCache(); |
||
692 | $messageMemc = wfGetMessageCacheStorage(); |
||
693 | $parserMemc = wfGetParserCacheStorage(); |
||
694 | |||
695 | wfDebugLog( 'caches', |
||
696 | 'cluster: ' . get_class( $wgMemc ) . |
||
697 | ', WAN: ' . ( $wgMainWANCache === CACHE_NONE ? 'CACHE_NONE' : $wgMainWANCache ) . |
||
698 | ', stash: ' . $wgMainStash . |
||
699 | ', message: ' . get_class( $messageMemc ) . |
||
700 | ', parser: ' . get_class( $parserMemc ) . |
||
701 | ', session: ' . get_class( ObjectCache::getInstance( $wgSessionCacheType ) ) |
||
702 | ); |
||
703 | |||
704 | Profiler::instance()->scopedProfileOut( $ps_memcached ); |
||
705 | |||
706 | // Most of the config is out, some might want to run hooks here. |
||
707 | Hooks::run( 'SetupAfterCache' ); |
||
708 | |||
709 | $ps_globals = Profiler::instance()->scopedProfileIn( $fname . '-globals' ); |
||
710 | |||
711 | /** |
||
712 | * @var Language $wgContLang |
||
713 | */ |
||
714 | $wgContLang = Language::factory( $wgLanguageCode ); |
||
715 | $wgContLang->initContLang(); |
||
716 | |||
717 | // Now that variant lists may be available... |
||
718 | $wgRequest->interpolateTitle(); |
||
719 | |||
720 | if ( !is_object( $wgAuth ) ) { |
||
721 | $wgAuth = new MediaWiki\Auth\AuthManagerAuthPlugin; |
||
722 | Hooks::run( 'AuthPluginSetup', [ &$wgAuth ] ); |
||
723 | } |
||
724 | if ( $wgAuth && !$wgAuth instanceof MediaWiki\Auth\AuthManagerAuthPlugin ) { |
||
725 | MediaWiki\Auth\AuthManager::singleton()->forcePrimaryAuthenticationProviders( [ |
||
726 | new MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider( [ |
||
727 | 'authoritative' => false, |
||
728 | ] ), |
||
729 | new MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider( $wgAuth ), |
||
730 | new MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider( [ |
||
731 | 'authoritative' => true, |
||
732 | ] ), |
||
733 | ], '$wgAuth is ' . get_class( $wgAuth ) ); |
||
734 | } |
||
735 | |||
736 | // Set up the session |
||
737 | $ps_session = Profiler::instance()->scopedProfileIn( $fname . '-session' ); |
||
738 | /** |
||
739 | * @var MediaWiki\Session\SessionId|null $wgInitialSessionId The persistent |
||
740 | * session ID (if any) loaded at startup |
||
741 | */ |
||
742 | $wgInitialSessionId = null; |
||
743 | if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) { |
||
744 | // If session.auto_start is there, we can't touch session name |
||
745 | if ( $wgPHPSessionHandling !== 'disable' && !wfIniGetBool( 'session.auto_start' ) ) { |
||
746 | session_name( $wgSessionName ? $wgSessionName : $wgCookiePrefix . '_session' ); |
||
747 | } |
||
748 | |||
749 | // Create the SessionManager singleton and set up our session handler, |
||
750 | // unless we're specifically asked not to. |
||
751 | if ( !defined( 'MW_NO_SESSION_HANDLER' ) ) { |
||
752 | MediaWiki\Session\PHPSessionHandler::install( |
||
753 | MediaWiki\Session\SessionManager::singleton() |
||
754 | ); |
||
755 | } |
||
756 | |||
757 | // Initialize the session |
||
758 | try { |
||
759 | $session = MediaWiki\Session\SessionManager::getGlobalSession(); |
||
760 | } catch ( OverflowException $ex ) { |
||
761 | if ( isset( $ex->sessionInfos ) && count( $ex->sessionInfos ) >= 2 ) { |
||
762 | // The exception is because the request had multiple possible |
||
763 | // sessions tied for top priority. Report this to the user. |
||
764 | $list = []; |
||
765 | foreach ( $ex->sessionInfos as $info ) { |
||
766 | $list[] = $info->getProvider()->describe( $wgContLang ); |
||
767 | } |
||
768 | $list = $wgContLang->listToText( $list ); |
||
769 | throw new HttpError( 400, |
||
770 | Message::newFromKey( 'sessionmanager-tie', $list )->inLanguage( $wgContLang )->plain() |
||
771 | ); |
||
772 | } |
||
773 | |||
774 | // Not the one we want, rethrow |
||
775 | throw $ex; |
||
776 | } |
||
777 | |||
778 | if ( $session->isPersistent() ) { |
||
779 | $wgInitialSessionId = $session->getSessionId(); |
||
780 | } |
||
781 | |||
782 | $session->renew(); |
||
783 | if ( MediaWiki\Session\PHPSessionHandler::isEnabled() && |
||
784 | ( $session->isPersistent() || $session->shouldRememberUser() ) |
||
785 | ) { |
||
786 | // Start the PHP-session for backwards compatibility |
||
787 | session_id( $session->getId() ); |
||
788 | MediaWiki\quietCall( 'session_start' ); |
||
789 | } |
||
790 | |||
791 | unset( $session ); |
||
792 | } else { |
||
793 | // Even if we didn't set up a global Session, still install our session |
||
794 | // handler unless specifically requested not to. |
||
795 | if ( !defined( 'MW_NO_SESSION_HANDLER' ) ) { |
||
796 | MediaWiki\Session\PHPSessionHandler::install( |
||
797 | MediaWiki\Session\SessionManager::singleton() |
||
798 | ); |
||
799 | } |
||
800 | } |
||
801 | Profiler::instance()->scopedProfileOut( $ps_session ); |
||
802 | |||
803 | /** |
||
804 | * @var User $wgUser |
||
805 | */ |
||
806 | $wgUser = RequestContext::getMain()->getUser(); // BackCompat |
||
807 | |||
808 | /** |
||
809 | * @var Language $wgLang |
||
810 | */ |
||
811 | $wgLang = new StubUserLang; |
||
812 | |||
813 | /** |
||
814 | * @var OutputPage $wgOut |
||
815 | */ |
||
816 | $wgOut = RequestContext::getMain()->getOutput(); // BackCompat |
||
817 | |||
818 | /** |
||
819 | * @var Parser $wgParser |
||
820 | */ |
||
821 | $wgParser = new StubObject( 'wgParser', function () { |
||
822 | return MediaWikiServices::getInstance()->getParser(); |
||
823 | } ); |
||
824 | |||
825 | /** |
||
826 | * @var Title $wgTitle |
||
827 | */ |
||
828 | $wgTitle = null; |
||
829 | |||
830 | Profiler::instance()->scopedProfileOut( $ps_globals ); |
||
831 | $ps_extensions = Profiler::instance()->scopedProfileIn( $fname . '-extensions' ); |
||
832 | |||
833 | // Extension setup functions |
||
834 | // Entries should be added to this variable during the inclusion |
||
835 | // of the extension file. This allows the extension to perform |
||
836 | // any necessary initialisation in the fully initialised environment |
||
837 | foreach ( $wgExtensionFunctions as $func ) { |
||
838 | // Allow closures in PHP 5.3+ |
||
839 | if ( is_object( $func ) && $func instanceof Closure ) { |
||
840 | $profName = $fname . '-extensions-closure'; |
||
841 | } elseif ( is_array( $func ) ) { |
||
842 | if ( is_object( $func[0] ) ) { |
||
843 | $profName = $fname . '-extensions-' . get_class( $func[0] ) . '::' . $func[1]; |
||
844 | } else { |
||
845 | $profName = $fname . '-extensions-' . implode( '::', $func ); |
||
846 | } |
||
847 | } else { |
||
848 | $profName = $fname . '-extensions-' . strval( $func ); |
||
849 | } |
||
850 | |||
851 | $ps_ext_func = Profiler::instance()->scopedProfileIn( $profName ); |
||
852 | call_user_func( $func ); |
||
853 | Profiler::instance()->scopedProfileOut( $ps_ext_func ); |
||
854 | } |
||
855 | |||
856 | // If the session user has a 0 id but a valid name, that means we need to |
||
857 | // autocreate it. |
||
858 | if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) { |
||
859 | $sessionUser = MediaWiki\Session\SessionManager::getGlobalSession()->getUser(); |
||
860 | if ( $sessionUser->getId() === 0 && User::isValidUserName( $sessionUser->getName() ) ) { |
||
861 | $ps_autocreate = Profiler::instance()->scopedProfileIn( $fname . '-autocreate' ); |
||
862 | $res = MediaWiki\Auth\AuthManager::singleton()->autoCreateUser( |
||
863 | $sessionUser, |
||
864 | MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSION, |
||
865 | true |
||
866 | ); |
||
867 | Profiler::instance()->scopedProfileOut( $ps_autocreate ); |
||
868 | \MediaWiki\Logger\LoggerFactory::getInstance( 'authevents' )->info( 'Autocreation attempt', [ |
||
869 | 'event' => 'autocreate', |
||
870 | 'status' => $res, |
||
871 | ] ); |
||
872 | unset( $res ); |
||
873 | } |
||
874 | unset( $sessionUser ); |
||
875 | } |
||
876 | |||
877 | if ( !$wgCommandLineMode ) { |
||
878 | Pingback::schedulePingback(); |
||
879 | } |
||
880 | |||
881 | wfDebug( "Fully initialised\n" ); |
||
882 | $wgFullyInitialised = true; |
||
883 | |||
884 | Profiler::instance()->scopedProfileOut( $ps_extensions ); |
||
885 | Profiler::instance()->scopedProfileOut( $ps_setup ); |
||
886 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.