Coverage Report

Created: 2026-10-28 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/poco/dependencies/expat/src/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
51.0M
  (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
1.72M
  (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3)                         \
95
1.72M
                + ((((byte)[0]) & 3) << 1) + ((((byte)[1]) >> 5) & 1)]         \
96
1.72M
   & (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
1.59M
  (namingBitmap                                                                \
105
1.59M
       [((pages)[((((byte)[0]) & 0xF) << 4) + ((((byte)[1]) >> 2) & 0xF)]      \
106
1.59M
         << 3)                                                                 \
107
1.59M
        + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)]                 \
108
1.59M
   & (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
673M
  ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
122
123
#define UTF8_INVALID3(p)                                                       \
124
10.7M
  (((p)[2] & 0x80) == 0                                                        \
125
10.7M
   || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD                          \
126
10.7M
                                      : ((p)[2] & 0xC0) == 0xC0)               \
127
10.7M
   || ((*p) == 0xE0                                                            \
128
10.7M
           ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0                          \
129
10.7M
           : ((p)[1] & 0x80) == 0                                              \
130
10.4M
                 || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
131
132
#define UTF8_INVALID4(p)                                                       \
133
290k
  (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 || ((p)[2] & 0x80) == 0     \
134
290k
   || ((p)[2] & 0xC0) == 0xC0                                                  \
135
290k
   || ((*p) == 0xF0                                                            \
136
289k
           ? (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0                          \
137
289k
           : ((p)[1] & 0x80) == 0                                              \
138
283k
                 || ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
139
140
static int
141
253
isNever(const ENCODING *enc, const char *p) {
142
253
  UNUSED_P(enc);
143
253
  UNUSED_P(p);
144
253
  return 0;
145
253
}
146
147
static int
148
1.32M
utf8_isName2(const ENCODING *enc, const char *p) {
149
1.32M
  UNUSED_P(enc);
150
1.32M
  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
151
1.32M
}
152
153
static int
154
1.34M
utf8_isName3(const ENCODING *enc, const char *p) {
155
1.34M
  UNUSED_P(enc);
156
1.34M
  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
157
1.34M
}
158
159
#define utf8_isName4 isNever
160
161
static int
162
399k
utf8_isNmstrt2(const ENCODING *enc, const char *p) {
163
399k
  UNUSED_P(enc);
164
399k
  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
165
399k
}
166
167
static int
168
257k
utf8_isNmstrt3(const ENCODING *enc, const char *p) {
169
257k
  UNUSED_P(enc);
170
257k
  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
171
257k
}
172
173
#define utf8_isNmstrt4 isNever
174
175
static int
176
673M
utf8_isInvalid2(const ENCODING *enc, const char *p) {
177
673M
  UNUSED_P(enc);
178
673M
  return UTF8_INVALID2((const unsigned char *)p);
179
673M
}
180
181
static int
182
10.7M
utf8_isInvalid3(const ENCODING *enc, const char *p) {
183
10.7M
  UNUSED_P(enc);
184
10.7M
  return UTF8_INVALID3((const unsigned char *)p);
185
10.7M
}
186
187
static int
188
290k
utf8_isInvalid4(const ENCODING *enc, const char *p) {
189
290k
  UNUSED_P(enc);
190
290k
  return UTF8_INVALID4((const unsigned char *)p);
191
290k
}
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
687M
#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
15.4G
#  define MINBPC(enc) 1
264
#endif
265
266
#define SB_BYTE_TYPE(enc, p)                                                   \
267
9.98G
  (((const struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
268
269
#ifdef XML_MIN_SIZE
270
static int
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
9.92G
#  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
282
sb_byteToAscii(const ENCODING *enc, const char *p) {
283
  UNUSED_P(enc);
284
  return *p;
285
}
286
#else
287
4.94M
#  define BYTE_TO_ASCII(enc, p) (*(p))
288
#endif
289
290
2.66M
#define IS_NAME_CHAR(enc, p, n) (AS_NORMAL_ENCODING(enc)->isName##n(enc, p))
291
658k
#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
686M
    (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
0
#  define IS_NAME_CHAR_MINBPC(enc, p) (0)
308
0
#  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
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
10.5M
#  define CHAR_MATCHES(enc, p, c) (*(p) == (c))
322
#endif
323
324
18.7M
#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
347
_INTERNAL_trim_to_complete_utf8_characters(const char *from,
348
53.4M
                                           const char **fromLimRef) {
349
53.4M
  const char *fromLim = *fromLimRef;
350
53.4M
  size_t walked = 0;
351
54.1M
  for (; fromLim > from; fromLim--, walked++) {
352
53.9M
    const unsigned char prev = (unsigned char)fromLim[-1];
353
53.9M
    if ((prev & 0xf8u)
354
53.9M
        == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
355
1.54k
      if (walked + 1 >= 4) {
356
1.41k
        fromLim += 4 - 1;
357
1.41k
        break;
358
1.41k
      } else {
359
131
        walked = 0;
360
131
      }
361
53.9M
    } else if ((prev & 0xf0u)
362
53.9M
               == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
363
53.8k
      if (walked + 1 >= 3) {
364
53.2k
        fromLim += 3 - 1;
365
53.2k
        break;
366
53.2k
      } else {
367
567
        walked = 0;
368
567
      }
369
53.8M
    } else if ((prev & 0xe0u)
370
53.8M
               == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
371
595k
      if (walked + 1 >= 2) {
372
593k
        fromLim += 2 - 1;
373
593k
        break;
374
593k
      } else {
375
2.33k
        walked = 0;
376
2.33k
      }
377
53.2M
    } else if ((prev & 0x80u)
378
53.2M
               == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
379
52.5M
      break;
380
52.5M
    }
381
53.9M
  }
382
53.4M
  *fromLimRef = fromLim;
383
53.4M
}
384
385
static enum XML_Convert_Result
386
utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
387
53.4M
            char **toP, const char *toLim) {
388
53.4M
  bool input_incomplete = false;
389
53.4M
  bool output_exhausted = false;
390
391
  /* Avoid copying partial characters (due to limited space). */
392
53.4M
  const ptrdiff_t bytesAvailable = fromLim - *fromP;
393
53.4M
  const ptrdiff_t bytesStorable = toLim - *toP;
394
53.4M
  UNUSED_P(enc);
395
53.4M
  if (bytesAvailable > bytesStorable) {
396
6.93M
    fromLim = *fromP + bytesStorable;
397
6.93M
    output_exhausted = true;
398
6.93M
  }
399
400
  /* Avoid copying partial characters (from incomplete input). */
401
53.4M
  {
402
53.4M
    const char *const fromLimBefore = fromLim;
403
53.4M
    _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim);
404
53.4M
    if (fromLim < fromLimBefore) {
405
3.03k
      input_incomplete = true;
406
3.03k
    }
407
53.4M
  }
408
409
53.4M
  {
410
53.4M
    const ptrdiff_t bytesToCopy = fromLim - *fromP;
411
53.4M
    memcpy(*toP, *fromP, bytesToCopy);
412
53.4M
    *fromP += bytesToCopy;
413
53.4M
    *toP += bytesToCopy;
414
53.4M
  }
415
416
53.4M
  if (output_exhausted) /* needs to go first */
417
6.93M
    return XML_CONVERT_OUTPUT_EXHAUSTED;
418
46.5M
  else if (input_incomplete)
419
0
    return XML_CONVERT_INPUT_INCOMPLETE;
420
46.5M
  else
421
46.5M
    return XML_CONVERT_COMPLETED;
422
53.4M
}
423
424
static enum XML_Convert_Result
425
utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
426
0
             unsigned short **toP, const unsigned short *toLim) {
427
0
  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
428
0
  unsigned short *to = *toP;
429
0
  const char *from = *fromP;
430
0
  while (from < fromLim && to < toLim) {
431
0
    switch (SB_BYTE_TYPE(enc, from)) {
432
0
    case BT_LEAD2:
433
0
      if (fromLim - from < 2) {
434
0
        res = XML_CONVERT_INPUT_INCOMPLETE;
435
0
        goto after;
436
0
      }
437
0
      *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
438
0
      from += 2;
439
0
      break;
440
0
    case BT_LEAD3:
441
0
      if (fromLim - from < 3) {
442
0
        res = XML_CONVERT_INPUT_INCOMPLETE;
443
0
        goto after;
444
0
      }
445
0
      *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6)
446
0
                               | (from[2] & 0x3f));
447
0
      from += 3;
448
0
      break;
449
0
    case BT_LEAD4: {
450
0
      unsigned long n;
451
0
      if (toLim - to < 2) {
452
0
        res = XML_CONVERT_OUTPUT_EXHAUSTED;
453
0
        goto after;
454
0
      }
455
0
      if (fromLim - from < 4) {
456
0
        res = XML_CONVERT_INPUT_INCOMPLETE;
457
0
        goto after;
458
0
      }
459
0
      n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
460
0
          | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
461
0
      n -= 0x10000;
462
0
      to[0] = (unsigned short)((n >> 10) | 0xD800);
463
0
      to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
464
0
      to += 2;
465
0
      from += 4;
466
0
    } break;
467
0
    default:
468
0
      *to++ = *from++;
469
0
      break;
470
0
    }
471
0
  }
472
0
  if (from < fromLim)
473
0
    res = XML_CONVERT_OUTPUT_EXHAUSTED;
474
0
after:
475
0
  *fromP = from;
476
0
  *toP = to;
477
0
  return res;
478
0
}
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
523
latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
524
1.69M
              char **toP, const char *toLim) {
525
1.69M
  UNUSED_P(enc);
526
295M
  for (;;) {
527
295M
    unsigned char c;
528
295M
    if (*fromP == fromLim)
529
1.67M
      return XML_CONVERT_COMPLETED;
530
294M
    c = (unsigned char)**fromP;
531
294M
    if (c & 0x80) {
532
256M
      if (toLim - *toP < 2)
533
23.6k
        return XML_CONVERT_OUTPUT_EXHAUSTED;
534
256M
      *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
535
256M
      *(*toP)++ = (char)((c & 0x3f) | 0x80);
536
256M
      (*fromP)++;
537
256M
    } else {
538
37.1M
      if (*toP == toLim)
539
4.40k
        return XML_CONVERT_OUTPUT_EXHAUSTED;
540
37.1M
      *(*toP)++ = *(*fromP)++;
541
37.1M
    }
542
294M
  }
543
1.69M
}
544
545
static enum XML_Convert_Result
546
latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
547
0
               unsigned short **toP, const unsigned short *toLim) {
548
0
  UNUSED_P(enc);
549
0
  while (*fromP < fromLim && *toP < toLim)
550
0
    *(*toP)++ = (unsigned char)*(*fromP)++;
551
552
0
  if ((*toP == toLim) && (*fromP < fromLim))
553
0
    return XML_CONVERT_OUTPUT_EXHAUSTED;
554
0
  else
555
0
    return XML_CONVERT_COMPLETED;
556
0
}
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
581
ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
582
3.01k
             char **toP, const char *toLim) {
583
3.01k
  UNUSED_P(enc);
584
22.2k
  while (*fromP < fromLim && *toP < toLim)
585
19.2k
    *(*toP)++ = *(*fromP)++;
586
587
3.01k
  if ((*toP == toLim) && (*fromP < fromLim))
588
356
    return XML_CONVERT_OUTPUT_EXHAUSTED;
589
2.65k
  else
590
2.65k
    return XML_CONVERT_COMPLETED;
591
3.01k
}
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
616
518M
unicode_byte_type(char hi, char lo) {
617
518M
  switch ((unsigned char)hi) {
618
  /* 0xD800-0xDBFF first 16-bit code unit or high surrogate (W1) */
619
88.8k
  case 0xD8:
620
423k
  case 0xD9:
621
462k
  case 0xDA:
622
479k
  case 0xDB:
623
479k
    return BT_LEAD4;
624
  /* 0xDC00-0xDFFF second 16-bit code unit or low surrogate (W2) */
625
491
  case 0xDC:
626
1.00k
  case 0xDD:
627
1.48k
  case 0xDE:
628
1.99k
  case 0xDF:
629
1.99k
    return BT_TRAIL;
630
1.48M
  case 0xFF:
631
1.48M
    switch ((unsigned char)lo) {
632
879
    case 0xFF: /* noncharacter-FFFF */
633
902
    case 0xFE: /* noncharacter-FFFE */
634
902
      return BT_NONXML;
635
1.48M
    }
636
1.48M
    break;
637
518M
  }
638
517M
  return BT_NONASCII;
639
518M
}
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
2.98M
      char **toP, const char *toLim) {                                         \
645
2.98M
    const char *from = *fromP;                                                 \
646
2.98M
    UNUSED_P(enc);                                                             \
647
2.98M
    fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */      \
648
124M
    for (; from < fromLim; from += 2) {                                        \
649
121M
      int plane;                                                               \
650
121M
      unsigned char lo2;                                                       \
651
121M
      unsigned char lo = GET_LO(from);                                         \
652
121M
      unsigned char hi = GET_HI(from);                                         \
653
121M
      switch (hi) {                                                            \
654
7.37M
      case 0:                                                                  \
655
7.37M
        if (lo < 0x80) {                                                       \
656
6.64M
          if (*toP == toLim) {                                                 \
657
15.6k
            *fromP = from;                                                     \
658
15.6k
            return XML_CONVERT_OUTPUT_EXHAUSTED;                               \
659
15.6k
          }                                                                    \
660
6.64M
          *(*toP)++ = lo;                                                      \
661
6.63M
          break;                                                               \
662
6.64M
        }                                                                      \
663
7.37M
        EXPAT_FALLTHROUGH;                                                     \
664
887k
      case 0x1:                                                                \
665
920k
      case 0x2:                                                                \
666
938k
      case 0x3:                                                                \
667
961k
      case 0x4:                                                                \
668
985k
      case 0x5:                                                                \
669
1.08M
      case 0x6:                                                                \
670
1.13M
      case 0x7:                                                                \
671
1.13M
        if (toLim - *toP < 2) {                                                \
672
1.41k
          *fromP = from;                                                       \
673
1.41k
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
674
1.41k
        }                                                                      \
675
1.13M
        *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2);                      \
676
1.13M
        *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
677
1.13M
        break;                                                                 \
678
113M
      default:                                                                 \
679
113M
        if (toLim - *toP < 3) {                                                \
680
47.4k
          *fromP = from;                                                       \
681
47.4k
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
682
47.4k
        }                                                                      \
683
113M
        /* 16 bits divided 4, 6, 6 amongst 3 bytes */                          \
684
113M
        *(*toP)++ = ((hi >> 4) | UTF8_cval3);                                  \
685
113M
        *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80);                    \
686
113M
        *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
687
113M
        break;                                                                 \
688
113M
      case 0xD8:                                                               \
689
131k
      case 0xD9:                                                               \
690
141k
      case 0xDA:                                                               \
691
145k
      case 0xDB:                                                               \
692
145k
        if (toLim - *toP < 4) {                                                \
693
448
          *fromP = from;                                                       \
694
448
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
695
448
        }                                                                      \
696
145k
        if (fromLim - from < 4) {                                              \
697
0
          *fromP = from;                                                       \
698
0
          return XML_CONVERT_INPUT_INCOMPLETE;                                 \
699
0
        }                                                                      \
700
145k
        plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1;                   \
701
145k
        *(*toP)++ = (char)((plane >> 2) | UTF8_cval4);                         \
702
145k
        *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80);         \
703
145k
        from += 2;                                                             \
704
145k
        lo2 = GET_LO(from);                                                    \
705
145k
        *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2)           \
706
145k
                     | (lo2 >> 6) | 0x80);                                     \
707
145k
        *(*toP)++ = ((lo2 & 0x3f) | 0x80);                                     \
708
145k
        break;                                                                 \
709
121M
      }                                                                        \
710
121M
    }                                                                          \
711
2.98M
    *fromP = from;                                                             \
712
2.92M
    if (from < fromLim)                                                        \
713
2.92M
      return XML_CONVERT_INPUT_INCOMPLETE;                                     \
714
2.92M
    else                                                                       \
715
2.92M
      return XML_CONVERT_COMPLETED;                                            \
716
2.92M
  }
xmltok.c:little2_toUtf8
Line
Count
Source
644
1.46M
      char **toP, const char *toLim) {                                         \
645
1.46M
    const char *from = *fromP;                                                 \
646
1.46M
    UNUSED_P(enc);                                                             \
647
1.46M
    fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */      \
648
28.4M
    for (; from < fromLim; from += 2) {                                        \
649
27.0M
      int plane;                                                               \
650
27.0M
      unsigned char lo2;                                                       \
651
27.0M
      unsigned char lo = GET_LO(from);                                         \
652
27.0M
      unsigned char hi = GET_HI(from);                                         \
653
27.0M
      switch (hi) {                                                            \
654
3.23M
      case 0:                                                                  \
655
3.23M
        if (lo < 0x80) {                                                       \
656
2.88M
          if (*toP == toLim) {                                                 \
657
14.8k
            *fromP = from;                                                     \
658
14.8k
            return XML_CONVERT_OUTPUT_EXHAUSTED;                               \
659
14.8k
          }                                                                    \
660
2.88M
          *(*toP)++ = lo;                                                      \
661
2.86M
          break;                                                               \
662
2.88M
        }                                                                      \
663
3.23M
        EXPAT_FALLTHROUGH;                                                     \
664
402k
      case 0x1:                                                                \
665
427k
      case 0x2:                                                                \
666
435k
      case 0x3:                                                                \
667
446k
      case 0x4:                                                                \
668
454k
      case 0x5:                                                                \
669
456k
      case 0x6:                                                                \
670
464k
      case 0x7:                                                                \
671
464k
        if (toLim - *toP < 2) {                                                \
672
984
          *fromP = from;                                                       \
673
984
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
674
984
        }                                                                      \
675
464k
        *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2);                      \
676
463k
        *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
677
463k
        break;                                                                 \
678
23.5M
      default:                                                                 \
679
23.5M
        if (toLim - *toP < 3) {                                                \
680
20.9k
          *fromP = from;                                                       \
681
20.9k
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
682
20.9k
        }                                                                      \
683
23.5M
        /* 16 bits divided 4, 6, 6 amongst 3 bytes */                          \
684
23.5M
        *(*toP)++ = ((hi >> 4) | UTF8_cval3);                                  \
685
23.5M
        *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80);                    \
686
23.5M
        *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
687
23.5M
        break;                                                                 \
688
23.5M
      case 0xD8:                                                               \
689
56.2k
      case 0xD9:                                                               \
690
62.7k
      case 0xDA:                                                               \
691
64.7k
      case 0xDB:                                                               \
692
64.7k
        if (toLim - *toP < 4) {                                                \
693
126
          *fromP = from;                                                       \
694
126
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
695
126
        }                                                                      \
696
64.7k
        if (fromLim - from < 4) {                                              \
697
0
          *fromP = from;                                                       \
698
0
          return XML_CONVERT_INPUT_INCOMPLETE;                                 \
699
0
        }                                                                      \
700
64.6k
        plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1;                   \
701
64.6k
        *(*toP)++ = (char)((plane >> 2) | UTF8_cval4);                         \
702
64.6k
        *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80);         \
703
64.6k
        from += 2;                                                             \
704
64.6k
        lo2 = GET_LO(from);                                                    \
705
64.6k
        *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2)           \
706
64.6k
                     | (lo2 >> 6) | 0x80);                                     \
707
64.6k
        *(*toP)++ = ((lo2 & 0x3f) | 0x80);                                     \
708
64.6k
        break;                                                                 \
709
27.0M
      }                                                                        \
710
27.0M
    }                                                                          \
711
1.46M
    *fromP = from;                                                             \
712
1.42M
    if (from < fromLim)                                                        \
713
1.42M
      return XML_CONVERT_INPUT_INCOMPLETE;                                     \
714
1.42M
    else                                                                       \
715
1.42M
      return XML_CONVERT_COMPLETED;                                            \
716
1.42M
  }
xmltok.c:big2_toUtf8
Line
Count
Source
644
1.52M
      char **toP, const char *toLim) {                                         \
645
1.52M
    const char *from = *fromP;                                                 \
646
1.52M
    UNUSED_P(enc);                                                             \
647
1.52M
    fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */      \
648
96.3M
    for (; from < fromLim; from += 2) {                                        \
649
94.8M
      int plane;                                                               \
650
94.8M
      unsigned char lo2;                                                       \
651
94.8M
      unsigned char lo = GET_LO(from);                                         \
652
94.8M
      unsigned char hi = GET_HI(from);                                         \
653
94.8M
      switch (hi) {                                                            \
654
4.14M
      case 0:                                                                  \
655
4.14M
        if (lo < 0x80) {                                                       \
656
3.76M
          if (*toP == toLim) {                                                 \
657
779
            *fromP = from;                                                     \
658
779
            return XML_CONVERT_OUTPUT_EXHAUSTED;                               \
659
779
          }                                                                    \
660
3.76M
          *(*toP)++ = lo;                                                      \
661
3.76M
          break;                                                               \
662
3.76M
        }                                                                      \
663
4.14M
        EXPAT_FALLTHROUGH;                                                     \
664
484k
      case 0x1:                                                                \
665
493k
      case 0x2:                                                                \
666
503k
      case 0x3:                                                                \
667
514k
      case 0x4:                                                                \
668
531k
      case 0x5:                                                                \
669
624k
      case 0x6:                                                                \
670
667k
      case 0x7:                                                                \
671
667k
        if (toLim - *toP < 2) {                                                \
672
431
          *fromP = from;                                                       \
673
431
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
674
431
        }                                                                      \
675
667k
        *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2);                      \
676
667k
        *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
677
667k
        break;                                                                 \
678
90.3M
      default:                                                                 \
679
90.3M
        if (toLim - *toP < 3) {                                                \
680
26.5k
          *fromP = from;                                                       \
681
26.5k
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
682
26.5k
        }                                                                      \
683
90.3M
        /* 16 bits divided 4, 6, 6 amongst 3 bytes */                          \
684
90.3M
        *(*toP)++ = ((hi >> 4) | UTF8_cval3);                                  \
685
90.3M
        *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80);                    \
686
90.3M
        *(*toP)++ = ((lo & 0x3f) | 0x80);                                      \
687
90.3M
        break;                                                                 \
688
90.3M
      case 0xD8:                                                               \
689
75.1k
      case 0xD9:                                                               \
690
78.5k
      case 0xDA:                                                               \
691
80.7k
      case 0xDB:                                                               \
692
80.7k
        if (toLim - *toP < 4) {                                                \
693
322
          *fromP = from;                                                       \
694
322
          return XML_CONVERT_OUTPUT_EXHAUSTED;                                 \
695
322
        }                                                                      \
696
80.7k
        if (fromLim - from < 4) {                                              \
697
0
          *fromP = from;                                                       \
698
0
          return XML_CONVERT_INPUT_INCOMPLETE;                                 \
699
0
        }                                                                      \
700
80.3k
        plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1;                   \
701
80.3k
        *(*toP)++ = (char)((plane >> 2) | UTF8_cval4);                         \
702
80.3k
        *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80);         \
703
80.3k
        from += 2;                                                             \
704
80.3k
        lo2 = GET_LO(from);                                                    \
705
80.3k
        *(*toP)++ = (((lo & 0x3) << 4) | ((GET_HI(from) & 0x3) << 2)           \
706
80.3k
                     | (lo2 >> 6) | 0x80);                                     \
707
80.3k
        *(*toP)++ = ((lo2 & 0x3f) | 0x80);                                     \
708
80.3k
        break;                                                                 \
709
94.8M
      }                                                                        \
710
94.8M
    }                                                                          \
711
1.52M
    *fromP = from;                                                             \
712
1.49M
    if (from < fromLim)                                                        \
713
1.49M
      return XML_CONVERT_INPUT_INCOMPLETE;                                     \
714
1.49M
    else                                                                       \
715
1.49M
      return XML_CONVERT_COMPLETED;                                            \
716
1.49M
  }
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
0
      unsigned short **toP, const unsigned short *toLim) {                     \
722
0
    enum XML_Convert_Result res = XML_CONVERT_COMPLETED;                       \
723
0
    UNUSED_P(enc);                                                             \
724
0
    fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */  \
725
0
    /* Avoid copying the first half (2 bytes) of surrogate pairs (4 bytes) */  \
726
0
    if (fromLim - *fromP > ((toLim - *toP) << 1)                               \
727
0
        && /* are the last two bytes a high surrogate (0xD800-0xDBFF)? */      \
728
0
        (GET_HI(fromLim - 2) & 0xFC) == 0xD8) {                                \
729
0
      fromLim -= 2;                                                            \
730
0
      res = XML_CONVERT_INPUT_INCOMPLETE;                                      \
731
0
    }                                                                          \
732
0
    for (; *fromP < fromLim && *toP < toLim; *fromP += 2)                      \
733
0
      *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP);                      \
734
0
    if ((*toP == toLim) && (*fromP < fromLim))                                 \
735
0
      return XML_CONVERT_OUTPUT_EXHAUSTED;                                     \
736
0
    else                                                                       \
737
0
      return res;                                                              \
738
0
  }
Unexecuted instantiation: xmltok.c:little2_toUtf16
Unexecuted instantiation: xmltok.c:big2_toUtf16
739
740
27.0M
#define GET_LO(ptr) ((unsigned char)(ptr)[0])
741
27.0M
#define GET_HI(ptr) ((unsigned char)(ptr)[1])
742
743
DEFINE_UTF16_TO_UTF8(little2_)
744
DEFINE_UTF16_TO_UTF16(little2_)
745
746
#undef GET_LO
747
#undef GET_HI
748
749
94.9M
#define GET_LO(ptr) ((unsigned char)(ptr)[1])
750
94.9M
#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
221M
  ((p)[1] == 0 ? SB_BYTE_TYPE(enc, p) : unicode_byte_type((p)[1], (p)[0]))
760
257k
#define LITTLE2_BYTE_TO_ASCII(p) ((p)[1] == 0 ? (p)[0] : -1)
761
914k
#define LITTLE2_CHAR_MATCHES(p, c) ((p)[1] == 0 && (p)[0] == (c))
762
#define LITTLE2_IS_NAME_CHAR_MINBPC(p)                                         \
763
35.4M
  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
764
#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)                                       \
765
112k
  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
156k
  ((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
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
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
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
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
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
809k
#  define PREFIX(ident) little2_##ident
816
433M
#  define MINBPC(enc) 2
817
/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
818
221M
#  define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
819
257k
#  define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(p)
820
914k
#  define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(p, c)
821
11
#  define IS_NAME_CHAR(enc, p, n) 0
822
35.4M
#  define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(p)
823
12
#  define IS_NMSTRT_CHAR(enc, p, n) (0)
824
112k
#  define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(p)
825
155k
#  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
359M
  ((p)[0] == 0 ? SB_BYTE_TYPE(enc, p + 1) : unicode_byte_type((p)[0], (p)[1]))
905
239k
#define BIG2_BYTE_TO_ASCII(p) ((p)[0] == 0 ? (p)[1] : -1)
906
1.10M
#define BIG2_CHAR_MATCHES(p, c) ((p)[0] == 0 && (p)[1] == (c))
907
#define BIG2_IS_NAME_CHAR_MINBPC(p)                                            \
908
15.1M
  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
909
#define BIG2_IS_NMSTRT_CHAR_MINBPC(p)                                          \
910
258k
  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
141k
  ((n) == 4 && ((unsigned char)(p)[2] & 0xFC) != 0xDC)
916
917
#ifdef XML_MIN_SIZE
918
919
static int
920
big2_byteType(const ENCODING *enc, const char *p) {
921
  return BIG2_BYTE_TYPE(enc, p);
922
}
923
924
static int
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
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
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
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
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
725k
#  define PREFIX(ident) big2_##ident
961
703M
#  define MINBPC(enc) 2
962
/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
963
359M
#  define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
964
239k
#  define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(p)
965
1.10M
#  define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(p, c)
966
35
#  define IS_NAME_CHAR(enc, p, n) 0
967
15.1M
#  define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(p)
968
24
#  define IS_NMSTRT_CHAR(enc, p, n) (0)
969
258k
#  define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(p)
970
141k
#  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
1051
13.4k
streqci(const char *s1, const char *s2) {
1052
54.1k
  for (;;) {
1053
54.1k
    char c1 = *s1++;
1054
54.1k
    char c2 = *s2++;
1055
54.1k
    if (ASCII_a <= c1 && c1 <= ASCII_z)
1056
11.4k
      c1 += ASCII_A - ASCII_a;
1057
54.1k
    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
0
      c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
1063
54.1k
    if (c1 != c2)
1064
10.9k
      return 0;
1065
43.1k
    if (! c1)
1066
2.41k
      break;
1067
43.1k
  }
1068
2.41k
  return 1;
1069
13.4k
}
1070
1071
static void
1072
initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end,
1073
72
                   POSITION *pos) {
1074
72
  UNUSED_P(enc);
1075
72
  normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
1076
72
}
1077
1078
static int
1079
6.91M
toAscii(const ENCODING *enc, const char *ptr, const char *end) {
1080
6.91M
  char buf[1];
1081
6.91M
  char *p = buf;
1082
6.91M
  XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
1083
6.91M
  if (p == buf)
1084
711
    return -1;
1085
6.91M
  else
1086
6.91M
    return buf[0];
1087
6.91M
}
1088
1089
static int
1090
784k
isSpace(int c) {
1091
784k
  switch (c) {
1092
12.5k
  case 0x20:
1093
31.0k
  case 0xD:
1094
35.0k
  case 0xA:
1095
37.3k
  case 0x9:
1096
37.3k
    return 1;
1097
784k
  }
1098
746k
  return 0;
1099
784k
}
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
1105
parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end,
1106
                     const char **namePtr, const char **nameEndPtr,
1107
12.1k
                     const char **valPtr, const char **nextTokPtr) {
1108
12.1k
  int c;
1109
12.1k
  char open;
1110
12.1k
  if (ptr == end) {
1111
3.65k
    *namePtr = NULL;
1112
3.65k
    return 1;
1113
3.65k
  }
1114
8.54k
  if (! isSpace(toAscii(enc, ptr, end))) {
1115
12
    *nextTokPtr = ptr;
1116
12
    return 0;
1117
12
  }
1118
20.3k
  do {
1119
20.3k
    ptr += enc->minBytesPerChar;
1120
20.3k
  } while (isSpace(toAscii(enc, ptr, end)));
1121
8.53k
  if (ptr == end) {
1122
132
    *namePtr = NULL;
1123
132
    return 1;
1124
132
  }
1125
8.40k
  *namePtr = ptr;
1126
738k
  for (;;) {
1127
738k
    c = toAscii(enc, ptr, end);
1128
738k
    if (c == -1) {
1129
135
      *nextTokPtr = ptr;
1130
135
      return 0;
1131
135
    }
1132
738k
    if (c == ASCII_EQUALS) {
1133
8.07k
      *nameEndPtr = ptr;
1134
8.07k
      break;
1135
8.07k
    }
1136
730k
    if (isSpace(c)) {
1137
195
      *nameEndPtr = ptr;
1138
11.4k
      do {
1139
11.4k
        ptr += enc->minBytesPerChar;
1140
11.4k
      } while (isSpace(c = toAscii(enc, ptr, end)));
1141
195
      if (c != ASCII_EQUALS) {
1142
171
        *nextTokPtr = ptr;
1143
171
        return 0;
1144
171
      }
1145
24
      break;
1146
195
    }
1147
730k
    ptr += enc->minBytesPerChar;
1148
730k
  }
1149
8.09k
  if (ptr == *namePtr) {
1150
6
    *nextTokPtr = ptr;
1151
6
    return 0;
1152
6
  }
1153
8.09k
  ptr += enc->minBytesPerChar;
1154
8.09k
  c = toAscii(enc, ptr, end);
1155
11.5k
  while (isSpace(c)) {
1156
3.45k
    ptr += enc->minBytesPerChar;
1157
3.45k
    c = toAscii(enc, ptr, end);
1158
3.45k
  }
1159
8.09k
  if (c != ASCII_QUOT && c != ASCII_APOS) {
1160
117
    *nextTokPtr = ptr;
1161
117
    return 0;
1162
117
  }
1163
7.97k
  open = (char)c;
1164
7.97k
  ptr += enc->minBytesPerChar;
1165
7.97k
  *valPtr = ptr;
1166
6.11M
  for (;; ptr += enc->minBytesPerChar) {
1167
6.11M
    c = toAscii(enc, ptr, end);
1168
6.11M
    if (c == open)
1169
7.75k
      break;
1170
6.11M
    if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)
1171
40.4k
        && ! (ASCII_0 <= c && c <= ASCII_9) && c != ASCII_PERIOD
1172
7.73k
        && c != ASCII_MINUS && c != ASCII_UNDERSCORE) {
1173
222
      *nextTokPtr = ptr;
1174
222
      return 0;
1175
222
    }
1176
6.11M
  }
1177
7.75k
  *nextTokPtr = ptr + enc->minBytesPerChar;
1178
7.75k
  return 1;
1179
7.97k
}
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
1206
checkXmlDeclVersionNum(const ENCODING *enc, const char *val,
1207
3.94k
                       const char *valEnd) {
1208
3.94k
  if (valEnd - val < 2 * enc->minBytesPerChar
1209
3.93k
      || ! XmlNameMatchesAscii(enc, val, val + 2 * enc->minBytesPerChar,
1210
3.94k
                               KW_1_dot))
1211
45
    return false;
1212
3.89k
  val += 2 * enc->minBytesPerChar;
1213
3.89k
  if (val == valEnd)
1214
3
    return false;
1215
9.09k
  for (; val != valEnd; val += enc->minBytesPerChar) {
1216
5.26k
    int c = toAscii(enc, val, valEnd);
1217
5.26k
    if (c < ASCII_0 || c > ASCII_9)
1218
66
      return false;
1219
5.26k
  }
1220
3.82k
  return true;
1221
3.89k
}
1222
1223
static int
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
4.72k
               const ENCODING **encoding, int *standalone) {
1230
4.72k
  const char *val = NULL;
1231
4.72k
  const char *name = NULL;
1232
4.72k
  const char *nameEnd = NULL;
1233
4.72k
  ptr += 5 * enc->minBytesPerChar;
1234
4.72k
  end -= 2 * enc->minBytesPerChar;
1235
4.72k
  if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
1236
4.10k
      || ! name) {
1237
729
    *badPtr = ptr;
1238
729
    return 0;
1239
729
  }
1240
3.99k
  if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
1241
42
    if (! isGeneralTextEntity) {
1242
42
      *badPtr = name;
1243
42
      return 0;
1244
42
    }
1245
3.95k
  } else {
1246
3.95k
    if (versionPtr)
1247
3.95k
      *versionPtr = val;
1248
3.95k
    if (versionEndPtr)
1249
3.95k
      *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
3.95k
    if (val == ptr - enc->minBytesPerChar) {
1254
12
      *badPtr = val;
1255
12
      return 0;
1256
12
    }
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
3.94k
    if (! checkXmlDeclVersionNum(enc, val, ptr - enc->minBytesPerChar)) {
1263
114
      *badPtr = val;
1264
114
      return 0;
1265
114
    }
1266
3.82k
    if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
1267
33
      *badPtr = ptr;
1268
33
      return 0;
1269
33
    }
1270
3.79k
    if (! name) {
1271
48
      if (isGeneralTextEntity) {
1272
        /* a TextDecl must have an EncodingDecl */
1273
0
        *badPtr = ptr;
1274
0
        return 0;
1275
0
      }
1276
48
      return 1;
1277
48
    }
1278
3.79k
  }
1279
3.74k
  if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
1280
3.65k
    int c = toAscii(enc, val, end);
1281
3.65k
    if (! (ASCII_a <= c && c <= ASCII_z) && ! (ASCII_A <= c && c <= ASCII_Z)) {
1282
9
      *badPtr = val;
1283
9
      return 0;
1284
9
    }
1285
3.64k
    if (encodingName)
1286
3.64k
      *encodingName = val;
1287
3.64k
    if (encoding)
1288
3.64k
      *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
1289
3.64k
    if (! parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
1290
9
      *badPtr = ptr;
1291
9
      return 0;
1292
9
    }
1293
3.63k
    if (! name)
1294
3.62k
      return 1;
1295
3.63k
  }
1296
102
  if (! XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
1297
90
      || isGeneralTextEntity) {
1298
12
    *badPtr = name;
1299
12
    return 0;
1300
12
  }
1301
90
  if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
1302
0
    if (standalone)
1303
0
      *standalone = 1;
1304
90
  } else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
1305
87
    if (standalone)
1306
87
      *standalone = 0;
1307
87
  } else {
1308
3
    *badPtr = val;
1309
3
    return 0;
1310
3
  }
1311
2.18k
  while (isSpace(toAscii(enc, ptr, end)))
1312
2.09k
    ptr += enc->minBytesPerChar;
1313
87
  if (ptr != end) {
1314
48
    *badPtr = ptr;
1315
48
    return 0;
1316
48
  }
1317
39
  return 1;
1318
87
}
1319
1320
static int
1321
288k
checkCharRefNumber(int result) {
1322
288k
  switch (result >> 8) {
1323
19
  case 0xD8:
1324
37
  case 0xD9:
1325
55
  case 0xDA:
1326
76
  case 0xDB:
1327
93
  case 0xDC:
1328
110
  case 0xDD:
1329
128
  case 0xDE:
1330
146
  case 0xDF:
1331
146
    return -1;
1332
94.1k
  case 0:
1333
94.1k
    if (latin1_encoding.type[result] == BT_NONXML)
1334
402
      return -1;
1335
93.7k
    break;
1336
93.7k
  case 0xFF:
1337
7.22k
    if (result == 0xFFFE || result == 0xFFFF)
1338
49
      return -1;
1339
7.17k
    break;
1340
288k
  }
1341
287k
  return result;
1342
288k
}
1343
1344
int
1345
286k
XmlUtf8Encode(int c, char *buf) {
1346
286k
  enum {
1347
    /* minN is minimum legal resulting value for N byte sequence */
1348
286k
    min2 = 0x80,
1349
286k
    min3 = 0x800,
1350
286k
    min4 = 0x10000
1351
286k
  };
1352
1353
286k
  if (c < 0)
1354
0
    return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */
1355
286k
  if (c < min2) {
1356
84.6k
    buf[0] = (char)(c | UTF8_cval1);
1357
84.6k
    return 1;
1358
84.6k
  }
1359
201k
  if (c < min3) {
1360
52.0k
    buf[0] = (char)((c >> 6) | UTF8_cval2);
1361
52.0k
    buf[1] = (char)((c & 0x3f) | 0x80);
1362
52.0k
    return 2;
1363
52.0k
  }
1364
149k
  if (c < min4) {
1365
126k
    buf[0] = (char)((c >> 12) | UTF8_cval3);
1366
126k
    buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
1367
126k
    buf[2] = (char)((c & 0x3f) | 0x80);
1368
126k
    return 3;
1369
126k
  }
1370
22.9k
  if (c < 0x110000) {
1371
22.9k
    buf[0] = (char)((c >> 18) | UTF8_cval4);
1372
22.9k
    buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
1373
22.9k
    buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
1374
22.9k
    buf[3] = (char)((c & 0x3f) | 0x80);
1375
22.9k
    return 4;
1376
22.9k
  }
1377
0
  return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
1378
22.9k
}
1379
1380
int
1381
0
XmlUtf16Encode(int charNum, unsigned short *buf) {
1382
0
  if (charNum < 0)
1383
0
    return 0;
1384
0
  if (charNum < 0x10000) {
1385
0
    buf[0] = (unsigned short)charNum;
1386
0
    return 1;
1387
0
  }
1388
0
  if (charNum < 0x110000) {
1389
0
    charNum -= 0x10000;
1390
0
    buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
1391
0
    buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
1392
0
    return 2;
1393
0
  }
1394
0
  return 0;
1395
0
}
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
176k
#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *)(enc))
1406
1407
int
1408
650
XmlSizeOfUnknownEncoding(void) {
1409
650
  return sizeof(struct unknown_encoding);
1410
650
}
1411
1412
static int
1413
1.63k
unknown_isName(const ENCODING *enc, const char *p) {
1414
1.63k
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1415
1.63k
  int c = uenc->convert(uenc->userData, p);
1416
1.63k
  if (c & ~0xFFFF)
1417
0
    return 0;
1418
1.63k
  return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
1419
1.63k
}
1420
1421
static int
1422
1.25k
unknown_isNmstrt(const ENCODING *enc, const char *p) {
1423
1.25k
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1424
1.25k
  int c = uenc->convert(uenc->userData, p);
1425
1.25k
  if (c & ~0xFFFF)
1426
0
    return 0;
1427
1.25k
  return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
1428
1.25k
}
1429
1430
static int
1431
110k
unknown_isInvalid(const ENCODING *enc, const char *p) {
1432
110k
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1433
110k
  int c = uenc->convert(uenc->userData, p);
1434
110k
  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
1435
110k
}
1436
1437
static enum XML_Convert_Result
1438
unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim,
1439
63.1k
               char **toP, const char *toLim) {
1440
63.1k
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1441
63.1k
  char buf[XML_UTF8_ENCODE_MAX];
1442
4.14M
  for (;;) {
1443
4.14M
    const char *utf8;
1444
4.14M
    int n;
1445
4.14M
    if (*fromP == fromLim)
1446
61.3k
      return XML_CONVERT_COMPLETED;
1447
4.08M
    utf8 = uenc->utf8[(unsigned char)**fromP];
1448
4.08M
    n = *utf8++;
1449
4.08M
    if (n == 0) {
1450
109k
      int c = uenc->convert(uenc->userData, *fromP);
1451
109k
      n = XmlUtf8Encode(c, buf);
1452
109k
      if (n > toLim - *toP)
1453
337
        return XML_CONVERT_OUTPUT_EXHAUSTED;
1454
108k
      utf8 = buf;
1455
108k
      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
1456
108k
                 - (BT_LEAD2 - 2));
1457
3.97M
    } else {
1458
3.97M
      if (n > toLim - *toP)
1459
1.43k
        return XML_CONVERT_OUTPUT_EXHAUSTED;
1460
3.97M
      (*fromP)++;
1461
3.97M
    }
1462
4.08M
    memcpy(*toP, utf8, n);
1463
4.08M
    *toP += n;
1464
4.08M
  }
1465
63.1k
}
1466
1467
static enum XML_Convert_Result
1468
unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim,
1469
0
                unsigned short **toP, const unsigned short *toLim) {
1470
0
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
1471
0
  while (*fromP < fromLim && *toP < toLim) {
1472
0
    unsigned short c = uenc->utf16[(unsigned char)**fromP];
1473
0
    if (c == 0) {
1474
0
      c = (unsigned short)uenc->convert(uenc->userData, *fromP);
1475
0
      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
1476
0
                 - (BT_LEAD2 - 2));
1477
0
    } else
1478
0
      (*fromP)++;
1479
0
    *(*toP)++ = c;
1480
0
  }
1481
1482
0
  if ((*toP == toLim) && (*fromP < fromLim))
1483
0
    return XML_CONVERT_OUTPUT_EXHAUSTED;
1484
0
  else
1485
0
    return XML_CONVERT_COMPLETED;
1486
0
}
1487
1488
ENCODING *
1489
XmlInitUnknownEncoding(void *mem, const int *table, CONVERTER convert,
1490
650
                       void *userData) {
1491
650
  int i;
1492
650
  struct unknown_encoding *e = (struct unknown_encoding *)mem;
1493
650
  memcpy(mem, &latin1_encoding, sizeof(struct normal_encoding));
1494
83.1k
  for (i = 0; i < 128; i++)
1495
82.4k
    if (latin1_encoding.type[i] != BT_OTHER
1496
76.6k
        && latin1_encoding.type[i] != BT_NONXML && table[i] != i)
1497
6
      return 0;
1498
165k
  for (i = 0; i < 256; i++) {
1499
164k
    int c = table[i];
1500
164k
    if (c == -1) {
1501
40.2k
      e->normal.type[i] = BT_MALFORM;
1502
      /* This shouldn't really get used. */
1503
40.2k
      e->utf16[i] = 0xFFFF;
1504
40.2k
      e->utf8[i][0] = 1;
1505
40.2k
      e->utf8[i][1] = 0;
1506
124k
    } else if (c < 0) {
1507
30.9k
      if (c < -4)
1508
0
        return 0;
1509
      /* Multi-byte sequences need a converter function */
1510
30.9k
      if (! convert)
1511
0
        return 0;
1512
30.9k
      e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
1513
30.9k
      e->utf8[i][0] = 0;
1514
30.9k
      e->utf16[i] = 0;
1515
93.6k
    } else if (c < 0x80) {
1516
82.4k
      if (latin1_encoding.type[c] != BT_OTHER
1517
76.6k
          && latin1_encoding.type[c] != BT_NONXML && c != i)
1518
0
        return 0;
1519
82.4k
      e->normal.type[i] = latin1_encoding.type[c];
1520
82.4k
      e->utf8[i][0] = 1;
1521
82.4k
      e->utf8[i][1] = (char)c;
1522
82.4k
      e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
1523
82.4k
    } else if (checkCharRefNumber(c) < 0) {
1524
0
      e->normal.type[i] = BT_NONXML;
1525
      /* This shouldn't really get used. */
1526
0
      e->utf16[i] = 0xFFFF;
1527
0
      e->utf8[i][0] = 1;
1528
0
      e->utf8[i][1] = 0;
1529
11.2k
    } else {
1530
11.2k
      if (c > 0xFFFF)
1531
0
        return 0;
1532
11.2k
      if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
1533
7.10k
        e->normal.type[i] = BT_NMSTRT;
1534
4.16k
      else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
1535
2
        e->normal.type[i] = BT_NAME;
1536
4.15k
      else
1537
4.15k
        e->normal.type[i] = BT_OTHER;
1538
11.2k
      e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
1539
11.2k
      e->utf16[i] = (unsigned short)c;
1540
11.2k
    }
1541
164k
  }
1542
644
  e->userData = userData;
1543
644
  e->convert = convert;
1544
644
  if (convert) {
1545
644
    e->normal.isName2 = unknown_isName;
1546
644
    e->normal.isName3 = unknown_isName;
1547
644
    e->normal.isName4 = unknown_isName;
1548
644
    e->normal.isNmstrt2 = unknown_isNmstrt;
1549
644
    e->normal.isNmstrt3 = unknown_isNmstrt;
1550
644
    e->normal.isNmstrt4 = unknown_isNmstrt;
1551
644
    e->normal.isInvalid2 = unknown_isInvalid;
1552
644
    e->normal.isInvalid3 = unknown_isInvalid;
1553
644
    e->normal.isInvalid4 = unknown_isInvalid;
1554
644
  }
1555
644
  e->normal.enc.utf8Convert = unknown_toUtf8;
1556
644
  e->normal.enc.utf16Convert = unknown_toUtf16;
1557
644
  return &(e->normal.enc);
1558
644
}
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
1592
369k
getEncodingIndex(const char *name) {
1593
369k
  static const char *const encodingNames[] = {
1594
369k
      KW_ISO_8859_1, KW_US_ASCII, KW_UTF_8, KW_UTF_16, KW_UTF_16BE, KW_UTF_16LE,
1595
369k
  };
1596
369k
  int i;
1597
369k
  if (name == NULL)
1598
365k
    return NO_ENC;
1599
11.0k
  for (i = 0; i < (int)(sizeof(encodingNames) / sizeof(encodingNames[0])); i++)
1600
9.79k
    if (streqci(name, encodingNames[i]))
1601
2.40k
      return i;
1602
1.20k
  return UNKNOWN_ENC;
1603
3.61k
}
1604
1605
/* For binary compatibility, we store the index of the encoding
1606
   specified at initialization in the isUtf16 member.
1607
*/
1608
1609
106k
#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
1610
365k
#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
1620
initScan(const ENCODING *const *encodingTable, const INIT_ENCODING *enc,
1621
301k
         int state, const char *ptr, const char *end, const char **nextTokPtr) {
1622
301k
  const ENCODING **encPtr;
1623
1624
301k
  if (ptr >= end)
1625
179k
    return XML_TOK_NONE;
1626
122k
  encPtr = enc->encPtr;
1627
122k
  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
109
    switch (INIT_ENC_INDEX(enc)) {
1637
0
    case UTF_16_ENC:
1638
0
    case UTF_16LE_ENC:
1639
0
    case UTF_16BE_ENC:
1640
0
      return XML_TOK_PARTIAL;
1641
109
    }
1642
109
    switch ((unsigned char)*ptr) {
1643
5
    case 0xFE:
1644
10
    case 0xFF:
1645
15
    case 0xEF: /* possibly first byte of UTF-8 BOM */
1646
15
      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
1647
0
        break;
1648
15
      EXPAT_FALLTHROUGH;
1649
20
    case 0x00:
1650
25
    case 0x3C:
1651
25
      return XML_TOK_PARTIAL;
1652
109
    }
1653
121k
  } else {
1654
121k
    switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
1655
66
    case 0xFEFF:
1656
66
      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
1657
0
        break;
1658
66
      *nextTokPtr = ptr + 2;
1659
66
      *encPtr = encodingTable[UTF_16BE_ENC];
1660
66
      return XML_TOK_BOM;
1661
    /* 00 3C is handled in the default case */
1662
14.9k
    case 0x3C00:
1663
14.9k
      if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
1664
14.9k
           || INIT_ENC_INDEX(enc) == UTF_16_ENC)
1665
0
          && state == XML_CONTENT_STATE)
1666
0
        break;
1667
14.9k
      *encPtr = encodingTable[UTF_16LE_ENC];
1668
14.9k
      return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
1669
69
    case 0xFFFE:
1670
69
      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE)
1671
0
        break;
1672
69
      *nextTokPtr = ptr + 2;
1673
69
      *encPtr = encodingTable[UTF_16LE_ENC];
1674
69
      return XML_TOK_BOM;
1675
7.85k
    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
7.85k
      if (state == XML_CONTENT_STATE) {
1684
0
        int e = INIT_ENC_INDEX(enc);
1685
0
        if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC
1686
0
            || e == UTF_16_ENC)
1687
0
          break;
1688
0
      }
1689
7.85k
      if (ptr + 2 == end)
1690
5
        return XML_TOK_PARTIAL;
1691
7.84k
      if ((unsigned char)ptr[2] == 0xBF) {
1692
7.80k
        *nextTokPtr = ptr + 3;
1693
7.80k
        *encPtr = encodingTable[UTF_8_ENC];
1694
7.80k
        return XML_TOK_BOM;
1695
7.80k
      }
1696
39
      break;
1697
98.9k
    default:
1698
98.9k
      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
19.3k
        if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
1706
0
          break;
1707
19.3k
        *encPtr = encodingTable[UTF_16BE_ENC];
1708
19.3k
        return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
1709
79.6k
      } 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
3.38k
        if (state == XML_CONTENT_STATE)
1720
0
          break;
1721
3.38k
        *encPtr = encodingTable[UTF_16LE_ENC];
1722
3.38k
        return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
1723
3.38k
      }
1724
76.2k
      break;
1725
121k
    }
1726
121k
  }
1727
76.3k
  *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
1728
76.3k
  return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
1729
122k
}
1730
1731
700k
#define NS(x) x
1732
93.9k
#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
339k
#  define NS(x) x##NS
1742
88.8k
#  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 *
1752
XmlInitUnknownEncodingNS(void *mem, const int *table, CONVERTER convert,
1753
330
                         void *userData) {
1754
330
  ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
1755
330
  if (enc)
1756
324
    ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
1757
330
  return enc;
1758
330
}
1759
1760
#endif /* XML_NS */