Merge branch 'master' into next
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / WCF.class.php
index 5e8d289cfae47a402139eac3deb6e9370b172483..3ab7dc1ac55791383949331b1eece7c1f01bcd72 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 namespace wcf\system;
 use wcf\data\application\Application;
 use wcf\data\option\OptionEditor;
@@ -48,7 +49,7 @@ if (!@ini_get('date.timezone')) {
 }
 
 // define current woltlab suite version
-define('WCF_VERSION', '3.1.1');
+define('WCF_VERSION', '3.1.2 pl 2');
 
 // define current API version
 define('WSC_API_VERSION', 2018);
@@ -266,6 +267,12 @@ class WCF {
         * @param       \Exception      $e
         */
        public static final function handleException($e) {
+               // backwards compatibility
+               if ($e instanceof IPrintableException) {
+                       $e->show();
+                       exit;
+               }
+               
                if (ob_get_level()) {
                        // discard any output generated before the exception occurred, prevents exception
                        // being hidden inside HTML elements and therefore not visible in browser output
@@ -273,17 +280,33 @@ class WCF {
                        // ob_get_level() can return values > 1, if the PHP setting `output_buffering` is on
                        while (ob_get_level()) ob_end_clean();
                        
-                       // `identity` is the default "encoding" and basically means that the client
-                       // must treat the content as if the header did not appear in first place, this
-                       // also overrules the gzip header if present
-                       @header('Content-Encoding: identity');
-                       HeaderUtil::exceptionDisableGzip();
-               }
-               
-               // backwards compatibility
-               if ($e instanceof IPrintableException) {
-                       $e->show();
-                       exit;
+                       // Some webservers are broken and will apply gzip encoding at all cost, but they fail
+                       // to set a proper `Content-Encoding` HTTP header and mess things up even more.
+                       // Especially the `identity` value appears to be unrecognized by some of them, hence
+                       // we'll just gzip the output of the exception to prevent them from tampering.
+                       // This part is copied from `HeaderUtil` in order to isolate the exception handler!
+                       if (defined('HTTP_ENABLE_GZIP') && HTTP_ENABLE_GZIP && !defined('HTTP_DISABLE_GZIP')) {
+                               if (function_exists('gzcompress') && !@ini_get('zlib.output_compression') && !@ini_get('output_handler') && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
+                                       if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip') !== false) {
+                                               @header('Content-Encoding: x-gzip');
+                                       }
+                                       else {
+                                               @header('Content-Encoding: gzip');
+                                       }
+                                       
+                                       ob_start(function($output) {
+                                               $size = strlen($output);
+                                               $crc = crc32($output);
+                                               
+                                               $newOutput = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff";
+                                               $newOutput .= substr(gzcompress($output, 1), 2, -4);
+                                               $newOutput .= pack('V', $crc);
+                                               $newOutput .= pack('V', $size);
+                                               
+                                               return $newOutput;
+                                       });
+                               }
+                       }
                }
                
                @header('HTTP/1.1 503 Service Unavailable');
@@ -298,14 +321,6 @@ class WCF {
                        echo "\n\nwas handled.</pre>";
                        exit;
                }
-               catch (\Exception $e2) {
-                       echo "<pre>An Exception was thrown while handling an Exception:\n\n";
-                       echo preg_replace('/Database->__construct\(.*\)/', 'Database->__construct(...)', $e2);
-                       echo "\n\nwas thrown while:\n\n";
-                       echo preg_replace('/Database->__construct\(.*\)/', 'Database->__construct(...)', $e);
-                       echo "\n\nwas handled.</pre>";
-                       exit;
-               }
        }
        
        /**
@@ -649,6 +664,7 @@ class WCF {
         * Returns the invoked application.
         * 
         * @return      Application
+        * @since       3.1
         */
        public static function getActiveApplication() {
                return ApplicationHandler::getInstance()->getActiveApplication();