xref: /freebsd/contrib/expat/lib/xmlrole.c (revision 207d96dabfec14d7b3699747abb539ab3c1118ab)
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