Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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