Make WordPress Core

Ticket #22952: 22952.3.diff

File 22952.3.diff, 4.6 KB (added by dd32, 10 years ago)
  • src/wp-includes/class-http.php

     
    20922092         * then the RFC 1951 standard deflate will be attempted. Finally, the RFC
    20932093         * 1952 standard gzip decode will be attempted. If all fail, then the
    20942094         * original compressed string will be returned.
    20952095         *
    20962096         * @since 2.8.0
    20972097         *
    20982098         * @param string $compressed String to decompress.
    20992099         * @param int $length The optional length of the compressed data.
    21002100         * @return string|bool False on failure.
    21012101         */
    21022102        public static function decompress( $compressed, $length = null ) {
    21032103
    21042104                if ( empty($compressed) )
    21052105                        return $compressed;
    21062106
    2107                 if ( false !== ( $decompressed = @gzinflate( $compressed ) ) )
    2108                         return $decompressed;
    2109 
    21102107                if ( false !== ( $decompressed = WP_Http_Encoding::compatible_gzinflate( $compressed ) ) )
    21112108                        return $decompressed;
    21122109
    21132110                if ( false !== ( $decompressed = @gzuncompress( $compressed ) ) )
    21142111                        return $decompressed;
    21152112
    21162113                if ( function_exists('gzdecode') ) {
    21172114                        $decompressed = @gzdecode( $compressed );
    21182115
    21192116                        if ( false !== $decompressed )
    21202117                                return $decompressed;
    21212118                }
    21222119
    21232120                return $compressed;
    21242121        }
     
    21492146                if ( substr($gzData, 0, 3) == "\x1f\x8b\x08" ) {
    21502147                        $i = 10;
    21512148                        $flg = ord( substr($gzData, 3, 1) );
    21522149                        if ( $flg > 0 ) {
    21532150                                if ( $flg & 4 ) {
    21542151                                        list($xlen) = unpack('v', substr($gzData, $i, 2) );
    21552152                                        $i = $i + 2 + $xlen;
    21562153                                }
    21572154                                if ( $flg & 8 )
    21582155                                        $i = strpos($gzData, "\0", $i) + 1;
    21592156                                if ( $flg & 16 )
    21602157                                        $i = strpos($gzData, "\0", $i) + 1;
    21612158                                if ( $flg & 2 )
    21622159                                        $i = $i + 2;
    21632160                        }
    2164                         $decompressed = @gzinflate( substr($gzData, $i, -8) );
    2165                         if ( false !== $decompressed )
     2161
     2162                        $decompressed = WP_Http_Encoding::compatible_gzinflate( substr( $gzData, $i ) );
     2163                        if ( false !== $decompressed ) {
    21662164                                return $decompressed;
     2165                        }
    21672166                }
    21682167
    2169                 // Compressed data from java.util.zip.Deflater amongst others.
    2170                 $decompressed = @gzinflate( substr($gzData, 2) );
    2171                 if ( false !== $decompressed )
     2168                // If the data is Huffman Encoded, we must first strip the leading 2 byte Huffman marker for gzinflate()
     2169                // The Response is Huffman coded by many compressors such as java.util.zip.Deflater,
     2170                // Ruby’s Zlib::Deflate, and .NET's System.IO.Compression.DeflateStream.
     2171                // See http://decompres.blogspot.com/ for a quick explanation of this data type
     2172                $huffman_encoded = false;
     2173                list( , $first_nibble ) = unpack( 'h', $gzData ); // low nibble of first byte should be 0x08
     2174                list( , $first_two_bytes ) = unpack( 'n', $gzData ); // First 2 bytes should be divisible by 0x1F
     2175                if ( 0x08 == $first_nibble && 0 == ( $first_two_bytes % 0x1F ) )
     2176                        $huffman_encoded = true;
     2177
     2178                if ( $huffman_encoded ) {
     2179                        if ( false !== ( $decompressed = @gzinflate( substr( $gzData, 2 ) ) ) )
     2180                                return $decompressed;
     2181                }
     2182
     2183                if ( "\x50\x4b\x03\x04" == substr( $gzData, 0, 4 ) ) {
     2184                        // ZIP file format header
     2185                        // Offset  6: 2 bytes, General-purpose field
     2186                        // Offset 26: 2 bytes, filename length
     2187                        // Offset 28: 2 bytes, optional field length
     2188                        // Offset 30: Filename field, followed by optional field, followed immediately by data
     2189                        list( , $general_purpose_flag ) = unpack( 'v', substr( $gzData, 6, 2 ) );
     2190
     2191                        // If the file has been compressed on the fly, 0x08 bit is set of the general purpose field
     2192                        // We can use this to differentiate between a compressed document, and a ZIP file
     2193                        $zip_compressed_on_the_fly = ( 0x08 == (0x08 & $general_purpose_flag ) );
     2194
     2195                        if ( ! $zip_compressed_on_the_fly ) {
     2196                                return $gzData; // Don't attempt to decode a compressed zip file from the server
     2197                        }
     2198
     2199                        // Determine the first byte of data, based on the above ZIP header offsets:
     2200                        $first_file_start = array_sum( unpack( 'v2', substr( $gzData, 26, 4 ) ) );
     2201                        if ( false !== ( $decompressed = @gzinflate( substr( $gzData, 30 + $first_file_start ) ) ) ) {
     2202                                return $decompressed;
     2203                        }
     2204
     2205                        return false;
     2206                }
     2207
     2208                // Finally fall back to straight gzinflate
     2209                if ( false !== ( $decompressed = @gzinflate( $gzData ) ) ) {
    21722210                        return $decompressed;
     2211                }
     2212
     2213                // Fallback for all above failing, not expected, but included for debugging and preventing regressions
     2214                if ( false !== ( $decompressed = @gzinflate( substr( $gzData, 2 ) ) ) ) {
     2215                        return $decompressed;
     2216                }
    21732217
    21742218                return false;
    21752219        }
    21762220
    21772221        /**
    21782222         * What encoding types to accept and their priority values.
    21792223         *
    21802224         * @since 2.8.0
    21812225         *
    21822226         * @return string Types of encoding to accept.
    21832227         */
    21842228        public static function accept_encoding( $url, $args ) {
    21852229                $type = array();
    21862230                $compression_enabled = WP_Http_Encoding::is_available();
    21872231