TYPO3 CMS  TYPO3_7-6
Check.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
20 
49 class Check
50 {
54  protected $requiredPhpExtensions = [
55  'filter',
56  'gd',
57  'hash',
58  'json',
59  'mysqli',
60  'openssl',
61  'session',
62  'soap',
63  'SPL',
64  'standard',
65  'xml',
66  'zip',
67  'zlib',
68  ];
69 
75  public function getStatus()
76  {
77  $statusArray = [];
78  $statusArray[] = $this->checkCurrentDirectoryIsInIncludePath();
79  $statusArray[] = $this->checkTrustedHostPattern();
80  $statusArray[] = $this->checkFileUploadEnabled();
82  $statusArray[] = $this->checkMemorySettings();
83  $statusArray[] = $this->checkPhpVersion();
84  $statusArray[] = $this->checkMaxExecutionTime();
85  $statusArray[] = $this->checkDisableFunctions();
86  $statusArray[] = $this->checkDownloadsPossible();
87  $statusArray[] = $this->checkMysqliReconnectSetting();
88  $statusArray[] = $this->checkAlwaysPopulateRawPostDataSetting();
89  $statusArray[] = $this->checkDocRoot();
90  $statusArray[] = $this->checkOpenBaseDir();
91  $statusArray[] = $this->checkXdebugMaxNestingLevel();
92  $statusArray[] = $this->checkOpenSslInstalled();
93  if ($this->isSuhosinLoadedAndActive()) {
94  $statusArray[] = $this->getSuhosinLoadedStatus();
95  $statusArray[] = $this->checkSuhosinRequestMaxVars();
96  $statusArray[] = $this->checkSuhosinRequestMaxVarnameLength();
97  $statusArray[] = $this->checkSuhosinPostMaxNameLength();
98  $statusArray[] = $this->checkSuhosinPostMaxVars();
99  $statusArray[] = $this->checkSuhosinGetMaxNameLength();
100  $statusArray[] = $this->checkSuhosinGetMaxValueLength();
101  $statusArray[] = $this->checkSuhosinExecutorIncludeWhiteListContainsPhar();
102  $statusArray[] = $this->checkSuhosinExecutorIncludeWhiteListContainsVfs();
103  }
104  $statusArray[] = $this->checkMaxInputVars();
105  $statusArray[] = $this->checkSomePhpOpcodeCacheIsLoaded();
106  $statusArray[] = $this->checkReflectionDocComment();
107  $statusArray[] = $this->checkSystemLocale();
108  $statusArray[] = $this->checkLocaleWithUTF8filesystem();
109  $statusArray[] = $this->checkWindowsApacheThreadStackSize();
110  foreach ($this->requiredPhpExtensions as $extension) {
111  $statusArray[] = $this->checkRequiredPhpExtension($extension);
112  }
113  $statusArray[] = $this->checkPcreVersion();
114  $statusArray[] = $this->checkGdLibTrueColorSupport();
115  $statusArray[] = $this->checkGdLibGifSupport();
116  $statusArray[] = $this->checkGdLibJpgSupport();
117  $statusArray[] = $this->checkGdLibPngSupport();
118  $statusArray[] = $this->checkGdLibFreeTypeSupport();
119  $statusArray[] = $this->checkRegisterGlobals();
120  $statusArray[] = $this->checkLibXmlBug();
121  $statusArray[] = $this->isTrueTypeFontWorking();
122  return $statusArray;
123  }
124 
131  {
132  $includePath = ini_get('include_path');
133  $delimiter = $this->isWindowsOs() ? ';' : ':';
134  $pathArray = $this->trimExplode($delimiter, $includePath);
135  if (!in_array('.', $pathArray)) {
136  $status = new Status\WarningStatus();
137  $status->setTitle('Current directory (./) is not within PHP include path');
138  $status->setMessage(
139  'include_path = ' . implode(' ', $pathArray) . LF .
140  'Normally the current path \'.\' is included in the' .
141  ' include_path of PHP. Although TYPO3 does not rely on this,' .
142  ' it is an unusual setting that may introduce problems for' .
143  ' some extensions.'
144  );
145  } else {
146  $status = new Status\OkStatus();
147  $status->setTitle('Current directory (./) is within PHP include path.');
148  }
149  return $status;
150  }
151 
157  protected function checkTrustedHostPattern()
158  {
159  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] === GeneralUtility::ENV_TRUSTED_HOSTS_PATTERN_ALLOW_ALL) {
160  $status = new Status\WarningStatus();
161  $status->setTitle('Trusted hosts pattern is insecure');
162  $status->setMessage('Trusted hosts pattern is configured to allow all header values. Check the pattern defined in Install Tool -> All configuration -> System -> trustedHostsPattern and adapt it to expected host value(s).');
163  } else {
165  $status = new Status\OkStatus();
166  $status->setTitle('Trusted hosts pattern is configured to allow current host value.');
167  } else {
168  $status = new Status\ErrorStatus();
169  $status->setTitle('Trusted hosts pattern mismatch');
170  $status->setMessage('The trusted hosts pattern will be configured to allow all header values. This is because your $SERVER_NAME is "' . htmlspecialchars($_SERVER['SERVER_NAME']) . '" while your HTTP_HOST is "' . htmlspecialchars($_SERVER['HTTP_HOST']) . '". Check the pattern defined in Install Tool -> All configuration -> System -> trustedHostsPattern and adapt it to expected host value(s).');
171  }
172  }
173 
174  return $status;
175  }
176 
182  protected function checkFileUploadEnabled()
183  {
184  if (!ini_get('file_uploads')) {
185  $status = new Status\ErrorStatus();
186  $status->setTitle('File uploads not allowed in PHP');
187  $status->setMessage(
188  'file_uploads=' . ini_get('file_uploads') . LF .
189  'TYPO3 uses the ability to upload files from the browser in various cases.' .
190  ' If this flag is disabled in PHP, you won\'t be able to upload files.' .
191  ' But it doesn\'t end here, because not only are files not accepted by' .
192  ' the server - ALL content in the forms are discarded and therefore' .
193  ' nothing at all will be editable if you don\'t set this flag!'
194  );
195  } else {
196  $status = new Status\OkStatus();
197  $status->setTitle('File uploads allowed in PHP');
198  }
199  return $status;
200  }
201 
208  {
209  $maximumUploadFilesize = $this->getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
210  $maximumPostSize = $this->getBytesFromSizeMeasurement(ini_get('post_max_size'));
211  if ($maximumPostSize > 0 && $maximumPostSize < $maximumUploadFilesize) {
212  $status = new Status\ErrorStatus();
213  $status->setTitle('Maximum size for POST requests is smaller than maximum upload filesize in PHP');
214  $status->setMessage(
215  'upload_max_filesize=' . ini_get('upload_max_filesize') . LF .
216  'post_max_size=' . ini_get('post_max_size') . LF .
217  'You have defined a maximum size for file uploads in PHP which' .
218  ' exceeds the allowed size for POST requests. Therefore the' .
219  ' file uploads can also not be larger than ' . ini_get('post_max_size') . '.'
220  );
221  } else {
222  $status = new Status\OkStatus();
223  $status->setTitle('Maximum post upload size correlates with maximum upload file size in PHP');
224  $status->setMessage('The maximum size for file uploads is actually set to ' . ini_get('upload_max_filesize'));
225  }
226  return $status;
227  }
228 
234  protected function checkMemorySettings()
235  {
236  $minimumMemoryLimit = 64;
237  $recommendedMemoryLimit = 128;
238  $memoryLimit = $this->getBytesFromSizeMeasurement(ini_get('memory_limit'));
239  if ($memoryLimit <= 0) {
240  $status = new Status\WarningStatus();
241  $status->setTitle('Unlimited memory limit for PHP');
242  $status->setMessage(
243  'PHP is configured not to limit memory usage at all. This is a risk' .
244  ' and should be avoided in production setup. In general it\'s best practice to limit this.' .
245  ' To be safe, set a limit in PHP, but with a minimum of ' . $recommendedMemoryLimit . 'MB:' . LF .
246  'memory_limit=' . $recommendedMemoryLimit . 'M'
247  );
248  } elseif ($memoryLimit < 1024 * 1024 * $minimumMemoryLimit) {
249  $status = new Status\ErrorStatus();
250  $status->setTitle('PHP Memory limit below ' . $minimumMemoryLimit . 'MB');
251  $status->setMessage(
252  'memory_limit=' . ini_get('memory_limit') . LF .
253  'Your system is configured to enforce a memory limit for PHP scripts lower than ' .
254  $minimumMemoryLimit . 'MB. It is required to raise the limit.' .
255  ' We recommend a minimum PHP memory limit of ' . $recommendedMemoryLimit . 'MB:' . LF .
256  'memory_limit=' . $recommendedMemoryLimit . 'M'
257  );
258  } elseif ($memoryLimit < 1024 * 1024 * $recommendedMemoryLimit) {
259  $status = new Status\WarningStatus();
260  $status->setTitle('PHP Memory limit below ' . $recommendedMemoryLimit . 'MB');
261  $status->setMessage(
262  'memory_limit=' . ini_get('memory_limit') . LF .
263  'Your system is configured to enforce a memory limit for PHP scripts lower than ' .
264  $recommendedMemoryLimit . 'MB.' .
265  ' A slim TYPO3 instance without many extensions will probably work, but you should monitor your' .
266  ' system for "allowed memory size of X bytes exhausted" messages, especially if using the backend.' .
267  ' To be on the safe side,' . ' we recommend a minimum PHP memory limit of ' .
268  $recommendedMemoryLimit . 'MB:' . LF .
269  'memory_limit=' . $recommendedMemoryLimit . 'M'
270  );
271  } else {
272  $status = new Status\OkStatus();
273  $status->setTitle('PHP Memory limit is equal to or more than ' . $recommendedMemoryLimit . 'MB');
274  }
275  return $status;
276  }
277 
283  protected function checkPhpVersion()
284  {
285  $minimumPhpVersion = '5.5.0';
286  $currentPhpVersion = phpversion();
287  if (version_compare($currentPhpVersion, $minimumPhpVersion) < 0) {
288  $status = new Status\ErrorStatus();
289  $status->setTitle('PHP version too low');
290  $status->setMessage(
291  'Your PHP version ' . $currentPhpVersion . ' is too old. TYPO3 CMS does not run' .
292  ' with this version. Update to at least PHP ' . $minimumPhpVersion
293  );
294  } else {
295  $status = new Status\OkStatus();
296  $status->setTitle('PHP version is fine');
297  }
298  return $status;
299  }
300 
306  protected function checkPcreVersion()
307  {
308  $minimumPcreVersion = '8.30';
309  if (!extension_loaded('pcre')) {
310  $status = new Status\ErrorStatus();
311  $status->setTitle('PHP extension pcre not loaded');
312  $status->setMessage(
313  'TYPO3 CMS uses PHP extension pcre but it is not loaded' .
314  ' in your environment. Change your environment to provide this extension' .
315  ' in with minimum version ' . $minimumPcreVersion . '.'
316  );
317  } else {
318  $installedPcreVersionString = trim(PCRE_VERSION); // '8.31 2012-07-06'
319  $mainPcreVersionString = explode(' ', $installedPcreVersionString);
320  $mainPcreVersionString = $mainPcreVersionString[0]; // '8.31'
321  if (version_compare($mainPcreVersionString, $minimumPcreVersion) < 0) {
322  $status = new Status\ErrorStatus();
323  $status->setTitle('PCRE version too low');
324  $status->setMessage(
325  'Your PCRE version ' . PCRE_VERSION . ' is too old. TYPO3 CMS may trigger PHP segmentantion' .
326  ' faults with this version. Update to at least PCRE ' . $minimumPcreVersion
327  );
328  } else {
329  $status = new Status\OkStatus();
330  $status->setTitle('PHP extension PCRE is loaded and version is fine');
331  }
332  }
333  return $status;
334  }
335 
341  protected function checkMaxExecutionTime()
342  {
343  $minimumMaximumExecutionTime = 30;
344  $recommendedMaximumExecutionTime = 240;
345  $currentMaximumExecutionTime = ini_get('max_execution_time');
346  if ($currentMaximumExecutionTime == 0) {
347  $status = new Status\WarningStatus();
348  $status->setTitle('Infinite PHP script execution time');
349  $status->setMessage(
350  'max_execution_time=0' . LF .
351  'While TYPO3 is fine with this, you risk a denial-of-service for your system if for whatever' .
352  ' reason some script hangs in an infinite loop. You are usually on the safe side ' .
353  ' if it is reduced to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
354  'max_execution_time=' . $recommendedMaximumExecutionTime
355  );
356  } elseif ($currentMaximumExecutionTime < $minimumMaximumExecutionTime) {
357  $status = new Status\ErrorStatus();
358  $status->setTitle('Low PHP script execution time');
359  $status->setMessage(
360  'max_execution_time=' . $currentMaximumExecutionTime . LF .
361  'Your max_execution_time is too low. Some expensive operations in TYPO3 can take longer than that.' .
362  ' It is recommended to raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
363  'max_execution_time=' . $recommendedMaximumExecutionTime
364  );
365  } elseif ($currentMaximumExecutionTime < $recommendedMaximumExecutionTime) {
366  $status = new Status\WarningStatus();
367  $status->setTitle('Low PHP script execution time');
368  $status->setMessage(
369  'max_execution_time=' . $currentMaximumExecutionTime . LF .
370  'Your max_execution_time is low. While TYPO3 often runs without problems' .
371  ' with ' . $minimumMaximumExecutionTime . ' seconds,' .
372  ' it may still happen that script execution is stopped before finishing' .
373  ' calculations. You should monitor the system for messages in this area' .
374  ' and maybe raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
375  'max_execution_time=' . $recommendedMaximumExecutionTime
376  );
377  } else {
378  $status = new Status\OkStatus();
379  $status->setTitle('Maximum PHP script execution time is equal to or more than '
380  . $recommendedMaximumExecutionTime);
381  }
382  return $status;
383  }
384 
390  protected function checkDisableFunctions()
391  {
392  $disabledFunctions = trim(ini_get('disable_functions'));
393 
394  // Filter "disable_functions"
395  $disabledFunctionsArray = $this->trimExplode(',', $disabledFunctions);
396 
397  // Array with strings to find
398  $findStrings = [
399  // Disabled by default on Ubuntu OS but this is okay since the Core does not use them
400  'pcntl_',
401  ];
402  foreach ($disabledFunctionsArray as $key => $disabledFunction) {
403  foreach ($findStrings as $findString) {
404  if (strpos($disabledFunction, $findString) !== false) {
405  unset($disabledFunctionsArray[$key]);
406  }
407  }
408  }
409 
410  if ($disabledFunctions !== '') {
411  if (!empty($disabledFunctionsArray)) {
412  $status = new Status\ErrorStatus();
413  $status->setTitle('Some PHP functions disabled');
414  $status->setMessage(
415  'disable_functions=' . implode(' ', explode(',', $disabledFunctions)) . LF .
416  'These function(s) are disabled. TYPO3 uses some of those, so there might be trouble.' .
417  ' TYPO3 is designed to use the default set of PHP functions plus some common extensions.' .
418  ' Possibly these functions are disabled' .
419  ' due to security considerations and most likely the list would include a function like' .
420  ' exec() which is used by TYPO3 at various places. Depending on which exact functions' .
421  ' are disabled, some parts of the system may just break without further notice.'
422  );
423  } else {
424  $status = new Status\NoticeStatus();
425  $status->setTitle('Some PHP functions currently disabled but OK');
426  $status->setMessage(
427  'disable_functions=' . implode(' ', explode(',', $disabledFunctions)) . LF .
428  'These function(s) are disabled. TYPO3 uses currently none of those, so you are good to go.'
429  );
430  }
431  } else {
432  $status = new Status\OkStatus();
433  $status->setTitle('No disabled PHP functions');
434  }
435  return $status;
436  }
437 
444  protected function checkDownloadsPossible()
445  {
446  $allowUrlFopen = (bool)ini_get('allow_url_fopen');
447  $curlEnabled = !empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse']);
448  if ($allowUrlFopen || $curlEnabled) {
449  $status = new Status\OkStatus();
450  $status->setTitle('Fetching external URLs is allowed');
451  } else {
452  $status = new Status\WarningStatus();
453  $status->setTitle('Fetching external URLs is not allowed');
454  $status->setMessage(
455  'Either enable PHP runtime setting "allow_url_fopen"' . LF . 'or enable curl by setting [SYS][curlUse] accordingly.'
456  );
457  }
458  return $status;
459  }
460 
466  protected function checkMysqliReconnectSetting()
467  {
468  $currentMysqliReconnectSetting = ini_get('mysqli.reconnect');
469  if ($currentMysqliReconnectSetting === '1') {
470  $status = new Status\ErrorStatus();
471  $status->setTitle('PHP mysqli.reconnect is enabled');
472  $status->setMessage(
473  'mysqli.reconnect=1' . LF .
474  'PHP is configured to automatically reconnect the database connection on disconnection.' . LF .
475  ' Warning: If (e.g. during a long-running task) the connection is dropped and automatically reconnected, ' .
476  ' it may not be reinitialized properly (e.g. charset) and write mangled data to the database!'
477  );
478  } else {
479  $status = new Status\OkStatus();
480  $status->setTitle('PHP mysqli.reconnect is fine');
481  }
482  return $status;
483  }
484 
491  {
492  $minimumPhpVersion = '5.6.0';
493  $maximumPhpVersion = '7.0.0';
494  $currentPhpVersion = phpversion();
495  $currentAlwaysPopulaterRawPostDataSetting = ini_get('always_populate_raw_post_data');
496  if (version_compare($currentPhpVersion, $maximumPhpVersion) >= 0) {
497  $status = new Status\OkStatus();
498  $status->setTitle('PHP always_populate_raw_post_data is removed as of PHP 7.0 or newer');
499  } elseif (version_compare($currentPhpVersion, $minimumPhpVersion) >= 0 && $currentAlwaysPopulaterRawPostDataSetting !== '-1') {
500  $status = new Status\ErrorStatus();
501  $status->setTitle('PHP always_populate_raw_post_data is deprecated');
502  $status->setMessage(
503  'always_populate_raw_post_data=' . $currentAlwaysPopulaterRawPostDataSetting . LF .
504  'PHP is configured to automatically populate $HTTP_RAW_POST_DATA.' . LF .
505  ' Warning: Expect fatal errors in central parts of the CMS' .
506  ' if the value is not changed to:' . LF .
507  'always_populate_raw_post_data=-1'
508  );
509  } else {
510  $status = new Status\OkStatus();
511  $status->setTitle('PHP always_populate_raw_post_data is fine');
512  }
513  return $status;
514  }
515 
521  protected function checkDocRoot()
522  {
523  $docRootSetting = trim(ini_get('doc_root'));
524  if ($docRootSetting !== '') {
525  $status = new Status\NoticeStatus();
526  $status->setTitle('doc_root is set');
527  $status->setMessage(
528  'doc_root=' . $docRootSetting . LF .
529  'PHP cannot execute scripts' .
530  ' outside this directory. This setting is seldom used and must correlate' .
531  ' with your actual document root. You might be in trouble if your' .
532  ' TYPO3 CMS core code is linked to some different location.' .
533  ' If that is a problem, the setting must be changed.'
534  );
535  } else {
536  $status = new Status\OkStatus();
537  $status->setTitle('PHP doc_root is not set');
538  }
539  return $status;
540  }
541 
547  protected function checkOpenBaseDir()
548  {
549  $openBaseDirSetting = trim(ini_get('open_basedir'));
550  if ($openBaseDirSetting !== '') {
551  $status = new Status\NoticeStatus();
552  $status->setTitle('PHP open_basedir is set');
553  $status->setMessage(
554  'open_basedir = ' . ini_get('open_basedir') . LF .
555  'This restricts TYPO3 to open and include files only in this' .
556  ' path. Please make sure that this does not prevent TYPO3 from running,' .
557  ' if for example your TYPO3 CMS core is linked to a different directory' .
558  ' not included in this path.'
559  );
560  } else {
561  $status = new Status\OkStatus();
562  $status->setTitle('PHP open_basedir is off');
563  }
564  return $status;
565  }
566 
572  protected function checkXdebugMaxNestingLevel()
573  {
574  if (extension_loaded('xdebug')) {
575  $recommendedMaxNestingLevel = 400;
576  $errorThreshold = 250;
577  $currentMaxNestingLevel = ini_get('xdebug.max_nesting_level');
578  if ($currentMaxNestingLevel < $errorThreshold) {
579  $status = new Status\ErrorStatus();
580  $status->setTitle('PHP xdebug.max_nesting_level is critically low');
581  $status->setMessage(
582  'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF .
583  'This setting controls the maximum number of nested function calls to protect against' .
584  ' infinite recursion. The current value is too low for TYPO3 CMS and must' .
585  ' be either raised or xdebug has to be unloaded. A value of ' . $recommendedMaxNestingLevel .
586  ' is recommended. Warning: Expect fatal PHP errors in central parts of the CMS' .
587  ' if the value is not raised significantly to:' . LF .
588  'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel
589  );
590  } elseif ($currentMaxNestingLevel < $recommendedMaxNestingLevel) {
591  $status = new Status\WarningStatus();
592  $status->setTitle('PHP xdebug.max_nesting_level is low');
593  $status->setMessage(
594  'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF .
595  'This setting controls the maximum number of nested function calls to protect against' .
596  ' infinite recursion. The current value is high enough for the TYPO3 CMS core to work' .
597  ' fine, but still some extensions could raise fatal PHP errors if the setting is not' .
598  ' raised further. A value of ' . $recommendedMaxNestingLevel . ' is recommended.' . LF .
599  'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel
600  );
601  } else {
602  $status = new Status\OkStatus();
603  $status->setTitle('PHP xdebug.max_nesting_level ok');
604  }
605  } else {
606  $status = new Status\OkStatus();
607  $status->setTitle('PHP xdebug extension not loaded');
608  }
609  return $status;
610  }
611 
617  protected function checkOpenSslInstalled()
618  {
619  if (extension_loaded('openssl')) {
620  $testKey = @openssl_pkey_new();
621  if (is_resource($testKey)) {
622  openssl_free_key($testKey);
623  $status = new Status\OkStatus();
624  $status->setTitle('PHP OpenSSL extension installed properly');
625  } else {
626  $status = new Status\ErrorStatus();
627  $status->setTitle('PHP OpenSSL extension not working');
628  $status->setMessage(
629  'Something went wrong while trying to create a new private key for testing.' .
630  ' Please check the integration of the PHP OpenSSL extension and if it is installed correctly.'
631  );
632  }
633  } else {
634  $status = new Status\ErrorStatus();
635  $status->setTitle('PHP OpenSSL extension not loaded');
636  $status->setMessage(
637  'OpenSSL is a PHP extension to encrypt/decrypt data between requests.' .
638  ' TYPO3 CMS requires it to be able to encrypt stored passwords to improve the security in the' .
639  ' database layer.'
640  );
641  }
642 
643  return $status;
644  }
645 
651  protected function checkMaxInputVars()
652  {
653  $recommendedMaxInputVars = 1500;
654  $minimumMaxInputVars = 1000;
655  $currentMaxInputVars = ini_get('max_input_vars');
656 
657  if ($currentMaxInputVars < $minimumMaxInputVars) {
658  $status = new Status\ErrorStatus();
659  $status->setTitle('PHP max_input_vars too low');
660  $status->setMessage(
661  'max_input_vars=' . $currentMaxInputVars . LF .
662  'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
663  ' (as the install tool does). It is highly recommended to raise this' .
664  ' to at least ' . $recommendedMaxInputVars . ':' . LF .
665  'max_input_vars=' . $recommendedMaxInputVars
666  );
667  } elseif ($currentMaxInputVars < $recommendedMaxInputVars) {
668  $status = new Status\WarningStatus();
669  $status->setTitle('PHP max_input_vars very low');
670  $status->setMessage(
671  'max_input_vars=' . $currentMaxInputVars . LF .
672  'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
673  ' (as the install tool does). It is highly recommended to raise this' .
674  ' to at least ' . $recommendedMaxInputVars . ':' . LF .
675  'max_input_vars=' . $recommendedMaxInputVars
676  );
677  } else {
678  $status = new Status\OkStatus();
679  $status->setTitle('PHP max_input_vars ok');
680  }
681  return $status;
682  }
683 
691  protected function getSuhosinLoadedStatus()
692  {
693  if ($this->isSuhosinLoadedAndActive()) {
694  $status = new Status\OkStatus();
695  $status->setTitle('PHP suhosin extension loaded and active');
696  return $status;
697  } else {
698  throw new \BadMethodCallException('Should be called only if suhosin extension is loaded', 1422634778);
699  }
700  }
701 
707  protected function checkSuhosinRequestMaxVars()
708  {
709  $recommendedRequestMaxVars = 400;
710  if ($this->isSuhosinLoadedAndActive()) {
711  $currentRequestMaxVars = ini_get('suhosin.request.max_vars');
712  if ($currentRequestMaxVars < $recommendedRequestMaxVars) {
713  $status = new Status\ErrorStatus();
714  $status->setTitle('PHP suhosin.request.max_vars too low');
715  $status->setMessage(
716  'suhosin.request.max_vars=' . $currentRequestMaxVars . LF .
717  'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
718  ' (as the install tool does). It is highly recommended to raise this' .
719  ' to at least ' . $recommendedRequestMaxVars . ':' . LF .
720  'suhosin.request.max_vars=' . $recommendedRequestMaxVars
721  );
722  } else {
723  $status = new Status\OkStatus();
724  $status->setTitle('PHP suhosin.request.max_vars ok');
725  }
726  } else {
727  $status = new Status\InfoStatus();
728  $status->setTitle('Suhosin not loaded');
729  $status->setMessage(
730  'If enabling suhosin, suhosin.request.max_vars' .
731  ' should be set to at least ' . $recommendedRequestMaxVars . ':' . LF .
732  'suhosin.request.max_vars=' . $recommendedRequestMaxVars
733  );
734  }
735  return $status;
736  }
737 
744  {
745  $recommendedRequestMaxVarnameLength = 200;
746  if ($this->isSuhosinLoadedAndActive()) {
747  $currentRequestMaxVarnameLength = ini_get('suhosin.request.max_varname_length');
748  if ($currentRequestMaxVarnameLength < $recommendedRequestMaxVarnameLength) {
749  $status = new Status\ErrorStatus();
750  $status->setTitle('PHP suhosin.request.max_varname_length too low');
751  $status->setMessage(
752  'suhosin.request.max_varname_length=' . $currentRequestMaxVarnameLength . LF .
753  'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
754  ' (as the install tool does). It is highly recommended to raise this' .
755  ' to at least ' . $recommendedRequestMaxVarnameLength . ':' . LF .
756  'suhosin.request.max_varname_length=' . $recommendedRequestMaxVarnameLength
757  );
758  } else {
759  $status = new Status\OkStatus();
760  $status->setTitle('PHP suhosin.request.max_varname_length ok');
761  }
762  } else {
763  $status = new Status\InfoStatus();
764  $status->setTitle('Suhosin not loaded');
765  $status->setMessage(
766  'If enabling suhosin, suhosin.request.max_varname_length' .
767  ' should be set to at least ' . $recommendedRequestMaxVarnameLength . ':' . LF .
768  'suhosin.request.max_varname_length=' . $recommendedRequestMaxVarnameLength
769  );
770  }
771  return $status;
772  }
773 
779  protected function checkSuhosinPostMaxNameLength()
780  {
781  $recommendedPostMaxNameLength = 200;
782  if ($this->isSuhosinLoadedAndActive()) {
783  $currentPostMaxNameLength = ini_get('suhosin.post.max_name_length');
784  if ($currentPostMaxNameLength < $recommendedPostMaxNameLength) {
785  $status = new Status\ErrorStatus();
786  $status->setTitle('PHP suhosin.post.max_name_length too low');
787  $status->setMessage(
788  'suhosin.post.max_name_length=' . $currentPostMaxNameLength . LF .
789  'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
790  ' (as the install tool does). It is highly recommended to raise this' .
791  ' to at least ' . $recommendedPostMaxNameLength . ':' . LF .
792  'suhosin.post.max_name_length=' . $recommendedPostMaxNameLength
793  );
794  } else {
795  $status = new Status\OkStatus();
796  $status->setTitle('PHP suhosin.post.max_name_length ok');
797  }
798  } else {
799  $status = new Status\InfoStatus();
800  $status->setTitle('Suhosin not loaded');
801  $status->setMessage(
802  'If enabling suhosin, suhosin.post.max_name_length' .
803  ' should be set to at least ' . $recommendedPostMaxNameLength . ':' . LF .
804  'suhosin.post.max_name_length=' . $recommendedPostMaxNameLength
805  );
806  }
807  return $status;
808  }
809 
815  protected function checkSuhosinPostMaxVars()
816  {
817  $recommendedPostMaxVars = 400;
818  if ($this->isSuhosinLoadedAndActive()) {
819  $currentPostMaxVars = ini_get('suhosin.post.max_vars');
820  if ($currentPostMaxVars < $recommendedPostMaxVars) {
821  $status = new Status\ErrorStatus();
822  $status->setTitle('PHP suhosin.post.max_vars too low');
823  $status->setMessage(
824  'suhosin.post.max_vars=' . $currentPostMaxVars . LF .
825  'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
826  ' (as the install tool does). It is highly recommended to raise this' .
827  ' to at least ' . $recommendedPostMaxVars . ':' . LF .
828  'suhosin.post.max_vars=' . $recommendedPostMaxVars
829  );
830  } else {
831  $status = new Status\OkStatus();
832  $status->setTitle('PHP suhosin.post.max_vars ok');
833  }
834  } else {
835  $status = new Status\InfoStatus();
836  $status->setTitle('Suhosin not loaded');
837  $status->setMessage(
838  'If enabling suhosin, suhosin.post.max_vars' .
839  ' should be set to at least ' . $recommendedPostMaxVars . ':' . LF .
840  'suhosin.post.max_vars=' . $recommendedPostMaxVars
841  );
842  }
843  return $status;
844  }
845 
851  protected function checkSuhosinGetMaxValueLength()
852  {
853  $recommendedGetMaxValueLength = 2000;
854  if ($this->isSuhosinLoadedAndActive()) {
855  $currentGetMaxValueLength = ini_get('suhosin.get.max_value_length');
856  if ($currentGetMaxValueLength < $recommendedGetMaxValueLength) {
857  $status = new Status\ErrorStatus();
858  $status->setTitle('PHP suhosin.get.max_value_length too low');
859  $status->setMessage(
860  'suhosin.get.max_value_length=' . $currentGetMaxValueLength . LF .
861  'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
862  ' (as the install tool does). It is highly recommended to raise this' .
863  ' to at least ' . $recommendedGetMaxValueLength . ':' . LF .
864  'suhosin.get.max_value_length=' . $recommendedGetMaxValueLength
865  );
866  } else {
867  $status = new Status\OkStatus();
868  $status->setTitle('PHP suhosin.get.max_value_length ok');
869  }
870  } else {
871  $status = new Status\InfoStatus();
872  $status->setTitle('Suhosin not loaded');
873  $status->setMessage(
874  'If enabling suhosin, suhosin.get.max_value_length' .
875  ' should be set to at least ' . $recommendedGetMaxValueLength . ':' . LF .
876  'suhosin.get.max_value_length=' . $recommendedGetMaxValueLength
877  );
878  }
879  return $status;
880  }
881 
887  protected function checkSuhosinGetMaxNameLength()
888  {
889  $recommendedGetMaxNameLength = 200;
890  if ($this->isSuhosinLoadedAndActive()) {
891  $currentGetMaxNameLength = ini_get('suhosin.get.max_name_length');
892  if ($currentGetMaxNameLength < $recommendedGetMaxNameLength) {
893  $status = new Status\ErrorStatus();
894  $status->setTitle('PHP suhosin.get.max_name_length too low');
895  $status->setMessage(
896  'suhosin.get.max_name_length=' . $currentGetMaxNameLength . LF .
897  'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
898  ' (as the install tool does). It is highly recommended to raise this' .
899  ' to at least ' . $recommendedGetMaxNameLength . ':' . LF .
900  'suhosin.get.max_name_length=' . $recommendedGetMaxNameLength
901  );
902  } else {
903  $status = new Status\OkStatus();
904  $status->setTitle('PHP suhosin.get.max_name_length ok');
905  }
906  } else {
907  $status = new Status\InfoStatus();
908  $status->setTitle('Suhosin not loaded');
909  $status->setMessage(
910  'If enabling suhosin, suhosin.get.max_name_length' .
911  ' should be set to at least ' . $recommendedGetMaxNameLength . ':' . LF .
912  'suhosin.get.max_name_length=' . $recommendedGetMaxNameLength
913  );
914  }
915  return $status;
916  }
917 
924  {
925  if ($this->isSuhosinLoadedAndActive()) {
926  $whitelist = (string)ini_get('suhosin.executor.include.whitelist');
927  if (strpos($whitelist, 'phar') === false) {
928  $status = new Status\NoticeStatus();
929  $status->setTitle('PHP suhosin.executor.include.whitelist does not contain phar');
930  $status->setMessage(
931  'suhosin.executor.include.whitelist= ' . $whitelist . LF .
932  '"phar" is currently not a hard requirement of TYPO3 CMS but is nice to have and a possible' .
933  ' requirement in future versions. A useful setting is:' . LF .
934  'suhosin.executor.include.whitelist=phar,vfs'
935  );
936  } else {
937  $status = new Status\OkStatus();
938  $status->setTitle('PHP suhosin.executor.include.whitelist contains phar');
939  }
940  } else {
941  $status = new Status\InfoStatus();
942  $status->setTitle('Suhosin not loaded');
943  $status->setMessage(
944  'If enabling suhosin, a useful setting is:' . LF .
945  'suhosin.executor.include.whitelist=phar,vfs'
946  );
947  }
948  return $status;
949  }
950 
957  {
958  if ($this->isSuhosinLoadedAndActive()) {
959  $whitelist = (string)ini_get('suhosin.executor.include.whitelist');
960  if (strpos($whitelist, 'vfs') === false) {
961  $status = new Status\WarningStatus();
962  $status->setTitle('PHP suhosin.executor.include.whitelist does not contain vfs');
963  $status->setMessage(
964  'suhosin.executor.include.whitelist= ' . $whitelist . LF .
965  '"vfs" is currently not a hard requirement of TYPO3 CMS but tons of unit tests rely on it.' .
966  ' Furthermore, vfs will likely be a base for an additional compatibility layer in the future.' .
967  ' A useful setting is:' . LF .
968  'suhosin.executor.include.whitelist=phar,vfs'
969  );
970  } else {
971  $status = new Status\OkStatus();
972  $status->setTitle('PHP suhosin.executor.include.whitelist contains vfs');
973  }
974  } else {
975  $status = new Status\InfoStatus();
976  $status->setTitle('Suhosin not loaded');
977  $status->setMessage(
978  'If enabling suhosin, a useful setting is:' . LF .
979  'suhosin.executor.include.whitelist=phar,vfs'
980  );
981  }
982  return $status;
983  }
984 
990  protected function checkSomePhpOpcodeCacheIsLoaded()
991  {
992  // Link to our wiki page, so we can update opcode cache issue information independent of TYPO3 CMS releases.
993  $wikiLink = 'For more information take a look in our wiki ' . TYPO3_URL_WIKI_OPCODECACHE . '.';
994  $opcodeCaches = GeneralUtility::makeInstance(OpcodeCacheService::class)->getAllActive();
995  if (empty($opcodeCaches)) {
996  // Set status to notice. It needs to be notice so email won't be triggered.
997  $status = new Status\NoticeStatus();
998  $status->setTitle('No PHP opcode cache loaded');
999  $status->setMessage(
1000  'PHP opcode caches hold a compiled version of executed PHP scripts in' .
1001  ' memory and do not require to recompile a script each time it is accessed.' .
1002  ' This can be a massive performance improvement and can reduce the load on a' .
1003  ' server in general. A parse time reduction by factor three for fully cached' .
1004  ' pages can be achieved easily if using an opcode cache.' .
1005  LF . $wikiLink
1006  );
1007  } else {
1008  $status = new Status\OkStatus();
1009  $message = '';
1010 
1011  foreach ($opcodeCaches as $opcodeCache => $properties) {
1012  $message .= 'Name: ' . $opcodeCache . ' Version: ' . $properties['version'];
1013  $message .= LF;
1014 
1015  if ($properties['error']) {
1016  // Set status to error if not already set
1017  if ($status->getSeverity() !== 'error') {
1018  $status = new Status\ErrorStatus();
1019  }
1020  $message .= ' This opcode cache is marked as malfunctioning by the TYPO3 CMS Team.';
1021  } elseif ($properties['canInvalidate']) {
1022  $message .= ' This opcode cache should work correctly and has good performance.';
1023  } else {
1024  // Set status to notice if not already error set. It needs to be notice so email won't be triggered.
1025  if ($status->getSeverity() !== 'error' || $status->getSeverity() !== 'warning') {
1026  $status = new Status\NoticeStatus();
1027  }
1028  $message .= ' This opcode cache may work correctly but has medium performance.';
1029  }
1030  $message .= LF;
1031  }
1032 
1033  $message .= $wikiLink;
1034 
1035  // Set title of status depending on serverity
1036  switch ($status->getSeverity()) {
1037  case 'error':
1038  $status->setTitle('A possibly malfunctioning PHP opcode cache is loaded');
1039  break;
1040  case 'warning':
1041  $status->setTitle('A PHP opcode cache is loaded which may cause problems');
1042  break;
1043  case 'ok':
1044  default:
1045  $status->setTitle('A PHP opcode cache is loaded');
1046  break;
1047  }
1048  $status->setMessage($message);
1049  }
1050  return $status;
1051  }
1052 
1058  protected function checkReflectionDocComment()
1059  {
1060  $testReflection = new \ReflectionMethod(get_class($this), __FUNCTION__);
1061  if ($testReflection->getDocComment() === false) {
1062  $status = new Status\AlertStatus();
1063  $status->setTitle('PHP Doc comment reflection broken');
1064  $status->setMessage(
1065  'TYPO3 CMS core extensions like extbase and fluid heavily rely on method'
1066  . ' comment parsing to fetch annotations and add magic belonging to them.'
1067  . ' This does not work in the current environment and so we cannot install'
1068  . ' TYPO3 CMS.' . LF
1069  . ' Here are some possibilities: ' . LF
1070  . '* In Zend OPcache you can disable saving/loading comments. If you are using'
1071  . ' Zend OPcache (included since PHP 5.5) then check your php.ini settings for'
1072  . ' opcache.save_comments and opcache.load_comments and enable them.' . LF
1073  . '* In Zend Optimizer+ you can disable saving comments. If you are using'
1074  . ' Zend Optimizer+ then check your php.ini settings for'
1075  . ' zend_optimizerplus.save_comments and enable it.' . LF
1076  . '* The PHP extension eaccelerator is known to break this if'
1077  . ' it is compiled without --with-eaccelerator-doc-comment-inclusion flag.'
1078  . ' This compile flag must be specified, otherwise TYPO3 CMS will not work.' . LF
1079  . 'For more information take a look in our wiki ' . TYPO3_URL_WIKI_OPCODECACHE . '.'
1080  );
1081  } else {
1082  $status = new Status\OkStatus();
1083  $status->setTitle('PHP Doc comment reflection works');
1084  }
1085  return $status;
1086  }
1087 
1093  protected function checkSystemLocale()
1094  {
1095  $currentLocale = setlocale(LC_CTYPE, 0);
1096 
1097  // On Windows an empty locale value uses the regional settings from the Control Panel
1098  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && TYPO3_OS !== 'WIN') {
1099  $status = new Status\InfoStatus();
1100  $status->setTitle('Empty systemLocale setting');
1101  $status->setMessage(
1102  '$GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is not set. This is fine as long as no UTF-8' .
1103  ' file system is used.'
1104  );
1105  } elseif (setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']) === false) {
1106  $status = new Status\ErrorStatus();
1107  $status->setTitle('Incorrect systemLocale setting');
1108  $status->setMessage(
1109  'Current value of the $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is incorrect. A locale with' .
1110  ' this name doesn\'t exist in the operating system.'
1111  );
1112  setlocale(LC_CTYPE, $currentLocale);
1113  } else {
1114  $status = new Status\OkStatus();
1115  $status->setTitle('System locale is correct');
1116  }
1117 
1118  return $status;
1119  }
1120 
1127  protected function checkLocaleWithUTF8filesystem()
1128  {
1129  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
1130  // On Windows an empty local value uses the regional settings from the Control Panel
1131  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && TYPO3_OS !== 'WIN') {
1132  $status = new Status\ErrorStatus();
1133  $status->setTitle('System locale not set on UTF-8 file system');
1134  $status->setMessage(
1135  '$GLOBALS[TYPO3_CONF_VARS][SYS][UTF8filesystem] is set, but $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale]' .
1136  ' is empty. Make sure a valid locale which supports UTF-8 is set.'
1137  );
1138  } else {
1139  $testString = 'ÖöĄĆŻĘĆćążąęó.jpg';
1140  $currentLocale = setlocale(LC_CTYPE, 0);
1141  $quote = TYPO3_OS === 'WIN' ? '"' : '\'';
1142 
1143  setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
1144 
1145  if (escapeshellarg($testString) === $quote . $testString . $quote) {
1146  $status = new Status\OkStatus();
1147  $status->setTitle('File names with UTF-8 characters can be used.');
1148  } else {
1149  $status = new Status\ErrorStatus();
1150  $status->setTitle('System locale setting doesn\'t support UTF-8 file names.');
1151  $status->setMessage(
1152  'Please check your $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] setting.'
1153  );
1154  }
1155 
1156  setlocale(LC_CTYPE, $currentLocale);
1157  }
1158  } else {
1159  $status = new Status\OkStatus();
1160  $status->setTitle('Skipping test, as UTF8filesystem is not enabled.');
1161  }
1162 
1163  return $status;
1164  }
1165 
1172  {
1173  if ($this->isWindowsOs()
1174  && substr($_SERVER['SERVER_SOFTWARE'], 0, 6) === 'Apache'
1175  ) {
1176  $status = new Status\WarningStatus();
1177  $status->setTitle('Windows apache thread stack size');
1178  $status->setMessage(
1179  'This current value cannot be checked by the system, so please ignore this warning if it' .
1180  ' is already taken care of: Fluid uses complex regular expressions which require a lot' .
1181  ' of stack space during the first processing.' .
1182  ' On Windows the default stack size for Apache is a lot smaller than on UNIX.' .
1183  ' You can increase the size to 8MB (default on UNIX) by adding the following configuration' .
1184  ' to httpd.conf and restarting Apache afterwards:' . LF .
1185  '<IfModule mpm_winnt_module>' . LF .
1186  'ThreadStackSize 8388608' . LF .
1187  '</IfModule>'
1188  );
1189  } else {
1190  $status = new Status\OkStatus();
1191  $status->setTitle('Apache ThreadStackSize is not an issue on UNIX systems');
1192  }
1193  return $status;
1194  }
1195 
1202  protected function checkRequiredPhpExtension($extension)
1203  {
1204  if (!extension_loaded($extension)) {
1205  $status = new Status\ErrorStatus();
1206  $status->setTitle('PHP extension ' . $extension . ' not loaded');
1207  $status->setMessage(
1208  'TYPO3 CMS uses PHP extension ' . $extension . ' but it is not loaded' .
1209  ' in your environment. Change your environment to provide this extension.'
1210  );
1211  } else {
1212  $status = new Status\OkStatus();
1213  $status->setTitle('PHP extension ' . $extension . ' loaded');
1214  }
1215  return $status;
1216  }
1217 
1223  protected function checkGdLibTrueColorSupport()
1224  {
1225  if (function_exists('imagecreatetruecolor')) {
1226  $imageResource = @imagecreatetruecolor(50, 100);
1227  if (is_resource($imageResource)) {
1228  imagedestroy($imageResource);
1229  $status = new Status\OkStatus();
1230  $status->setTitle('PHP GD library true color works');
1231  } else {
1232  $status = new Status\ErrorStatus();
1233  $status->setTitle('PHP GD library true color support broken');
1234  $status->setMessage(
1235  'GD is loaded, but calling imagecreatetruecolor() fails.' .
1236  ' This must be fixed, TYPO3 CMS won\'t work well otherwise.'
1237  );
1238  }
1239  } else {
1240  $status = new Status\ErrorStatus();
1241  $status->setTitle('PHP GD library true color support missing');
1242  $status->setMessage(
1243  'Gdlib is essential for TYPO3 CMS to work properly.'
1244  );
1245  }
1246  return $status;
1247  }
1248 
1254  protected function checkGdLibGifSupport()
1255  {
1256  if (function_exists('imagecreatefromgif')
1257  && function_exists('imagegif')
1258  && (imagetypes() & IMG_GIF)
1259  ) {
1260  $imageResource = @imagecreatefromgif(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.gif');
1261  if (is_resource($imageResource)) {
1262  imagedestroy($imageResource);
1263  $status = new Status\OkStatus();
1264  $status->setTitle('PHP GD library has gif support');
1265  } else {
1266  $status = new Status\ErrorStatus();
1267  $status->setTitle('PHP GD library gif support broken');
1268  $status->setMessage(
1269  'GD is loaded, but calling imagecreatefromgif() fails.' .
1270  ' This must be fixed, TYPO3 CMS won\'t work well otherwise.'
1271  );
1272  }
1273  } else {
1274  $status = new Status\ErrorStatus();
1275  $status->setTitle('PHP GD library gif support missing');
1276  $status->setMessage(
1277  'GD must be compiled with gif support. This is essential for' .
1278  ' TYPO3 CMS to work properly.'
1279  );
1280  }
1281  return $status;
1282  }
1283 
1289  protected function checkGdLibJpgSupport()
1290  {
1291  if (function_exists('imagecreatefromjpeg')
1292  && function_exists('imagejpeg')
1293  && (imagetypes() & IMG_JPG)
1294  ) {
1295  $status = new Status\OkStatus();
1296  $status->setTitle('PHP GD library has jpg support');
1297  } else {
1298  $status = new Status\ErrorStatus();
1299  $status->setTitle('PHP GD library jpg support missing');
1300  $status->setMessage(
1301  'GD must be compiled with jpg support. This is essential for' .
1302  ' TYPO3 CMS to work properly.'
1303  );
1304  }
1305  return $status;
1306  }
1307 
1313  protected function checkGdLibPngSupport()
1314  {
1315  if (function_exists('imagecreatefrompng')
1316  && function_exists('imagepng')
1317  && (imagetypes() & IMG_PNG)
1318  ) {
1319  $imageResource = @imagecreatefrompng(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.png');
1320  if (is_resource($imageResource)) {
1321  imagedestroy($imageResource);
1322  $status = new Status\OkStatus();
1323  $status->setTitle('PHP GD library has png support');
1324  } else {
1325  $status = new Status\ErrorStatus();
1326  $status->setTitle('PHP GD library png support broken');
1327  $status->setMessage(
1328  'GD is compiled with png support, but calling imagecreatefrompng() fails.' .
1329  ' Check your environment and fix it, png in GD lib is important' .
1330  ' for TYPO3 CMS to work properly.'
1331  );
1332  }
1333  } else {
1334  $status = new Status\ErrorStatus();
1335  $status->setTitle('PHP GD library png support missing');
1336  $status->setMessage(
1337  'GD must be compiled with png support. This is essential for' .
1338  ' TYPO3 CMS to work properly'
1339  );
1340  }
1341  return $status;
1342  }
1343 
1349  protected function checkGdLibFreeTypeSupport()
1350  {
1351  if (function_exists('imagettftext')) {
1352  $status = new Status\OkStatus();
1353  $status->setTitle('PHP GD library has freetype font support');
1354  $status->setMessage(
1355  'There is a difference between the font size setting which the GD' .
1356  ' library should be supplied with. If installation is completed' .
1357  ' a test in the install tool helps to find out the value you need.'
1358  );
1359  } else {
1360  $status = new Status\ErrorStatus();
1361  $status->setTitle('PHP GD library freetype support missing');
1362  $status->setMessage(
1363  'Some core functionality and extension rely on the GD' .
1364  ' to render fonts on images. This support is missing' .
1365  ' in your environment. Install it.'
1366  );
1367  }
1368  return $status;
1369  }
1370 
1376  protected function isTrueTypeFontWorking()
1377  {
1378  if (function_exists('imageftbbox')) {
1379  // 20 Pixels at 96 DPI
1380  $fontSize = (20 / 96 * 72);
1381  $textDimensions = @imageftbbox(
1382  $fontSize,
1383  0,
1384  __DIR__ . '/../../Resources/Private/Font/vera.ttf',
1385  'Testing true type support'
1386  );
1387  $fontBoxWidth = $textDimensions[2] - $textDimensions[0];
1388  if ($fontBoxWidth < 300 && $fontBoxWidth > 200) {
1389  $status = new Status\OkStatus();
1390  $status->setTitle('FreeType True Type Font DPI');
1391  $status->setMessage('Fonts are rendered by FreeType library. ' .
1392  'We need to ensure that the final dimensions are as expected. ' .
1393  'This server renderes fonts based on 96 DPI correctly');
1394  } else {
1395  $status = new Status\NoticeStatus();
1396  $status->setTitle('FreeType True Type Font DPI');
1397  $status->setMessage('Fonts are rendered by FreeType library. ' .
1398  'This server does not render fonts as expected. ' .
1399  'Please check your FreeType 2 module.');
1400  }
1401  } else {
1402  $status = new Status\ErrorStatus();
1403  $status->setTitle('PHP GD library freetype2 support missing');
1404  $status->setMessage(
1405  'The core relies on GD library compiled into PHP with freetype2' .
1406  ' support. This is missing on your system. Please install it.'
1407  );
1408  }
1409 
1410  return $status;
1411  }
1412 
1418  protected function checkRegisterGlobals()
1419  {
1420  $registerGlobalsEnabled = filter_var(
1421  ini_get('register_globals'),
1422  FILTER_VALIDATE_BOOLEAN,
1423  [FILTER_REQUIRE_SCALAR, FILTER_NULL_ON_FAILURE]
1424  );
1425  if ($registerGlobalsEnabled === true) {
1426  $status = new Status\ErrorStatus();
1427  $status->setTitle('PHP register globals on');
1428  $status->setMessage(
1429  'register_globals=' . ini_get('register_globals') . LF .
1430  'TYPO3 requires PHP setting "register_globals" set to off.' .
1431  ' This ancient PHP setting is a big security problem and should' .
1432  ' never be enabled:' . LF .
1433  'register_globals=Off'
1434  );
1435  } else {
1436  $status = new Status\OkStatus();
1437  $status->setTitle('PHP register globals off');
1438  }
1439  return $status;
1440  }
1441 
1447  protected function checkLibXmlBug()
1448  {
1449  $sampleArray = ['Test>><<Data'];
1450 
1451  $xmlContent = '<numIndex index="0">Test&gt;&gt;&lt;&lt;Data</numIndex>' . LF;
1452 
1453  $xml = \TYPO3\CMS\Core\Utility\GeneralUtility::array2xml($sampleArray, '', -1);
1454 
1455  if ($xmlContent !== $xml) {
1456  $status = new Status\ErrorStatus();
1457  $status->setTitle('PHP libxml bug present');
1458  $status->setMessage(
1459  'Some hosts have problems saving ">><<" in a flexform.' .
1460  ' To fix this, enable [BE][flexformForceCDATA] in' .
1461  ' All Configuration.'
1462  );
1463  } else {
1464  $status = new Status\OkStatus();
1465  $status->setTitle('PHP libxml bug not present');
1466  }
1467  return $status;
1468  }
1469 
1480  protected function isValidIp($ip)
1481  {
1482  return filter_var($ip, FILTER_VALIDATE_IP) !== false;
1483  }
1484 
1490  protected function isWindowsOs()
1491  {
1492  $windowsOs = false;
1493  if (!stristr(PHP_OS, 'darwin') && stristr(PHP_OS, 'win')) {
1494  $windowsOs = true;
1495  }
1496  return $windowsOs;
1497  }
1498 
1504  protected function isSuhosinLoadedAndActive()
1505  {
1506  $suhosinLoaded = false;
1507  if (extension_loaded('suhosin')) {
1508  $suhosinInSimulationMode = filter_var(
1509  ini_get('suhosin.simulation'),
1510  FILTER_VALIDATE_BOOLEAN,
1511  [FILTER_REQUIRE_SCALAR, FILTER_NULL_ON_FAILURE]
1512  );
1513  if (!$suhosinInSimulationMode) {
1514  $suhosinLoaded = true;
1515  }
1516  }
1517  return $suhosinLoaded;
1518  }
1519 
1528  protected function trimExplode($delimiter, $string)
1529  {
1530  $explodedValues = explode($delimiter, $string);
1531  $resultWithPossibleEmptyValues = array_map('trim', $explodedValues);
1532  $result = [];
1533  foreach ($resultWithPossibleEmptyValues as $value) {
1534  if ($value !== '') {
1535  $result[] = $value;
1536  }
1537  }
1538  return $result;
1539  }
1540 
1547  protected function getBytesFromSizeMeasurement($measurement)
1548  {
1549  $bytes = floatval($measurement);
1550  if (stripos($measurement, 'G')) {
1551  $bytes *= 1024 * 1024 * 1024;
1552  } elseif (stripos($measurement, 'M')) {
1553  $bytes *= 1024 * 1024;
1554  } elseif (stripos($measurement, 'K')) {
1555  $bytes *= 1024;
1556  }
1557  return (int)$bytes;
1558  }
1559 }
static array2xml(array $array, $NSprefix='', $level=0, $docTag='phparray', $spaceInd=0, array $options=[], array $stackData=[])
static hostHeaderValueMatchesTrustedHostsPattern($hostHeaderValue)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']