Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

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