1 /*
2 __ __ _
3 ___\ \/ /_ __ __ _| |_
4 / _ \\ /| '_ \ / _` | __|
5 | __// \| |_) | (_| | |_
6 \___/_/\_\ .__/ \__,_|\__|
7 |_| XML parser
8
9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10 Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
11 Copyright (c) 2002 Greg Stein <gstein@users.sourceforge.net>
12 Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
13 Copyright (c) 2002-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
14 Copyright (c) 2005-2009 Steven Solie <steven@solie.ca>
15 Copyright (c) 2016-2023 Sebastian Pipping <sebastian@pipping.org>
16 Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
17 Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
18 Copyright (c) 2021 Donghee Na <donghee.na@python.org>
19 Copyright (c) 2025 Alfonso Gregory <gfunni234@gmail.com>
20 Licensed under the MIT license:
21
22 Permission is hereby granted, free of charge, to any person obtaining
23 a copy of this software and associated documentation files (the
24 "Software"), to deal in the Software without restriction, including
25 without limitation the rights to use, copy, modify, merge, publish,
26 distribute, sublicense, and/or sell copies of the Software, and to permit
27 persons to whom the Software is furnished to do so, subject to the
28 following conditions:
29
30 The above copyright notice and this permission notice shall be included
31 in all copies or substantial portions of the Software.
32
33 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
35 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
36 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
37 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
38 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
39 USE OR OTHER DEALINGS IN THE SOFTWARE.
40
41 SPDX-License-Identifier: MIT
42 */
43
44 #include "expat_config.h"
45
46 #include <stddef.h>
47
48 #ifdef _WIN32
49 # include "winconfig.h"
50 #endif
51
52 #include "internal.h"
53 #include "xmlrole.h"
54 #include "ascii.h"
55
56 /* Doesn't check:
57
58 that ,| are not mixed in a model group
59 content of literals
60
61 */
62
63 static const char KW_ANY[] = {ASCII_A, ASCII_N, ASCII_Y, '\0'};
64 static const char KW_ATTLIST[]
65 = {ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0'};
66 static const char KW_CDATA[]
67 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
68 static const char KW_DOCTYPE[]
69 = {ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0'};
70 static const char KW_ELEMENT[]
71 = {ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0'};
72 static const char KW_EMPTY[]
73 = {ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0'};
74 static const char KW_ENTITIES[] = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
75 ASCII_I, ASCII_E, ASCII_S, '\0'};
76 static const char KW_ENTITY[]
77 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
78 static const char KW_FIXED[]
79 = {ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0'};
80 static const char KW_ID[] = {ASCII_I, ASCII_D, '\0'};
81 static const char KW_IDREF[]
82 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
83 static const char KW_IDREFS[]
84 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
85 #ifdef XML_DTD
86 static const char KW_IGNORE[]
87 = {ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0'};
88 #endif
89 static const char KW_IMPLIED[]
90 = {ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0'};
91 #ifdef XML_DTD
92 static const char KW_INCLUDE[]
93 = {ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0'};
94 #endif
95 static const char KW_NDATA[]
96 = {ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
97 static const char KW_NMTOKEN[]
98 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
99 static const char KW_NMTOKENS[] = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
100 ASCII_E, ASCII_N, ASCII_S, '\0'};
101 static const char KW_NOTATION[] = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T,
102 ASCII_I, ASCII_O, ASCII_N, '\0'};
103 static const char KW_PCDATA[]
104 = {ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
105 static const char KW_PUBLIC[]
106 = {ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0'};
107 static const char KW_REQUIRED[] = {ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I,
108 ASCII_R, ASCII_E, ASCII_D, '\0'};
109 static const char KW_SYSTEM[]
110 = {ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0'};
111
112 #ifndef MIN_BYTES_PER_CHAR
113 # define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
114 #endif
115
116 #ifdef XML_DTD
117 # define setTopLevel(state) \
118 ((state)->handler \
119 = ((state)->documentEntity ? internalSubset : externalSubset1))
120 #else /* not XML_DTD */
121 # define setTopLevel(state) ((state)->handler = internalSubset)
122 #endif /* not XML_DTD */
123
124 typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, int tok,
125 const char *ptr, const char *end,
126 const ENCODING *enc);
127
128 static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2,
129 doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2,
130 entity3, entity4, entity5, entity6, entity7, entity8, entity9, entity10,
131 notation0, notation1, notation2, notation3, notation4, attlist0, attlist1,
132 attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8,
133 attlist9, element0, element1, element2, element3, element4, element5,
134 element6, element7,
135 #ifdef XML_DTD
136 externalSubset0, externalSubset1, condSect0, condSect1, condSect2,
137 #endif /* XML_DTD */
138 declClose, error;
139
140 static int FASTCALL common(PROLOG_STATE *state, int tok);
141
142 static int PTRCALL
prolog0(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)143 prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
144 const ENCODING *enc) {
145 switch (tok) {
146 case XML_TOK_PROLOG_S:
147 state->handler = prolog1;
148 return XML_ROLE_NONE;
149 case XML_TOK_XML_DECL:
150 state->handler = prolog1;
151 return XML_ROLE_XML_DECL;
152 case XML_TOK_PI:
153 state->handler = prolog1;
154 return XML_ROLE_PI;
155 case XML_TOK_COMMENT:
156 state->handler = prolog1;
157 return XML_ROLE_COMMENT;
158 case XML_TOK_BOM:
159 return XML_ROLE_NONE;
160 case XML_TOK_DECL_OPEN:
161 if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
162 KW_DOCTYPE))
163 break;
164 state->handler = doctype0;
165 return XML_ROLE_DOCTYPE_NONE;
166 case XML_TOK_INSTANCE_START:
167 state->handler = error;
168 return XML_ROLE_INSTANCE_START;
169 }
170 return common(state, tok);
171 }
172
173 static int PTRCALL
prolog1(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)174 prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
175 const ENCODING *enc) {
176 switch (tok) {
177 case XML_TOK_PROLOG_S:
178 return XML_ROLE_NONE;
179 case XML_TOK_PI:
180 return XML_ROLE_PI;
181 case XML_TOK_COMMENT:
182 return XML_ROLE_COMMENT;
183 case XML_TOK_BOM:
184 /* This case can never arise. To reach this role function, the
185 * parse must have passed through prolog0 and therefore have had
186 * some form of input, even if only a space. At that point, a
187 * byte order mark is no longer a valid character (though
188 * technically it should be interpreted as a non-breaking space),
189 * so will be rejected by the tokenizing stages.
190 */
191 return XML_ROLE_NONE; /* LCOV_EXCL_LINE */
192 case XML_TOK_DECL_OPEN:
193 if (! XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
194 KW_DOCTYPE))
195 break;
196 state->handler = doctype0;
197 return XML_ROLE_DOCTYPE_NONE;
198 case XML_TOK_INSTANCE_START:
199 state->handler = error;
200 return XML_ROLE_INSTANCE_START;
201 }
202 return common(state, tok);
203 }
204
205 static int PTRCALL
prolog2(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)206 prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
207 const ENCODING *enc) {
208 UNUSED_P(ptr);
209 UNUSED_P(end);
210 UNUSED_P(enc);
211 switch (tok) {
212 case XML_TOK_PROLOG_S:
213 return XML_ROLE_NONE;
214 case XML_TOK_PI:
215 return XML_ROLE_PI;
216 case XML_TOK_COMMENT:
217 return XML_ROLE_COMMENT;
218 case XML_TOK_INSTANCE_START:
219 state->handler = error;
220 return XML_ROLE_INSTANCE_START;
221 }
222 return common(state, tok);
223 }
224
225 static int PTRCALL
doctype0(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)226 doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
227 const ENCODING *enc) {
228 UNUSED_P(ptr);
229 UNUSED_P(end);
230 UNUSED_P(enc);
231 switch (tok) {
232 case XML_TOK_PROLOG_S:
233 return XML_ROLE_DOCTYPE_NONE;
234 case XML_TOK_NAME:
235 case XML_TOK_PREFIXED_NAME:
236 state->handler = doctype1;
237 return XML_ROLE_DOCTYPE_NAME;
238 }
239 return common(state, tok);
240 }
241
242 static int PTRCALL
doctype1(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)243 doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
244 const ENCODING *enc) {
245 switch (tok) {
246 case XML_TOK_PROLOG_S:
247 return XML_ROLE_DOCTYPE_NONE;
248 case XML_TOK_OPEN_BRACKET:
249 state->handler = internalSubset;
250 return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
251 case XML_TOK_DECL_CLOSE:
252 state->handler = prolog2;
253 return XML_ROLE_DOCTYPE_CLOSE;
254 case XML_TOK_NAME:
255 if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
256 state->handler = doctype3;
257 return XML_ROLE_DOCTYPE_NONE;
258 }
259 if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
260 state->handler = doctype2;
261 return XML_ROLE_DOCTYPE_NONE;
262 }
263 break;
264 }
265 return common(state, tok);
266 }
267
268 static int PTRCALL
doctype2(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)269 doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
270 const ENCODING *enc) {
271 UNUSED_P(ptr);
272 UNUSED_P(end);
273 UNUSED_P(enc);
274 switch (tok) {
275 case XML_TOK_PROLOG_S:
276 return XML_ROLE_DOCTYPE_NONE;
277 case XML_TOK_LITERAL:
278 state->handler = doctype3;
279 return XML_ROLE_DOCTYPE_PUBLIC_ID;
280 }
281 return common(state, tok);
282 }
283
284 static int PTRCALL
doctype3(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)285 doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
286 const ENCODING *enc) {
287 UNUSED_P(ptr);
288 UNUSED_P(end);
289 UNUSED_P(enc);
290 switch (tok) {
291 case XML_TOK_PROLOG_S:
292 return XML_ROLE_DOCTYPE_NONE;
293 case XML_TOK_LITERAL:
294 state->handler = doctype4;
295 return XML_ROLE_DOCTYPE_SYSTEM_ID;
296 }
297 return common(state, tok);
298 }
299
300 static int PTRCALL
doctype4(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)301 doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
302 const ENCODING *enc) {
303 UNUSED_P(ptr);
304 UNUSED_P(end);
305 UNUSED_P(enc);
306 switch (tok) {
307 case XML_TOK_PROLOG_S:
308 return XML_ROLE_DOCTYPE_NONE;
309 case XML_TOK_OPEN_BRACKET:
310 state->handler = internalSubset;
311 return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
312 case XML_TOK_DECL_CLOSE:
313 state->handler = prolog2;
314 return XML_ROLE_DOCTYPE_CLOSE;
315 }
316 return common(state, tok);
317 }
318
319 static int PTRCALL
doctype5(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)320 doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
321 const ENCODING *enc) {
322 UNUSED_P(ptr);
323 UNUSED_P(end);
324 UNUSED_P(enc);
325 switch (tok) {
326 case XML_TOK_PROLOG_S:
327 return XML_ROLE_DOCTYPE_NONE;
328 case XML_TOK_DECL_CLOSE:
329 state->handler = prolog2;
330 return XML_ROLE_DOCTYPE_CLOSE;
331 }
332 return common(state, tok);
333 }
334
335 static int PTRCALL
internalSubset(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)336 internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
337 const ENCODING *enc) {
338 switch (tok) {
339 case XML_TOK_PROLOG_S:
340 return XML_ROLE_NONE;
341 case XML_TOK_DECL_OPEN:
342 if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
343 KW_ENTITY)) {
344 state->handler = entity0;
345 return XML_ROLE_ENTITY_NONE;
346 }
347 if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
348 KW_ATTLIST)) {
349 state->handler = attlist0;
350 return XML_ROLE_ATTLIST_NONE;
351 }
352 if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
353 KW_ELEMENT)) {
354 state->handler = element0;
355 return XML_ROLE_ELEMENT_NONE;
356 }
357 if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), end,
358 KW_NOTATION)) {
359 state->handler = notation0;
360 return XML_ROLE_NOTATION_NONE;
361 }
362 break;
363 case XML_TOK_PI:
364 return XML_ROLE_PI;
365 case XML_TOK_COMMENT:
366 return XML_ROLE_COMMENT;
367 case XML_TOK_PARAM_ENTITY_REF:
368 return XML_ROLE_PARAM_ENTITY_REF;
369 case XML_TOK_CLOSE_BRACKET:
370 state->handler = doctype5;
371 return XML_ROLE_DOCTYPE_NONE;
372 case XML_TOK_NONE:
373 return XML_ROLE_NONE;
374 }
375 return common(state, tok);
376 }
377
378 #ifdef XML_DTD
379
380 static int PTRCALL
externalSubset0(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)381 externalSubset0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
382 const ENCODING *enc) {
383 state->handler = externalSubset1;
384 if (tok == XML_TOK_XML_DECL)
385 return XML_ROLE_TEXT_DECL;
386 return externalSubset1(state, tok, ptr, end, enc);
387 }
388
389 static int PTRCALL
externalSubset1(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)390 externalSubset1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
391 const ENCODING *enc) {
392 switch (tok) {
393 case XML_TOK_COND_SECT_OPEN:
394 state->handler = condSect0;
395 return XML_ROLE_NONE;
396 case XML_TOK_COND_SECT_CLOSE:
397 if (state->includeLevel == 0)
398 break;
399 state->includeLevel -= 1;
400 return XML_ROLE_NONE;
401 case XML_TOK_PROLOG_S:
402 return XML_ROLE_NONE;
403 case XML_TOK_CLOSE_BRACKET:
404 break;
405 case XML_TOK_NONE:
406 if (state->includeLevel)
407 break;
408 return XML_ROLE_NONE;
409 default:
410 return internalSubset(state, tok, ptr, end, enc);
411 }
412 return common(state, tok);
413 }
414
415 #endif /* XML_DTD */
416
417 static int PTRCALL
entity0(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)418 entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
419 const ENCODING *enc) {
420 UNUSED_P(ptr);
421 UNUSED_P(end);
422 UNUSED_P(enc);
423 switch (tok) {
424 case XML_TOK_PROLOG_S:
425 return XML_ROLE_ENTITY_NONE;
426 case XML_TOK_PERCENT:
427 state->handler = entity1;
428 return XML_ROLE_ENTITY_NONE;
429 case XML_TOK_NAME:
430 state->handler = entity2;
431 return XML_ROLE_GENERAL_ENTITY_NAME;
432 }
433 return common(state, tok);
434 }
435
436 static int PTRCALL
entity1(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)437 entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
438 const ENCODING *enc) {
439 UNUSED_P(ptr);
440 UNUSED_P(end);
441 UNUSED_P(enc);
442 switch (tok) {
443 case XML_TOK_PROLOG_S:
444 return XML_ROLE_ENTITY_NONE;
445 case XML_TOK_NAME:
446 state->handler = entity7;
447 return XML_ROLE_PARAM_ENTITY_NAME;
448 }
449 return common(state, tok);
450 }
451
452 static int PTRCALL
entity2(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)453 entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
454 const ENCODING *enc) {
455 switch (tok) {
456 case XML_TOK_PROLOG_S:
457 return XML_ROLE_ENTITY_NONE;
458 case XML_TOK_NAME:
459 if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
460 state->handler = entity4;
461 return XML_ROLE_ENTITY_NONE;
462 }
463 if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
464 state->handler = entity3;
465 return XML_ROLE_ENTITY_NONE;
466 }
467 break;
468 case XML_TOK_LITERAL:
469 state->handler = declClose;
470 state->role_none = XML_ROLE_ENTITY_NONE;
471 return XML_ROLE_ENTITY_VALUE;
472 }
473 return common(state, tok);
474 }
475
476 static int PTRCALL
entity3(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)477 entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
478 const ENCODING *enc) {
479 UNUSED_P(ptr);
480 UNUSED_P(end);
481 UNUSED_P(enc);
482 switch (tok) {
483 case XML_TOK_PROLOG_S:
484 return XML_ROLE_ENTITY_NONE;
485 case XML_TOK_LITERAL:
486 state->handler = entity4;
487 return XML_ROLE_ENTITY_PUBLIC_ID;
488 }
489 return common(state, tok);
490 }
491
492 static int PTRCALL
entity4(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)493 entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
494 const ENCODING *enc) {
495 UNUSED_P(ptr);
496 UNUSED_P(end);
497 UNUSED_P(enc);
498 switch (tok) {
499 case XML_TOK_PROLOG_S:
500 return XML_ROLE_ENTITY_NONE;
501 case XML_TOK_LITERAL:
502 state->handler = entity5;
503 return XML_ROLE_ENTITY_SYSTEM_ID;
504 }
505 return common(state, tok);
506 }
507
508 static int PTRCALL
entity5(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)509 entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
510 const ENCODING *enc) {
511 switch (tok) {
512 case XML_TOK_PROLOG_S:
513 return XML_ROLE_ENTITY_NONE;
514 case XML_TOK_DECL_CLOSE:
515 setTopLevel(state);
516 return XML_ROLE_ENTITY_COMPLETE;
517 case XML_TOK_NAME:
518 if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
519 state->handler = entity6;
520 return XML_ROLE_ENTITY_NONE;
521 }
522 break;
523 }
524 return common(state, tok);
525 }
526
527 static int PTRCALL
entity6(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)528 entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
529 const ENCODING *enc) {
530 UNUSED_P(ptr);
531 UNUSED_P(end);
532 UNUSED_P(enc);
533 switch (tok) {
534 case XML_TOK_PROLOG_S:
535 return XML_ROLE_ENTITY_NONE;
536 case XML_TOK_NAME:
537 state->handler = declClose;
538 state->role_none = XML_ROLE_ENTITY_NONE;
539 return XML_ROLE_ENTITY_NOTATION_NAME;
540 }
541 return common(state, tok);
542 }
543
544 static int PTRCALL
entity7(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)545 entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
546 const ENCODING *enc) {
547 switch (tok) {
548 case XML_TOK_PROLOG_S:
549 return XML_ROLE_ENTITY_NONE;
550 case XML_TOK_NAME:
551 if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
552 state->handler = entity9;
553 return XML_ROLE_ENTITY_NONE;
554 }
555 if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
556 state->handler = entity8;
557 return XML_ROLE_ENTITY_NONE;
558 }
559 break;
560 case XML_TOK_LITERAL:
561 state->handler = declClose;
562 state->role_none = XML_ROLE_ENTITY_NONE;
563 return XML_ROLE_ENTITY_VALUE;
564 }
565 return common(state, tok);
566 }
567
568 static int PTRCALL
entity8(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)569 entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
570 const ENCODING *enc) {
571 UNUSED_P(ptr);
572 UNUSED_P(end);
573 UNUSED_P(enc);
574 switch (tok) {
575 case XML_TOK_PROLOG_S:
576 return XML_ROLE_ENTITY_NONE;
577 case XML_TOK_LITERAL:
578 state->handler = entity9;
579 return XML_ROLE_ENTITY_PUBLIC_ID;
580 }
581 return common(state, tok);
582 }
583
584 static int PTRCALL
entity9(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)585 entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
586 const ENCODING *enc) {
587 UNUSED_P(ptr);
588 UNUSED_P(end);
589 UNUSED_P(enc);
590 switch (tok) {
591 case XML_TOK_PROLOG_S:
592 return XML_ROLE_ENTITY_NONE;
593 case XML_TOK_LITERAL:
594 state->handler = entity10;
595 return XML_ROLE_ENTITY_SYSTEM_ID;
596 }
597 return common(state, tok);
598 }
599
600 static int PTRCALL
entity10(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)601 entity10(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
602 const ENCODING *enc) {
603 UNUSED_P(ptr);
604 UNUSED_P(end);
605 UNUSED_P(enc);
606 switch (tok) {
607 case XML_TOK_PROLOG_S:
608 return XML_ROLE_ENTITY_NONE;
609 case XML_TOK_DECL_CLOSE:
610 setTopLevel(state);
611 return XML_ROLE_ENTITY_COMPLETE;
612 }
613 return common(state, tok);
614 }
615
616 static int PTRCALL
notation0(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)617 notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
618 const ENCODING *enc) {
619 UNUSED_P(ptr);
620 UNUSED_P(end);
621 UNUSED_P(enc);
622 switch (tok) {
623 case XML_TOK_PROLOG_S:
624 return XML_ROLE_NOTATION_NONE;
625 case XML_TOK_NAME:
626 state->handler = notation1;
627 return XML_ROLE_NOTATION_NAME;
628 }
629 return common(state, tok);
630 }
631
632 static int PTRCALL
notation1(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)633 notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
634 const ENCODING *enc) {
635 switch (tok) {
636 case XML_TOK_PROLOG_S:
637 return XML_ROLE_NOTATION_NONE;
638 case XML_TOK_NAME:
639 if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
640 state->handler = notation3;
641 return XML_ROLE_NOTATION_NONE;
642 }
643 if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
644 state->handler = notation2;
645 return XML_ROLE_NOTATION_NONE;
646 }
647 break;
648 }
649 return common(state, tok);
650 }
651
652 static int PTRCALL
notation2(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)653 notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
654 const ENCODING *enc) {
655 UNUSED_P(ptr);
656 UNUSED_P(end);
657 UNUSED_P(enc);
658 switch (tok) {
659 case XML_TOK_PROLOG_S:
660 return XML_ROLE_NOTATION_NONE;
661 case XML_TOK_LITERAL:
662 state->handler = notation4;
663 return XML_ROLE_NOTATION_PUBLIC_ID;
664 }
665 return common(state, tok);
666 }
667
668 static int PTRCALL
notation3(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)669 notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
670 const ENCODING *enc) {
671 UNUSED_P(ptr);
672 UNUSED_P(end);
673 UNUSED_P(enc);
674 switch (tok) {
675 case XML_TOK_PROLOG_S:
676 return XML_ROLE_NOTATION_NONE;
677 case XML_TOK_LITERAL:
678 state->handler = declClose;
679 state->role_none = XML_ROLE_NOTATION_NONE;
680 return XML_ROLE_NOTATION_SYSTEM_ID;
681 }
682 return common(state, tok);
683 }
684
685 static int PTRCALL
notation4(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)686 notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
687 const ENCODING *enc) {
688 UNUSED_P(ptr);
689 UNUSED_P(end);
690 UNUSED_P(enc);
691 switch (tok) {
692 case XML_TOK_PROLOG_S:
693 return XML_ROLE_NOTATION_NONE;
694 case XML_TOK_LITERAL:
695 state->handler = declClose;
696 state->role_none = XML_ROLE_NOTATION_NONE;
697 return XML_ROLE_NOTATION_SYSTEM_ID;
698 case XML_TOK_DECL_CLOSE:
699 setTopLevel(state);
700 return XML_ROLE_NOTATION_NO_SYSTEM_ID;
701 }
702 return common(state, tok);
703 }
704
705 static int PTRCALL
attlist0(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)706 attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
707 const ENCODING *enc) {
708 UNUSED_P(ptr);
709 UNUSED_P(end);
710 UNUSED_P(enc);
711 switch (tok) {
712 case XML_TOK_PROLOG_S:
713 return XML_ROLE_ATTLIST_NONE;
714 case XML_TOK_NAME:
715 case XML_TOK_PREFIXED_NAME:
716 state->handler = attlist1;
717 return XML_ROLE_ATTLIST_ELEMENT_NAME;
718 }
719 return common(state, tok);
720 }
721
722 static int PTRCALL
attlist1(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)723 attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
724 const ENCODING *enc) {
725 UNUSED_P(ptr);
726 UNUSED_P(end);
727 UNUSED_P(enc);
728 switch (tok) {
729 case XML_TOK_PROLOG_S:
730 return XML_ROLE_ATTLIST_NONE;
731 case XML_TOK_DECL_CLOSE:
732 setTopLevel(state);
733 return XML_ROLE_ATTLIST_NONE;
734 case XML_TOK_NAME:
735 case XML_TOK_PREFIXED_NAME:
736 state->handler = attlist2;
737 return XML_ROLE_ATTRIBUTE_NAME;
738 }
739 return common(state, tok);
740 }
741
742 static int PTRCALL
attlist2(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)743 attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
744 const ENCODING *enc) {
745 switch (tok) {
746 case XML_TOK_PROLOG_S:
747 return XML_ROLE_ATTLIST_NONE;
748 case XML_TOK_NAME: {
749 static const char *const types[] = {
750 KW_CDATA, KW_ID, KW_IDREF, KW_IDREFS,
751 KW_ENTITY, KW_ENTITIES, KW_NMTOKEN, KW_NMTOKENS,
752 };
753 int i;
754 for (i = 0; i < (int)(sizeof(types) / sizeof(types[0])); i++)
755 if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
756 state->handler = attlist8;
757 return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
758 }
759 }
760 if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
761 state->handler = attlist5;
762 return XML_ROLE_ATTLIST_NONE;
763 }
764 break;
765 case XML_TOK_OPEN_PAREN:
766 state->handler = attlist3;
767 return XML_ROLE_ATTLIST_NONE;
768 }
769 return common(state, tok);
770 }
771
772 static int PTRCALL
attlist3(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)773 attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
774 const ENCODING *enc) {
775 UNUSED_P(ptr);
776 UNUSED_P(end);
777 UNUSED_P(enc);
778 switch (tok) {
779 case XML_TOK_PROLOG_S:
780 return XML_ROLE_ATTLIST_NONE;
781 case XML_TOK_NMTOKEN:
782 case XML_TOK_NAME:
783 case XML_TOK_PREFIXED_NAME:
784 state->handler = attlist4;
785 return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
786 }
787 return common(state, tok);
788 }
789
790 static int PTRCALL
attlist4(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)791 attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
792 const ENCODING *enc) {
793 UNUSED_P(ptr);
794 UNUSED_P(end);
795 UNUSED_P(enc);
796 switch (tok) {
797 case XML_TOK_PROLOG_S:
798 return XML_ROLE_ATTLIST_NONE;
799 case XML_TOK_CLOSE_PAREN:
800 state->handler = attlist8;
801 return XML_ROLE_ATTLIST_NONE;
802 case XML_TOK_OR:
803 state->handler = attlist3;
804 return XML_ROLE_ATTLIST_NONE;
805 }
806 return common(state, tok);
807 }
808
809 static int PTRCALL
attlist5(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)810 attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
811 const ENCODING *enc) {
812 UNUSED_P(ptr);
813 UNUSED_P(end);
814 UNUSED_P(enc);
815 switch (tok) {
816 case XML_TOK_PROLOG_S:
817 return XML_ROLE_ATTLIST_NONE;
818 case XML_TOK_OPEN_PAREN:
819 state->handler = attlist6;
820 return XML_ROLE_ATTLIST_NONE;
821 }
822 return common(state, tok);
823 }
824
825 static int PTRCALL
attlist6(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)826 attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
827 const ENCODING *enc) {
828 UNUSED_P(ptr);
829 UNUSED_P(end);
830 UNUSED_P(enc);
831 switch (tok) {
832 case XML_TOK_PROLOG_S:
833 return XML_ROLE_ATTLIST_NONE;
834 case XML_TOK_NAME:
835 state->handler = attlist7;
836 return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
837 }
838 return common(state, tok);
839 }
840
841 static int PTRCALL
attlist7(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)842 attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
843 const ENCODING *enc) {
844 UNUSED_P(ptr);
845 UNUSED_P(end);
846 UNUSED_P(enc);
847 switch (tok) {
848 case XML_TOK_PROLOG_S:
849 return XML_ROLE_ATTLIST_NONE;
850 case XML_TOK_CLOSE_PAREN:
851 state->handler = attlist8;
852 return XML_ROLE_ATTLIST_NONE;
853 case XML_TOK_OR:
854 state->handler = attlist6;
855 return XML_ROLE_ATTLIST_NONE;
856 }
857 return common(state, tok);
858 }
859
860 /* default value */
861 static int PTRCALL
attlist8(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)862 attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
863 const ENCODING *enc) {
864 switch (tok) {
865 case XML_TOK_PROLOG_S:
866 return XML_ROLE_ATTLIST_NONE;
867 case XML_TOK_POUND_NAME:
868 if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
869 KW_IMPLIED)) {
870 state->handler = attlist1;
871 return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
872 }
873 if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
874 KW_REQUIRED)) {
875 state->handler = attlist1;
876 return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
877 }
878 if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
879 KW_FIXED)) {
880 state->handler = attlist9;
881 return XML_ROLE_ATTLIST_NONE;
882 }
883 break;
884 case XML_TOK_LITERAL:
885 state->handler = attlist1;
886 return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
887 }
888 return common(state, tok);
889 }
890
891 static int PTRCALL
attlist9(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)892 attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
893 const ENCODING *enc) {
894 UNUSED_P(ptr);
895 UNUSED_P(end);
896 UNUSED_P(enc);
897 switch (tok) {
898 case XML_TOK_PROLOG_S:
899 return XML_ROLE_ATTLIST_NONE;
900 case XML_TOK_LITERAL:
901 state->handler = attlist1;
902 return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
903 }
904 return common(state, tok);
905 }
906
907 static int PTRCALL
element0(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)908 element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
909 const ENCODING *enc) {
910 UNUSED_P(ptr);
911 UNUSED_P(end);
912 UNUSED_P(enc);
913 switch (tok) {
914 case XML_TOK_PROLOG_S:
915 return XML_ROLE_ELEMENT_NONE;
916 case XML_TOK_NAME:
917 case XML_TOK_PREFIXED_NAME:
918 state->handler = element1;
919 return XML_ROLE_ELEMENT_NAME;
920 }
921 return common(state, tok);
922 }
923
924 static int PTRCALL
element1(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)925 element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
926 const ENCODING *enc) {
927 switch (tok) {
928 case XML_TOK_PROLOG_S:
929 return XML_ROLE_ELEMENT_NONE;
930 case XML_TOK_NAME:
931 if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
932 state->handler = declClose;
933 state->role_none = XML_ROLE_ELEMENT_NONE;
934 return XML_ROLE_CONTENT_EMPTY;
935 }
936 if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
937 state->handler = declClose;
938 state->role_none = XML_ROLE_ELEMENT_NONE;
939 return XML_ROLE_CONTENT_ANY;
940 }
941 break;
942 case XML_TOK_OPEN_PAREN:
943 state->handler = element2;
944 state->level = 1;
945 return XML_ROLE_GROUP_OPEN;
946 }
947 return common(state, tok);
948 }
949
950 static int PTRCALL
element2(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)951 element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
952 const ENCODING *enc) {
953 switch (tok) {
954 case XML_TOK_PROLOG_S:
955 return XML_ROLE_ELEMENT_NONE;
956 case XML_TOK_POUND_NAME:
957 if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), end,
958 KW_PCDATA)) {
959 state->handler = element3;
960 return XML_ROLE_CONTENT_PCDATA;
961 }
962 break;
963 case XML_TOK_OPEN_PAREN:
964 state->level = 2;
965 state->handler = element6;
966 return XML_ROLE_GROUP_OPEN;
967 case XML_TOK_NAME:
968 case XML_TOK_PREFIXED_NAME:
969 state->handler = element7;
970 return XML_ROLE_CONTENT_ELEMENT;
971 case XML_TOK_NAME_QUESTION:
972 state->handler = element7;
973 return XML_ROLE_CONTENT_ELEMENT_OPT;
974 case XML_TOK_NAME_ASTERISK:
975 state->handler = element7;
976 return XML_ROLE_CONTENT_ELEMENT_REP;
977 case XML_TOK_NAME_PLUS:
978 state->handler = element7;
979 return XML_ROLE_CONTENT_ELEMENT_PLUS;
980 }
981 return common(state, tok);
982 }
983
984 static int PTRCALL
element3(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)985 element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
986 const ENCODING *enc) {
987 UNUSED_P(ptr);
988 UNUSED_P(end);
989 UNUSED_P(enc);
990 switch (tok) {
991 case XML_TOK_PROLOG_S:
992 return XML_ROLE_ELEMENT_NONE;
993 case XML_TOK_CLOSE_PAREN:
994 state->handler = declClose;
995 state->role_none = XML_ROLE_ELEMENT_NONE;
996 return XML_ROLE_GROUP_CLOSE;
997 case XML_TOK_CLOSE_PAREN_ASTERISK:
998 state->handler = declClose;
999 state->role_none = XML_ROLE_ELEMENT_NONE;
1000 return XML_ROLE_GROUP_CLOSE_REP;
1001 case XML_TOK_OR:
1002 state->handler = element4;
1003 return XML_ROLE_ELEMENT_NONE;
1004 }
1005 return common(state, tok);
1006 }
1007
1008 static int PTRCALL
element4(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1009 element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1010 const ENCODING *enc) {
1011 UNUSED_P(ptr);
1012 UNUSED_P(end);
1013 UNUSED_P(enc);
1014 switch (tok) {
1015 case XML_TOK_PROLOG_S:
1016 return XML_ROLE_ELEMENT_NONE;
1017 case XML_TOK_NAME:
1018 case XML_TOK_PREFIXED_NAME:
1019 state->handler = element5;
1020 return XML_ROLE_CONTENT_ELEMENT;
1021 }
1022 return common(state, tok);
1023 }
1024
1025 static int PTRCALL
element5(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1026 element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1027 const ENCODING *enc) {
1028 UNUSED_P(ptr);
1029 UNUSED_P(end);
1030 UNUSED_P(enc);
1031 switch (tok) {
1032 case XML_TOK_PROLOG_S:
1033 return XML_ROLE_ELEMENT_NONE;
1034 case XML_TOK_CLOSE_PAREN_ASTERISK:
1035 state->handler = declClose;
1036 state->role_none = XML_ROLE_ELEMENT_NONE;
1037 return XML_ROLE_GROUP_CLOSE_REP;
1038 case XML_TOK_OR:
1039 state->handler = element4;
1040 return XML_ROLE_ELEMENT_NONE;
1041 }
1042 return common(state, tok);
1043 }
1044
1045 static int PTRCALL
element6(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1046 element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1047 const ENCODING *enc) {
1048 UNUSED_P(ptr);
1049 UNUSED_P(end);
1050 UNUSED_P(enc);
1051 switch (tok) {
1052 case XML_TOK_PROLOG_S:
1053 return XML_ROLE_ELEMENT_NONE;
1054 case XML_TOK_OPEN_PAREN:
1055 state->level += 1;
1056 return XML_ROLE_GROUP_OPEN;
1057 case XML_TOK_NAME:
1058 case XML_TOK_PREFIXED_NAME:
1059 state->handler = element7;
1060 return XML_ROLE_CONTENT_ELEMENT;
1061 case XML_TOK_NAME_QUESTION:
1062 state->handler = element7;
1063 return XML_ROLE_CONTENT_ELEMENT_OPT;
1064 case XML_TOK_NAME_ASTERISK:
1065 state->handler = element7;
1066 return XML_ROLE_CONTENT_ELEMENT_REP;
1067 case XML_TOK_NAME_PLUS:
1068 state->handler = element7;
1069 return XML_ROLE_CONTENT_ELEMENT_PLUS;
1070 }
1071 return common(state, tok);
1072 }
1073
1074 static int PTRCALL
element7(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1075 element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1076 const ENCODING *enc) {
1077 UNUSED_P(ptr);
1078 UNUSED_P(end);
1079 UNUSED_P(enc);
1080 switch (tok) {
1081 case XML_TOK_PROLOG_S:
1082 return XML_ROLE_ELEMENT_NONE;
1083 case XML_TOK_CLOSE_PAREN:
1084 state->level -= 1;
1085 if (state->level == 0) {
1086 state->handler = declClose;
1087 state->role_none = XML_ROLE_ELEMENT_NONE;
1088 }
1089 return XML_ROLE_GROUP_CLOSE;
1090 case XML_TOK_CLOSE_PAREN_ASTERISK:
1091 state->level -= 1;
1092 if (state->level == 0) {
1093 state->handler = declClose;
1094 state->role_none = XML_ROLE_ELEMENT_NONE;
1095 }
1096 return XML_ROLE_GROUP_CLOSE_REP;
1097 case XML_TOK_CLOSE_PAREN_QUESTION:
1098 state->level -= 1;
1099 if (state->level == 0) {
1100 state->handler = declClose;
1101 state->role_none = XML_ROLE_ELEMENT_NONE;
1102 }
1103 return XML_ROLE_GROUP_CLOSE_OPT;
1104 case XML_TOK_CLOSE_PAREN_PLUS:
1105 state->level -= 1;
1106 if (state->level == 0) {
1107 state->handler = declClose;
1108 state->role_none = XML_ROLE_ELEMENT_NONE;
1109 }
1110 return XML_ROLE_GROUP_CLOSE_PLUS;
1111 case XML_TOK_COMMA:
1112 state->handler = element6;
1113 return XML_ROLE_GROUP_SEQUENCE;
1114 case XML_TOK_OR:
1115 state->handler = element6;
1116 return XML_ROLE_GROUP_CHOICE;
1117 }
1118 return common(state, tok);
1119 }
1120
1121 #ifdef XML_DTD
1122
1123 static int PTRCALL
condSect0(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1124 condSect0(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1125 const ENCODING *enc) {
1126 switch (tok) {
1127 case XML_TOK_PROLOG_S:
1128 return XML_ROLE_NONE;
1129 case XML_TOK_NAME:
1130 if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
1131 state->handler = condSect1;
1132 return XML_ROLE_NONE;
1133 }
1134 if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
1135 state->handler = condSect2;
1136 return XML_ROLE_NONE;
1137 }
1138 break;
1139 }
1140 return common(state, tok);
1141 }
1142
1143 static int PTRCALL
condSect1(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1144 condSect1(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1145 const ENCODING *enc) {
1146 UNUSED_P(ptr);
1147 UNUSED_P(end);
1148 UNUSED_P(enc);
1149 switch (tok) {
1150 case XML_TOK_PROLOG_S:
1151 return XML_ROLE_NONE;
1152 case XML_TOK_OPEN_BRACKET:
1153 state->handler = externalSubset1;
1154 state->includeLevel += 1;
1155 return XML_ROLE_NONE;
1156 }
1157 return common(state, tok);
1158 }
1159
1160 static int PTRCALL
condSect2(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1161 condSect2(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1162 const ENCODING *enc) {
1163 UNUSED_P(ptr);
1164 UNUSED_P(end);
1165 UNUSED_P(enc);
1166 switch (tok) {
1167 case XML_TOK_PROLOG_S:
1168 return XML_ROLE_NONE;
1169 case XML_TOK_OPEN_BRACKET:
1170 state->handler = externalSubset1;
1171 return XML_ROLE_IGNORE_SECT;
1172 }
1173 return common(state, tok);
1174 }
1175
1176 #endif /* XML_DTD */
1177
1178 static int PTRCALL
declClose(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1179 declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1180 const ENCODING *enc) {
1181 UNUSED_P(ptr);
1182 UNUSED_P(end);
1183 UNUSED_P(enc);
1184 switch (tok) {
1185 case XML_TOK_PROLOG_S:
1186 return state->role_none;
1187 case XML_TOK_DECL_CLOSE:
1188 setTopLevel(state);
1189 return state->role_none;
1190 }
1191 return common(state, tok);
1192 }
1193
1194 /* This function will only be invoked if the internal logic of the
1195 * parser has broken down. It is used in two cases:
1196 *
1197 * 1: When the XML prolog has been finished. At this point the
1198 * processor (the parser level above these role handlers) should
1199 * switch from prologProcessor to contentProcessor and reinitialise
1200 * the handler function.
1201 *
1202 * 2: When an error has been detected (via common() below). At this
1203 * point again the processor should be switched to errorProcessor,
1204 * which will never call a handler.
1205 *
1206 * The result of this is that error() can only be called if the
1207 * processor switch failed to happen, which is an internal error and
1208 * therefore we shouldn't be able to provoke it simply by using the
1209 * library. It is a necessary backstop, however, so we merely exclude
1210 * it from the coverage statistics.
1211 *
1212 * LCOV_EXCL_START
1213 */
1214 static int PTRCALL
error(PROLOG_STATE * state,int tok,const char * ptr,const char * end,const ENCODING * enc)1215 error(PROLOG_STATE *state, int tok, const char *ptr, const char *end,
1216 const ENCODING *enc) {
1217 UNUSED_P(state);
1218 UNUSED_P(tok);
1219 UNUSED_P(ptr);
1220 UNUSED_P(end);
1221 UNUSED_P(enc);
1222 return XML_ROLE_NONE;
1223 }
1224 /* LCOV_EXCL_STOP */
1225
1226 static int FASTCALL
common(PROLOG_STATE * state,int tok)1227 common(PROLOG_STATE *state, int tok) {
1228 #ifdef XML_DTD
1229 if (! state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
1230 return XML_ROLE_INNER_PARAM_ENTITY_REF;
1231 #else
1232 UNUSED_P(tok);
1233 #endif
1234 state->handler = error;
1235 return XML_ROLE_ERROR;
1236 }
1237
1238 void
XmlPrologStateInit(PROLOG_STATE * state)1239 XmlPrologStateInit(PROLOG_STATE *state) {
1240 state->handler = prolog0;
1241 #ifdef XML_DTD
1242 state->documentEntity = 1;
1243 state->includeLevel = 0;
1244 state->inEntityValue = 0;
1245 #endif /* XML_DTD */
1246 }
1247
1248 #ifdef XML_DTD
1249
1250 void
XmlPrologStateInitExternalEntity(PROLOG_STATE * state)1251 XmlPrologStateInitExternalEntity(PROLOG_STATE *state) {
1252 state->handler = externalSubset0;
1253 state->documentEntity = 0;
1254 state->includeLevel = 0;
1255 }
1256
1257 #endif /* XML_DTD */
1258