Coverage Report

Created: 2026-07-10 11:04

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