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