Coverage Report

Created: 2026-08-25 06:40

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