[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/simplepie/library/SimplePie/ -> gzdecode.php (source)

   1  <?php
   2  /**
   3   * SimplePie
   4   *
   5   * A PHP-Based RSS and Atom Feed Framework.
   6   * Takes the hard work out of managing a complete RSS/Atom solution.
   7   *
   8   * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
   9   * All rights reserved.
  10   *
  11   * Redistribution and use in source and binary forms, with or without modification, are
  12   * permitted provided that the following conditions are met:
  13   *
  14   *     * Redistributions of source code must retain the above copyright notice, this list of
  15   *       conditions and the following disclaimer.
  16   *
  17   *     * Redistributions in binary form must reproduce the above copyright notice, this list
  18   *       of conditions and the following disclaimer in the documentation and/or other materials
  19   *       provided with the distribution.
  20   *
  21   *     * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22   *       to endorse or promote products derived from this software without specific prior
  23   *       written permission.
  24   *
  25   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26   * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27   * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28   * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33   * POSSIBILITY OF SUCH DAMAGE.
  34   *
  35   * @package SimplePie
  36   * @version 1.3.1
  37   * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
  38   * @author Ryan Parman
  39   * @author Geoffrey Sneddon
  40   * @author Ryan McCue
  41   * @link http://simplepie.org/ SimplePie
  42   * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  43   */
  44  
  45  
  46  /**
  47   * Decode 'gzip' encoded HTTP data
  48   *
  49   * @package SimplePie
  50   * @subpackage HTTP
  51   * @link http://www.gzip.org/format.txt
  52   */
  53  class SimplePie_gzdecode
  54  {
  55      /**
  56       * Compressed data
  57       *
  58       * @access private
  59       * @var string
  60       * @see gzdecode::$data
  61       */
  62      var $compressed_data;
  63  
  64      /**
  65       * Size of compressed data
  66       *
  67       * @access private
  68       * @var int
  69       */
  70      var $compressed_size;
  71  
  72      /**
  73       * Minimum size of a valid gzip string
  74       *
  75       * @access private
  76       * @var int
  77       */
  78      var $min_compressed_size = 18;
  79  
  80      /**
  81       * Current position of pointer
  82       *
  83       * @access private
  84       * @var int
  85       */
  86      var $position = 0;
  87  
  88      /**
  89       * Flags (FLG)
  90       *
  91       * @access private
  92       * @var int
  93       */
  94      var $flags;
  95  
  96      /**
  97       * Uncompressed data
  98       *
  99       * @access public
 100       * @see gzdecode::$compressed_data
 101       * @var string
 102       */
 103      var $data;
 104  
 105      /**
 106       * Modified time
 107       *
 108       * @access public
 109       * @var int
 110       */
 111      var $MTIME;
 112  
 113      /**
 114       * Extra Flags
 115       *
 116       * @access public
 117       * @var int
 118       */
 119      var $XFL;
 120  
 121      /**
 122       * Operating System
 123       *
 124       * @access public
 125       * @var int
 126       */
 127      var $OS;
 128  
 129      /**
 130       * Subfield ID 1
 131       *
 132       * @access public
 133       * @see gzdecode::$extra_field
 134       * @see gzdecode::$SI2
 135       * @var string
 136       */
 137      var $SI1;
 138  
 139      /**
 140       * Subfield ID 2
 141       *
 142       * @access public
 143       * @see gzdecode::$extra_field
 144       * @see gzdecode::$SI1
 145       * @var string
 146       */
 147      var $SI2;
 148  
 149      /**
 150       * Extra field content
 151       *
 152       * @access public
 153       * @see gzdecode::$SI1
 154       * @see gzdecode::$SI2
 155       * @var string
 156       */
 157      var $extra_field;
 158  
 159      /**
 160       * Original filename
 161       *
 162       * @access public
 163       * @var string
 164       */
 165      var $filename;
 166  
 167      /**
 168       * Human readable comment
 169       *
 170       * @access public
 171       * @var string
 172       */
 173      var $comment;
 174  
 175      /**
 176       * Don't allow anything to be set
 177       *
 178       * @param string $name
 179       * @param mixed $value
 180       */
 181  	public function __set($name, $value)
 182      {
 183          trigger_error("Cannot write property $name", E_USER_ERROR);
 184      }
 185  
 186      /**
 187       * Set the compressed string and related properties
 188       *
 189       * @param string $data
 190       */
 191  	public function __construct($data)
 192      {
 193          $this->compressed_data = $data;
 194          $this->compressed_size = strlen($data);
 195      }
 196  
 197      /**
 198       * Decode the GZIP stream
 199       *
 200       * @return bool Successfulness
 201       */
 202  	public function parse()
 203      {
 204          if ($this->compressed_size >= $this->min_compressed_size)
 205          {
 206              // Check ID1, ID2, and CM
 207              if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
 208              {
 209                  return false;
 210              }
 211  
 212              // Get the FLG (FLaGs)
 213              $this->flags = ord($this->compressed_data[3]);
 214  
 215              // FLG bits above (1 << 4) are reserved
 216              if ($this->flags > 0x1F)
 217              {
 218                  return false;
 219              }
 220  
 221              // Advance the pointer after the above
 222              $this->position += 4;
 223  
 224              // MTIME
 225              $mtime = substr($this->compressed_data, $this->position, 4);
 226              // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
 227              if (current(unpack('S', "\x00\x01")) === 1)
 228              {
 229                  $mtime = strrev($mtime);
 230              }
 231              $this->MTIME = current(unpack('l', $mtime));
 232              $this->position += 4;
 233  
 234              // Get the XFL (eXtra FLags)
 235              $this->XFL = ord($this->compressed_data[$this->position++]);
 236  
 237              // Get the OS (Operating System)
 238              $this->OS = ord($this->compressed_data[$this->position++]);
 239  
 240              // Parse the FEXTRA
 241              if ($this->flags & 4)
 242              {
 243                  // Read subfield IDs
 244                  $this->SI1 = $this->compressed_data[$this->position++];
 245                  $this->SI2 = $this->compressed_data[$this->position++];
 246  
 247                  // SI2 set to zero is reserved for future use
 248                  if ($this->SI2 === "\x00")
 249                  {
 250                      return false;
 251                  }
 252  
 253                  // Get the length of the extra field
 254                  $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
 255                  $this->position += 2;
 256  
 257                  // Check the length of the string is still valid
 258                  $this->min_compressed_size += $len + 4;
 259                  if ($this->compressed_size >= $this->min_compressed_size)
 260                  {
 261                      // Set the extra field to the given data
 262                      $this->extra_field = substr($this->compressed_data, $this->position, $len);
 263                      $this->position += $len;
 264                  }
 265                  else
 266                  {
 267                      return false;
 268                  }
 269              }
 270  
 271              // Parse the FNAME
 272              if ($this->flags & 8)
 273              {
 274                  // Get the length of the filename
 275                  $len = strcspn($this->compressed_data, "\x00", $this->position);
 276  
 277                  // Check the length of the string is still valid
 278                  $this->min_compressed_size += $len + 1;
 279                  if ($this->compressed_size >= $this->min_compressed_size)
 280                  {
 281                      // Set the original filename to the given string
 282                      $this->filename = substr($this->compressed_data, $this->position, $len);
 283                      $this->position += $len + 1;
 284                  }
 285                  else
 286                  {
 287                      return false;
 288                  }
 289              }
 290  
 291              // Parse the FCOMMENT
 292              if ($this->flags & 16)
 293              {
 294                  // Get the length of the comment
 295                  $len = strcspn($this->compressed_data, "\x00", $this->position);
 296  
 297                  // Check the length of the string is still valid
 298                  $this->min_compressed_size += $len + 1;
 299                  if ($this->compressed_size >= $this->min_compressed_size)
 300                  {
 301                      // Set the original comment to the given string
 302                      $this->comment = substr($this->compressed_data, $this->position, $len);
 303                      $this->position += $len + 1;
 304                  }
 305                  else
 306                  {
 307                      return false;
 308                  }
 309              }
 310  
 311              // Parse the FHCRC
 312              if ($this->flags & 2)
 313              {
 314                  // Check the length of the string is still valid
 315                  $this->min_compressed_size += $len + 2;
 316                  if ($this->compressed_size >= $this->min_compressed_size)
 317                  {
 318                      // Read the CRC
 319                      $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
 320  
 321                      // Check the CRC matches
 322                      if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
 323                      {
 324                          $this->position += 2;
 325                      }
 326                      else
 327                      {
 328                          return false;
 329                      }
 330                  }
 331                  else
 332                  {
 333                      return false;
 334                  }
 335              }
 336  
 337              // Decompress the actual data
 338              if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
 339              {
 340                  return false;
 341              }
 342              else
 343              {
 344                  $this->position = $this->compressed_size - 8;
 345              }
 346  
 347              // Check CRC of data
 348              $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
 349              $this->position += 4;
 350              /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
 351              {
 352                  return false;
 353              }*/
 354  
 355              // Check ISIZE of data
 356              $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
 357              $this->position += 4;
 358              if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
 359              {
 360                  return false;
 361              }
 362  
 363              // Wow, against all odds, we've actually got a valid gzip string
 364              return true;
 365          }
 366          else
 367          {
 368              return false;
 369          }
 370      }
 371  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1