PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/wp-includes/SimplePie/gzdecode.php

https://bitbucket.org/dkrzos/phc
PHP | 371 lines | 142 code | 38 blank | 191 comment | 16 complexity | c538e2bc0e866197db616c17841134d4 MD5 | raw file
Possible License(s): GPL-2.0
  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. * Decode 'gzip' encoded HTTP data
  46. *
  47. * @package SimplePie
  48. * @subpackage HTTP
  49. * @link http://www.gzip.org/format.txt
  50. */
  51. class SimplePie_gzdecode
  52. {
  53. /**
  54. * Compressed data
  55. *
  56. * @access private
  57. * @var string
  58. * @see gzdecode::$data
  59. */
  60. var $compressed_data;
  61. /**
  62. * Size of compressed data
  63. *
  64. * @access private
  65. * @var int
  66. */
  67. var $compressed_size;
  68. /**
  69. * Minimum size of a valid gzip string
  70. *
  71. * @access private
  72. * @var int
  73. */
  74. var $min_compressed_size = 18;
  75. /**
  76. * Current position of pointer
  77. *
  78. * @access private
  79. * @var int
  80. */
  81. var $position = 0;
  82. /**
  83. * Flags (FLG)
  84. *
  85. * @access private
  86. * @var int
  87. */
  88. var $flags;
  89. /**
  90. * Uncompressed data
  91. *
  92. * @access public
  93. * @see gzdecode::$compressed_data
  94. * @var string
  95. */
  96. var $data;
  97. /**
  98. * Modified time
  99. *
  100. * @access public
  101. * @var int
  102. */
  103. var $MTIME;
  104. /**
  105. * Extra Flags
  106. *
  107. * @access public
  108. * @var int
  109. */
  110. var $XFL;
  111. /**
  112. * Operating System
  113. *
  114. * @access public
  115. * @var int
  116. */
  117. var $OS;
  118. /**
  119. * Subfield ID 1
  120. *
  121. * @access public
  122. * @see gzdecode::$extra_field
  123. * @see gzdecode::$SI2
  124. * @var string
  125. */
  126. var $SI1;
  127. /**
  128. * Subfield ID 2
  129. *
  130. * @access public
  131. * @see gzdecode::$extra_field
  132. * @see gzdecode::$SI1
  133. * @var string
  134. */
  135. var $SI2;
  136. /**
  137. * Extra field content
  138. *
  139. * @access public
  140. * @see gzdecode::$SI1
  141. * @see gzdecode::$SI2
  142. * @var string
  143. */
  144. var $extra_field;
  145. /**
  146. * Original filename
  147. *
  148. * @access public
  149. * @var string
  150. */
  151. var $filename;
  152. /**
  153. * Human readable comment
  154. *
  155. * @access public
  156. * @var string
  157. */
  158. var $comment;
  159. /**
  160. * Don't allow anything to be set
  161. *
  162. * @param string $name
  163. * @param mixed $value
  164. */
  165. public function __set($name, $value)
  166. {
  167. trigger_error("Cannot write property $name", E_USER_ERROR);
  168. }
  169. /**
  170. * Set the compressed string and related properties
  171. *
  172. * @param string $data
  173. */
  174. public function __construct($data)
  175. {
  176. $this->compressed_data = $data;
  177. $this->compressed_size = strlen($data);
  178. }
  179. /**
  180. * Decode the GZIP stream
  181. *
  182. * @return bool Successfulness
  183. */
  184. public function parse()
  185. {
  186. if ($this->compressed_size >= $this->min_compressed_size)
  187. {
  188. // Check ID1, ID2, and CM
  189. if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
  190. {
  191. return false;
  192. }
  193. // Get the FLG (FLaGs)
  194. $this->flags = ord($this->compressed_data[3]);
  195. // FLG bits above (1 << 4) are reserved
  196. if ($this->flags > 0x1F)
  197. {
  198. return false;
  199. }
  200. // Advance the pointer after the above
  201. $this->position += 4;
  202. // MTIME
  203. $mtime = substr($this->compressed_data, $this->position, 4);
  204. // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
  205. if (current(unpack('S', "\x00\x01")) === 1)
  206. {
  207. $mtime = strrev($mtime);
  208. }
  209. $this->MTIME = current(unpack('l', $mtime));
  210. $this->position += 4;
  211. // Get the XFL (eXtra FLags)
  212. $this->XFL = ord($this->compressed_data[$this->position++]);
  213. // Get the OS (Operating System)
  214. $this->OS = ord($this->compressed_data[$this->position++]);
  215. // Parse the FEXTRA
  216. if ($this->flags & 4)
  217. {
  218. // Read subfield IDs
  219. $this->SI1 = $this->compressed_data[$this->position++];
  220. $this->SI2 = $this->compressed_data[$this->position++];
  221. // SI2 set to zero is reserved for future use
  222. if ($this->SI2 === "\x00")
  223. {
  224. return false;
  225. }
  226. // Get the length of the extra field
  227. $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  228. $this->position += 2;
  229. // Check the length of the string is still valid
  230. $this->min_compressed_size += $len + 4;
  231. if ($this->compressed_size >= $this->min_compressed_size)
  232. {
  233. // Set the extra field to the given data
  234. $this->extra_field = substr($this->compressed_data, $this->position, $len);
  235. $this->position += $len;
  236. }
  237. else
  238. {
  239. return false;
  240. }
  241. }
  242. // Parse the FNAME
  243. if ($this->flags & 8)
  244. {
  245. // Get the length of the filename
  246. $len = strcspn($this->compressed_data, "\x00", $this->position);
  247. // Check the length of the string is still valid
  248. $this->min_compressed_size += $len + 1;
  249. if ($this->compressed_size >= $this->min_compressed_size)
  250. {
  251. // Set the original filename to the given string
  252. $this->filename = substr($this->compressed_data, $this->position, $len);
  253. $this->position += $len + 1;
  254. }
  255. else
  256. {
  257. return false;
  258. }
  259. }
  260. // Parse the FCOMMENT
  261. if ($this->flags & 16)
  262. {
  263. // Get the length of the comment
  264. $len = strcspn($this->compressed_data, "\x00", $this->position);
  265. // Check the length of the string is still valid
  266. $this->min_compressed_size += $len + 1;
  267. if ($this->compressed_size >= $this->min_compressed_size)
  268. {
  269. // Set the original comment to the given string
  270. $this->comment = substr($this->compressed_data, $this->position, $len);
  271. $this->position += $len + 1;
  272. }
  273. else
  274. {
  275. return false;
  276. }
  277. }
  278. // Parse the FHCRC
  279. if ($this->flags & 2)
  280. {
  281. // Check the length of the string is still valid
  282. $this->min_compressed_size += $len + 2;
  283. if ($this->compressed_size >= $this->min_compressed_size)
  284. {
  285. // Read the CRC
  286. $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
  287. // Check the CRC matches
  288. if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
  289. {
  290. $this->position += 2;
  291. }
  292. else
  293. {
  294. return false;
  295. }
  296. }
  297. else
  298. {
  299. return false;
  300. }
  301. }
  302. // Decompress the actual data
  303. if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
  304. {
  305. return false;
  306. }
  307. else
  308. {
  309. $this->position = $this->compressed_size - 8;
  310. }
  311. // Check CRC of data
  312. $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  313. $this->position += 4;
  314. /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
  315. {
  316. return false;
  317. }*/
  318. // Check ISIZE of data
  319. $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
  320. $this->position += 4;
  321. if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
  322. {
  323. return false;
  324. }
  325. // Wow, against all odds, we've actually got a valid gzip string
  326. return true;
  327. }
  328. else
  329. {
  330. return false;
  331. }
  332. }
  333. }