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