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\XML\Declaration;
47
 
48
/**
49
 * Parses the XML Declaration
50
 *
51
 * @package SimplePie
52
 * @subpackage Parsing
53
 */
54
class Parser
55
{
56
    /**
57
     * XML Version
58
     *
59
     * @access public
60
     * @var string
61
     */
62
    public $version = '1.0';
63
 
64
    /**
65
     * Encoding
66
     *
67
     * @access public
68
     * @var string
69
     */
70
    public $encoding = 'UTF-8';
71
 
72
    /**
73
     * Standalone
74
     *
75
     * @access public
76
     * @var bool
77
     */
78
    public $standalone = false;
79
 
80
    private const STATE_BEFORE_VERSION_NAME = 'before_version_name';
81
 
82
    private const STATE_VERSION_NAME = 'version_name';
83
 
84
    private const STATE_VERSION_EQUALS = 'version_equals';
85
 
86
    private const STATE_VERSION_VALUE = 'version_value';
87
 
88
    private const STATE_ENCODING_NAME = 'encoding_name';
89
 
90
    private const STATE_EMIT = 'emit';
91
 
92
    private const STATE_ENCODING_EQUALS = 'encoding_equals';
93
 
94
    private const STATE_STANDALONE_NAME = 'standalone_name';
95
 
96
    private const STATE_ENCODING_VALUE = 'encoding_value';
97
 
98
    private const STATE_STANDALONE_EQUALS = 'standalone_equals';
99
 
100
    private const STATE_STANDALONE_VALUE = 'standalone_value';
101
 
102
    private const STATE_ERROR = false;
103
 
104
    /**
105
     * Current state of the state machine
106
     *
107
     * @access private
108
     * @var self::STATE_*
109
     */
110
    public $state = self::STATE_BEFORE_VERSION_NAME;
111
 
112
    /**
113
     * Input data
114
     *
115
     * @access private
116
     * @var string
117
     */
118
    public $data = '';
119
 
120
    /**
121
     * Input data length (to avoid calling strlen() everytime this is needed)
122
     *
123
     * @access private
124
     * @var int
125
     */
126
    public $data_length = 0;
127
 
128
    /**
129
     * Current position of the pointer
130
     *
131
     * @var int
132
     * @access private
133
     */
134
    public $position = 0;
135
 
136
    /**
137
     * Create an instance of the class with the input data
138
     *
139
     * @access public
140
     * @param string $data Input data
141
     */
142
    public function __construct($data)
143
    {
144
        $this->data = $data;
145
        $this->data_length = strlen($this->data);
146
    }
147
 
148
    /**
149
     * Parse the input data
150
     *
151
     * @access public
152
     * @return bool true on success, false on failure
153
     */
154
    public function parse()
155
    {
156
        while ($this->state && $this->state !== self::STATE_EMIT && $this->has_data()) {
157
            $state = $this->state;
158
            $this->$state();
159
        }
160
        $this->data = '';
161
        if ($this->state === self::STATE_EMIT) {
162
            return true;
163
        }
164
 
165
        $this->version = '';
166
        $this->encoding = '';
167
        $this->standalone = '';
168
        return false;
169
    }
170
 
171
    /**
172
     * Check whether there is data beyond the pointer
173
     *
174
     * @access private
175
     * @return bool true if there is further data, false if not
176
     */
177
    public function has_data()
178
    {
179
        return (bool) ($this->position < $this->data_length);
180
    }
181
 
182
    /**
183
     * Advance past any whitespace
184
     *
185
     * @return int Number of whitespace characters passed
186
     */
187
    public function skip_whitespace()
188
    {
189
        $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
190
        $this->position += $whitespace;
191
        return $whitespace;
192
    }
193
 
194
    /**
195
     * Read value
196
     */
197
    public function get_value()
198
    {
199
        $quote = substr($this->data, $this->position, 1);
200
        if ($quote === '"' || $quote === "'") {
201
            $this->position++;
202
            $len = strcspn($this->data, $quote, $this->position);
203
            if ($this->has_data()) {
204
                $value = substr($this->data, $this->position, $len);
205
                $this->position += $len + 1;
206
                return $value;
207
            }
208
        }
209
        return false;
210
    }
211
 
212
    public function before_version_name()
213
    {
214
        if ($this->skip_whitespace()) {
215
            $this->state = self::STATE_VERSION_NAME;
216
        } else {
217
            $this->state = self::STATE_ERROR;
218
        }
219
    }
220
 
221
    public function version_name()
222
    {
223
        if (substr($this->data, $this->position, 7) === 'version') {
224
            $this->position += 7;
225
            $this->skip_whitespace();
226
            $this->state = self::STATE_VERSION_EQUALS;
227
        } else {
228
            $this->state = self::STATE_ERROR;
229
        }
230
    }
231
 
232
    public function version_equals()
233
    {
234
        if (substr($this->data, $this->position, 1) === '=') {
235
            $this->position++;
236
            $this->skip_whitespace();
237
            $this->state = self::STATE_VERSION_VALUE;
238
        } else {
239
            $this->state = self::STATE_ERROR;
240
        }
241
    }
242
 
243
    public function version_value()
244
    {
245
        if ($this->version = $this->get_value()) {
246
            $this->skip_whitespace();
247
            if ($this->has_data()) {
248
                $this->state = self::STATE_ENCODING_NAME;
249
            } else {
250
                $this->state = self::STATE_EMIT;
251
            }
252
        } else {
253
            $this->state = self::STATE_ERROR;
254
        }
255
    }
256
 
257
    public function encoding_name()
258
    {
259
        if (substr($this->data, $this->position, 8) === 'encoding') {
260
            $this->position += 8;
261
            $this->skip_whitespace();
262
            $this->state = self::STATE_ENCODING_EQUALS;
263
        } else {
264
            $this->state = self::STATE_STANDALONE_NAME;
265
        }
266
    }
267
 
268
    public function encoding_equals()
269
    {
270
        if (substr($this->data, $this->position, 1) === '=') {
271
            $this->position++;
272
            $this->skip_whitespace();
273
            $this->state = self::STATE_ENCODING_VALUE;
274
        } else {
275
            $this->state = self::STATE_ERROR;
276
        }
277
    }
278
 
279
    public function encoding_value()
280
    {
281
        if ($this->encoding = $this->get_value()) {
282
            $this->skip_whitespace();
283
            if ($this->has_data()) {
284
                $this->state = self::STATE_STANDALONE_NAME;
285
            } else {
286
                $this->state = self::STATE_EMIT;
287
            }
288
        } else {
289
            $this->state = self::STATE_ERROR;
290
        }
291
    }
292
 
293
    public function standalone_name()
294
    {
295
        if (substr($this->data, $this->position, 10) === 'standalone') {
296
            $this->position += 10;
297
            $this->skip_whitespace();
298
            $this->state = self::STATE_STANDALONE_EQUALS;
299
        } else {
300
            $this->state = self::STATE_ERROR;
301
        }
302
    }
303
 
304
    public function standalone_equals()
305
    {
306
        if (substr($this->data, $this->position, 1) === '=') {
307
            $this->position++;
308
            $this->skip_whitespace();
309
            $this->state = self::STATE_STANDALONE_VALUE;
310
        } else {
311
            $this->state = self::STATE_ERROR;
312
        }
313
    }
314
 
315
    public function standalone_value()
316
    {
317
        if ($standalone = $this->get_value()) {
318
            switch ($standalone) {
319
                case 'yes':
320
                    $this->standalone = true;
321
                    break;
322
 
323
                case 'no':
324
                    $this->standalone = false;
325
                    break;
326
 
327
                default:
328
                    $this->state = self::STATE_ERROR;
329
                    return;
330
            }
331
 
332
            $this->skip_whitespace();
333
            if ($this->has_data()) {
334
                $this->state = self::STATE_ERROR;
335
            } else {
336
                $this->state = self::STATE_EMIT;
337
            }
338
        } else {
339
            $this->state = self::STATE_ERROR;
340
        }
341
    }
342
}
343
 
344
class_alias('SimplePie\XML\Declaration\Parser', 'SimplePie_XML_Declaration_Parser');