xref: /freebsd/contrib/expat/lib/xmltok.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) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
12    Copyright (c) 2002      Greg Stein <gstein@users.sourceforge.net>
13    Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
14    Copyright (c) 2005-2009 Steven Solie <steven@solie.ca>
15    Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
16    Copyright (c) 2016      Pascal Cuoq <cuoq@trust-in-soft.com>
17    Copyright (c) 2016      Don Lewis <truckman@apache.org>
18    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
19    Copyright (c) 2017      Alexander Bluhm <alexander.bluhm@gmx.net>
20    Copyright (c) 2017      Benbuck Nason <bnason@netflix.com>
21    Copyright (c) 2017      José Gutiérrez de la Concha <jose@zeroc.com>
22    Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
23    Copyright (c) 2021      Donghee Na <donghee.na@python.org>
24    Copyright (c) 2022      Martin Ettl <ettl.martin78@googlemail.com>
25    Copyright (c) 2022      Sean McBride <sean@rogue-research.com>
26    Copyright (c) 2023      Hanno Böck <hanno@gentoo.org>
27    Copyright (c) 2025      Alfonso Gregory <gfunni234@gmail.com>
28    Copyright (c) 2026      Nick Begg <nick@stunttruck.net>
29    Copyright (c) 2026      Kartik Kenchi <netliomax25@gmail.com>
30    Licensed under the MIT license:
31 
32    Permission is  hereby granted,  free of charge,  to any  person obtaining
33    a  copy  of  this  software   and  associated  documentation  files  (the
34    "Software"),  to  deal in  the  Software  without restriction,  including
35    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
36    distribute, sublicense, and/or sell copies of the Software, and to permit
37    persons  to whom  the Software  is  furnished to  do so,  subject to  the
38    following conditions:
39 
40    The above copyright  notice and this permission notice  shall be included
41    in all copies or substantial portions of the Software.
42 
43    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
44    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
45    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
46    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
47    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
48    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
49    USE OR OTHER DEALINGS IN THE SOFTWARE.
50 
51    SPDX-License-Identifier: MIT
52 */
53 
54 #include "expat_config.h"
55 
56 #include <stddef.h>
57 #include <string.h> /* memcpy */
58 #include <stdbool.h>
59 
60 #ifdef _WIN32
61 #  include "winconfig.h"
62 #endif
63 
64 #include "internal.h"
65 #include "fallthrough.h"
66 #include "xmltok.h"
67 #include "nametab.h"
68 
69 #ifdef XML_DTD
70 #  define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
71 #else
72 #  define IGNORE_SECTION_TOK_VTABLE /* as nothing */
73 #endif
74 
75 #define VTABLE1                                                                \
76   {PREFIX(prologTok), PREFIX(contentTok),                                      \
77    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE},                         \
78       {PREFIX(attributeValueTok), PREFIX(entityValueTok)},                     \
79       PREFIX(nameMatchesAscii), PREFIX(nameLength), PREFIX(skipS),             \
80       PREFIX(getAtts), PREFIX(charRefNumber), PREFIX(predefinedEntityName),    \
81       PREFIX(updatePosition), PREFIX(isPublicId)
82 
83 #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
84 
85 #define UCS2_GET_NAMING(pages, hi, lo)                                         \
86   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
87 
88 /* A 2 byte UTF-8 representation splits the characters 11 bits between
89    the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into
90    pages, 3 bits to add to that index and 5 bits to generate the mask.
91 */
92 #define UTF8_GET_NAMING2(pages, byte)                                          \
93   (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3)                         \
94                 + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)]         \
95    & (1u << (((byte)[1]) & 0x1F)))
96 
97 /* A 3 byte UTF-8 representation splits the characters 16 bits between
98    the bottom 4, 6 and 6 bits of the bytes.  We need 8 bits to index
99    into pages, 3 bits to add to that index and 5 bits to generate the
100    mask.
101 */
102 #define UTF8_GET_NAMING3(pages, byte)                                          \
103   (namingBitmap                                                                \
104        [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)]      \
105          << 3)                                                                 \
106         + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)]                 \
107    & (1u << (((byte)[2]) & 0x1F)))
108 
109 /* Detection of invalid UTF-8 sequences is based on Table 3.1B
110    of Unicode 3.2: https://www.unicode.org/unicode/reports/tr28/
111    with the additional restriction of not allowing the Unicode
112    code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
113    Implementation details:
114      (A & 0x80) == 0     means A < 0x80
115    and
116      (A & 0xC0) == 0xC0  means A > 0xBF
117 */
118 
119 #define UTF8_INVALID2(p)                                                       \
120   ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
121 
122 #define UTF8_INVALID3(p)                                                       \
123   (((p)[2] & 0x80) == 0                                                        \
124    || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD                          \
125                                       : ((p)[2] & 0xC0) == 0xC0)               \
126    || ((*p) == 0xE0                                                            \
127            ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0                          \
128            : ((p)[1] & 0x80) == 0                                              \
129                  || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
130 
131 #define UTF8_INVALID4(p)                                                       \
132   (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0     \
133    || ((p)[2] & 0xC0) == 0xC0                                                  \
134    || ((*p) == 0xF0                                                            \
135            ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0                          \
136            : ((p)[1] & 0x80) == 0                                              \
137                  || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
138 
139 static int PTRFASTCALL
isNever(const ENCODING * enc,const char * p)140 isNever(const ENCODING *enc, const char *p) {
141   UNUSED_P(enc);
142   UNUSED_P(p);
143   return 0;
144 }
145 
146 static int PTRFASTCALL
utf8_isName2(const ENCODING * enc,const char * p)147 utf8_isName2(const ENCODING *enc, const char *p) {
148   UNUSED_P(enc);
149   return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
150 }
151 
152 static int PTRFASTCALL
utf8_isName3(const ENCODING * enc,const char * p)153 utf8_isName3(const ENCODING *enc, const char *p) {
154   UNUSED_P(enc);
155   return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
156 }
157 
158 #define utf8_isName4 isNever
159 
160 static int PTRFASTCALL
utf8_isNmstrt2(const ENCODING * enc,const char * p)161 utf8_isNmstrt2(const ENCODING *enc, const char *p) {
162   UNUSED_P(enc);
163   return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
164 }
165 
166 static int PTRFASTCALL
utf8_isNmstrt3(const ENCODING * enc,const char * p)167 utf8_isNmstrt3(const ENCODING *enc, const char *p) {
168   UNUSED_P(enc);
169   return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
170 }
171 
172 #define utf8_isNmstrt4 isNever
173 
174 static int PTRFASTCALL
utf8_isInvalid2(const ENCODING * enc,const char * p)175 utf8_isInvalid2(const ENCODING *enc, const char *p) {
176   UNUSED_P(enc);
177   return UTF8_INVALID2((const unsigned char *)p);
178 }
179 
180 static int PTRFASTCALL
utf8_isInvalid3(const ENCODING * enc,const char * p)181 utf8_isInvalid3(const ENCODING *enc, const char *p) {
182   UNUSED_P(enc);
183   return UTF8_INVALID3((const unsigned char *)p);
184 }
185 
186 static int PTRFASTCALL
utf8_isInvalid4(const ENCODING * enc,const char * p)187 utf8_isInvalid4(const ENCODING *enc, const char *p) {
188   UNUSED_P(enc);
189   return UTF8_INVALID4((const unsigned char *)p);
190 }
191 
192 struct normal_encoding {
193   ENCODING enc;
194   unsigned char type[256];
195 #ifdef XML_MIN_SIZE
196   int(PTRFASTCALL *byteType)(const ENCODING *, const char *);
197   int(PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
198   int(PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
199   int(PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
200   int(PTRCALL *charMatches)(const ENCODING *, const char *, int);
201 #endif /* XML_MIN_SIZE */
202   int(PTRFASTCALL *isName2)(const ENCODING *, const char *);
203   int(PTRFASTCALL *isName3)(const ENCODING *, const char *);
204   int(PTRFASTCALL *isName4)(const ENCODING *, const char *);
205   int(PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
206   int(PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
207   int(PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
208   int(PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
209   int(PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
210   int(PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
211 };
212 
213 #define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *)(enc))
214 
215 #ifdef XML_MIN_SIZE
216 
217 #  define STANDARD_VTABLE(E)                                                   \
218     E##byteType, E##isNameMin, E##isNmstrtMin, E##byteToAscii, E##charMatches,
219 
220 #else
221 
222 #  define STANDARD_VTABLE(E) /* as nothing */
223 
224 #endif
225 
226 #define NORMAL_VTABLE(E)                                                       \
227   E##isName2, E##isName3, E##isName4, E##isNmstrt2, E##isNmstrt3,              \
228       E##isNmstrt4, E##isInvalid2, E##isInvalid3, E##isInvalid4
229 
230 #define NULL_VTABLE                                                            \
231   /* isName2 */ NULL, /* isName3 */ NULL, /* isName4 */ NULL,                  \
232       /* isNmstrt2 */ NULL, /* isNmstrt3 */ NULL, /* isNmstrt4 */ NULL,        \
233       /* isInvalid2 */ NULL, /* isInvalid3 */ NULL, /* isInvalid4 */ NULL
234 
235 static int FASTCALL checkCharRefNumber(int result);
236 
237 #include "xmltok_impl.h"
238 #include "ascii.h"
239 
240 #ifdef XML_MIN_SIZE
241 #  define sb_isNameMin isNever
242 #  define sb_isNmstrtMin isNever
243 #endif
244 
245 #ifdef XML_MIN_SIZE
246 #  define MINBPC(enc) ((enc)->minBytesPerChar)
247 #else
248 /* minimum bytes per character */
249 #  define MINBPC(enc) 1
250 #endif
251 
252 #define SB_BYTE_TYPE(enc, p)                                                   \
253   (((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
254 
255 #ifdef XML_MIN_SIZE
256 static int PTRFASTCALL
sb_byteType(const ENCODING * enc,const char * p)257 sb_byteType(const ENCODING *enc, const char *p) {
258   return SB_BYTE_TYPE(enc, p);
259 }
260 #  define BYTE_TYPE(enc, p) (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
261 #else
262 #  define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
263 #endif
264 
265 #ifdef XML_MIN_SIZE
266 #  define BYTE_TO_ASCII(enc, p) (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
267 static int PTRFASTCALL
sb_byteToAscii(const ENCODING * enc,const char * p)268 sb_byteToAscii(const ENCODING *enc, const char *p) {
269   UNUSED_P(enc);
270   return *p;
271 }
272 #else
273 #  define BYTE_TO_ASCII(enc, p) (*(p))
274 #endif
275 
276 #define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p))
277 #define IS_NMSTRT_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isNmstrt##n(enc, p))
278 #ifdef XML_MIN_SIZE
279 #  define IS_INVALID_CHAR(enc, p, n)                                           \
280     (AS_NORMAL_ENCODING(enc)->isInvalid##n                                     \
281      && AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
282 #else
283 #  define IS_INVALID_CHAR(enc, p, n)                                           \
284     (AS_NORMAL_ENCODING(enc)->isInvalid##n(enc, p))
285 #endif
286 
287 #ifdef XML_MIN_SIZE
288 #  define IS_NAME_CHAR_MINBPC(enc, p)                                          \
289     (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
290 #  define IS_NMSTRT_CHAR_MINBPC(enc, p)                                        \
291     (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
292 #else
293 #  define IS_NAME_CHAR_MINBPC(enc, p) (0)
294 #  define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
295 #endif
296 
297 #ifdef XML_MIN_SIZE
298 #  define CHAR_MATCHES(enc, p, c)                                              \
299     (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
300 static int PTRCALL
sb_charMatches(const ENCODING * enc,const char * p,int c)301 sb_charMatches(const ENCODING *enc, const char *p, int c) {
302   UNUSED_P(enc);
303   return *p == c;
304 }
305 #else
306 /* c is an ASCII character */
307 #  define CHAR_MATCHES(enc, p, c) (*(p) == (c))
308 #endif
309 
310 #define PREFIX(ident) normal_##ident
311 #define XML_TOK_IMPL_C
312 #include "xmltok_impl.c"
313 #undef XML_TOK_IMPL_C
314 
315 #undef MINBPC
316 #undef BYTE_TYPE
317 #undef BYTE_TO_ASCII
318 #undef CHAR_MATCHES
319 #undef IS_NAME_CHAR
320 #undef IS_NAME_CHAR_MINBPC
321 #undef IS_NMSTRT_CHAR
322 #undef IS_NMSTRT_CHAR_MINBPC
323 #undef IS_INVALID_CHAR
324 
325 enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
326        UTF8_cval1 = 0x00,
327        UTF8_cval2 = 0xc0,
328        UTF8_cval3 = 0xe0,
329        UTF8_cval4 = 0xf0
330 };
331 
332 void
_INTERNAL_trim_to_complete_utf8_characters(const char * from,const char ** fromLimRef)333 _INTERNAL_trim_to_complete_utf8_characters(const char *from,
334                                            const char **fromLimRef) {
335   const char *fromLim = *fromLimRef;
336   size_t walked = 0;
337   for (; fromLim > from; fromLim--, walked++) {
338     const unsigned char prev = (unsigned char)fromLim[-1];
339     if ((prev & 0xf8u)
340         == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
341       if (walked + 1 >= 4) {
342         fromLim += 4 - 1;
343         break;
344       } else {
345         walked = 0;
346       }
347     } else if ((prev & 0xf0u)
348                == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
349       if (walked + 1 >= 3) {
350         fromLim += 3 - 1;
351         break;
352       } else {
353         walked = 0;
354       }
355     } else if ((prev & 0xe0u)
356                == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
357       if (walked + 1 >= 2) {
358         fromLim += 2 - 1;
359         break;
360       } else {
361         walked = 0;
362       }
363     } else if ((prev & 0x80u)
364                == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
365       break;
366     }
367   }
368   *fromLimRef = fromLim;
369 }
370 
371 static enum XML_Convert_Result PTRCALL
utf8_toUtf8(const ENCODING * enc,const char ** fromP,const char * fromLim,char ** toP,const char * toLim)372 utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
373             char **toP, const char *toLim) {
374   bool input_incomplete = false;
375   bool output_exhausted = false;
376 
377   /* Avoid copying partial characters (due to limited space). */
378   const ptrdiff_t bytesAvailable = fromLim - *fromP;
379   const ptrdiff_t bytesStorable = toLim - *toP;
380   UNUSED_P(enc);
381   if (bytesAvailable > bytesStorable) {
382     fromLim = *fromP + bytesStorable;
383     output_exhausted = true;
384   }
385 
386   /* Avoid copying partial characters (from incomplete input). */
387   {
388     const char *const fromLimBefore = fromLim;
389     _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim);
390     if (fromLim < fromLimBefore) {
391       input_incomplete = true;
392     }
393   }
394 
395   {
396     const ptrdiff_t bytesToCopy = fromLim - *fromP;
397     memcpy(*toP, *fromP, bytesToCopy);
398     *fromP += bytesToCopy;
399     *toP += bytesToCopy;
400   }
401 
402   if (output_exhausted) /* needs to go first */
403     return XML_CONVERT_OUTPUT_EXHAUSTED;
404   else if (input_incomplete)
405     return XML_CONVERT_INPUT_INCOMPLETE;
406   else
407     return XML_CONVERT_COMPLETED;
408 }
409 
410 static enum XML_Convert_Result PTRCALL
utf8_toUtf16(const ENCODING * enc,const char ** fromP,const char * fromLim,unsigned short ** toP,const unsigned short * toLim)411 utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
412              unsigned short **toP, const unsigned short *toLim) {
413   enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
414   unsigned short *to = *toP;
415   const char *from = *fromP;
416   while (from < fromLim && to < toLim) {
417     switch (SB_BYTE_TYPE(enc, from)) {
418     case BT_LEAD2:
419       if (fromLim - from < 2) {
420         res = XML_CONVERT_INPUT_INCOMPLETE;
421         goto after;
422       }
423       *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
424       from += 2;
425       break;
426     case BT_LEAD3:
427       if (fromLim - from < 3) {
428         res = XML_CONVERT_INPUT_INCOMPLETE;
429         goto after;
430       }
431       *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6)
432                                | (from[2] & 0x3f));
433       from += 3;
434       break;
435     case BT_LEAD4: {
436       unsigned long n;
437       if (toLim - to < 2) {
438         res = XML_CONVERT_OUTPUT_EXHAUSTED;
439         goto after;
440       }
441       if (fromLim - from < 4) {
442         res = XML_CONVERT_INPUT_INCOMPLETE;
443         goto after;
444       }
445       n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
446           | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
447       n -= 0x10000;
448       to[0] = (unsigned short)((n >> 10) | 0xD800);
449       to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
450       to += 2;
451       from += 4;
452     } break;
453     default:
454       *to++ = *from++;
455       break;
456     }
457   }
458   if (from < fromLim)
459     res = XML_CONVERT_OUTPUT_EXHAUSTED;
460 after:
461   *fromP = from;
462   *toP = to;
463   return res;
464 }
465 
466 #ifdef XML_NS
467 static const struct normal_encoding utf8_encoding_ns
468     = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
469        {
470 #  include "asciitab.h"
471 #  include "utf8tab.h"
472        },
473        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
474 #endif
475 
476 static const struct normal_encoding utf8_encoding
477     = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
478        {
479 #define BT_COLON BT_NMSTRT
480 #include "asciitab.h"
481 #undef BT_COLON
482 #include "utf8tab.h"
483        },
484        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
485 
486 #ifdef XML_NS
487 
488 static const struct normal_encoding internal_utf8_encoding_ns
489     = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
490        {
491 #  include "iasciitab.h"
492 #  include "utf8tab.h"
493        },
494        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
495 
496 #endif
497 
498 static const struct normal_encoding internal_utf8_encoding
499     = {{VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0},
500        {
501 #define BT_COLON BT_NMSTRT
502 #include "iasciitab.h"
503 #undef BT_COLON
504 #include "utf8tab.h"
505        },
506        STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)};
507 
508 static enum XML_Convert_Result PTRCALL
latin1_toUtf8(const ENCODING * enc,const char ** fromP,const char * fromLim,char ** toP,const char * toLim)509 latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
510               char **toP, const char *toLim) {
511   UNUSED_P(enc);
512   for (;;) {
513     unsigned char c;
514     if (*fromP == fromLim)
515       return XML_CONVERT_COMPLETED;
516     c = (unsigned char)**fromP;
517     if (c & 0x80) {
518       if (toLim - *toP < 2)
519         return XML_CONVERT_OUTPUT_EXHAUSTED;
520       *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
521       *(*toP)++ = (char)((c & 0x3f) | 0x80);
522       (*fromP)++;
523     } else {
524       if (*toP == toLim)
525         return XML_CONVERT_OUTPUT_EXHAUSTED;
526       *(*toP)++ = *(*fromP)++;
527     }
528   }
529 }
530 
531 static enum XML_Convert_Result PTRCALL
latin1_toUtf16(const ENCODING * enc,const char ** fromP,const char * fromLim,unsigned short ** toP,const unsigned short * toLim)532 latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
533                unsigned short **toP, const unsigned short *toLim) {
534   UNUSED_P(enc);
535   while (*fromP < fromLim && *toP < toLim)
536     *(*toP)++ = (unsigned char)*(*fromP)++;
537 
538   if ((*toP == toLim) && (*fromP < fromLim))
539     return XML_CONVERT_OUTPUT_EXHAUSTED;
540   else
541     return XML_CONVERT_COMPLETED;
542 }
543 
544 #ifdef XML_NS
545 
546 static const struct normal_encoding latin1_encoding_ns
547     = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0},
548        {
549 #  include "asciitab.h"
550 #  include "latin1tab.h"
551        },
552        STANDARD_VTABLE(sb_) NULL_VTABLE};
553 
554 #endif
555 
556 static const struct normal_encoding latin1_encoding
557     = {{VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0},
558        {
559 #define BT_COLON BT_NMSTRT
560 #include "asciitab.h"
561 #undef BT_COLON
562 #include "latin1tab.h"
563        },
564        STANDARD_VTABLE(sb_) NULL_VTABLE};
565 
566 static enum XML_Convert_Result PTRCALL
ascii_toUtf8(const ENCODING * enc,const char ** fromP,const char * fromLim,char ** toP,const char * toLim)567 ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
568              char **toP, const char *toLim) {
569   UNUSED_P(enc);
570   while (*fromP < fromLim && *toP < toLim)
571     *(*toP)++ = *(*fromP)++;
572 
573   if ((*toP == toLim) && (*fromP < fromLim))
574     return XML_CONVERT_OUTPUT_EXHAUSTED;
575   else
576     return XML_CONVERT_COMPLETED;
577 }
578 
579 #ifdef XML_NS
580 
581 static const struct normal_encoding ascii_encoding_ns
582     = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0},
583        {
584 #  include "asciitab.h"
585            /* BT_NONXML == 0 */
586        },
587        STANDARD_VTABLE(sb_) NULL_VTABLE};
588 
589 #endif
590 
591 static const struct normal_encoding ascii_encoding
592     = {{VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0},
593        {
594 #define BT_COLON BT_NMSTRT
595 #include "asciitab.h"
596 #undef BT_COLON
597            /* BT_NONXML == 0 */
598        },
599        STANDARD_VTABLE(sb_) NULL_VTABLE};
600 
601 static int PTRFASTCALL
unicode_byte_type(char hi,char lo)602 unicode_byte_type(char hi, char lo) {
603   switch ((unsigned char)hi) {
604   /* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */
605   case 0xD8:
606   case 0xD9:
607   case 0xDA:
608   case 0xDB:
609     return BT_LEAD4;
610   /* 0xDC00-0xDFFF second 16-bit code unit or low surrogate (W2) */
611   case 0xDC:
612   case 0xDD:
613   case 0xDE:
614   case 0xDF:
615     return BT_TRAIL;
616   case 0xFF:
617     switch ((unsigned char)lo) {
618     case 0xFF: /* noncharacter-FFFF */
619     case 0xFE: /* noncharacter-FFFE */
620       return BT_NONXML;
621     }
622     break;
623   }
624   return BT_NONASCII;
625 }
626 
627 #define DEFINE_UTF16_TO_UTF8(E)                                                \
628   static enum XML_Convert_Result PTRCALL E##toUtf8(                            \
629       const ENCODING *enc, const char **fromP, const char *fromLim,            \
630       char **toP, const char *toLim) {                                         \
631     const char *from = *fromP;                                                 \
632     UNUSED_P(enc);                                                             \
633     fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */      \
634     for (; from < fromLim; from += 2) {                                        \
635       int plane;                                                               \
636       unsigned char lo2;                                                       \
637       unsigned char lo = GET_LO(from);                                         \
638       unsigned char hi = GET_HI(from);                                         \
639       switch (hi) {                                                            \
640       case 0:                                                                  \
641         if (lo < 0x80) {                                                       \
642           if (*toP == toLim) {                                                 \
643             *fromP = from;                                                     \
644             return XML_CONVERT_OUTPUT_EXHAUSTED;                               \
645           }                                                                    \
646           *(*toP)++ = lo;                                                      \
647           break;                                                               \
648         }                                                                      \
649         EXPAT_FALLTHROUGH;                                                     \
650       case 0x1:                                                                \
651       case 0x2:                                                                \
652       case 0x3:                                                                \
653       case 0x4:                                                                \
654       case 0x5:                                                                \
655       case 0x6:                                                                \
656       case 0x7:                                                                \
657         if (toLim - *toP < 2) {                                                \
658           *fromP = from;                                                       \
659           return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
660         }                                                                      \
661         *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2);                      \
662         *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
663         break;                                                                 \
664       default:                                                                 \
665         if (toLim - *toP < 3) {                                                \
666           *fromP = from;                                                       \
667           return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
668         }                                                                      \
669         /* 16 bits divided 4, 6, 6 amongst 3 bytes */                          \
670         *(*toP)++ = ((hi >> 4) | UTF8_cval3);                                  \
671         *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80);                    \
672         *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
673         break;                                                                 \
674       case 0xD8:                                                               \
675       case 0xD9:                                                               \
676       case 0xDA:                                                               \
677       case 0xDB:                                                               \
678         if (toLim - *toP < 4) {                                                \
679           *fromP = from;                                                       \
680           return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
681         }                                                                      \
682         if (fromLim - from < 4) {                                              \
683           *fromP = from;                                                       \
684           return XML_CONVERT_INPUT_INCOMPLETE;                                 \
685         }                                                                      \
686         plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1;                   \
687         *(*toP)++ = (char)((plane >> 2) | UTF8_cval4);                         \
688         *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80);         \
689         from += 2;                                                             \
690         lo2 = GET_LO(from);                                                    \
691         *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2)           \
692                      | (lo2 >> 6) | 0x80);                                     \
693         *(*toP)++ = ((lo2 & 0x3f) | 0x80);                                     \
694         break;                                                                 \
695       }                                                                        \
696     }                                                                          \
697     *fromP = from;                                                             \
698     if (from < fromLim)                                                        \
699       return XML_CONVERT_INPUT_INCOMPLETE;                                     \
700     else                                                                       \
701       return XML_CONVERT_COMPLETED;                                            \
702   }
703 
704 #define DEFINE_UTF16_TO_UTF16(E)                                               \
705   static enum XML_Convert_Result PTRCALL E##toUtf16(                           \
706       const ENCODING *enc, const char **fromP, const char *fromLim,            \
707       unsigned short **toP, const unsigned short *toLim) {                     \
708     enum XML_Convert_Result res = XML_CONVERT_COMPLETED;                       \
709     UNUSED_P(enc);                                                             \
710     fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */  \
711     /* Avoid copying the first half (2 bytes) of surrogate pairs (4 bytes) */  \
712     if (fromLim - *fromP > ((toLim - *toP) << 1)                               \
713         && /* are the last two bytes a high surrogate (0xD800-0xDBFF)? */      \
714         (GET_HI(fromLim - 2) & 0xFC) == 0xD8) {                                \
715       fromLim -= 2;                                                            \
716       res = XML_CONVERT_INPUT_INCOMPLETE;                                      \
717     }                                                                          \
718     for (; *fromP < fromLim && *toP < toLim; *fromP += 2)                      \
719       *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP);                      \
720     if ((*toP == toLim) && (*fromP < fromLim))                                 \
721       return XML_CONVERT_OUTPUT_EXHAUSTED;                                     \
722     else                                                                       \
723       return res;                                                              \
724   }
725 
726 #define GET_LO(ptr) ((unsigned char)(ptr)[0])
727 #define GET_HI(ptr) ((unsigned char)(ptr)[1])
728 
729 DEFINE_UTF16_TO_UTF8(little2_)
DEFINE_UTF16_TO_UTF16(little2_)730 DEFINE_UTF16_TO_UTF16(little2_)
731 
732 #undef GET_LO
733 #undef GET_HI
734 
735 #define GET_LO(ptr) ((unsigned char)(ptr)[1])
736 #define GET_HI(ptr) ((unsigned char)(ptr)[0])
737 
738 DEFINE_UTF16_TO_UTF8(big2_)
739 DEFINE_UTF16_TO_UTF16(big2_)
740 
741 #undef GET_LO
742 #undef GET_HI
743 
744 #define LITTLE2_BYTE_TYPE(enc, p)                                              \
745   ((p)[1] == 0 ? SB_BYTE_TYPE(enc, p) : unicode_byte_type((p)[1], (p)[0]))
746 #define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1)
747 #define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c))
748 #define LITTLE2_IS_NAME_CHAR_MINBPC(p)                                         \
749   UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
750 #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)                                       \
751   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
752 
753 #ifdef XML_MIN_SIZE
754 
755 static int PTRFASTCALL
756 little2_byteType(const ENCODING *enc, const char *p) {
757   return LITTLE2_BYTE_TYPE(enc, p);
758 }
759 
760 static int PTRFASTCALL
little2_byteToAscii(const ENCODING * enc,const char * p)761 little2_byteToAscii(const ENCODING *enc, const char *p) {
762   UNUSED_P(enc);
763   return LITTLE2_BYTE_TO_ASCII(p);
764 }
765 
766 static int PTRCALL
little2_charMatches(const ENCODING * enc,const char * p,int c)767 little2_charMatches(const ENCODING *enc, const char *p, int c) {
768   UNUSED_P(enc);
769   return LITTLE2_CHAR_MATCHES(p, c);
770 }
771 
772 static int PTRFASTCALL
little2_isNameMin(const ENCODING * enc,const char * p)773 little2_isNameMin(const ENCODING *enc, const char *p) {
774   UNUSED_P(enc);
775   return LITTLE2_IS_NAME_CHAR_MINBPC(p);
776 }
777 
778 static int PTRFASTCALL
little2_isNmstrtMin(const ENCODING * enc,const char * p)779 little2_isNmstrtMin(const ENCODING *enc, const char *p) {
780   UNUSED_P(enc);
781   return LITTLE2_IS_NMSTRT_CHAR_MINBPC(p);
782 }
783 
784 #  undef VTABLE
785 #  define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
786 
787 #else /* not XML_MIN_SIZE */
788 
789 #  undef PREFIX
790 #  define PREFIX(ident) little2_##ident
791 #  define MINBPC(enc) 2
792 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
793 #  define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
794 #  define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p)
795 #  define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c)
796 #  define IS_NAME_CHAR(enc, p, n) 0
797 #  define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
798 #  define IS_NMSTRT_CHAR(enc, p, n) (0)
799 #  define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
800 
801 #  define XML_TOK_IMPL_C
802 #  include "xmltok_impl.c"
803 #  undef XML_TOK_IMPL_C
804 
805 #  undef MINBPC
806 #  undef BYTE_TYPE
807 #  undef BYTE_TO_ASCII
808 #  undef CHAR_MATCHES
809 #  undef IS_NAME_CHAR
810 #  undef IS_NAME_CHAR_MINBPC
811 #  undef IS_NMSTRT_CHAR
812 #  undef IS_NMSTRT_CHAR_MINBPC
813 #  undef IS_INVALID_CHAR
814 
815 #endif /* not XML_MIN_SIZE */
816 
817 #ifdef XML_NS
818 
819 static const struct normal_encoding little2_encoding_ns
820     = {{VTABLE, 2, 0,
821 #  if BYTEORDER == 1234
822         1
823 #  else
824         0
825 #  endif
826        },
827        {
828 #  include "asciitab.h"
829 #  include "latin1tab.h"
830        },
831        STANDARD_VTABLE(little2_) NULL_VTABLE};
832 
833 #endif
834 
835 static const struct normal_encoding little2_encoding
836     = {{VTABLE, 2, 0,
837 #if BYTEORDER == 1234
838         1
839 #else
840         0
841 #endif
842        },
843        {
844 #define BT_COLON BT_NMSTRT
845 #include "asciitab.h"
846 #undef BT_COLON
847 #include "latin1tab.h"
848        },
849        STANDARD_VTABLE(little2_) NULL_VTABLE};
850 
851 #if BYTEORDER != 4321
852 
853 #  ifdef XML_NS
854 
855 static const struct normal_encoding internal_little2_encoding_ns
856     = {{VTABLE, 2, 0, 1},
857        {
858 #    include "iasciitab.h"
859 #    include "latin1tab.h"
860        },
861        STANDARD_VTABLE(little2_) NULL_VTABLE};
862 
863 #  endif
864 
865 static const struct normal_encoding internal_little2_encoding
866     = {{VTABLE, 2, 0, 1},
867        {
868 #  define BT_COLON BT_NMSTRT
869 #  include "iasciitab.h"
870 #  undef BT_COLON
871 #  include "latin1tab.h"
872        },
873        STANDARD_VTABLE(little2_) NULL_VTABLE};
874 
875 #endif
876 
877 #define BIG2_BYTE_TYPE(enc, p)                                                 \
878   ((p)[0] == 0 ? SB_BYTE_TYPE(enc, p + 1) : unicode_byte_type((p)[0], (p)[1]))
879 #define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1)
880 #define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c))
881 #define BIG2_IS_NAME_CHAR_MINBPC(p)                                            \
882   UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
883 #define BIG2_IS_NMSTRT_CHAR_MINBPC(p)                                          \
884   UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
885 
886 #ifdef XML_MIN_SIZE
887 
888 static int PTRFASTCALL
big2_byteType(const ENCODING * enc,const char * p)889 big2_byteType(const ENCODING *enc, const char *p) {
890   return BIG2_BYTE_TYPE(enc, p);
891 }
892 
893 static int PTRFASTCALL
big2_byteToAscii(const ENCODING * enc,const char * p)894 big2_byteToAscii(const ENCODING *enc, const char *p) {
895   UNUSED_P(enc);
896   return BIG2_BYTE_TO_ASCII(p);
897 }
898 
899 static int PTRCALL
big2_charMatches(const ENCODING * enc,const char * p,int c)900 big2_charMatches(const ENCODING *enc, const char *p, int c) {
901   UNUSED_P(enc);
902   return BIG2_CHAR_MATCHES(p, c);
903 }
904 
905 static int PTRFASTCALL
big2_isNameMin(const ENCODING * enc,const char * p)906 big2_isNameMin(const ENCODING *enc, const char *p) {
907   UNUSED_P(enc);
908   return BIG2_IS_NAME_CHAR_MINBPC(p);
909 }
910 
911 static int PTRFASTCALL
big2_isNmstrtMin(const ENCODING * enc,const char * p)912 big2_isNmstrtMin(const ENCODING *enc, const char *p) {
913   UNUSED_P(enc);
914   return BIG2_IS_NMSTRT_CHAR_MINBPC(p);
915 }
916 
917 #  undef VTABLE
918 #  define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
919 
920 #else /* not XML_MIN_SIZE */
921 
922 #  undef PREFIX
923 #  define PREFIX(ident) big2_##ident
924 #  define MINBPC(enc) 2
925 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
926 #  define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
927 #  define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p)
928 #  define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c)
929 #  define IS_NAME_CHAR(enc, p, n) 0
930 #  define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
931 #  define IS_NMSTRT_CHAR(enc, p, n) (0)
932 #  define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
933 
934 #  define XML_TOK_IMPL_C
935 #  include "xmltok_impl.c"
936 #  undef XML_TOK_IMPL_C
937 
938 #  undef MINBPC
939 #  undef BYTE_TYPE
940 #  undef BYTE_TO_ASCII
941 #  undef CHAR_MATCHES
942 #  undef IS_NAME_CHAR
943 #  undef IS_NAME_CHAR_MINBPC
944 #  undef IS_NMSTRT_CHAR
945 #  undef IS_NMSTRT_CHAR_MINBPC
946 #  undef IS_INVALID_CHAR
947 
948 #endif /* not XML_MIN_SIZE */
949 
950 #ifdef XML_NS
951 
952 static const struct normal_encoding big2_encoding_ns
953     = {{VTABLE, 2, 0,
954 #  if BYTEORDER == 4321
955         1
956 #  else
957         0
958 #  endif
959        },
960        {
961 #  include "asciitab.h"
962 #  include "latin1tab.h"
963        },
964        STANDARD_VTABLE(big2_) NULL_VTABLE};
965 
966 #endif
967 
968 static const struct normal_encoding big2_encoding
969     = {{VTABLE, 2, 0,
970 #if BYTEORDER == 4321
971         1
972 #else
973         0
974 #endif
975        },
976        {
977 #define BT_COLON BT_NMSTRT
978 #include "asciitab.h"
979 #undef BT_COLON
980 #include "latin1tab.h"
981        },
982        STANDARD_VTABLE(big2_) NULL_VTABLE};
983 
984 #if BYTEORDER != 1234
985 
986 #  ifdef XML_NS
987 
988 static const struct normal_encoding internal_big2_encoding_ns
989     = {{VTABLE, 2, 0, 1},
990        {
991 #    include "iasciitab.h"
992 #    include "latin1tab.h"
993        },
994        STANDARD_VTABLE(big2_) NULL_VTABLE};
995 
996 #  endif
997 
998 static const struct normal_encoding internal_big2_encoding
999     = {{VTABLE, 2, 0, 1},
1000        {
1001 #  define BT_COLON BT_NMSTRT
1002 #  include "iasciitab.h"
1003 #  undef BT_COLON
1004 #  include "latin1tab.h"
1005        },
1006        STANDARD_VTABLE(big2_) NULL_VTABLE};
1007 
1008 #endif
1009 
1010 #undef PREFIX
1011 
1012 static int FASTCALL
streqci(const char * s1,const char * s2)1013 streqci(const char *s1, const char *s2) {
1014   for (;;) {
1015     char c1 = *s1++;
1016     char c2 = *s2++;
1017     if (ASCII_a <= c1 && c1 <= ASCII_z)
1018       c1 += ASCII_A - ASCII_a;
1019     if (ASCII_a <= c2 && c2 <= ASCII_z)
1020       /* The following line will never get executed.  streqci() is
1021        * only called from two places, both of which guarantee to put
1022        * upper-case strings into s2.
1023        */
1024       c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
1025     if (c1 != c2)
1026       return 0;
1027     if (! c1)
1028       break;
1029   }
1030   return 1;
1031 }
1032 
1033 static void PTRCALL
initUpdatePosition(const ENCODING * enc,const char * ptr,const char * end,POSITION * pos)1034 initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end,
1035                    POSITION *pos) {
1036   UNUSED_P(enc);
1037   normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
1038 }
1039 
1040 static int
toAscii(const ENCODING * enc,const char * ptr,const char * end)1041 toAscii(const ENCODING *enc, const char *ptr, const char *end) {
1042   char buf[1];
1043   char *p = buf;
1044   XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
1045   if (p == buf)
1046     return -1;
1047   else
1048     return buf[0];
1049 }
1050 
1051 static int FASTCALL
isSpace(int c)1052 isSpace(int c) {
1053   switch (c) {
1054   case 0x20:
1055   case 0xD:
1056   case 0xA:
1057   case 0x9:
1058     return 1;
1059   }
1060   return 0;
1061 }
1062 
1063 /* Return 1 if there's just optional white space or there's an S
1064    followed by name=val.
1065 */
1066 static int
parsePseudoAttribute(const ENCODING * enc,const char * ptr,const char * end,const char ** namePtr,const char ** nameEndPtr,const char ** valPtr,const char ** nextTokPtr)1067 parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end,
1068                      const char **namePtr, const char **nameEndPtr,
1069                      const char **valPtr, const char **nextTokPtr) {
1070   int c;
1071   char open;
1072   if (ptr == end) {
1073     *namePtr = NULL;
1074     return 1;
1075   }
1076   if (! isSpace(toAscii(enc, ptr, end))) {
1077     *nextTokPtr = ptr;
1078     return 0;
1079   }
1080   do {
1081     ptr += enc->minBytesPerChar;
1082   } while (isSpace(toAscii(enc, ptr, end)));
1083   if (ptr == end) {
1084     *namePtr = NULL;
1085     return 1;
1086   }
1087   *namePtr = ptr;
1088   for (;;) {
1089     c = toAscii(enc, ptr, end);
1090     if (c == -1) {
1091       *nextTokPtr = ptr;
1092       return 0;
1093     }
1094     if (c == ASCII_EQUALS) {
1095       *nameEndPtr = ptr;
1096       break;
1097     }
1098     if (isSpace(c)) {
1099       *nameEndPtr = ptr;
1100       do {
1101         ptr += enc->minBytesPerChar;
1102       } while (isSpace(c = toAscii(enc, ptr, end)));
1103       if (c != ASCII_EQUALS) {
1104         *nextTokPtr = ptr;
1105         return 0;
1106       }
1107       break;
1108     }
1109     ptr += enc->minBytesPerChar;
1110   }
1111   if (ptr == *namePtr) {
1112     *nextTokPtr = ptr;
1113     return 0;
1114   }
1115   ptr += enc->minBytesPerChar;
1116   c = toAscii(enc, ptr, end);
1117   while (isSpace(c)) {
1118     ptr += enc->minBytesPerChar;
1119     c = toAscii(enc, ptr, end);
1120   }
1121   if (c != ASCII_QUOT && c != ASCII_APOS) {
1122     *nextTokPtr = ptr;
1123     return 0;
1124   }
1125   open = (char)c;
1126   ptr += enc->minBytesPerChar;
1127   *valPtr = ptr;
1128   for (;; ptr += enc->minBytesPerChar) {
1129     c = toAscii(enc, ptr, end);
1130     if (c == open)
1131       break;
1132     if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)
1133         && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD
1134         && c != ASCII_MINUS && c != ASCII_UNDERSCORE) {
1135       *nextTokPtr = ptr;
1136       return 0;
1137     }
1138   }
1139   *nextTokPtr = ptr + enc->minBytesPerChar;
1140   return 1;
1141 }
1142 
1143 static const char KW_version[]
1144     = {ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'};
1145 
1146 static const char KW_encoding[] = {ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d,
1147                                    ASCII_i, ASCII_n, ASCII_g, '\0'};
1148 
1149 static const char KW_standalone[]
1150     = {ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a,
1151        ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'};
1152 
1153 static const char KW_yes[] = {ASCII_y, ASCII_e, ASCII_s, '\0'};
1154 
1155 static const char KW_no[] = {ASCII_n, ASCII_o, '\0'};
1156 
1157 static int
doParseXmlDecl(const ENCODING * (* encodingFinder)(const ENCODING *,const char *,const char *),int isGeneralTextEntity,const ENCODING * enc,const char * ptr,const char * end,const char ** badPtr,const char ** versionPtr,const char ** versionEndPtr,const char ** encodingName,const ENCODING ** encoding,int * standalone)1158 doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *,
1159                                                  const char *),
1160                int isGeneralTextEntity, const ENCODING *enc, const char *ptr,
1161                const char *end, const char **badPtr, const char **versionPtr,
1162                const char **versionEndPtr, const char **encodingName,
1163                const ENCODING **encoding, int *standalone) {
1164   const char *val = NULL;
1165   const char *name = NULL;
1166   const char *nameEnd = NULL;
1167   ptr += 5 * enc->minBytesPerChar;
1168   end -= 2 * enc->minBytesPerChar;
1169   if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
1170       || ! name) {
1171     *badPtr = ptr;
1172     return 0;
1173   }
1174   if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
1175     if (! isGeneralTextEntity) {
1176       *badPtr = name;
1177       return 0;
1178     }
1179   } else {
1180     if (versionPtr)
1181       *versionPtr = val;
1182     if (versionEndPtr)
1183       *versionEndPtr = ptr;
1184     /* The version number must not be empty; VersionNum requires at least
1185        one character.  The encoding and standalone pseudo-attributes below
1186        already reject an empty value, so keep version consistent. */
1187     if (val == ptr - enc->minBytesPerChar) {
1188       *badPtr = val;
1189       return 0;
1190     }
1191     if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
1192       *badPtr = ptr;
1193       return 0;
1194     }
1195     if (! name) {
1196       if (isGeneralTextEntity) {
1197         /* a TextDecl must have an EncodingDecl */
1198         *badPtr = ptr;
1199         return 0;
1200       }
1201       return 1;
1202     }
1203   }
1204   if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
1205     int c = toAscii(enc, val, end);
1206     if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) {
1207       *badPtr = val;
1208       return 0;
1209     }
1210     if (encodingName)
1211       *encodingName = val;
1212     if (encoding)
1213       *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
1214     if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
1215       *badPtr = ptr;
1216       return 0;
1217     }
1218     if (! name)
1219       return 1;
1220   }
1221   if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
1222       || isGeneralTextEntity) {
1223     *badPtr = name;
1224     return 0;
1225   }
1226   if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
1227     if (standalone)
1228       *standalone = 1;
1229   } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
1230     if (standalone)
1231       *standalone = 0;
1232   } else {
1233     *badPtr = val;
1234     return 0;
1235   }
1236   while (isSpace(toAscii(enc, ptr, end)))
1237     ptr += enc->minBytesPerChar;
1238   if (ptr != end) {
1239     *badPtr = ptr;
1240     return 0;
1241   }
1242   return 1;
1243 }
1244 
1245 static int FASTCALL
checkCharRefNumber(int result)1246 checkCharRefNumber(int result) {
1247   switch (result >> 8) {
1248   case 0xD8:
1249   case 0xD9:
1250   case 0xDA:
1251   case 0xDB:
1252   case 0xDC:
1253   case 0xDD:
1254   case 0xDE:
1255   case 0xDF:
1256     return -1;
1257   case 0:
1258     if (latin1_encoding.type[result] == BT_NONXML)
1259       return -1;
1260     break;
1261   case 0xFF:
1262     if (result == 0xFFFE || result == 0xFFFF)
1263       return -1;
1264     break;
1265   }
1266   return result;
1267 }
1268 
1269 int FASTCALL
XmlUtf8Encode(int c,char * buf)1270 XmlUtf8Encode(int c, char *buf) {
1271   enum {
1272     /* minN is minimum legal resulting value for N byte sequence */
1273     min2 = 0x80,
1274     min3 = 0x800,
1275     min4 = 0x10000
1276   };
1277 
1278   if (c < 0)
1279     return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */
1280   if (c < min2) {
1281     buf[0] = (char)(c | UTF8_cval1);
1282     return 1;
1283   }
1284   if (c < min3) {
1285     buf[0] = (char)((c >> 6) | UTF8_cval2);
1286     buf[1] = (char)((c & 0x3f) | 0x80);
1287     return 2;
1288   }
1289   if (c < min4) {
1290     buf[0] = (char)((c >> 12) | UTF8_cval3);
1291     buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
1292     buf[2] = (char)((c & 0x3f) | 0x80);
1293     return 3;
1294   }
1295   if (c < 0x110000) {
1296     buf[0] = (char)((c >> 18) | UTF8_cval4);
1297     buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
1298     buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
1299     buf[3] = (char)((c & 0x3f) | 0x80);
1300     return 4;
1301   }
1302   return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
1303 }
1304 
1305 int FASTCALL
XmlUtf16Encode(int charNum,unsigned short * buf)1306 XmlUtf16Encode(int charNum, unsigned short *buf) {
1307   if (charNum < 0)
1308     return 0;
1309   if (charNum < 0x10000) {
1310     buf[0] = (unsigned short)charNum;
1311     return 1;
1312   }
1313   if (charNum < 0x110000) {
1314     charNum -= 0x10000;
1315     buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
1316     buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
1317     return 2;
1318   }
1319   return 0;
1320 }
1321 
1322 struct unknown_encoding {
1323   struct normal_encoding normal;
1324   CONVERTER convert;
1325   void *userData;
1326   unsigned short utf16[256];
1327   char utf8[256][4];
1328 };
1329 
1330 #define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc))
1331 
1332 int
XmlSizeOfUnknownEncoding(void)1333 XmlSizeOfUnknownEncoding(void) {
1334   return sizeof(struct unknown_encoding);
1335 }
1336 
1337 static int PTRFASTCALL
unknown_isName(const ENCODING * enc,const char * p)1338 unknown_isName(const ENCODING *enc, const char *p) {
1339   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1340   int c = uenc->convert(uenc->userData, p);
1341   if (c & ~0xFFFF)
1342     return 0;
1343   return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
1344 }
1345 
1346 static int PTRFASTCALL
unknown_isNmstrt(const ENCODING * enc,const char * p)1347 unknown_isNmstrt(const ENCODING *enc, const char *p) {
1348   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1349   int c = uenc->convert(uenc->userData, p);
1350   if (c & ~0xFFFF)
1351     return 0;
1352   return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
1353 }
1354 
1355 static int PTRFASTCALL
unknown_isInvalid(const ENCODING * enc,const char * p)1356 unknown_isInvalid(const ENCODING *enc, const char *p) {
1357   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1358   int c = uenc->convert(uenc->userData, p);
1359   return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
1360 }
1361 
1362 static enum XML_Convert_Result PTRCALL
unknown_toUtf8(const ENCODING * enc,const char ** fromP,const char * fromLim,char ** toP,const char * toLim)1363 unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
1364                char **toP, const char *toLim) {
1365   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1366   char buf[XML_UTF8_ENCODE_MAX];
1367   for (;;) {
1368     const char *utf8;
1369     int n;
1370     if (*fromP == fromLim)
1371       return XML_CONVERT_COMPLETED;
1372     utf8 = uenc->utf8[(unsigned char)**fromP];
1373     n = *utf8++;
1374     if (n == 0) {
1375       int c = uenc->convert(uenc->userData, *fromP);
1376       n = XmlUtf8Encode(c, buf);
1377       if (n > toLim - *toP)
1378         return XML_CONVERT_OUTPUT_EXHAUSTED;
1379       utf8 = buf;
1380       *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
1381                  - (BT_LEAD2 - 2));
1382     } else {
1383       if (n > toLim - *toP)
1384         return XML_CONVERT_OUTPUT_EXHAUSTED;
1385       (*fromP)++;
1386     }
1387     memcpy(*toP, utf8, n);
1388     *toP += n;
1389   }
1390 }
1391 
1392 static enum XML_Convert_Result PTRCALL
unknown_toUtf16(const ENCODING * enc,const char ** fromP,const char * fromLim,unsigned short ** toP,const unsigned short * toLim)1393 unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
1394                 unsigned short **toP, const unsigned short *toLim) {
1395   const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1396   while (*fromP < fromLim && *toP < toLim) {
1397     unsigned short c = uenc->utf16[(unsigned char)**fromP];
1398     if (c == 0) {
1399       c = (unsigned short)uenc->convert(uenc->userData, *fromP);
1400       *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
1401                  - (BT_LEAD2 - 2));
1402     } else
1403       (*fromP)++;
1404     *(*toP)++ = c;
1405   }
1406 
1407   if ((*toP == toLim) && (*fromP < fromLim))
1408     return XML_CONVERT_OUTPUT_EXHAUSTED;
1409   else
1410     return XML_CONVERT_COMPLETED;
1411 }
1412 
1413 ENCODING *
XmlInitUnknownEncoding(void * mem,const int * table,CONVERTER convert,void * userData)1414 XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert,
1415                        void *userData) {
1416   int i;
1417   struct unknown_encoding *e = (struct unknown_encoding *)mem;
1418   memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding));
1419   for (i = 0; i < 128; i++)
1420     if (latin1_encoding.type[i] != BT_OTHER
1421         && latin1_encoding.type[i] != BT_NONXML && table[i] != i)
1422       return 0;
1423   for (i = 0; i < 256; i++) {
1424     int c = table[i];
1425     if (c == -1) {
1426       e->normal.type[i] = BT_MALFORM;
1427       /* This shouldn't really get used. */
1428       e->utf16[i] = 0xFFFF;
1429       e->utf8[i][0] = 1;
1430       e->utf8[i][1] = 0;
1431     } else if (c < 0) {
1432       if (c < -4)
1433         return 0;
1434       /* Multi-byte sequences need a converter function */
1435       if (! convert)
1436         return 0;
1437       e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
1438       e->utf8[i][0] = 0;
1439       e->utf16[i] = 0;
1440     } else if (c < 0x80) {
1441       if (latin1_encoding.type[c] != BT_OTHER
1442           && latin1_encoding.type[c] != BT_NONXML && c != i)
1443         return 0;
1444       e->normal.type[i] = latin1_encoding.type[c];
1445       e->utf8[i][0] = 1;
1446       e->utf8[i][1] = (char)c;
1447       e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
1448     } else if (checkCharRefNumber(c) < 0) {
1449       e->normal.type[i] = BT_NONXML;
1450       /* This shouldn't really get used. */
1451       e->utf16[i] = 0xFFFF;
1452       e->utf8[i][0] = 1;
1453       e->utf8[i][1] = 0;
1454     } else {
1455       if (c > 0xFFFF)
1456         return 0;
1457       if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
1458         e->normal.type[i] = BT_NMSTRT;
1459       else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
1460         e->normal.type[i] = BT_NAME;
1461       else
1462         e->normal.type[i] = BT_OTHER;
1463       e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
1464       e->utf16[i] = (unsigned short)c;
1465     }
1466   }
1467   e->userData = userData;
1468   e->convert = convert;
1469   if (convert) {
1470     e->normal.isName2 = unknown_isName;
1471     e->normal.isName3 = unknown_isName;
1472     e->normal.isName4 = unknown_isName;
1473     e->normal.isNmstrt2 = unknown_isNmstrt;
1474     e->normal.isNmstrt3 = unknown_isNmstrt;
1475     e->normal.isNmstrt4 = unknown_isNmstrt;
1476     e->normal.isInvalid2 = unknown_isInvalid;
1477     e->normal.isInvalid3 = unknown_isInvalid;
1478     e->normal.isInvalid4 = unknown_isInvalid;
1479   }
1480   e->normal.enc.utf8Convert = unknown_toUtf8;
1481   e->normal.enc.utf16Convert = unknown_toUtf16;
1482   return &(e->normal.enc);
1483 }
1484 
1485 /* If this enumeration is changed, getEncodingIndex and encodings
1486 must also be changed. */
1487 enum {
1488   UNKNOWN_ENC = -1,
1489   ISO_8859_1_ENC = 0,
1490   US_ASCII_ENC,
1491   UTF_8_ENC,
1492   UTF_16_ENC,
1493   UTF_16BE_ENC,
1494   UTF_16LE_ENC,
1495   /* must match encodingNames up to here */
1496   NO_ENC
1497 };
1498 
1499 static const char KW_ISO_8859_1[]
1500     = {ASCII_I, ASCII_S, ASCII_O,     ASCII_MINUS, ASCII_8, ASCII_8,
1501        ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1,     '\0'};
1502 static const char KW_US_ASCII[]
1503     = {ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S,
1504        ASCII_C, ASCII_I, ASCII_I,     '\0'};
1505 static const char KW_UTF_8[]
1506     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'};
1507 static const char KW_UTF_16[]
1508     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'};
1509 static const char KW_UTF_16BE[]
1510     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
1511        ASCII_6, ASCII_B, ASCII_E, '\0'};
1512 static const char KW_UTF_16LE[]
1513     = {ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1,
1514        ASCII_6, ASCII_L, ASCII_E, '\0'};
1515 
1516 static int FASTCALL
getEncodingIndex(const char * name)1517 getEncodingIndex(const char *name) {
1518   static const char *const encodingNames[] = {
1519       KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE,
1520   };
1521   int i;
1522   if (name == NULL)
1523     return NO_ENC;
1524   for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++)
1525     if (streqci(name, encodingNames[i]))
1526       return i;
1527   return UNKNOWN_ENC;
1528 }
1529 
1530 /* For binary compatibility, we store the index of the encoding
1531    specified at initialization in the isUtf16 member.
1532 */
1533 
1534 #define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
1535 #define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
1536 
1537 /* This is what detects the encoding.  encodingTable maps from
1538    encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
1539    the external (protocol) specified encoding; state is
1540    XML_CONTENT_STATE if we're parsing an external text entity, and
1541    XML_PROLOG_STATE otherwise.
1542 */
1543 
1544 static int
initScan(const ENCODING * const * encodingTable,const INIT_ENCODING * enc,int state,const char * ptr,const char * end,const char ** nextTokPtr)1545 initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc,
1546          int state, const char *ptr, const char *end, const char **nextTokPtr) {
1547   const ENCODING **encPtr;
1548 
1549   if (ptr >= end)
1550     return XML_TOK_NONE;
1551   encPtr = enc->encPtr;
1552   if (ptr + 1 == end) {
1553     /* only a single byte available for auto-detection */
1554 #ifndef XML_DTD /* FIXME */
1555     /* a well-formed document entity must have more than one byte */
1556     if (state != XML_CONTENT_STATE)
1557       return XML_TOK_PARTIAL;
1558 #endif
1559     /* so we're parsing an external text entity... */
1560     /* if UTF-16 was externally specified, then we need at least 2 bytes */
1561     switch (INIT_ENC_INDEX(enc)) {
1562     case UTF_16_ENC:
1563     case UTF_16LE_ENC:
1564     case UTF_16BE_ENC:
1565       return XML_TOK_PARTIAL;
1566     }
1567     switch ((unsigned char)*ptr) {
1568     case 0xFE:
1569     case 0xFF:
1570     case 0xEF: /* possibly first byte of UTF-8 BOM */
1571       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
1572         break;
1573       EXPAT_FALLTHROUGH;
1574     case 0x00:
1575     case 0x3C:
1576       return XML_TOK_PARTIAL;
1577     }
1578   } else {
1579     switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
1580     case 0xFEFF:
1581       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
1582         break;
1583       *nextTokPtr = ptr + 2;
1584       *encPtr = encodingTable[UTF_16BE_ENC];
1585       return XML_TOK_BOM;
1586     /* 00 3C is handled in the default case */
1587     case 0x3C00:
1588       if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
1589            || INIT_ENC_INDEX(enc) == UTF_16_ENC)
1590           && state == XML_CONTENT_STATE)
1591         break;
1592       *encPtr = encodingTable[UTF_16LE_ENC];
1593       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
1594     case 0xFFFE:
1595       if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
1596         break;
1597       *nextTokPtr = ptr + 2;
1598       *encPtr = encodingTable[UTF_16LE_ENC];
1599       return XML_TOK_BOM;
1600     case 0xEFBB:
1601       /* Maybe a UTF-8 BOM (EF BB BF) */
1602       /* If there's an explicitly specified (external) encoding
1603          of ISO-8859-1 or some flavour of UTF-16
1604          and this is an external text entity,
1605          don't look for the BOM,
1606          because it might be a legal data.
1607       */
1608       if (state == XML_CONTENT_STATE) {
1609         int e = INIT_ENC_INDEX(enc);
1610         if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC
1611             || e == UTF_16_ENC)
1612           break;
1613       }
1614       if (ptr + 2 == end)
1615         return XML_TOK_PARTIAL;
1616       if ((unsigned char)ptr[2] == 0xBF) {
1617         *nextTokPtr = ptr + 3;
1618         *encPtr = encodingTable[UTF_8_ENC];
1619         return XML_TOK_BOM;
1620       }
1621       break;
1622     default:
1623       if (ptr[0] == '\0') {
1624         /* 0 isn't a legal data character. Furthermore a document
1625            entity can only start with ASCII characters.  So the only
1626            way this can fail to be big-endian UTF-16 if it it's an
1627            external parsed general entity that's labelled as
1628            UTF-16LE.
1629         */
1630         if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
1631           break;
1632         *encPtr = encodingTable[UTF_16BE_ENC];
1633         return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
1634       } else if (ptr[1] == '\0') {
1635         /* We could recover here in the case:
1636             - parsing an external entity
1637             - second byte is 0
1638             - no externally specified encoding
1639             - no encoding declaration
1640            by assuming UTF-16LE.  But we don't, because this would mean when
1641            presented just with a single byte, we couldn't reliably determine
1642            whether we needed further bytes.
1643         */
1644         if (state == XML_CONTENT_STATE)
1645           break;
1646         *encPtr = encodingTable[UTF_16LE_ENC];
1647         return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
1648       }
1649       break;
1650     }
1651   }
1652   *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
1653   return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
1654 }
1655 
1656 #define NS(x) x
1657 #define ns(x) x
1658 #define XML_TOK_NS_C
1659 #include "xmltok_ns.c"
1660 #undef XML_TOK_NS_C
1661 #undef NS
1662 #undef ns
1663 
1664 #ifdef XML_NS
1665 
1666 #  define NS(x) x##NS
1667 #  define ns(x) x##_ns
1668 
1669 #  define XML_TOK_NS_C
1670 #  include "xmltok_ns.c"
1671 #  undef XML_TOK_NS_C
1672 
1673 #  undef NS
1674 #  undef ns
1675 
1676 ENCODING *
XmlInitUnknownEncodingNS(void * mem,const int * table,CONVERTER convert,void * userData)1677 XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert,
1678                          void *userData) {
1679   ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
1680   if (enc)
1681     ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
1682   return enc;
1683 }
1684 
1685 #endif /* XML_NS */
1686