Coverage Report

Created: 2026-10-28 06:38

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