PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.9.16
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.9.16
1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 All 163 releases
woocommerce-pos / vendor_prefixed / masterminds / html5 / src / HTML5 / Parser / Scanner.php

Scanner.php in WCPOS – Point of Sale (POS) plugin for WooCommerce 1.9.16, at vendor_prefixed/masterminds/html5/src/HTML5/Parser/Scanner.php

363 lines 11.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WCPOS\Vendor\Masterminds\HTML5\Parser;
4
5 use WCPOS\Vendor\Masterminds\HTML5\Exception;
6 /**
7 * The scanner scans over a given data input to react appropriately to characters.
8 */
9 class Scanner
10 {
11 const CHARS_HEX = 'abcdefABCDEF01234567890';
12 const CHARS_ALNUM = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890';
13 const CHARS_ALPHA = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
14 /**
15 * The string data we're parsing.
16 */
17 private $data;
18 /**
19 * The current integer byte position we are in $data.
20 */
21 private $char;
22 /**
23 * Length of $data; when $char === $data, we are at the end-of-file.
24 */
25 private $EOF;
26 /**
27 * Parse errors.
28 */
29 public $errors = array();
30 /**
31 * Create a new Scanner.
32 *
33 * @param string $data Data to parse.
34 * @param string $encoding The encoding to use for the data.
35 *
36 * @throws Exception If the given data cannot be encoded to UTF-8.
37 */
38 public function __construct($data, $encoding = 'UTF-8')
39 {
40 if ($data instanceof InputStream) {
41 @\trigger_error('InputStream objects are deprecated since version 2.4 and will be removed in 3.0. Use strings instead.', \E_USER_DEPRECATED);
42 $data = (string) $data;
43 }
44 $data = UTF8Utils::convertToUTF8($data, $encoding);
45 // There is good reason to question whether it makes sense to
46 // do this here, since most of these checks are done during
47 // parsing, and since this check doesn't actually *do* anything.
48 $this->errors = UTF8Utils::checkForIllegalCodepoints($data);
49 $data = $this->replaceLinefeeds($data);
50 $this->data = $data;
51 $this->char = 0;
52 $this->EOF = \strlen($data);
53 }
54 /**
55 * Check if upcomming chars match the given sequence.
56 *
57 * This will read the stream for the $sequence. If it's
58 * found, this will return true. If not, return false.
59 * Since this unconsumes any chars it reads, the caller
60 * will still need to read the next sequence, even if
61 * this returns true.
62 *
63 * Example: $this->scanner->sequenceMatches('</script>') will
64 * see if the input stream is at the start of a
65 * '</script>' string.
66 *
67 * @param string $sequence
68 * @param bool $caseSensitive
69 *
70 * @return bool
71 */
72 public function sequenceMatches($sequence, $caseSensitive = \true)
73 {
74 $portion = \substr($this->data, $this->char, \strlen($sequence));
75 return $caseSensitive ? $portion === $sequence : 0 === \strcasecmp($portion, $sequence);
76 }
77 /**
78 * Get the current position.
79 *
80 * @return int The current intiger byte position.
81 */
82 public function position()
83 {
84 return $this->char;
85 }
86 /**
87 * Take a peek at the next character in the data.
88 *
89 * @return string The next character.
90 */
91 public function peek()
92 {
93 if ($this->char + 1 < $this->EOF) {
94 return $this->data[$this->char + 1];
95 }
96 return \false;
97 }
98 /**
99 * Get the next character.
100 * Note: This advances the pointer.
101 *
102 * @return string The next character.
103 */
104 public function next()
105 {
106 ++$this->char;
107 if ($this->char < $this->EOF) {
108 return $this->data[$this->char];
109 }
110 return \false;
111 }
112 /**
113 * Get the current character.
114 * Note, this does not advance the pointer.
115 *
116 * @return string The current character.
117 */
118 public function current()
119 {
120 if ($this->char < $this->EOF) {
121 return $this->data[$this->char];
122 }
123 return \false;
124 }
125 /**
126 * Silently consume N chars.
127 *
128 * @param int $count
129 */
130 public function consume($count = 1)
131 {
132 $this->char += $count;
133 }
134 /**
135 * Unconsume some of the data.
136 * This moves the data pointer backwards.
137 *
138 * @param int $howMany The number of characters to move the pointer back.
139 */
140 public function unconsume($howMany = 1)
141 {
142 if ($this->char - $howMany >= 0) {
143 $this->char -= $howMany;
144 }
145 }
146 /**
147 * Get the next group of that contains hex characters.
148 * Note, along with getting the characters the pointer in the data will be
149 * moved as well.
150 *
151 * @return string The next group that is hex characters.
152 */
153 public function getHex()
154 {
155 return $this->doCharsWhile(static::CHARS_HEX);
156 }
157 /**
158 * Get the next group of characters that are ASCII Alpha characters.
159 * Note, along with getting the characters the pointer in the data will be
160 * moved as well.
161 *
162 * @return string The next group of ASCII alpha characters.
163 */
164 public function getAsciiAlpha()
165 {
166 return $this->doCharsWhile(static::CHARS_ALPHA);
167 }
168 /**
169 * Get the next group of characters that are ASCII Alpha characters and numbers.
170 * Note, along with getting the characters the pointer in the data will be
171 * moved as well.
172 *
173 * @return string The next group of ASCII alpha characters and numbers.
174 */
175 public function getAsciiAlphaNum()
176 {
177 return $this->doCharsWhile(static::CHARS_ALNUM);
178 }
179 /**
180 * Get the next group of numbers.
181 * Note, along with getting the characters the pointer in the data will be
182 * moved as well.
183 *
184 * @return string The next group of numbers.
185 */
186 public function getNumeric()
187 {
188 return $this->doCharsWhile('0123456789');
189 }
190 /**
191 * Consume whitespace.
192 * Whitespace in HTML5 is: formfeed, tab, newline, space.
193 *
194 * @return int The length of the matched whitespaces.
195 */
196 public function whitespace()
197 {
198 if ($this->char >= $this->EOF) {
199 return \false;
200 }
201 $len = \strspn($this->data, "\n\t\f ", $this->char);
202 $this->char += $len;
203 return $len;
204 }
205 /**
206 * Returns the current line that is being consumed.
207 *
208 * @return int The current line number.
209 */
210 public function currentLine()
211 {
212 if (empty($this->EOF) || 0 === $this->char) {
213 return 1;
214 }
215 // Add one to $this->char because we want the number for the next
216 // byte to be processed.
217 return \substr_count($this->data, "\n", 0, \min($this->char, $this->EOF)) + 1;
218 }
219 /**
220 * Read chars until something in the mask is encountered.
221 *
222 * @param string $mask
223 *
224 * @return mixed
225 */
226 public function charsUntil($mask)
227 {
228 return $this->doCharsUntil($mask);
229 }
230 /**
231 * Read chars as long as the mask matches.
232 *
233 * @param string $mask
234 *
235 * @return int
236 */
237 public function charsWhile($mask)
238 {
239 return $this->doCharsWhile($mask);
240 }
241 /**
242 * Returns the current column of the current line that the tokenizer is at.
243 *
244 * Newlines are column 0. The first char after a newline is column 1.
245 *
246 * @return int The column number.
247 */
248 public function columnOffset()
249 {
250 // Short circuit for the first char.
251 if (0 === $this->char) {
252 return 0;
253 }
254 // strrpos is weird, and the offset needs to be negative for what we
255 // want (i.e., the last \n before $this->char). This needs to not have
256 // one (to make it point to the next character, the one we want the
257 // position of) added to it because strrpos's behaviour includes the
258 // final offset byte.
259 $backwardFrom = $this->char - 1 - \strlen($this->data);
260 $lastLine = \strrpos($this->data, "\n", $backwardFrom);
261 // However, for here we want the length up until the next byte to be
262 // processed, so add one to the current byte ($this->char).
263 if (\false !== $lastLine) {
264 $findLengthOf = \substr($this->data, $lastLine + 1, $this->char - 1 - $lastLine);
265 } else {
266 // After a newline.
267 $findLengthOf = \substr($this->data, 0, $this->char);
268 }
269 return UTF8Utils::countChars($findLengthOf);
270 }
271 /**
272 * Get all characters until EOF.
273 *
274 * This consumes characters until the EOF.
275 *
276 * @return int The number of characters remaining.
277 */
278 public function remainingChars()
279 {
280 if ($this->char < $this->EOF) {
281 $data = \substr($this->data, $this->char);
282 $this->char = $this->EOF;
283 return $data;
284 }
285 return '';
286 // false;
287 }
288 /**
289 * Replace linefeed characters according to the spec.
290 *
291 * @param $data
292 *
293 * @return string
294 */
295 private function replaceLinefeeds($data)
296 {
297 /*
298 * U+000D CARRIAGE RETURN (CR) characters and U+000A LINE FEED (LF) characters are treated specially.
299 * Any CR characters that are followed by LF characters must be removed, and any CR characters not
300 * followed by LF characters must be converted to LF characters. Thus, newlines in HTML DOMs are
301 * represented by LF characters, and there are never any CR characters in the input to the tokenization
302 * stage.
303 */
304 $crlfTable = array("\x00" => "", "\r\n" => "\n", "\r" => "\n");
305 return \strtr($data, $crlfTable);
306 }
307 /**
308 * Read to a particular match (or until $max bytes are consumed).
309 *
310 * This operates on byte sequences, not characters.
311 *
312 * Matches as far as possible until we reach a certain set of bytes
313 * and returns the matched substring.
314 *
315 * @param string $bytes Bytes to match.
316 * @param int $max Maximum number of bytes to scan.
317 *
318 * @return mixed Index or false if no match is found. You should use strong
319 * equality when checking the result, since index could be 0.
320 */
321 private function doCharsUntil($bytes, $max = null)
322 {
323 if ($this->char >= $this->EOF) {
324 return \false;
325 }
326 if (0 === $max || $max) {
327 $len = \strcspn($this->data, $bytes, $this->char, $max);
328 } else {
329 $len = \strcspn($this->data, $bytes, $this->char);
330 }
331 $string = (string) \substr($this->data, $this->char, $len);
332 $this->char += $len;
333 return $string;
334 }
335 /**
336 * Returns the string so long as $bytes matches.
337 *
338 * Matches as far as possible with a certain set of bytes
339 * and returns the matched substring.
340 *
341 * @param string $bytes A mask of bytes to match. If ANY byte in this mask matches the
342 * current char, the pointer advances and the char is part of the
343 * substring.
344 * @param int $max The max number of chars to read.
345 *
346 * @return string
347 */
348 private function doCharsWhile($bytes, $max = null)
349 {
350 if ($this->char >= $this->EOF) {
351 return \false;
352 }
353 if (0 === $max || $max) {
354 $len = \strspn($this->data, $bytes, $this->char, $max);
355 } else {
356 $len = \strspn($this->data, $bytes, $this->char);
357 }
358 $string = (string) \substr($this->data, $this->char, $len);
359 $this->char += $len;
360 return $string;
361 }
362 }
363