~canonical-sysadmins/wordpress/4.7.4

« back to all changes in this revision

Viewing changes to wp-includes/SimplePie/gzdecode.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}