Coverage Report

Created: 2024-05-20 06:20

/src/expat/expat/lib/xmlparse.c
Line
Count
Source (jump to first uncovered line)
1
/* 2a14271ad4d35e82bde8ba210b4edb7998794bcbae54deab114046a300f9639a (2.6.2+)
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) 2000-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
12
   Copyright (c) 2001-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      Eric Rahm <erahm@mozilla.com>
16
   Copyright (c) 2016-2024 Sebastian Pipping <sebastian@pipping.org>
17
   Copyright (c) 2016      Gaurav <g.gupta@samsung.com>
18
   Copyright (c) 2016      Thomas Beutlich <tc@tbeu.de>
19
   Copyright (c) 2016      Gustavo Grieco <gustavo.grieco@imag.fr>
20
   Copyright (c) 2016      Pascal Cuoq <cuoq@trust-in-soft.com>
21
   Copyright (c) 2016      Ed Schouten <ed@nuxi.nl>
22
   Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
23
   Copyright (c) 2017      Václav Slavík <vaclav@slavik.io>
24
   Copyright (c) 2017      Viktor Szakats <commit@vsz.me>
25
   Copyright (c) 2017      Chanho Park <chanho61.park@samsung.com>
26
   Copyright (c) 2017      Rolf Eike Beer <eike@sf-mail.de>
27
   Copyright (c) 2017      Hans Wennborg <hans@chromium.org>
28
   Copyright (c) 2018      Anton Maklakov <antmak.pub@gmail.com>
29
   Copyright (c) 2018      Benjamin Peterson <benjamin@python.org>
30
   Copyright (c) 2018      Marco Maggi <marco.maggi-ipsu@poste.it>
31
   Copyright (c) 2018      Mariusz Zaborski <oshogbo@vexillium.org>
32
   Copyright (c) 2019      David Loffredo <loffredo@steptools.com>
33
   Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org>
34
   Copyright (c) 2019      Vadim Zeitlin <vadim@zeitlins.org>
35
   Copyright (c) 2021      Donghee Na <donghee.na@python.org>
36
   Copyright (c) 2022      Samanta Navarro <ferivoz@riseup.net>
37
   Copyright (c) 2022      Jeffrey Walton <noloader@gmail.com>
38
   Copyright (c) 2022      Jann Horn <jannh@google.com>
39
   Copyright (c) 2022      Sean McBride <sean@rogue-research.com>
40
   Copyright (c) 2023      Owain Davies <owaind@bath.edu>
41
   Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
42
   Licensed under the MIT license:
43
44
   Permission is  hereby granted,  free of charge,  to any  person obtaining
45
   a  copy  of  this  software   and  associated  documentation  files  (the
46
   "Software"),  to  deal in  the  Software  without restriction,  including
47
   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
48
   distribute, sublicense, and/or sell copies of the Software, and to permit
49
   persons  to whom  the Software  is  furnished to  do so,  subject to  the
50
   following conditions:
51
52
   The above copyright  notice and this permission notice  shall be included
53
   in all copies or substantial portions of the Software.
54
55
   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
56
   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
57
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
58
   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
59
   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
60
   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
61
   USE OR OTHER DEALINGS IN THE SOFTWARE.
62
*/
63
64
#define XML_BUILDING_EXPAT 1
65
66
#include "expat_config.h"
67
68
#if ! defined(XML_GE) || (1 - XML_GE - 1 == 2) || (XML_GE < 0) || (XML_GE > 1)
69
#  error XML_GE (for general entities) must be defined, non-empty, either 1 or 0 (0 to disable, 1 to enable; 1 is a common default)
70
#endif
71
72
#if defined(XML_DTD) && XML_GE == 0
73
#  error Either undefine XML_DTD or define XML_GE to 1.
74
#endif
75
76
#if ! defined(XML_CONTEXT_BYTES) || (1 - XML_CONTEXT_BYTES - 1 == 2)           \
77
    || (XML_CONTEXT_BYTES + 0 < 0)
78
#  error XML_CONTEXT_BYTES must be defined, non-empty and >=0 (0 to disable, >=1 to enable; 1024 is a common default)
79
#endif
80
81
#if defined(HAVE_SYSCALL_GETRANDOM)
82
#  if ! defined(_GNU_SOURCE)
83
#    define _GNU_SOURCE 1 /* syscall prototype */
84
#  endif
85
#endif
86
87
#ifdef _WIN32
88
/* force stdlib to define rand_s() */
89
#  if ! defined(_CRT_RAND_S)
90
#    define _CRT_RAND_S
91
#  endif
92
#endif
93
94
#include <stdbool.h>
95
#include <stddef.h>
96
#include <string.h> /* memset(), memcpy() */
97
#include <assert.h>
98
#include <limits.h> /* UINT_MAX */
99
#include <stdio.h>  /* fprintf */
100
#include <stdlib.h> /* getenv, rand_s */
101
#include <stdint.h> /* uintptr_t */
102
#include <math.h>   /* isnan */
103
104
#ifdef _WIN32
105
#  define getpid GetCurrentProcessId
106
#else
107
#  include <sys/time.h>  /* gettimeofday() */
108
#  include <sys/types.h> /* getpid() */
109
#  include <unistd.h>    /* getpid() */
110
#  include <fcntl.h>     /* O_RDONLY */
111
#  include <errno.h>
112
#endif
113
114
#ifdef _WIN32
115
#  include "winconfig.h"
116
#endif
117
118
#include "ascii.h"
119
#include "expat.h"
120
#include "siphash.h"
121
122
#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
123
#  if defined(HAVE_GETRANDOM)
124
#    include <sys/random.h> /* getrandom */
125
#  else
126
#    include <unistd.h>      /* syscall */
127
#    include <sys/syscall.h> /* SYS_getrandom */
128
#  endif
129
#  if ! defined(GRND_NONBLOCK)
130
#    define GRND_NONBLOCK 0x0001
131
#  endif /* defined(GRND_NONBLOCK) */
132
#endif   /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
133
134
#if defined(HAVE_LIBBSD)                                                       \
135
    && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
136
#  include <bsd/stdlib.h>
137
#endif
138
139
#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
140
#  define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
141
#endif
142
143
#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM)             \
144
    && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)            \
145
    && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32)                         \
146
    && ! defined(XML_POOR_ENTROPY)
147
#  error You do not have support for any sources of high quality entropy \
148
    enabled.  For end user security, that is probably not what you want. \
149
    \
150
    Your options include: \
151
      * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
152
      * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
153
      * BSD / macOS >=10.7 / glibc >=2.36 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
154
      * BSD / macOS (including <10.7) / glibc >=2.36 (arc4random): HAVE_ARC4RANDOM, \
155
      * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
156
      * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
157
      * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \
158
      * Windows >=Vista (rand_s): _WIN32. \
159
    \
160
    If insist on not using any of these, bypass this error by defining \
161
    XML_POOR_ENTROPY; you have been warned. \
162
    \
163
    If you have reasons to patch this detection code away or need changes \
164
    to the build system, please open a bug.  Thank you!
165
#endif
166
167
#ifdef XML_UNICODE
168
#  define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
169
#  define XmlConvert XmlUtf16Convert
170
#  define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
171
#  define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
172
#  define XmlEncode XmlUtf16Encode
173
#  define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))
174
typedef unsigned short ICHAR;
175
#else
176
#  define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
177
70.7M
#  define XmlConvert XmlUtf8Convert
178
60.6k
#  define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
179
20.2k
#  define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
180
115k
#  define XmlEncode XmlUtf8Encode
181
7.53M
#  define MUST_CONVERT(enc, s) (! (enc)->isUtf8)
182
typedef char ICHAR;
183
#endif
184
185
#ifndef XML_NS
186
187
#  define XmlInitEncodingNS XmlInitEncoding
188
#  define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
189
#  undef XmlGetInternalEncodingNS
190
#  define XmlGetInternalEncodingNS XmlGetInternalEncoding
191
#  define XmlParseXmlDeclNS XmlParseXmlDecl
192
193
#endif
194
195
#ifdef XML_UNICODE
196
197
#  ifdef XML_UNICODE_WCHAR_T
198
#    define XML_T(x) (const wchar_t) x
199
#    define XML_L(x) L##x
200
#  else
201
#    define XML_T(x) (const unsigned short)x
202
#    define XML_L(x) x
203
#  endif
204
205
#else
206
207
16.1M
#  define XML_T(x) x
208
78.6k
#  define XML_L(x) x
209
210
#endif
211
212
/* Round up n to be a multiple of sz, where sz is a power of 2. */
213
879k
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
214
215
/* Do safe (NULL-aware) pointer arithmetic */
216
956k
#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0)
217
218
80.8k
#define EXPAT_MIN(a, b) (((a) < (b)) ? (a) : (b))
219
220
#include "internal.h"
221
#include "xmltok.h"
222
#include "xmlrole.h"
223
224
typedef const XML_Char *KEY;
225
226
typedef struct {
227
  KEY name;
228
} NAMED;
229
230
typedef struct {
231
  NAMED **v;
232
  unsigned char power;
233
  size_t size;
234
  size_t used;
235
  const XML_Memory_Handling_Suite *mem;
236
} HASH_TABLE;
237
238
static size_t keylen(KEY s);
239
240
static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
241
242
/* For probing (after a collision) we need a step size relative prime
243
   to the hash table size, which is a power of 2. We use double-hashing,
244
   since we can calculate a second hash value cheaply by taking those bits
245
   of the first hash value that were discarded (masked out) when the table
246
   index was calculated: index = hash & mask, where mask = table->size - 1.
247
   We limit the maximum step size to table->size / 4 (mask >> 2) and make
248
   it odd, since odd numbers are always relative prime to a power of 2.
249
*/
250
#define SECOND_HASH(hash, mask, power)                                         \
251
190k
  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
252
#define PROBE_STEP(hash, mask, power)                                          \
253
190k
  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
254
255
typedef struct {
256
  NAMED **p;
257
  NAMED **end;
258
} HASH_TABLE_ITER;
259
260
2.64M
#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
261
80.8k
#define INIT_DATA_BUF_SIZE 1024
262
82.8k
#define INIT_ATTS_SIZE 16
263
316
#define INIT_ATTS_VERSION 0xFFFFFFFF
264
169k
#define INIT_BLOCK_SIZE 1024
265
80.8k
#define INIT_BUFFER_SIZE 1024
266
267
52.6k
#define EXPAND_SPARE 24
268
269
typedef struct binding {
270
  struct prefix *prefix;
271
  struct binding *nextTagBinding;
272
  struct binding *prevPrefixBinding;
273
  const struct attribute_id *attId;
274
  XML_Char *uri;
275
  int uriLen;
276
  int uriAlloc;
277
} BINDING;
278
279
typedef struct prefix {
280
  const XML_Char *name;
281
  BINDING *binding;
282
} PREFIX;
283
284
typedef struct {
285
  const XML_Char *str;
286
  const XML_Char *localPart;
287
  const XML_Char *prefix;
288
  int strLen;
289
  int uriLen;
290
  int prefixLen;
291
} TAG_NAME;
292
293
/* TAG represents an open element.
294
   The name of the element is stored in both the document and API
295
   encodings.  The memory buffer 'buf' is a separately-allocated
296
   memory area which stores the name.  During the XML_Parse()/
297
   XMLParseBuffer() when the element is open, the memory for the 'raw'
298
   version of the name (in the document encoding) is shared with the
299
   document buffer.  If the element is open across calls to
300
   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
301
   contain the 'raw' name as well.
302
303
   A parser reuses these structures, maintaining a list of allocated
304
   TAG objects in a free list.
305
*/
306
typedef struct tag {
307
  struct tag *parent;  /* parent of this element */
308
  const char *rawName; /* tagName in the original encoding */
309
  int rawNameLength;
310
  TAG_NAME name; /* tagName in the API encoding */
311
  char *buf;     /* buffer for name components */
312
  char *bufEnd;  /* end of the buffer */
313
  BINDING *bindings;
314
} TAG;
315
316
typedef struct {
317
  const XML_Char *name;
318
  const XML_Char *textPtr;
319
  int textLen;   /* length in XML_Chars */
320
  int processed; /* # of processed bytes - when suspended */
321
  const XML_Char *systemId;
322
  const XML_Char *base;
323
  const XML_Char *publicId;
324
  const XML_Char *notation;
325
  XML_Bool open;
326
  XML_Bool is_param;
327
  XML_Bool is_internal; /* true if declared in internal subset outside PE */
328
} ENTITY;
329
330
typedef struct {
331
  enum XML_Content_Type type;
332
  enum XML_Content_Quant quant;
333
  const XML_Char *name;
334
  int firstchild;
335
  int lastchild;
336
  int childcnt;
337
  int nextsib;
338
} CONTENT_SCAFFOLD;
339
340
0
#define INIT_SCAFFOLD_ELEMENTS 32
341
342
typedef struct block {
343
  struct block *next;
344
  int size;
345
  XML_Char s[1];
346
} BLOCK;
347
348
typedef struct {
349
  BLOCK *blocks;
350
  BLOCK *freeBlocks;
351
  const XML_Char *end;
352
  XML_Char *ptr;
353
  XML_Char *start;
354
  const XML_Memory_Handling_Suite *mem;
355
} STRING_POOL;
356
357
/* The XML_Char before the name is used to determine whether
358
   an attribute has been specified. */
359
typedef struct attribute_id {
360
  XML_Char *name;
361
  PREFIX *prefix;
362
  XML_Bool maybeTokenized;
363
  XML_Bool xmlns;
364
} ATTRIBUTE_ID;
365
366
typedef struct {
367
  const ATTRIBUTE_ID *id;
368
  XML_Bool isCdata;
369
  const XML_Char *value;
370
} DEFAULT_ATTRIBUTE;
371
372
typedef struct {
373
  unsigned long version;
374
  unsigned long hash;
375
  const XML_Char *uriName;
376
} NS_ATT;
377
378
typedef struct {
379
  const XML_Char *name;
380
  PREFIX *prefix;
381
  const ATTRIBUTE_ID *idAtt;
382
  int nDefaultAtts;
383
  int allocDefaultAtts;
384
  DEFAULT_ATTRIBUTE *defaultAtts;
385
} ELEMENT_TYPE;
386
387
typedef struct {
388
  HASH_TABLE generalEntities;
389
  HASH_TABLE elementTypes;
390
  HASH_TABLE attributeIds;
391
  HASH_TABLE prefixes;
392
  STRING_POOL pool;
393
  STRING_POOL entityValuePool;
394
  /* false once a parameter entity reference has been skipped */
395
  XML_Bool keepProcessing;
396
  /* true once an internal or external PE reference has been encountered;
397
     this includes the reference to an external subset */
398
  XML_Bool hasParamEntityRefs;
399
  XML_Bool standalone;
400
#ifdef XML_DTD
401
  /* indicates if external PE has been read */
402
  XML_Bool paramEntityRead;
403
  HASH_TABLE paramEntities;
404
#endif /* XML_DTD */
405
  PREFIX defaultPrefix;
406
  /* === scaffolding for building content model === */
407
  XML_Bool in_eldecl;
408
  CONTENT_SCAFFOLD *scaffold;
409
  unsigned contentStringLen;
410
  unsigned scaffSize;
411
  unsigned scaffCount;
412
  int scaffLevel;
413
  int *scaffIndex;
414
} DTD;
415
416
typedef struct open_internal_entity {
417
  const char *internalEventPtr;
418
  const char *internalEventEndPtr;
419
  struct open_internal_entity *next;
420
  ENTITY *entity;
421
  int startTagLevel;
422
  XML_Bool betweenDecl; /* WFC: PE Between Declarations */
423
} OPEN_INTERNAL_ENTITY;
424
425
enum XML_Account {
426
  XML_ACCOUNT_DIRECT,           /* bytes directly passed to the Expat parser */
427
  XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity
428
                                   expansion */
429
  XML_ACCOUNT_NONE              /* i.e. do not account, was accounted already */
430
};
431
432
#if XML_GE == 1
433
typedef unsigned long long XmlBigCount;
434
typedef struct accounting {
435
  XmlBigCount countBytesDirect;
436
  XmlBigCount countBytesIndirect;
437
  unsigned long debugLevel;
438
  float maximumAmplificationFactor; // >=1.0
439
  unsigned long long activationThresholdBytes;
440
} ACCOUNTING;
441
442
typedef struct entity_stats {
443
  unsigned int countEverOpened;
444
  unsigned int currentDepth;
445
  unsigned int maximumDepthSeen;
446
  unsigned long debugLevel;
447
} ENTITY_STATS;
448
#endif /* XML_GE == 1 */
449
450
typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
451
                                         const char *end, const char **endPtr);
452
453
static Processor prologProcessor;
454
static Processor prologInitProcessor;
455
static Processor contentProcessor;
456
static Processor cdataSectionProcessor;
457
#ifdef XML_DTD
458
static Processor ignoreSectionProcessor;
459
static Processor externalParEntProcessor;
460
static Processor externalParEntInitProcessor;
461
static Processor entityValueProcessor;
462
static Processor entityValueInitProcessor;
463
#endif /* XML_DTD */
464
static Processor epilogProcessor;
465
static Processor errorProcessor;
466
static Processor externalEntityInitProcessor;
467
static Processor externalEntityInitProcessor2;
468
static Processor externalEntityInitProcessor3;
469
static Processor externalEntityContentProcessor;
470
static Processor internalEntityProcessor;
471
472
static enum XML_Error handleUnknownEncoding(XML_Parser parser,
473
                                            const XML_Char *encodingName);
474
static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
475
                                     const char *s, const char *next);
476
static enum XML_Error initializeEncoding(XML_Parser parser);
477
static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
478
                               const char *s, const char *end, int tok,
479
                               const char *next, const char **nextPtr,
480
                               XML_Bool haveMore, XML_Bool allowClosingDoctype,
481
                               enum XML_Account account);
482
static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,
483
                                            XML_Bool betweenDecl);
484
static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
485
                                const ENCODING *enc, const char *start,
486
                                const char *end, const char **endPtr,
487
                                XML_Bool haveMore, enum XML_Account account);
488
static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *enc,
489
                                     const char **startPtr, const char *end,
490
                                     const char **nextPtr, XML_Bool haveMore,
491
                                     enum XML_Account account);
492
#ifdef XML_DTD
493
static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *enc,
494
                                      const char **startPtr, const char *end,
495
                                      const char **nextPtr, XML_Bool haveMore);
496
#endif /* XML_DTD */
497
498
static void freeBindings(XML_Parser parser, BINDING *bindings);
499
static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
500
                                const char *attStr, TAG_NAME *tagNamePtr,
501
                                BINDING **bindingsPtr,
502
                                enum XML_Account account);
503
static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
504
                                 const ATTRIBUTE_ID *attId, const XML_Char *uri,
505
                                 BINDING **bindingsPtr);
506
static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId,
507
                           XML_Bool isCdata, XML_Bool isId,
508
                           const XML_Char *value, XML_Parser parser);
509
static enum XML_Error storeAttributeValue(XML_Parser parser,
510
                                          const ENCODING *enc, XML_Bool isCdata,
511
                                          const char *ptr, const char *end,
512
                                          STRING_POOL *pool,
513
                                          enum XML_Account account);
514
static enum XML_Error appendAttributeValue(XML_Parser parser,
515
                                           const ENCODING *enc,
516
                                           XML_Bool isCdata, const char *ptr,
517
                                           const char *end, STRING_POOL *pool,
518
                                           enum XML_Account account);
519
static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
520
                                    const char *start, const char *end);
521
static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType);
522
#if XML_GE == 1
523
static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
524
                                       const char *start, const char *end,
525
                                       enum XML_Account account);
526
#else
527
static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity);
528
#endif
529
static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
530
                                       const char *start, const char *end);
531
static int reportComment(XML_Parser parser, const ENCODING *enc,
532
                         const char *start, const char *end);
533
static void reportDefault(XML_Parser parser, const ENCODING *enc,
534
                          const char *start, const char *end);
535
536
static const XML_Char *getContext(XML_Parser parser);
537
static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
538
539
static void FASTCALL normalizePublicId(XML_Char *s);
540
541
static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);
542
/* do not call if m_parentParser != NULL */
543
static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
544
static void dtdDestroy(DTD *p, XML_Bool isDocEntity,
545
                       const XML_Memory_Handling_Suite *ms);
546
static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
547
                   const XML_Memory_Handling_Suite *ms);
548
static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
549
                           STRING_POOL *newPool, const HASH_TABLE *oldTable);
550
static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
551
                     size_t createSize);
552
static void FASTCALL hashTableInit(HASH_TABLE *table,
553
                                   const XML_Memory_Handling_Suite *ms);
554
static void FASTCALL hashTableClear(HASH_TABLE *table);
555
static void FASTCALL hashTableDestroy(HASH_TABLE *table);
556
static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *iter,
557
                                       const HASH_TABLE *table);
558
static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *iter);
559
560
static void FASTCALL poolInit(STRING_POOL *pool,
561
                              const XML_Memory_Handling_Suite *ms);
562
static void FASTCALL poolClear(STRING_POOL *pool);
563
static void FASTCALL poolDestroy(STRING_POOL *pool);
564
static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
565
                            const char *ptr, const char *end);
566
static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
567
                                 const char *ptr, const char *end);
568
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
569
static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
570
                                               const XML_Char *s);
571
static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
572
                                       int n);
573
static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
574
                                                 const XML_Char *s);
575
576
static int FASTCALL nextScaffoldPart(XML_Parser parser);
577
static XML_Content *build_model(XML_Parser parser);
578
static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
579
                                    const char *ptr, const char *end);
580
581
static XML_Char *copyString(const XML_Char *s,
582
                            const XML_Memory_Handling_Suite *memsuite);
583
584
static unsigned long generate_hash_secret_salt(XML_Parser parser);
585
static XML_Bool startParsing(XML_Parser parser);
586
587
static XML_Parser parserCreate(const XML_Char *encodingName,
588
                               const XML_Memory_Handling_Suite *memsuite,
589
                               const XML_Char *nameSep, DTD *dtd);
590
591
static void parserInit(XML_Parser parser, const XML_Char *encodingName);
592
593
#if XML_GE == 1
594
static float accountingGetCurrentAmplification(XML_Parser rootParser);
595
static void accountingReportStats(XML_Parser originParser, const char *epilog);
596
static void accountingOnAbort(XML_Parser originParser);
597
static void accountingReportDiff(XML_Parser rootParser,
598
                                 unsigned int levelsAwayFromRootParser,
599
                                 const char *before, const char *after,
600
                                 ptrdiff_t bytesMore, int source_line,
601
                                 enum XML_Account account);
602
static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok,
603
                                        const char *before, const char *after,
604
                                        int source_line,
605
                                        enum XML_Account account);
606
607
static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity,
608
                                      const char *action, int sourceLine);
609
static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity,
610
                                 int sourceLine);
611
static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity,
612
                                  int sourceLine);
613
614
static XML_Parser getRootParserOf(XML_Parser parser,
615
                                  unsigned int *outLevelDiff);
616
#endif /* XML_GE == 1 */
617
618
static unsigned long getDebugLevel(const char *variableName,
619
                                   unsigned long defaultDebugLevel);
620
621
228k
#define poolStart(pool) ((pool)->start)
622
196k
#define poolLength(pool) ((pool)->ptr - (pool)->start)
623
763
#define poolChop(pool) ((void)--(pool->ptr))
624
131k
#define poolLastChar(pool) (((pool)->ptr)[-1])
625
4.01M
#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
626
2.46M
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
627
#define poolAppendChar(pool, c)                                                \
628
370M
  (((pool)->ptr == (pool)->end && ! poolGrow(pool))                            \
629
370M
       ? 0                                                                     \
630
370M
       : ((*((pool)->ptr)++ = c), 1))
631
632
#if ! defined(XML_TESTING)
633
const
634
#endif
635
    XML_Bool g_reparseDeferralEnabledDefault
636
    = XML_TRUE; // write ONLY in runtests.c
637
#if defined(XML_TESTING)
638
unsigned int g_bytesScanned = 0; // used for testing only
639
#endif
640
641
struct XML_ParserStruct {
642
  /* The first member must be m_userData so that the XML_GetUserData
643
     macro works. */
644
  void *m_userData;
645
  void *m_handlerArg;
646
647
  // How the four parse buffer pointers below relate in time and space:
648
  //
649
  //   m_buffer <= m_bufferPtr <= m_bufferEnd  <= m_bufferLim
650
  //   |           |              |               |
651
  //   <--parsed-->|              |               |
652
  //               <---parsing--->|               |
653
  //                              <--unoccupied-->|
654
  //   <---------total-malloced/realloced-------->|
655
656
  char *m_buffer; // malloc/realloc base pointer of parse buffer
657
  const XML_Memory_Handling_Suite m_mem;
658
  const char *m_bufferPtr; // first character to be parsed
659
  char *m_bufferEnd;       // past last character to be parsed
660
  const char *m_bufferLim; // allocated end of m_buffer
661
662
  XML_Index m_parseEndByteIndex;
663
  const char *m_parseEndPtr;
664
  size_t m_partialTokenBytesBefore; /* used in heuristic to avoid O(n^2) */
665
  XML_Bool m_reparseDeferralEnabled;
666
  int m_lastBufferRequestSize;
667
  XML_Char *m_dataBuf;
668
  XML_Char *m_dataBufEnd;
669
  XML_StartElementHandler m_startElementHandler;
670
  XML_EndElementHandler m_endElementHandler;
671
  XML_CharacterDataHandler m_characterDataHandler;
672
  XML_ProcessingInstructionHandler m_processingInstructionHandler;
673
  XML_CommentHandler m_commentHandler;
674
  XML_StartCdataSectionHandler m_startCdataSectionHandler;
675
  XML_EndCdataSectionHandler m_endCdataSectionHandler;
676
  XML_DefaultHandler m_defaultHandler;
677
  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
678
  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
679
  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
680
  XML_NotationDeclHandler m_notationDeclHandler;
681
  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
682
  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
683
  XML_NotStandaloneHandler m_notStandaloneHandler;
684
  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
685
  XML_Parser m_externalEntityRefHandlerArg;
686
  XML_SkippedEntityHandler m_skippedEntityHandler;
687
  XML_UnknownEncodingHandler m_unknownEncodingHandler;
688
  XML_ElementDeclHandler m_elementDeclHandler;
689
  XML_AttlistDeclHandler m_attlistDeclHandler;
690
  XML_EntityDeclHandler m_entityDeclHandler;
691
  XML_XmlDeclHandler m_xmlDeclHandler;
692
  const ENCODING *m_encoding;
693
  INIT_ENCODING m_initEncoding;
694
  const ENCODING *m_internalEncoding;
695
  const XML_Char *m_protocolEncodingName;
696
  XML_Bool m_ns;
697
  XML_Bool m_ns_triplets;
698
  void *m_unknownEncodingMem;
699
  void *m_unknownEncodingData;
700
  void *m_unknownEncodingHandlerData;
701
  void(XMLCALL *m_unknownEncodingRelease)(void *);
702
  PROLOG_STATE m_prologState;
703
  Processor *m_processor;
704
  enum XML_Error m_errorCode;
705
  const char *m_eventPtr;
706
  const char *m_eventEndPtr;
707
  const char *m_positionPtr;
708
  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
709
  OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
710
  XML_Bool m_defaultExpandInternalEntities;
711
  int m_tagLevel;
712
  ENTITY *m_declEntity;
713
  const XML_Char *m_doctypeName;
714
  const XML_Char *m_doctypeSysid;
715
  const XML_Char *m_doctypePubid;
716
  const XML_Char *m_declAttributeType;
717
  const XML_Char *m_declNotationName;
718
  const XML_Char *m_declNotationPublicId;
719
  ELEMENT_TYPE *m_declElementType;
720
  ATTRIBUTE_ID *m_declAttributeId;
721
  XML_Bool m_declAttributeIsCdata;
722
  XML_Bool m_declAttributeIsId;
723
  DTD *m_dtd;
724
  const XML_Char *m_curBase;
725
  TAG *m_tagStack;
726
  TAG *m_freeTagList;
727
  BINDING *m_inheritedBindings;
728
  BINDING *m_freeBindingList;
729
  int m_attsSize;
730
  int m_nSpecifiedAtts;
731
  int m_idAttIndex;
732
  ATTRIBUTE *m_atts;
733
  NS_ATT *m_nsAtts;
734
  unsigned long m_nsAttsVersion;
735
  unsigned char m_nsAttsPower;
736
#ifdef XML_ATTR_INFO
737
  XML_AttrInfo *m_attInfo;
738
#endif
739
  POSITION m_position;
740
  STRING_POOL m_tempPool;
741
  STRING_POOL m_temp2Pool;
742
  char *m_groupConnector;
743
  unsigned int m_groupSize;
744
  XML_Char m_namespaceSeparator;
745
  XML_Parser m_parentParser;
746
  XML_ParsingStatus m_parsingStatus;
747
#ifdef XML_DTD
748
  XML_Bool m_isParamEntity;
749
  XML_Bool m_useForeignDTD;
750
  enum XML_ParamEntityParsing m_paramEntityParsing;
751
#endif
752
  unsigned long m_hash_secret_salt;
753
#if XML_GE == 1
754
  ACCOUNTING m_accounting;
755
  ENTITY_STATS m_entity_stats;
756
#endif
757
};
758
759
5.59M
#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s)))
760
17.8k
#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s)))
761
6.02M
#define FREE(parser, p) (parser->m_mem.free_fcn((p)))
762
763
XML_Parser XMLCALL
764
20.2k
XML_ParserCreate(const XML_Char *encodingName) {
765
20.2k
  return XML_ParserCreate_MM(encodingName, NULL, NULL);
766
20.2k
}
767
768
XML_Parser XMLCALL
769
20.2k
XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
770
20.2k
  XML_Char tmp[2] = {nsSep, 0};
771
20.2k
  return XML_ParserCreate_MM(encodingName, NULL, tmp);
772
20.2k
}
773
774
// "xml=http://www.w3.org/XML/1998/namespace"
775
static const XML_Char implicitContext[]
776
    = {ASCII_x,     ASCII_m,     ASCII_l,      ASCII_EQUALS, ASCII_h,
777
       ASCII_t,     ASCII_t,     ASCII_p,      ASCII_COLON,  ASCII_SLASH,
778
       ASCII_SLASH, ASCII_w,     ASCII_w,      ASCII_w,      ASCII_PERIOD,
779
       ASCII_w,     ASCII_3,     ASCII_PERIOD, ASCII_o,      ASCII_r,
780
       ASCII_g,     ASCII_SLASH, ASCII_X,      ASCII_M,      ASCII_L,
781
       ASCII_SLASH, ASCII_1,     ASCII_9,      ASCII_9,      ASCII_8,
782
       ASCII_SLASH, ASCII_n,     ASCII_a,      ASCII_m,      ASCII_e,
783
       ASCII_s,     ASCII_p,     ASCII_a,      ASCII_c,      ASCII_e,
784
       '\0'};
785
786
/* To avoid warnings about unused functions: */
787
#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
788
789
#  if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
790
791
/* Obtain entropy on Linux 3.17+ */
792
static int
793
0
writeRandomBytes_getrandom_nonblock(void *target, size_t count) {
794
0
  int success = 0; /* full count bytes written? */
795
0
  size_t bytesWrittenTotal = 0;
796
0
  const unsigned int getrandomFlags = GRND_NONBLOCK;
797
798
0
  do {
799
0
    void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
800
0
    const size_t bytesToWrite = count - bytesWrittenTotal;
801
802
0
    const int bytesWrittenMore =
803
0
#    if defined(HAVE_GETRANDOM)
804
0
        getrandom(currentTarget, bytesToWrite, getrandomFlags);
805
#    else
806
        syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
807
#    endif
808
809
0
    if (bytesWrittenMore > 0) {
810
0
      bytesWrittenTotal += bytesWrittenMore;
811
0
      if (bytesWrittenTotal >= count)
812
0
        success = 1;
813
0
    }
814
0
  } while (! success && (errno == EINTR));
815
816
0
  return success;
817
0
}
818
819
#  endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
820
821
#  if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
822
823
/* Extract entropy from /dev/urandom */
824
static int
825
0
writeRandomBytes_dev_urandom(void *target, size_t count) {
826
0
  int success = 0; /* full count bytes written? */
827
0
  size_t bytesWrittenTotal = 0;
828
829
0
  const int fd = open("/dev/urandom", O_RDONLY);
830
0
  if (fd < 0) {
831
0
    return 0;
832
0
  }
833
834
0
  do {
835
0
    void *const currentTarget = (void *)((char *)target + bytesWrittenTotal);
836
0
    const size_t bytesToWrite = count - bytesWrittenTotal;
837
838
0
    const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);
839
840
0
    if (bytesWrittenMore > 0) {
841
0
      bytesWrittenTotal += bytesWrittenMore;
842
0
      if (bytesWrittenTotal >= count)
843
0
        success = 1;
844
0
    }
845
0
  } while (! success && (errno == EINTR));
846
847
0
  close(fd);
848
0
  return success;
849
0
}
850
851
#  endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
852
853
#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
854
855
#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF)
856
857
static void
858
writeRandomBytes_arc4random(void *target, size_t count) {
859
  size_t bytesWrittenTotal = 0;
860
861
  while (bytesWrittenTotal < count) {
862
    const uint32_t random32 = arc4random();
863
    size_t i = 0;
864
865
    for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
866
         i++, bytesWrittenTotal++) {
867
      const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
868
      ((uint8_t *)target)[bytesWrittenTotal] = random8;
869
    }
870
  }
871
}
872
873
#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */
874
875
#ifdef _WIN32
876
877
/* Provide declaration of rand_s() for MinGW-32 (not 64, which has it),
878
   as it didn't declare it in its header prior to version 5.3.0 of its
879
   runtime package (mingwrt, containing stdlib.h).  The upstream fix
880
   was introduced at https://osdn.net/projects/mingw/ticket/39658 . */
881
#  if defined(__MINGW32__) && defined(__MINGW32_VERSION)                       \
882
      && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR)
883
__declspec(dllimport) int rand_s(unsigned int *);
884
#  endif
885
886
/* Obtain entropy on Windows using the rand_s() function which
887
 * generates cryptographically secure random numbers.  Internally it
888
 * uses RtlGenRandom API which is present in Windows XP and later.
889
 */
890
static int
891
writeRandomBytes_rand_s(void *target, size_t count) {
892
  size_t bytesWrittenTotal = 0;
893
894
  while (bytesWrittenTotal < count) {
895
    unsigned int random32 = 0;
896
    size_t i = 0;
897
898
    if (rand_s(&random32))
899
      return 0; /* failure */
900
901
    for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
902
         i++, bytesWrittenTotal++) {
903
      const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
904
      ((uint8_t *)target)[bytesWrittenTotal] = random8;
905
    }
906
  }
907
  return 1; /* success */
908
}
909
910
#endif /* _WIN32 */
911
912
#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)
913
914
static unsigned long
915
0
gather_time_entropy(void) {
916
#  ifdef _WIN32
917
  FILETIME ft;
918
  GetSystemTimeAsFileTime(&ft); /* never fails */
919
  return ft.dwHighDateTime ^ ft.dwLowDateTime;
920
#  else
921
0
  struct timeval tv;
922
0
  int gettimeofday_res;
923
924
0
  gettimeofday_res = gettimeofday(&tv, NULL);
925
926
#    if defined(NDEBUG)
927
  (void)gettimeofday_res;
928
#    else
929
0
  assert(gettimeofday_res == 0);
930
0
#    endif /* defined(NDEBUG) */
931
932
  /* Microseconds time is <20 bits entropy */
933
0
  return tv.tv_usec;
934
0
#  endif
935
0
}
936
937
#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
938
939
static unsigned long
940
0
ENTROPY_DEBUG(const char *label, unsigned long entropy) {
941
0
  if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) {
942
0
    fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label,
943
0
            (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy));
944
0
  }
945
0
  return entropy;
946
0
}
947
948
static unsigned long
949
0
generate_hash_secret_salt(XML_Parser parser) {
950
0
  unsigned long entropy;
951
0
  (void)parser;
952
953
  /* "Failproof" high quality providers: */
954
#if defined(HAVE_ARC4RANDOM_BUF)
955
  arc4random_buf(&entropy, sizeof(entropy));
956
  return ENTROPY_DEBUG("arc4random_buf", entropy);
957
#elif defined(HAVE_ARC4RANDOM)
958
  writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
959
  return ENTROPY_DEBUG("arc4random", entropy);
960
#else
961
  /* Try high quality providers first .. */
962
#  ifdef _WIN32
963
  if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) {
964
    return ENTROPY_DEBUG("rand_s", entropy);
965
  }
966
#  elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
967
0
  if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
968
0
    return ENTROPY_DEBUG("getrandom", entropy);
969
0
  }
970
0
#  endif
971
0
#  if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
972
0
  if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
973
0
    return ENTROPY_DEBUG("/dev/urandom", entropy);
974
0
  }
975
0
#  endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
976
  /* .. and self-made low quality for backup: */
977
978
  /* Process ID is 0 bits entropy if attacker has local access */
979
0
  entropy = gather_time_entropy() ^ getpid();
980
981
  /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
982
0
  if (sizeof(unsigned long) == 4) {
983
0
    return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
984
0
  } else {
985
0
    return ENTROPY_DEBUG("fallback(8)",
986
0
                         entropy * (unsigned long)2305843009213693951ULL);
987
0
  }
988
0
#endif
989
0
}
990
991
static unsigned long
992
9.67M
get_hash_secret_salt(XML_Parser parser) {
993
9.67M
  if (parser->m_parentParser != NULL)
994
1.81M
    return get_hash_secret_salt(parser->m_parentParser);
995
7.86M
  return parser->m_hash_secret_salt;
996
9.67M
}
997
998
static enum XML_Error
999
callProcessor(XML_Parser parser, const char *start, const char *end,
1000
161k
              const char **endPtr) {
1001
161k
  const size_t have_now = EXPAT_SAFE_PTR_DIFF(end, start);
1002
1003
161k
  if (parser->m_reparseDeferralEnabled
1004
161k
      && ! parser->m_parsingStatus.finalBuffer) {
1005
    // Heuristic: don't try to parse a partial token again until the amount of
1006
    // available data has increased significantly.
1007
80.8k
    const size_t had_before = parser->m_partialTokenBytesBefore;
1008
    // ...but *do* try anyway if we're close to causing a reallocation.
1009
80.8k
    size_t available_buffer
1010
80.8k
        = EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
1011
80.8k
#if XML_CONTEXT_BYTES > 0
1012
80.8k
    available_buffer -= EXPAT_MIN(available_buffer, XML_CONTEXT_BYTES);
1013
80.8k
#endif
1014
80.8k
    available_buffer
1015
80.8k
        += EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd);
1016
    // m_lastBufferRequestSize is never assigned a value < 0, so the cast is ok
1017
80.8k
    const bool enough
1018
80.8k
        = (have_now >= 2 * had_before)
1019
80.8k
          || ((size_t)parser->m_lastBufferRequestSize > available_buffer);
1020
1021
80.8k
    if (! enough) {
1022
0
      *endPtr = start; // callers may expect this to be set
1023
0
      return XML_ERROR_NONE;
1024
0
    }
1025
80.8k
  }
1026
#if defined(XML_TESTING)
1027
  g_bytesScanned += (unsigned)have_now;
1028
#endif
1029
161k
  const enum XML_Error ret = parser->m_processor(parser, start, end, endPtr);
1030
161k
  if (ret == XML_ERROR_NONE) {
1031
    // if we consumed nothing, remember what we had on this parse attempt.
1032
31.7k
    if (*endPtr == start) {
1033
9.40k
      parser->m_partialTokenBytesBefore = have_now;
1034
22.3k
    } else {
1035
22.3k
      parser->m_partialTokenBytesBefore = 0;
1036
22.3k
    }
1037
31.7k
  }
1038
161k
  return ret;
1039
161k
}
1040
1041
static XML_Bool /* only valid for root parser */
1042
40.4k
startParsing(XML_Parser parser) {
1043
  /* hash functions must be initialized before setContext() is called */
1044
40.4k
  if (parser->m_hash_secret_salt == 0)
1045
0
    parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
1046
40.4k
  if (parser->m_ns) {
1047
    /* implicit context only set for root parser, since child
1048
       parsers (i.e. external entity parsers) will inherit it
1049
    */
1050
20.2k
    return setContext(parser, implicitContext);
1051
20.2k
  }
1052
20.2k
  return XML_TRUE;
1053
40.4k
}
1054
1055
XML_Parser XMLCALL
1056
XML_ParserCreate_MM(const XML_Char *encodingName,
1057
                    const XML_Memory_Handling_Suite *memsuite,
1058
40.4k
                    const XML_Char *nameSep) {
1059
40.4k
  return parserCreate(encodingName, memsuite, nameSep, NULL);
1060
40.4k
}
1061
1062
static XML_Parser
1063
parserCreate(const XML_Char *encodingName,
1064
             const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
1065
80.8k
             DTD *dtd) {
1066
80.8k
  XML_Parser parser;
1067
1068
80.8k
  if (memsuite) {
1069
40.4k
    XML_Memory_Handling_Suite *mtemp;
1070
40.4k
    parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
1071
40.4k
    if (parser != NULL) {
1072
40.4k
      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
1073
40.4k
      mtemp->malloc_fcn = memsuite->malloc_fcn;
1074
40.4k
      mtemp->realloc_fcn = memsuite->realloc_fcn;
1075
40.4k
      mtemp->free_fcn = memsuite->free_fcn;
1076
40.4k
    }
1077
40.4k
  } else {
1078
40.4k
    XML_Memory_Handling_Suite *mtemp;
1079
40.4k
    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
1080
40.4k
    if (parser != NULL) {
1081
40.4k
      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
1082
40.4k
      mtemp->malloc_fcn = malloc;
1083
40.4k
      mtemp->realloc_fcn = realloc;
1084
40.4k
      mtemp->free_fcn = free;
1085
40.4k
    }
1086
40.4k
  }
1087
1088
80.8k
  if (! parser)
1089
0
    return parser;
1090
1091
80.8k
  parser->m_buffer = NULL;
1092
80.8k
  parser->m_bufferLim = NULL;
1093
1094
80.8k
  parser->m_attsSize = INIT_ATTS_SIZE;
1095
80.8k
  parser->m_atts
1096
80.8k
      = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
1097
80.8k
  if (parser->m_atts == NULL) {
1098
0
    FREE(parser, parser);
1099
0
    return NULL;
1100
0
  }
1101
#ifdef XML_ATTR_INFO
1102
  parser->m_attInfo = (XML_AttrInfo *)MALLOC(
1103
      parser, parser->m_attsSize * sizeof(XML_AttrInfo));
1104
  if (parser->m_attInfo == NULL) {
1105
    FREE(parser, parser->m_atts);
1106
    FREE(parser, parser);
1107
    return NULL;
1108
  }
1109
#endif
1110
80.8k
  parser->m_dataBuf
1111
80.8k
      = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
1112
80.8k
  if (parser->m_dataBuf == NULL) {
1113
0
    FREE(parser, parser->m_atts);
1114
#ifdef XML_ATTR_INFO
1115
    FREE(parser, parser->m_attInfo);
1116
#endif
1117
0
    FREE(parser, parser);
1118
0
    return NULL;
1119
0
  }
1120
80.8k
  parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
1121
1122
80.8k
  if (dtd)
1123
20.2k
    parser->m_dtd = dtd;
1124
60.6k
  else {
1125
60.6k
    parser->m_dtd = dtdCreate(&parser->m_mem);
1126
60.6k
    if (parser->m_dtd == NULL) {
1127
0
      FREE(parser, parser->m_dataBuf);
1128
0
      FREE(parser, parser->m_atts);
1129
#ifdef XML_ATTR_INFO
1130
      FREE(parser, parser->m_attInfo);
1131
#endif
1132
0
      FREE(parser, parser);
1133
0
      return NULL;
1134
0
    }
1135
60.6k
  }
1136
1137
80.8k
  parser->m_freeBindingList = NULL;
1138
80.8k
  parser->m_freeTagList = NULL;
1139
80.8k
  parser->m_freeInternalEntities = NULL;
1140
1141
80.8k
  parser->m_groupSize = 0;
1142
80.8k
  parser->m_groupConnector = NULL;
1143
1144
80.8k
  parser->m_unknownEncodingHandler = NULL;
1145
80.8k
  parser->m_unknownEncodingHandlerData = NULL;
1146
1147
80.8k
  parser->m_namespaceSeparator = ASCII_EXCL;
1148
80.8k
  parser->m_ns = XML_FALSE;
1149
80.8k
  parser->m_ns_triplets = XML_FALSE;
1150
1151
80.8k
  parser->m_nsAtts = NULL;
1152
80.8k
  parser->m_nsAttsVersion = 0;
1153
80.8k
  parser->m_nsAttsPower = 0;
1154
1155
80.8k
  parser->m_protocolEncodingName = NULL;
1156
1157
80.8k
  poolInit(&parser->m_tempPool, &(parser->m_mem));
1158
80.8k
  poolInit(&parser->m_temp2Pool, &(parser->m_mem));
1159
80.8k
  parserInit(parser, encodingName);
1160
1161
80.8k
  if (encodingName && ! parser->m_protocolEncodingName) {
1162
0
    if (dtd) {
1163
      // We need to stop the upcoming call to XML_ParserFree from happily
1164
      // destroying parser->m_dtd because the DTD is shared with the parent
1165
      // parser and the only guard that keeps XML_ParserFree from destroying
1166
      // parser->m_dtd is parser->m_isParamEntity but it will be set to
1167
      // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all).
1168
0
      parser->m_dtd = NULL;
1169
0
    }
1170
0
    XML_ParserFree(parser);
1171
0
    return NULL;
1172
0
  }
1173
1174
80.8k
  if (nameSep) {
1175
20.2k
    parser->m_ns = XML_TRUE;
1176
20.2k
    parser->m_internalEncoding = XmlGetInternalEncodingNS();
1177
20.2k
    parser->m_namespaceSeparator = *nameSep;
1178
60.6k
  } else {
1179
60.6k
    parser->m_internalEncoding = XmlGetInternalEncoding();
1180
60.6k
  }
1181
1182
80.8k
  return parser;
1183
80.8k
}
1184
1185
static void
1186
98.0k
parserInit(XML_Parser parser, const XML_Char *encodingName) {
1187
98.0k
  parser->m_processor = prologInitProcessor;
1188
98.0k
  XmlPrologStateInit(&parser->m_prologState);
1189
98.0k
  if (encodingName != NULL) {
1190
20.2k
    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
1191
20.2k
  }
1192
98.0k
  parser->m_curBase = NULL;
1193
98.0k
  XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
1194
98.0k
  parser->m_userData = NULL;
1195
98.0k
  parser->m_handlerArg = NULL;
1196
98.0k
  parser->m_startElementHandler = NULL;
1197
98.0k
  parser->m_endElementHandler = NULL;
1198
98.0k
  parser->m_characterDataHandler = NULL;
1199
98.0k
  parser->m_processingInstructionHandler = NULL;
1200
98.0k
  parser->m_commentHandler = NULL;
1201
98.0k
  parser->m_startCdataSectionHandler = NULL;
1202
98.0k
  parser->m_endCdataSectionHandler = NULL;
1203
98.0k
  parser->m_defaultHandler = NULL;
1204
98.0k
  parser->m_startDoctypeDeclHandler = NULL;
1205
98.0k
  parser->m_endDoctypeDeclHandler = NULL;
1206
98.0k
  parser->m_unparsedEntityDeclHandler = NULL;
1207
98.0k
  parser->m_notationDeclHandler = NULL;
1208
98.0k
  parser->m_startNamespaceDeclHandler = NULL;
1209
98.0k
  parser->m_endNamespaceDeclHandler = NULL;
1210
98.0k
  parser->m_notStandaloneHandler = NULL;
1211
98.0k
  parser->m_externalEntityRefHandler = NULL;
1212
98.0k
  parser->m_externalEntityRefHandlerArg = parser;
1213
98.0k
  parser->m_skippedEntityHandler = NULL;
1214
98.0k
  parser->m_elementDeclHandler = NULL;
1215
98.0k
  parser->m_attlistDeclHandler = NULL;
1216
98.0k
  parser->m_entityDeclHandler = NULL;
1217
98.0k
  parser->m_xmlDeclHandler = NULL;
1218
98.0k
  parser->m_bufferPtr = parser->m_buffer;
1219
98.0k
  parser->m_bufferEnd = parser->m_buffer;
1220
98.0k
  parser->m_parseEndByteIndex = 0;
1221
98.0k
  parser->m_parseEndPtr = NULL;
1222
98.0k
  parser->m_partialTokenBytesBefore = 0;
1223
98.0k
  parser->m_reparseDeferralEnabled = g_reparseDeferralEnabledDefault;
1224
98.0k
  parser->m_lastBufferRequestSize = 0;
1225
98.0k
  parser->m_declElementType = NULL;
1226
98.0k
  parser->m_declAttributeId = NULL;
1227
98.0k
  parser->m_declEntity = NULL;
1228
98.0k
  parser->m_doctypeName = NULL;
1229
98.0k
  parser->m_doctypeSysid = NULL;
1230
98.0k
  parser->m_doctypePubid = NULL;
1231
98.0k
  parser->m_declAttributeType = NULL;
1232
98.0k
  parser->m_declNotationName = NULL;
1233
98.0k
  parser->m_declNotationPublicId = NULL;
1234
98.0k
  parser->m_declAttributeIsCdata = XML_FALSE;
1235
98.0k
  parser->m_declAttributeIsId = XML_FALSE;
1236
98.0k
  memset(&parser->m_position, 0, sizeof(POSITION));
1237
98.0k
  parser->m_errorCode = XML_ERROR_NONE;
1238
98.0k
  parser->m_eventPtr = NULL;
1239
98.0k
  parser->m_eventEndPtr = NULL;
1240
98.0k
  parser->m_positionPtr = NULL;
1241
98.0k
  parser->m_openInternalEntities = NULL;
1242
98.0k
  parser->m_defaultExpandInternalEntities = XML_TRUE;
1243
98.0k
  parser->m_tagLevel = 0;
1244
98.0k
  parser->m_tagStack = NULL;
1245
98.0k
  parser->m_inheritedBindings = NULL;
1246
98.0k
  parser->m_nSpecifiedAtts = 0;
1247
98.0k
  parser->m_unknownEncodingMem = NULL;
1248
98.0k
  parser->m_unknownEncodingRelease = NULL;
1249
98.0k
  parser->m_unknownEncodingData = NULL;
1250
98.0k
  parser->m_parentParser = NULL;
1251
98.0k
  parser->m_parsingStatus.parsing = XML_INITIALIZED;
1252
98.0k
#ifdef XML_DTD
1253
98.0k
  parser->m_isParamEntity = XML_FALSE;
1254
98.0k
  parser->m_useForeignDTD = XML_FALSE;
1255
98.0k
  parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
1256
98.0k
#endif
1257
98.0k
  parser->m_hash_secret_salt = 0;
1258
1259
98.0k
#if XML_GE == 1
1260
98.0k
  memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
1261
98.0k
  parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u);
1262
98.0k
  parser->m_accounting.maximumAmplificationFactor
1263
98.0k
      = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT;
1264
98.0k
  parser->m_accounting.activationThresholdBytes
1265
98.0k
      = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT;
1266
1267
98.0k
  memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS));
1268
98.0k
  parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u);
1269
98.0k
#endif
1270
98.0k
}
1271
1272
/* moves list of bindings to m_freeBindingList */
1273
static void FASTCALL
1274
865k
moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
1275
876k
  while (bindings) {
1276
10.9k
    BINDING *b = bindings;
1277
10.9k
    bindings = bindings->nextTagBinding;
1278
10.9k
    b->nextTagBinding = parser->m_freeBindingList;
1279
10.9k
    parser->m_freeBindingList = b;
1280
10.9k
  }
1281
865k
}
1282
1283
XML_Bool XMLCALL
1284
34.5k
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
1285
34.5k
  TAG *tStk;
1286
34.5k
  OPEN_INTERNAL_ENTITY *openEntityList;
1287
1288
34.5k
  if (parser == NULL)
1289
0
    return XML_FALSE;
1290
1291
34.5k
  if (parser->m_parentParser)
1292
17.2k
    return XML_FALSE;
1293
  /* move m_tagStack to m_freeTagList */
1294
17.2k
  tStk = parser->m_tagStack;
1295
865k
  while (tStk) {
1296
848k
    TAG *tag = tStk;
1297
848k
    tStk = tStk->parent;
1298
848k
    tag->parent = parser->m_freeTagList;
1299
848k
    moveToFreeBindingList(parser, tag->bindings);
1300
848k
    tag->bindings = NULL;
1301
848k
    parser->m_freeTagList = tag;
1302
848k
  }
1303
  /* move m_openInternalEntities to m_freeInternalEntities */
1304
17.2k
  openEntityList = parser->m_openInternalEntities;
1305
18.9k
  while (openEntityList) {
1306
1.68k
    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
1307
1.68k
    openEntityList = openEntity->next;
1308
1.68k
    openEntity->next = parser->m_freeInternalEntities;
1309
1.68k
    parser->m_freeInternalEntities = openEntity;
1310
1.68k
  }
1311
17.2k
  moveToFreeBindingList(parser, parser->m_inheritedBindings);
1312
17.2k
  FREE(parser, parser->m_unknownEncodingMem);
1313
17.2k
  if (parser->m_unknownEncodingRelease)
1314
0
    parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1315
17.2k
  poolClear(&parser->m_tempPool);
1316
17.2k
  poolClear(&parser->m_temp2Pool);
1317
17.2k
  FREE(parser, (void *)parser->m_protocolEncodingName);
1318
17.2k
  parser->m_protocolEncodingName = NULL;
1319
17.2k
  parserInit(parser, encodingName);
1320
17.2k
  dtdReset(parser->m_dtd, &parser->m_mem);
1321
17.2k
  return XML_TRUE;
1322
34.5k
}
1323
1324
enum XML_Status XMLCALL
1325
0
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
1326
0
  if (parser == NULL)
1327
0
    return XML_STATUS_ERROR;
1328
  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1329
     XXX There's no way for the caller to determine which of the
1330
     XXX possible error cases caused the XML_STATUS_ERROR return.
1331
  */
1332
0
  if (parser->m_parsingStatus.parsing == XML_PARSING
1333
0
      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1334
0
    return XML_STATUS_ERROR;
1335
1336
  /* Get rid of any previous encoding name */
1337
0
  FREE(parser, (void *)parser->m_protocolEncodingName);
1338
1339
0
  if (encodingName == NULL)
1340
    /* No new encoding name */
1341
0
    parser->m_protocolEncodingName = NULL;
1342
0
  else {
1343
    /* Copy the new encoding name into allocated memory */
1344
0
    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
1345
0
    if (! parser->m_protocolEncodingName)
1346
0
      return XML_STATUS_ERROR;
1347
0
  }
1348
0
  return XML_STATUS_OK;
1349
0
}
1350
1351
XML_Parser XMLCALL
1352
XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
1353
40.4k
                               const XML_Char *encodingName) {
1354
40.4k
  XML_Parser parser = oldParser;
1355
40.4k
  DTD *newDtd = NULL;
1356
40.4k
  DTD *oldDtd;
1357
40.4k
  XML_StartElementHandler oldStartElementHandler;
1358
40.4k
  XML_EndElementHandler oldEndElementHandler;
1359
40.4k
  XML_CharacterDataHandler oldCharacterDataHandler;
1360
40.4k
  XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1361
40.4k
  XML_CommentHandler oldCommentHandler;
1362
40.4k
  XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1363
40.4k
  XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1364
40.4k
  XML_DefaultHandler oldDefaultHandler;
1365
40.4k
  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1366
40.4k
  XML_NotationDeclHandler oldNotationDeclHandler;
1367
40.4k
  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1368
40.4k
  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1369
40.4k
  XML_NotStandaloneHandler oldNotStandaloneHandler;
1370
40.4k
  XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1371
40.4k
  XML_SkippedEntityHandler oldSkippedEntityHandler;
1372
40.4k
  XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1373
40.4k
  XML_ElementDeclHandler oldElementDeclHandler;
1374
40.4k
  XML_AttlistDeclHandler oldAttlistDeclHandler;
1375
40.4k
  XML_EntityDeclHandler oldEntityDeclHandler;
1376
40.4k
  XML_XmlDeclHandler oldXmlDeclHandler;
1377
40.4k
  ELEMENT_TYPE *oldDeclElementType;
1378
1379
40.4k
  void *oldUserData;
1380
40.4k
  void *oldHandlerArg;
1381
40.4k
  XML_Bool oldDefaultExpandInternalEntities;
1382
40.4k
  XML_Parser oldExternalEntityRefHandlerArg;
1383
40.4k
#ifdef XML_DTD
1384
40.4k
  enum XML_ParamEntityParsing oldParamEntityParsing;
1385
40.4k
  int oldInEntityValue;
1386
40.4k
#endif
1387
40.4k
  XML_Bool oldns_triplets;
1388
  /* Note that the new parser shares the same hash secret as the old
1389
     parser, so that dtdCopy and copyEntityTable can lookup values
1390
     from hash tables associated with either parser without us having
1391
     to worry which hash secrets each table has.
1392
  */
1393
40.4k
  unsigned long oldhash_secret_salt;
1394
40.4k
  XML_Bool oldReparseDeferralEnabled;
1395
1396
  /* Validate the oldParser parameter before we pull everything out of it */
1397
40.4k
  if (oldParser == NULL)
1398
0
    return NULL;
1399
1400
  /* Stash the original parser contents on the stack */
1401
40.4k
  oldDtd = parser->m_dtd;
1402
40.4k
  oldStartElementHandler = parser->m_startElementHandler;
1403
40.4k
  oldEndElementHandler = parser->m_endElementHandler;
1404
40.4k
  oldCharacterDataHandler = parser->m_characterDataHandler;
1405
40.4k
  oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
1406
40.4k
  oldCommentHandler = parser->m_commentHandler;
1407
40.4k
  oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
1408
40.4k
  oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
1409
40.4k
  oldDefaultHandler = parser->m_defaultHandler;
1410
40.4k
  oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1411
40.4k
  oldNotationDeclHandler = parser->m_notationDeclHandler;
1412
40.4k
  oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1413
40.4k
  oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1414
40.4k
  oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1415
40.4k
  oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1416
40.4k
  oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1417
40.4k
  oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1418
40.4k
  oldElementDeclHandler = parser->m_elementDeclHandler;
1419
40.4k
  oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1420
40.4k
  oldEntityDeclHandler = parser->m_entityDeclHandler;
1421
40.4k
  oldXmlDeclHandler = parser->m_xmlDeclHandler;
1422
40.4k
  oldDeclElementType = parser->m_declElementType;
1423
1424
40.4k
  oldUserData = parser->m_userData;
1425
40.4k
  oldHandlerArg = parser->m_handlerArg;
1426
40.4k
  oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1427
40.4k
  oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1428
40.4k
#ifdef XML_DTD
1429
40.4k
  oldParamEntityParsing = parser->m_paramEntityParsing;
1430
40.4k
  oldInEntityValue = parser->m_prologState.inEntityValue;
1431
40.4k
#endif
1432
40.4k
  oldns_triplets = parser->m_ns_triplets;
1433
  /* Note that the new parser shares the same hash secret as the old
1434
     parser, so that dtdCopy and copyEntityTable can lookup values
1435
     from hash tables associated with either parser without us having
1436
     to worry which hash secrets each table has.
1437
  */
1438
40.4k
  oldhash_secret_salt = parser->m_hash_secret_salt;
1439
40.4k
  oldReparseDeferralEnabled = parser->m_reparseDeferralEnabled;
1440
1441
40.4k
#ifdef XML_DTD
1442
40.4k
  if (! context)
1443
20.2k
    newDtd = oldDtd;
1444
40.4k
#endif /* XML_DTD */
1445
1446
  /* Note that the magical uses of the pre-processor to make field
1447
     access look more like C++ require that `parser' be overwritten
1448
     here.  This makes this function more painful to follow than it
1449
     would be otherwise.
1450
  */
1451
40.4k
  if (parser->m_ns) {
1452
0
    XML_Char tmp[2] = {parser->m_namespaceSeparator, 0};
1453
0
    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1454
40.4k
  } else {
1455
40.4k
    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1456
40.4k
  }
1457
1458
40.4k
  if (! parser)
1459
0
    return NULL;
1460
1461
40.4k
  parser->m_startElementHandler = oldStartElementHandler;
1462
40.4k
  parser->m_endElementHandler = oldEndElementHandler;
1463
40.4k
  parser->m_characterDataHandler = oldCharacterDataHandler;
1464
40.4k
  parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1465
40.4k
  parser->m_commentHandler = oldCommentHandler;
1466
40.4k
  parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1467
40.4k
  parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1468
40.4k
  parser->m_defaultHandler = oldDefaultHandler;
1469
40.4k
  parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1470
40.4k
  parser->m_notationDeclHandler = oldNotationDeclHandler;
1471
40.4k
  parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1472
40.4k
  parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1473
40.4k
  parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1474
40.4k
  parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1475
40.4k
  parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1476
40.4k
  parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1477
40.4k
  parser->m_elementDeclHandler = oldElementDeclHandler;
1478
40.4k
  parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1479
40.4k
  parser->m_entityDeclHandler = oldEntityDeclHandler;
1480
40.4k
  parser->m_xmlDeclHandler = oldXmlDeclHandler;
1481
40.4k
  parser->m_declElementType = oldDeclElementType;
1482
40.4k
  parser->m_userData = oldUserData;
1483
40.4k
  if (oldUserData == oldHandlerArg)
1484
40.4k
    parser->m_handlerArg = parser->m_userData;
1485
0
  else
1486
0
    parser->m_handlerArg = parser;
1487
40.4k
  if (oldExternalEntityRefHandlerArg != oldParser)
1488
0
    parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1489
40.4k
  parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1490
40.4k
  parser->m_ns_triplets = oldns_triplets;
1491
40.4k
  parser->m_hash_secret_salt = oldhash_secret_salt;
1492
40.4k
  parser->m_reparseDeferralEnabled = oldReparseDeferralEnabled;
1493
40.4k
  parser->m_parentParser = oldParser;
1494
40.4k
#ifdef XML_DTD
1495
40.4k
  parser->m_paramEntityParsing = oldParamEntityParsing;
1496
40.4k
  parser->m_prologState.inEntityValue = oldInEntityValue;
1497
40.4k
  if (context) {
1498
20.2k
#endif /* XML_DTD */
1499
20.2k
    if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
1500
20.2k
        || ! setContext(parser, context)) {
1501
0
      XML_ParserFree(parser);
1502
0
      return NULL;
1503
0
    }
1504
20.2k
    parser->m_processor = externalEntityInitProcessor;
1505
20.2k
#ifdef XML_DTD
1506
20.2k
  } else {
1507
    /* The DTD instance referenced by parser->m_dtd is shared between the
1508
       document's root parser and external PE parsers, therefore one does not
1509
       need to call setContext. In addition, one also *must* not call
1510
       setContext, because this would overwrite existing prefix->binding
1511
       pointers in parser->m_dtd with ones that get destroyed with the external
1512
       PE parser. This would leave those prefixes with dangling pointers.
1513
    */
1514
20.2k
    parser->m_isParamEntity = XML_TRUE;
1515
20.2k
    XmlPrologStateInitExternalEntity(&parser->m_prologState);
1516
20.2k
    parser->m_processor = externalParEntInitProcessor;
1517
20.2k
  }
1518
40.4k
#endif /* XML_DTD */
1519
40.4k
  return parser;
1520
40.4k
}
1521
1522
static void FASTCALL
1523
2.80M
destroyBindings(BINDING *bindings, XML_Parser parser) {
1524
2.82M
  for (;;) {
1525
2.82M
    BINDING *b = bindings;
1526
2.82M
    if (! b)
1527
2.80M
      break;
1528
25.0k
    bindings = b->nextTagBinding;
1529
25.0k
    FREE(parser, b->uri);
1530
25.0k
    FREE(parser, b);
1531
25.0k
  }
1532
2.80M
}
1533
1534
void XMLCALL
1535
80.8k
XML_ParserFree(XML_Parser parser) {
1536
80.8k
  TAG *tagList;
1537
80.8k
  OPEN_INTERNAL_ENTITY *entityList;
1538
80.8k
  if (parser == NULL)
1539
0
    return;
1540
  /* free m_tagStack and m_freeTagList */
1541
80.8k
  tagList = parser->m_tagStack;
1542
2.72M
  for (;;) {
1543
2.72M
    TAG *p;
1544
2.72M
    if (tagList == NULL) {
1545
85.7k
      if (parser->m_freeTagList == NULL)
1546
80.8k
        break;
1547
4.93k
      tagList = parser->m_freeTagList;
1548
4.93k
      parser->m_freeTagList = NULL;
1549
4.93k
    }
1550
2.64M
    p = tagList;
1551
2.64M
    tagList = tagList->parent;
1552
2.64M
    FREE(parser, p->buf);
1553
2.64M
    destroyBindings(p->bindings, parser);
1554
2.64M
    FREE(parser, p);
1555
2.64M
  }
1556
  /* free m_openInternalEntities and m_freeInternalEntities */
1557
80.8k
  entityList = parser->m_openInternalEntities;
1558
83.8k
  for (;;) {
1559
83.8k
    OPEN_INTERNAL_ENTITY *openEntity;
1560
83.8k
    if (entityList == NULL) {
1561
82.9k
      if (parser->m_freeInternalEntities == NULL)
1562
80.8k
        break;
1563
2.13k
      entityList = parser->m_freeInternalEntities;
1564
2.13k
      parser->m_freeInternalEntities = NULL;
1565
2.13k
    }
1566
3.03k
    openEntity = entityList;
1567
3.03k
    entityList = entityList->next;
1568
3.03k
    FREE(parser, openEntity);
1569
3.03k
  }
1570
1571
80.8k
  destroyBindings(parser->m_freeBindingList, parser);
1572
80.8k
  destroyBindings(parser->m_inheritedBindings, parser);
1573
80.8k
  poolDestroy(&parser->m_tempPool);
1574
80.8k
  poolDestroy(&parser->m_temp2Pool);
1575
80.8k
  FREE(parser, (void *)parser->m_protocolEncodingName);
1576
80.8k
#ifdef XML_DTD
1577
  /* external parameter entity parsers share the DTD structure
1578
     parser->m_dtd with the root parser, so we must not destroy it
1579
  */
1580
80.8k
  if (! parser->m_isParamEntity && parser->m_dtd)
1581
#else
1582
  if (parser->m_dtd)
1583
#endif /* XML_DTD */
1584
60.6k
    dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser,
1585
60.6k
               &parser->m_mem);
1586
80.8k
  FREE(parser, (void *)parser->m_atts);
1587
#ifdef XML_ATTR_INFO
1588
  FREE(parser, (void *)parser->m_attInfo);
1589
#endif
1590
80.8k
  FREE(parser, parser->m_groupConnector);
1591
80.8k
  FREE(parser, parser->m_buffer);
1592
80.8k
  FREE(parser, parser->m_dataBuf);
1593
80.8k
  FREE(parser, parser->m_nsAtts);
1594
80.8k
  FREE(parser, parser->m_unknownEncodingMem);
1595
80.8k
  if (parser->m_unknownEncodingRelease)
1596
0
    parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1597
80.8k
  FREE(parser, parser);
1598
80.8k
}
1599
1600
void XMLCALL
1601
0
XML_UseParserAsHandlerArg(XML_Parser parser) {
1602
0
  if (parser != NULL)
1603
0
    parser->m_handlerArg = parser;
1604
0
}
1605
1606
enum XML_Error XMLCALL
1607
0
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
1608
0
  if (parser == NULL)
1609
0
    return XML_ERROR_INVALID_ARGUMENT;
1610
0
#ifdef XML_DTD
1611
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1612
0
  if (parser->m_parsingStatus.parsing == XML_PARSING
1613
0
      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1614
0
    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1615
0
  parser->m_useForeignDTD = useDTD;
1616
0
  return XML_ERROR_NONE;
1617
#else
1618
  UNUSED_P(useDTD);
1619
  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1620
#endif
1621
0
}
1622
1623
void XMLCALL
1624
0
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
1625
0
  if (parser == NULL)
1626
0
    return;
1627
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1628
0
  if (parser->m_parsingStatus.parsing == XML_PARSING
1629
0
      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1630
0
    return;
1631
0
  parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1632
0
}
1633
1634
void XMLCALL
1635
80.8k
XML_SetUserData(XML_Parser parser, void *p) {
1636
80.8k
  if (parser == NULL)
1637
0
    return;
1638
80.8k
  if (parser->m_handlerArg == parser->m_userData)
1639
80.8k
    parser->m_handlerArg = parser->m_userData = p;
1640
0
  else
1641
0
    parser->m_userData = p;
1642
80.8k
}
1643
1644
enum XML_Status XMLCALL
1645
0
XML_SetBase(XML_Parser parser, const XML_Char *p) {
1646
0
  if (parser == NULL)
1647
0
    return XML_STATUS_ERROR;
1648
0
  if (p) {
1649
0
    p = poolCopyString(&parser->m_dtd->pool, p);
1650
0
    if (! p)
1651
0
      return XML_STATUS_ERROR;
1652
0
    parser->m_curBase = p;
1653
0
  } else
1654
0
    parser->m_curBase = NULL;
1655
0
  return XML_STATUS_OK;
1656
0
}
1657
1658
const XML_Char *XMLCALL
1659
0
XML_GetBase(XML_Parser parser) {
1660
0
  if (parser == NULL)
1661
0
    return NULL;
1662
0
  return parser->m_curBase;
1663
0
}
1664
1665
int XMLCALL
1666
0
XML_GetSpecifiedAttributeCount(XML_Parser parser) {
1667
0
  if (parser == NULL)
1668
0
    return -1;
1669
0
  return parser->m_nSpecifiedAtts;
1670
0
}
1671
1672
int XMLCALL
1673
0
XML_GetIdAttributeIndex(XML_Parser parser) {
1674
0
  if (parser == NULL)
1675
0
    return -1;
1676
0
  return parser->m_idAttIndex;
1677
0
}
1678
1679
#ifdef XML_ATTR_INFO
1680
const XML_AttrInfo *XMLCALL
1681
XML_GetAttributeInfo(XML_Parser parser) {
1682
  if (parser == NULL)
1683
    return NULL;
1684
  return parser->m_attInfo;
1685
}
1686
#endif
1687
1688
void XMLCALL
1689
XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
1690
80.8k
                      XML_EndElementHandler end) {
1691
80.8k
  if (parser == NULL)
1692
0
    return;
1693
80.8k
  parser->m_startElementHandler = start;
1694
80.8k
  parser->m_endElementHandler = end;
1695
80.8k
}
1696
1697
void XMLCALL
1698
0
XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
1699
0
  if (parser != NULL)
1700
0
    parser->m_startElementHandler = start;
1701
0
}
1702
1703
void XMLCALL
1704
0
XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
1705
0
  if (parser != NULL)
1706
0
    parser->m_endElementHandler = end;
1707
0
}
1708
1709
void XMLCALL
1710
XML_SetCharacterDataHandler(XML_Parser parser,
1711
80.8k
                            XML_CharacterDataHandler handler) {
1712
80.8k
  if (parser != NULL)
1713
80.8k
    parser->m_characterDataHandler = handler;
1714
80.8k
}
1715
1716
void XMLCALL
1717
XML_SetProcessingInstructionHandler(XML_Parser parser,
1718
0
                                    XML_ProcessingInstructionHandler handler) {
1719
0
  if (parser != NULL)
1720
0
    parser->m_processingInstructionHandler = handler;
1721
0
}
1722
1723
void XMLCALL
1724
0
XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
1725
0
  if (parser != NULL)
1726
0
    parser->m_commentHandler = handler;
1727
0
}
1728
1729
void XMLCALL
1730
XML_SetCdataSectionHandler(XML_Parser parser,
1731
                           XML_StartCdataSectionHandler start,
1732
0
                           XML_EndCdataSectionHandler end) {
1733
0
  if (parser == NULL)
1734
0
    return;
1735
0
  parser->m_startCdataSectionHandler = start;
1736
0
  parser->m_endCdataSectionHandler = end;
1737
0
}
1738
1739
void XMLCALL
1740
XML_SetStartCdataSectionHandler(XML_Parser parser,
1741
0
                                XML_StartCdataSectionHandler start) {
1742
0
  if (parser != NULL)
1743
0
    parser->m_startCdataSectionHandler = start;
1744
0
}
1745
1746
void XMLCALL
1747
XML_SetEndCdataSectionHandler(XML_Parser parser,
1748
0
                              XML_EndCdataSectionHandler end) {
1749
0
  if (parser != NULL)
1750
0
    parser->m_endCdataSectionHandler = end;
1751
0
}
1752
1753
void XMLCALL
1754
0
XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
1755
0
  if (parser == NULL)
1756
0
    return;
1757
0
  parser->m_defaultHandler = handler;
1758
0
  parser->m_defaultExpandInternalEntities = XML_FALSE;
1759
0
}
1760
1761
void XMLCALL
1762
0
XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
1763
0
  if (parser == NULL)
1764
0
    return;
1765
0
  parser->m_defaultHandler = handler;
1766
0
  parser->m_defaultExpandInternalEntities = XML_TRUE;
1767
0
}
1768
1769
void XMLCALL
1770
XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
1771
0
                          XML_EndDoctypeDeclHandler end) {
1772
0
  if (parser == NULL)
1773
0
    return;
1774
0
  parser->m_startDoctypeDeclHandler = start;
1775
0
  parser->m_endDoctypeDeclHandler = end;
1776
0
}
1777
1778
void XMLCALL
1779
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1780
0
                               XML_StartDoctypeDeclHandler start) {
1781
0
  if (parser != NULL)
1782
0
    parser->m_startDoctypeDeclHandler = start;
1783
0
}
1784
1785
void XMLCALL
1786
0
XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
1787
0
  if (parser != NULL)
1788
0
    parser->m_endDoctypeDeclHandler = end;
1789
0
}
1790
1791
void XMLCALL
1792
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1793
0
                                 XML_UnparsedEntityDeclHandler handler) {
1794
0
  if (parser != NULL)
1795
0
    parser->m_unparsedEntityDeclHandler = handler;
1796
0
}
1797
1798
void XMLCALL
1799
0
XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
1800
0
  if (parser != NULL)
1801
0
    parser->m_notationDeclHandler = handler;
1802
0
}
1803
1804
void XMLCALL
1805
XML_SetNamespaceDeclHandler(XML_Parser parser,
1806
                            XML_StartNamespaceDeclHandler start,
1807
0
                            XML_EndNamespaceDeclHandler end) {
1808
0
  if (parser == NULL)
1809
0
    return;
1810
0
  parser->m_startNamespaceDeclHandler = start;
1811
0
  parser->m_endNamespaceDeclHandler = end;
1812
0
}
1813
1814
void XMLCALL
1815
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1816
0
                                 XML_StartNamespaceDeclHandler start) {
1817
0
  if (parser != NULL)
1818
0
    parser->m_startNamespaceDeclHandler = start;
1819
0
}
1820
1821
void XMLCALL
1822
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1823
0
                               XML_EndNamespaceDeclHandler end) {
1824
0
  if (parser != NULL)
1825
0
    parser->m_endNamespaceDeclHandler = end;
1826
0
}
1827
1828
void XMLCALL
1829
XML_SetNotStandaloneHandler(XML_Parser parser,
1830
0
                            XML_NotStandaloneHandler handler) {
1831
0
  if (parser != NULL)
1832
0
    parser->m_notStandaloneHandler = handler;
1833
0
}
1834
1835
void XMLCALL
1836
XML_SetExternalEntityRefHandler(XML_Parser parser,
1837
0
                                XML_ExternalEntityRefHandler handler) {
1838
0
  if (parser != NULL)
1839
0
    parser->m_externalEntityRefHandler = handler;
1840
0
}
1841
1842
void XMLCALL
1843
0
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
1844
0
  if (parser == NULL)
1845
0
    return;
1846
0
  if (arg)
1847
0
    parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
1848
0
  else
1849
0
    parser->m_externalEntityRefHandlerArg = parser;
1850
0
}
1851
1852
void XMLCALL
1853
XML_SetSkippedEntityHandler(XML_Parser parser,
1854
0
                            XML_SkippedEntityHandler handler) {
1855
0
  if (parser != NULL)
1856
0
    parser->m_skippedEntityHandler = handler;
1857
0
}
1858
1859
void XMLCALL
1860
XML_SetUnknownEncodingHandler(XML_Parser parser,
1861
0
                              XML_UnknownEncodingHandler handler, void *data) {
1862
0
  if (parser == NULL)
1863
0
    return;
1864
0
  parser->m_unknownEncodingHandler = handler;
1865
0
  parser->m_unknownEncodingHandlerData = data;
1866
0
}
1867
1868
void XMLCALL
1869
0
XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
1870
0
  if (parser != NULL)
1871
0
    parser->m_elementDeclHandler = eldecl;
1872
0
}
1873
1874
void XMLCALL
1875
0
XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
1876
0
  if (parser != NULL)
1877
0
    parser->m_attlistDeclHandler = attdecl;
1878
0
}
1879
1880
void XMLCALL
1881
0
XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
1882
0
  if (parser != NULL)
1883
0
    parser->m_entityDeclHandler = handler;
1884
0
}
1885
1886
void XMLCALL
1887
0
XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
1888
0
  if (parser != NULL)
1889
0
    parser->m_xmlDeclHandler = handler;
1890
0
}
1891
1892
int XMLCALL
1893
XML_SetParamEntityParsing(XML_Parser parser,
1894
0
                          enum XML_ParamEntityParsing peParsing) {
1895
0
  if (parser == NULL)
1896
0
    return 0;
1897
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1898
0
  if (parser->m_parsingStatus.parsing == XML_PARSING
1899
0
      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1900
0
    return 0;
1901
0
#ifdef XML_DTD
1902
0
  parser->m_paramEntityParsing = peParsing;
1903
0
  return 1;
1904
#else
1905
  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1906
#endif
1907
0
}
1908
1909
int XMLCALL
1910
121k
XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
1911
121k
  if (parser == NULL)
1912
0
    return 0;
1913
121k
  if (parser->m_parentParser)
1914
40.4k
    return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1915
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1916
80.8k
  if (parser->m_parsingStatus.parsing == XML_PARSING
1917
80.8k
      || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1918
23.1k
    return 0;
1919
57.6k
  parser->m_hash_secret_salt = hash_salt;
1920
57.6k
  return 1;
1921
80.8k
}
1922
1923
enum XML_Status XMLCALL
1924
0
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
1925
0
  if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1926
0
    if (parser != NULL)
1927
0
      parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
1928
0
    return XML_STATUS_ERROR;
1929
0
  }
1930
0
  switch (parser->m_parsingStatus.parsing) {
1931
0
  case XML_SUSPENDED:
1932
0
    parser->m_errorCode = XML_ERROR_SUSPENDED;
1933
0
    return XML_STATUS_ERROR;
1934
0
  case XML_FINISHED:
1935
0
    parser->m_errorCode = XML_ERROR_FINISHED;
1936
0
    return XML_STATUS_ERROR;
1937
0
  case XML_INITIALIZED:
1938
0
    if (parser->m_parentParser == NULL && ! startParsing(parser)) {
1939
0
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
1940
0
      return XML_STATUS_ERROR;
1941
0
    }
1942
    /* fall through */
1943
0
  default:
1944
0
    parser->m_parsingStatus.parsing = XML_PARSING;
1945
0
  }
1946
1947
#if XML_CONTEXT_BYTES == 0
1948
  if (parser->m_bufferPtr == parser->m_bufferEnd) {
1949
    const char *end;
1950
    int nLeftOver;
1951
    enum XML_Status result;
1952
    /* Detect overflow (a+b > MAX <==> b > MAX-a) */
1953
    if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
1954
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
1955
      parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1956
      parser->m_processor = errorProcessor;
1957
      return XML_STATUS_ERROR;
1958
    }
1959
    // though this isn't a buffer request, we assume that `len` is the app's
1960
    // preferred buffer fill size, and therefore save it here.
1961
    parser->m_lastBufferRequestSize = len;
1962
    parser->m_parseEndByteIndex += len;
1963
    parser->m_positionPtr = s;
1964
    parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
1965
1966
    parser->m_errorCode
1967
        = callProcessor(parser, s, parser->m_parseEndPtr = s + len, &end);
1968
1969
    if (parser->m_errorCode != XML_ERROR_NONE) {
1970
      parser->m_eventEndPtr = parser->m_eventPtr;
1971
      parser->m_processor = errorProcessor;
1972
      return XML_STATUS_ERROR;
1973
    } else {
1974
      switch (parser->m_parsingStatus.parsing) {
1975
      case XML_SUSPENDED:
1976
        result = XML_STATUS_SUSPENDED;
1977
        break;
1978
      case XML_INITIALIZED:
1979
      case XML_PARSING:
1980
        if (isFinal) {
1981
          parser->m_parsingStatus.parsing = XML_FINISHED;
1982
          return XML_STATUS_OK;
1983
        }
1984
      /* fall through */
1985
      default:
1986
        result = XML_STATUS_OK;
1987
      }
1988
    }
1989
1990
    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,
1991
                      &parser->m_position);
1992
    nLeftOver = s + len - end;
1993
    if (nLeftOver) {
1994
      // Back up and restore the parsing status to avoid XML_ERROR_SUSPENDED
1995
      // (and XML_ERROR_FINISHED) from XML_GetBuffer.
1996
      const enum XML_Parsing originalStatus = parser->m_parsingStatus.parsing;
1997
      parser->m_parsingStatus.parsing = XML_PARSING;
1998
      void *const temp = XML_GetBuffer(parser, nLeftOver);
1999
      parser->m_parsingStatus.parsing = originalStatus;
2000
      // GetBuffer may have overwritten this, but we want to remember what the
2001
      // app requested, not how many bytes were left over after parsing.
2002
      parser->m_lastBufferRequestSize = len;
2003
      if (temp == NULL) {
2004
        // NOTE: parser->m_errorCode has already been set by XML_GetBuffer().
2005
        parser->m_eventPtr = parser->m_eventEndPtr = NULL;
2006
        parser->m_processor = errorProcessor;
2007
        return XML_STATUS_ERROR;
2008
      }
2009
      // Since we know that the buffer was empty and XML_CONTEXT_BYTES is 0, we
2010
      // don't have any data to preserve, and can copy straight into the start
2011
      // of the buffer rather than the GetBuffer return pointer (which may be
2012
      // pointing further into the allocated buffer).
2013
      memcpy(parser->m_buffer, end, nLeftOver);
2014
    }
2015
    parser->m_bufferPtr = parser->m_buffer;
2016
    parser->m_bufferEnd = parser->m_buffer + nLeftOver;
2017
    parser->m_positionPtr = parser->m_bufferPtr;
2018
    parser->m_parseEndPtr = parser->m_bufferEnd;
2019
    parser->m_eventPtr = parser->m_bufferPtr;
2020
    parser->m_eventEndPtr = parser->m_bufferPtr;
2021
    return result;
2022
  }
2023
#endif /* XML_CONTEXT_BYTES == 0 */
2024
0
  void *buff = XML_GetBuffer(parser, len);
2025
0
  if (buff == NULL)
2026
0
    return XML_STATUS_ERROR;
2027
0
  if (len > 0) {
2028
0
    assert(s != NULL); // make sure s==NULL && len!=0 was rejected above
2029
0
    memcpy(buff, s, len);
2030
0
  }
2031
0
  return XML_ParseBuffer(parser, len, isFinal);
2032
0
}
2033
2034
enum XML_Status XMLCALL
2035
161k
XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
2036
161k
  const char *start;
2037
161k
  enum XML_Status result = XML_STATUS_OK;
2038
2039
161k
  if (parser == NULL)
2040
0
    return XML_STATUS_ERROR;
2041
161k
  switch (parser->m_parsingStatus.parsing) {
2042
0
  case XML_SUSPENDED:
2043
0
    parser->m_errorCode = XML_ERROR_SUSPENDED;
2044
0
    return XML_STATUS_ERROR;
2045
0
  case XML_FINISHED:
2046
0
    parser->m_errorCode = XML_ERROR_FINISHED;
2047
0
    return XML_STATUS_ERROR;
2048
80.8k
  case XML_INITIALIZED:
2049
    /* Has someone called XML_GetBuffer successfully before? */
2050
80.8k
    if (! parser->m_bufferPtr) {
2051
0
      parser->m_errorCode = XML_ERROR_NO_BUFFER;
2052
0
      return XML_STATUS_ERROR;
2053
0
    }
2054
2055
80.8k
    if (parser->m_parentParser == NULL && ! startParsing(parser)) {
2056
0
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
2057
0
      return XML_STATUS_ERROR;
2058
0
    }
2059
    /* fall through */
2060
161k
  default:
2061
161k
    parser->m_parsingStatus.parsing = XML_PARSING;
2062
161k
  }
2063
2064
161k
  start = parser->m_bufferPtr;
2065
161k
  parser->m_positionPtr = start;
2066
161k
  parser->m_bufferEnd += len;
2067
161k
  parser->m_parseEndPtr = parser->m_bufferEnd;
2068
161k
  parser->m_parseEndByteIndex += len;
2069
161k
  parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
2070
2071
161k
  parser->m_errorCode = callProcessor(parser, start, parser->m_parseEndPtr,
2072
161k
                                      &parser->m_bufferPtr);
2073
2074
161k
  if (parser->m_errorCode != XML_ERROR_NONE) {
2075
129k
    parser->m_eventEndPtr = parser->m_eventPtr;
2076
129k
    parser->m_processor = errorProcessor;
2077
129k
    return XML_STATUS_ERROR;
2078
129k
  } else {
2079
31.7k
    switch (parser->m_parsingStatus.parsing) {
2080
202
    case XML_SUSPENDED:
2081
202
      result = XML_STATUS_SUSPENDED;
2082
202
      break;
2083
0
    case XML_INITIALIZED:
2084
31.5k
    case XML_PARSING:
2085
31.5k
      if (isFinal) {
2086
1.95k
        parser->m_parsingStatus.parsing = XML_FINISHED;
2087
1.95k
        return result;
2088
1.95k
      }
2089
29.5k
    default:; /* should not happen */
2090
31.7k
    }
2091
31.7k
  }
2092
2093
29.7k
  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2094
29.7k
                    parser->m_bufferPtr, &parser->m_position);
2095
29.7k
  parser->m_positionPtr = parser->m_bufferPtr;
2096
29.7k
  return result;
2097
161k
}
2098
2099
void *XMLCALL
2100
161k
XML_GetBuffer(XML_Parser parser, int len) {
2101
161k
  if (parser == NULL)
2102
0
    return NULL;
2103
161k
  if (len < 0) {
2104
0
    parser->m_errorCode = XML_ERROR_NO_MEMORY;
2105
0
    return NULL;
2106
0
  }
2107
161k
  switch (parser->m_parsingStatus.parsing) {
2108
73
  case XML_SUSPENDED:
2109
73
    parser->m_errorCode = XML_ERROR_SUSPENDED;
2110
73
    return NULL;
2111
39
  case XML_FINISHED:
2112
39
    parser->m_errorCode = XML_ERROR_FINISHED;
2113
39
    return NULL;
2114
161k
  default:;
2115
161k
  }
2116
2117
  // whether or not the request succeeds, `len` seems to be the app's preferred
2118
  // buffer fill size; remember it.
2119
161k
  parser->m_lastBufferRequestSize = len;
2120
161k
  if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)
2121
161k
      || parser->m_buffer == NULL) {
2122
92.2k
#if XML_CONTEXT_BYTES > 0
2123
92.2k
    int keep;
2124
92.2k
#endif /* XML_CONTEXT_BYTES > 0 */
2125
    /* Do not invoke signed arithmetic overflow: */
2126
92.2k
    int neededSize = (int)((unsigned)len
2127
92.2k
                           + (unsigned)EXPAT_SAFE_PTR_DIFF(
2128
92.2k
                               parser->m_bufferEnd, parser->m_bufferPtr));
2129
92.2k
    if (neededSize < 0) {
2130
0
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
2131
0
      return NULL;
2132
0
    }
2133
92.2k
#if XML_CONTEXT_BYTES > 0
2134
92.2k
    keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer);
2135
92.2k
    if (keep > XML_CONTEXT_BYTES)
2136
1.15k
      keep = XML_CONTEXT_BYTES;
2137
    /* Detect and prevent integer overflow */
2138
92.2k
    if (keep > INT_MAX - neededSize) {
2139
0
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
2140
0
      return NULL;
2141
0
    }
2142
92.2k
    neededSize += keep;
2143
92.2k
#endif /* XML_CONTEXT_BYTES > 0 */
2144
92.2k
    if (parser->m_buffer && parser->m_bufferPtr
2145
92.2k
        && neededSize
2146
11.4k
               <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) {
2147
618
#if XML_CONTEXT_BYTES > 0
2148
618
      if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) {
2149
618
        int offset
2150
618
            = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)
2151
618
              - keep;
2152
        /* The buffer pointers cannot be NULL here; we have at least some bytes
2153
         * in the buffer */
2154
618
        memmove(parser->m_buffer, &parser->m_buffer[offset],
2155
618
                parser->m_bufferEnd - parser->m_bufferPtr + keep);
2156
618
        parser->m_bufferEnd -= offset;
2157
618
        parser->m_bufferPtr -= offset;
2158
618
      }
2159
#else
2160
      memmove(parser->m_buffer, parser->m_bufferPtr,
2161
              EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
2162
      parser->m_bufferEnd
2163
          = parser->m_buffer
2164
            + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2165
      parser->m_bufferPtr = parser->m_buffer;
2166
#endif /* XML_CONTEXT_BYTES > 0 */
2167
91.6k
    } else {
2168
91.6k
      char *newBuf;
2169
91.6k
      int bufferSize
2170
91.6k
          = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer);
2171
91.6k
      if (bufferSize == 0)
2172
80.8k
        bufferSize = INIT_BUFFER_SIZE;
2173
135k
      do {
2174
        /* Do not invoke signed arithmetic overflow: */
2175
135k
        bufferSize = (int)(2U * (unsigned)bufferSize);
2176
135k
      } while (bufferSize < neededSize && bufferSize > 0);
2177
91.6k
      if (bufferSize <= 0) {
2178
0
        parser->m_errorCode = XML_ERROR_NO_MEMORY;
2179
0
        return NULL;
2180
0
      }
2181
91.6k
      newBuf = (char *)MALLOC(parser, bufferSize);
2182
91.6k
      if (newBuf == 0) {
2183
0
        parser->m_errorCode = XML_ERROR_NO_MEMORY;
2184
0
        return NULL;
2185
0
      }
2186
91.6k
      parser->m_bufferLim = newBuf + bufferSize;
2187
91.6k
#if XML_CONTEXT_BYTES > 0
2188
91.6k
      if (parser->m_bufferPtr) {
2189
10.7k
        memcpy(newBuf, &parser->m_bufferPtr[-keep],
2190
10.7k
               EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2191
10.7k
                   + keep);
2192
10.7k
        FREE(parser, parser->m_buffer);
2193
10.7k
        parser->m_buffer = newBuf;
2194
10.7k
        parser->m_bufferEnd
2195
10.7k
            = parser->m_buffer
2196
10.7k
              + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
2197
10.7k
              + keep;
2198
10.7k
        parser->m_bufferPtr = parser->m_buffer + keep;
2199
80.8k
      } else {
2200
        /* This must be a brand new buffer with no data in it yet */
2201
80.8k
        parser->m_bufferEnd = newBuf;
2202
80.8k
        parser->m_bufferPtr = parser->m_buffer = newBuf;
2203
80.8k
      }
2204
#else
2205
      if (parser->m_bufferPtr) {
2206
        memcpy(newBuf, parser->m_bufferPtr,
2207
               EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
2208
        FREE(parser, parser->m_buffer);
2209
        parser->m_bufferEnd
2210
            = newBuf
2211
              + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
2212
      } else {
2213
        /* This must be a brand new buffer with no data in it yet */
2214
        parser->m_bufferEnd = newBuf;
2215
      }
2216
      parser->m_bufferPtr = parser->m_buffer = newBuf;
2217
#endif /* XML_CONTEXT_BYTES > 0 */
2218
91.6k
    }
2219
92.2k
    parser->m_eventPtr = parser->m_eventEndPtr = NULL;
2220
92.2k
    parser->m_positionPtr = NULL;
2221
92.2k
  }
2222
161k
  return parser->m_bufferEnd;
2223
161k
}
2224
2225
enum XML_Status XMLCALL
2226
778
XML_StopParser(XML_Parser parser, XML_Bool resumable) {
2227
778
  if (parser == NULL)
2228
0
    return XML_STATUS_ERROR;
2229
778
  switch (parser->m_parsingStatus.parsing) {
2230
324
  case XML_SUSPENDED:
2231
324
    if (resumable) {
2232
305
      parser->m_errorCode = XML_ERROR_SUSPENDED;
2233
305
      return XML_STATUS_ERROR;
2234
305
    }
2235
19
    parser->m_parsingStatus.parsing = XML_FINISHED;
2236
19
    break;
2237
210
  case XML_FINISHED:
2238
210
    parser->m_errorCode = XML_ERROR_FINISHED;
2239
210
    return XML_STATUS_ERROR;
2240
244
  default:
2241
244
    if (resumable) {
2242
221
#ifdef XML_DTD
2243
221
      if (parser->m_isParamEntity) {
2244
0
        parser->m_errorCode = XML_ERROR_SUSPEND_PE;
2245
0
        return XML_STATUS_ERROR;
2246
0
      }
2247
221
#endif
2248
221
      parser->m_parsingStatus.parsing = XML_SUSPENDED;
2249
221
    } else
2250
23
      parser->m_parsingStatus.parsing = XML_FINISHED;
2251
778
  }
2252
263
  return XML_STATUS_OK;
2253
778
}
2254
2255
enum XML_Status XMLCALL
2256
0
XML_ResumeParser(XML_Parser parser) {
2257
0
  enum XML_Status result = XML_STATUS_OK;
2258
2259
0
  if (parser == NULL)
2260
0
    return XML_STATUS_ERROR;
2261
0
  if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
2262
0
    parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
2263
0
    return XML_STATUS_ERROR;
2264
0
  }
2265
0
  parser->m_parsingStatus.parsing = XML_PARSING;
2266
2267
0
  parser->m_errorCode = callProcessor(
2268
0
      parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
2269
2270
0
  if (parser->m_errorCode != XML_ERROR_NONE) {
2271
0
    parser->m_eventEndPtr = parser->m_eventPtr;
2272
0
    parser->m_processor = errorProcessor;
2273
0
    return XML_STATUS_ERROR;
2274
0
  } else {
2275
0
    switch (parser->m_parsingStatus.parsing) {
2276
0
    case XML_SUSPENDED:
2277
0
      result = XML_STATUS_SUSPENDED;
2278
0
      break;
2279
0
    case XML_INITIALIZED:
2280
0
    case XML_PARSING:
2281
0
      if (parser->m_parsingStatus.finalBuffer) {
2282
0
        parser->m_parsingStatus.parsing = XML_FINISHED;
2283
0
        return result;
2284
0
      }
2285
0
    default:;
2286
0
    }
2287
0
  }
2288
2289
0
  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2290
0
                    parser->m_bufferPtr, &parser->m_position);
2291
0
  parser->m_positionPtr = parser->m_bufferPtr;
2292
0
  return result;
2293
0
}
2294
2295
void XMLCALL
2296
0
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
2297
0
  if (parser == NULL)
2298
0
    return;
2299
0
  assert(status != NULL);
2300
0
  *status = parser->m_parsingStatus;
2301
0
}
2302
2303
enum XML_Error XMLCALL
2304
78.6k
XML_GetErrorCode(XML_Parser parser) {
2305
78.6k
  if (parser == NULL)
2306
0
    return XML_ERROR_INVALID_ARGUMENT;
2307
78.6k
  return parser->m_errorCode;
2308
78.6k
}
2309
2310
XML_Index XMLCALL
2311
0
XML_GetCurrentByteIndex(XML_Parser parser) {
2312
0
  if (parser == NULL)
2313
0
    return -1;
2314
0
  if (parser->m_eventPtr)
2315
0
    return (XML_Index)(parser->m_parseEndByteIndex
2316
0
                       - (parser->m_parseEndPtr - parser->m_eventPtr));
2317
0
  return -1;
2318
0
}
2319
2320
int XMLCALL
2321
0
XML_GetCurrentByteCount(XML_Parser parser) {
2322
0
  if (parser == NULL)
2323
0
    return 0;
2324
0
  if (parser->m_eventEndPtr && parser->m_eventPtr)
2325
0
    return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
2326
0
  return 0;
2327
0
}
2328
2329
const char *XMLCALL
2330
0
XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
2331
0
#if XML_CONTEXT_BYTES > 0
2332
0
  if (parser == NULL)
2333
0
    return NULL;
2334
0
  if (parser->m_eventPtr && parser->m_buffer) {
2335
0
    if (offset != NULL)
2336
0
      *offset = (int)(parser->m_eventPtr - parser->m_buffer);
2337
0
    if (size != NULL)
2338
0
      *size = (int)(parser->m_bufferEnd - parser->m_buffer);
2339
0
    return parser->m_buffer;
2340
0
  }
2341
#else
2342
  (void)parser;
2343
  (void)offset;
2344
  (void)size;
2345
#endif /* XML_CONTEXT_BYTES > 0 */
2346
0
  return (const char *)0;
2347
0
}
2348
2349
XML_Size XMLCALL
2350
80.7k
XML_GetCurrentLineNumber(XML_Parser parser) {
2351
80.7k
  if (parser == NULL)
2352
0
    return 0;
2353
80.7k
  if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
2354
68.7k
    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2355
68.7k
                      parser->m_eventPtr, &parser->m_position);
2356
68.7k
    parser->m_positionPtr = parser->m_eventPtr;
2357
68.7k
  }
2358
80.7k
  return parser->m_position.lineNumber + 1;
2359
80.7k
}
2360
2361
XML_Size XMLCALL
2362
0
XML_GetCurrentColumnNumber(XML_Parser parser) {
2363
0
  if (parser == NULL)
2364
0
    return 0;
2365
0
  if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
2366
0
    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,
2367
0
                      parser->m_eventPtr, &parser->m_position);
2368
0
    parser->m_positionPtr = parser->m_eventPtr;
2369
0
  }
2370
0
  return parser->m_position.columnNumber;
2371
0
}
2372
2373
void XMLCALL
2374
0
XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
2375
0
  if (parser != NULL)
2376
0
    FREE(parser, model);
2377
0
}
2378
2379
void *XMLCALL
2380
0
XML_MemMalloc(XML_Parser parser, size_t size) {
2381
0
  if (parser == NULL)
2382
0
    return NULL;
2383
0
  return MALLOC(parser, size);
2384
0
}
2385
2386
void *XMLCALL
2387
0
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
2388
0
  if (parser == NULL)
2389
0
    return NULL;
2390
0
  return REALLOC(parser, ptr, size);
2391
0
}
2392
2393
void XMLCALL
2394
0
XML_MemFree(XML_Parser parser, void *ptr) {
2395
0
  if (parser != NULL)
2396
0
    FREE(parser, ptr);
2397
0
}
2398
2399
void XMLCALL
2400
0
XML_DefaultCurrent(XML_Parser parser) {
2401
0
  if (parser == NULL)
2402
0
    return;
2403
0
  if (parser->m_defaultHandler) {
2404
0
    if (parser->m_openInternalEntities)
2405
0
      reportDefault(parser, parser->m_internalEncoding,
2406
0
                    parser->m_openInternalEntities->internalEventPtr,
2407
0
                    parser->m_openInternalEntities->internalEventEndPtr);
2408
0
    else
2409
0
      reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
2410
0
                    parser->m_eventEndPtr);
2411
0
  }
2412
0
}
2413
2414
const XML_LChar *XMLCALL
2415
78.6k
XML_ErrorString(enum XML_Error code) {
2416
78.6k
  switch (code) {
2417
0
  case XML_ERROR_NONE:
2418
0
    return NULL;
2419
0
  case XML_ERROR_NO_MEMORY:
2420
0
    return XML_L("out of memory");
2421
19.5k
  case XML_ERROR_SYNTAX:
2422
19.5k
    return XML_L("syntax error");
2423
3.35k
  case XML_ERROR_NO_ELEMENTS:
2424
3.35k
    return XML_L("no element found");
2425
44.9k
  case XML_ERROR_INVALID_TOKEN:
2426
44.9k
    return XML_L("not well-formed (invalid token)");
2427
2.14k
  case XML_ERROR_UNCLOSED_TOKEN:
2428
2.14k
    return XML_L("unclosed token");
2429
1.16k
  case XML_ERROR_PARTIAL_CHAR:
2430
1.16k
    return XML_L("partial character");
2431
346
  case XML_ERROR_TAG_MISMATCH:
2432
346
    return XML_L("mismatched tag");
2433
651
  case XML_ERROR_DUPLICATE_ATTRIBUTE:
2434
651
    return XML_L("duplicate attribute");
2435
334
  case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
2436
334
    return XML_L("junk after document element");
2437
399
  case XML_ERROR_PARAM_ENTITY_REF:
2438
399
    return XML_L("illegal parameter entity reference");
2439
631
  case XML_ERROR_UNDEFINED_ENTITY:
2440
631
    return XML_L("undefined entity");
2441
29
  case XML_ERROR_RECURSIVE_ENTITY_REF:
2442
29
    return XML_L("recursive entity reference");
2443
1.87k
  case XML_ERROR_ASYNC_ENTITY:
2444
1.87k
    return XML_L("asynchronous entity");
2445
396
  case XML_ERROR_BAD_CHAR_REF:
2446
396
    return XML_L("reference to invalid character number");
2447
7
  case XML_ERROR_BINARY_ENTITY_REF:
2448
7
    return XML_L("reference to binary entity");
2449
4
  case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
2450
4
    return XML_L("reference to external entity in attribute");
2451
121
  case XML_ERROR_MISPLACED_XML_PI:
2452
121
    return XML_L("XML or text declaration not at start of entity");
2453
92
  case XML_ERROR_UNKNOWN_ENCODING:
2454
92
    return XML_L("unknown encoding");
2455
5
  case XML_ERROR_INCORRECT_ENCODING:
2456
5
    return XML_L("encoding specified in XML declaration is incorrect");
2457
964
  case XML_ERROR_UNCLOSED_CDATA_SECTION:
2458
964
    return XML_L("unclosed CDATA section");
2459
0
  case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
2460
0
    return XML_L("error in processing external entity reference");
2461
0
  case XML_ERROR_NOT_STANDALONE:
2462
0
    return XML_L("document is not standalone");
2463
0
  case XML_ERROR_UNEXPECTED_STATE:
2464
0
    return XML_L("unexpected parser state - please send a bug report");
2465
0
  case XML_ERROR_ENTITY_DECLARED_IN_PE:
2466
0
    return XML_L("entity declared in parameter entity");
2467
0
  case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
2468
0
    return XML_L("requested feature requires XML_DTD support in Expat");
2469
0
  case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
2470
0
    return XML_L("cannot change setting once parsing has begun");
2471
  /* Added in 1.95.7. */
2472
146
  case XML_ERROR_UNBOUND_PREFIX:
2473
146
    return XML_L("unbound prefix");
2474
  /* Added in 1.95.8. */
2475
3
  case XML_ERROR_UNDECLARING_PREFIX:
2476
3
    return XML_L("must not undeclare prefix");
2477
86
  case XML_ERROR_INCOMPLETE_PE:
2478
86
    return XML_L("incomplete markup in parameter entity");
2479
294
  case XML_ERROR_XML_DECL:
2480
294
    return XML_L("XML declaration not well-formed");
2481
466
  case XML_ERROR_TEXT_DECL:
2482
466
    return XML_L("text declaration not well-formed");
2483
558
  case XML_ERROR_PUBLICID:
2484
558
    return XML_L("illegal character(s) in public id");
2485
0
  case XML_ERROR_SUSPENDED:
2486
0
    return XML_L("parser suspended");
2487
0
  case XML_ERROR_NOT_SUSPENDED:
2488
0
    return XML_L("parser not suspended");
2489
3
  case XML_ERROR_ABORTED:
2490
3
    return XML_L("parsing aborted");
2491
0
  case XML_ERROR_FINISHED:
2492
0
    return XML_L("parsing finished");
2493
0
  case XML_ERROR_SUSPEND_PE:
2494
0
    return XML_L("cannot suspend in external parameter entity");
2495
  /* Added in 2.0.0. */
2496
23
  case XML_ERROR_RESERVED_PREFIX_XML:
2497
23
    return XML_L(
2498
0
        "reserved prefix (xml) must not be undeclared or bound to another namespace name");
2499
1
  case XML_ERROR_RESERVED_PREFIX_XMLNS:
2500
1
    return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
2501
0
  case XML_ERROR_RESERVED_NAMESPACE_URI:
2502
0
    return XML_L(
2503
0
        "prefix must not be bound to one of the reserved namespace names");
2504
  /* Added in 2.2.5. */
2505
0
  case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
2506
0
    return XML_L("invalid argument");
2507
    /* Added in 2.3.0. */
2508
0
  case XML_ERROR_NO_BUFFER:
2509
0
    return XML_L(
2510
0
        "a successful prior call to function XML_GetBuffer is required");
2511
  /* Added in 2.4.0. */
2512
73
  case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:
2513
73
    return XML_L(
2514
78.6k
        "limit on input amplification factor (from DTD and entities) breached");
2515
78.6k
  }
2516
0
  return NULL;
2517
78.6k
}
2518
2519
const XML_LChar *XMLCALL
2520
0
XML_ExpatVersion(void) {
2521
  /* V1 is used to string-ize the version number. However, it would
2522
     string-ize the actual version macro *names* unless we get them
2523
     substituted before being passed to V1. CPP is defined to expand
2524
     a macro, then rescan for more expansions. Thus, we use V2 to expand
2525
     the version macros, then CPP will expand the resulting V1() macro
2526
     with the correct numerals. */
2527
  /* ### I'm assuming cpp is portable in this respect... */
2528
2529
0
#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
2530
0
#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
2531
2532
0
  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2533
2534
0
#undef V1
2535
0
#undef V2
2536
0
}
2537
2538
XML_Expat_Version XMLCALL
2539
0
XML_ExpatVersionInfo(void) {
2540
0
  XML_Expat_Version version;
2541
2542
0
  version.major = XML_MAJOR_VERSION;
2543
0
  version.minor = XML_MINOR_VERSION;
2544
0
  version.micro = XML_MICRO_VERSION;
2545
2546
0
  return version;
2547
0
}
2548
2549
const XML_Feature *XMLCALL
2550
0
XML_GetFeatureList(void) {
2551
0
  static const XML_Feature features[] = {
2552
0
      {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2553
0
       sizeof(XML_Char)},
2554
0
      {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2555
0
       sizeof(XML_LChar)},
2556
#ifdef XML_UNICODE
2557
      {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
2558
#endif
2559
#ifdef XML_UNICODE_WCHAR_T
2560
      {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
2561
#endif
2562
0
#ifdef XML_DTD
2563
0
      {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
2564
0
#endif
2565
0
#if XML_CONTEXT_BYTES > 0
2566
0
      {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2567
0
       XML_CONTEXT_BYTES},
2568
0
#endif
2569
#ifdef XML_MIN_SIZE
2570
      {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
2571
#endif
2572
0
#ifdef XML_NS
2573
0
      {XML_FEATURE_NS, XML_L("XML_NS"), 0},
2574
0
#endif
2575
#ifdef XML_LARGE_SIZE
2576
      {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
2577
#endif
2578
#ifdef XML_ATTR_INFO
2579
      {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
2580
#endif
2581
0
#if XML_GE == 1
2582
      /* Added in Expat 2.4.0 for XML_DTD defined and
2583
       * added in Expat 2.6.0 for XML_GE == 1. */
2584
0
      {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
2585
0
       XML_L("XML_BLAP_MAX_AMP"),
2586
0
       (long int)
2587
0
           EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT},
2588
0
      {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
2589
0
       XML_L("XML_BLAP_ACT_THRES"),
2590
0
       EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT},
2591
      /* Added in Expat 2.6.0. */
2592
0
      {XML_FEATURE_GE, XML_L("XML_GE"), 0},
2593
0
#endif
2594
0
      {XML_FEATURE_END, NULL, 0}};
2595
2596
0
  return features;
2597
0
}
2598
2599
#if XML_GE == 1
2600
XML_Bool XMLCALL
2601
XML_SetBillionLaughsAttackProtectionMaximumAmplification(
2602
0
    XML_Parser parser, float maximumAmplificationFactor) {
2603
0
  if ((parser == NULL) || (parser->m_parentParser != NULL)
2604
0
      || isnan(maximumAmplificationFactor)
2605
0
      || (maximumAmplificationFactor < 1.0f)) {
2606
0
    return XML_FALSE;
2607
0
  }
2608
0
  parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor;
2609
0
  return XML_TRUE;
2610
0
}
2611
2612
XML_Bool XMLCALL
2613
XML_SetBillionLaughsAttackProtectionActivationThreshold(
2614
0
    XML_Parser parser, unsigned long long activationThresholdBytes) {
2615
0
  if ((parser == NULL) || (parser->m_parentParser != NULL)) {
2616
0
    return XML_FALSE;
2617
0
  }
2618
0
  parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
2619
0
  return XML_TRUE;
2620
0
}
2621
#endif /* XML_GE == 1 */
2622
2623
XML_Bool XMLCALL
2624
0
XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled) {
2625
0
  if (parser != NULL && (enabled == XML_TRUE || enabled == XML_FALSE)) {
2626
0
    parser->m_reparseDeferralEnabled = enabled;
2627
0
    return XML_TRUE;
2628
0
  }
2629
0
  return XML_FALSE;
2630
0
}
2631
2632
/* Initially tag->rawName always points into the parse buffer;
2633
   for those TAG instances opened while the current parse buffer was
2634
   processed, and not yet closed, we need to store tag->rawName in a more
2635
   permanent location, since the parse buffer is about to be discarded.
2636
*/
2637
static XML_Bool
2638
16.4k
storeRawNames(XML_Parser parser) {
2639
16.4k
  TAG *tag = parser->m_tagStack;
2640
895k
  while (tag) {
2641
879k
    int bufSize;
2642
879k
    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2643
879k
    size_t rawNameLen;
2644
879k
    char *rawNameBuf = tag->buf + nameLen;
2645
    /* Stop if already stored.  Since m_tagStack is a stack, we can stop
2646
       at the first entry that has already been copied; everything
2647
       below it in the stack is already been accounted for in a
2648
       previous call to this function.
2649
    */
2650
879k
    if (tag->rawName == rawNameBuf)
2651
115
      break;
2652
    /* For reuse purposes we need to ensure that the
2653
       size of tag->buf is a multiple of sizeof(XML_Char).
2654
    */
2655
879k
    rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2656
    /* Detect and prevent integer overflow. */
2657
879k
    if (rawNameLen > (size_t)INT_MAX - nameLen)
2658
0
      return XML_FALSE;
2659
879k
    bufSize = nameLen + (int)rawNameLen;
2660
879k
    if (bufSize > tag->bufEnd - tag->buf) {
2661
8.05k
      char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2662
8.05k
      if (temp == NULL)
2663
0
        return XML_FALSE;
2664
      /* if tag->name.str points to tag->buf (only when namespace
2665
         processing is off) then we have to update it
2666
      */
2667
8.05k
      if (tag->name.str == (XML_Char *)tag->buf)
2668
6.11k
        tag->name.str = (XML_Char *)temp;
2669
      /* if tag->name.localPart is set (when namespace processing is on)
2670
         then update it as well, since it will always point into tag->buf
2671
      */
2672
8.05k
      if (tag->name.localPart)
2673
1.93k
        tag->name.localPart
2674
1.93k
            = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
2675
8.05k
      tag->buf = temp;
2676
8.05k
      tag->bufEnd = temp + bufSize;
2677
8.05k
      rawNameBuf = temp + nameLen;
2678
8.05k
    }
2679
879k
    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2680
879k
    tag->rawName = rawNameBuf;
2681
879k
    tag = tag->parent;
2682
879k
  }
2683
16.4k
  return XML_TRUE;
2684
16.4k
}
2685
2686
static enum XML_Error PTRCALL
2687
contentProcessor(XML_Parser parser, const char *start, const char *end,
2688
21.5k
                 const char **endPtr) {
2689
21.5k
  enum XML_Error result = doContent(
2690
21.5k
      parser, 0, parser->m_encoding, start, end, endPtr,
2691
21.5k
      (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
2692
21.5k
  if (result == XML_ERROR_NONE) {
2693
8.25k
    if (! storeRawNames(parser))
2694
0
      return XML_ERROR_NO_MEMORY;
2695
8.25k
  }
2696
21.5k
  return result;
2697
21.5k
}
2698
2699
static enum XML_Error PTRCALL
2700
externalEntityInitProcessor(XML_Parser parser, const char *start,
2701
20.2k
                            const char *end, const char **endPtr) {
2702
20.2k
  enum XML_Error result = initializeEncoding(parser);
2703
20.2k
  if (result != XML_ERROR_NONE)
2704
0
    return result;
2705
20.2k
  parser->m_processor = externalEntityInitProcessor2;
2706
20.2k
  return externalEntityInitProcessor2(parser, start, end, endPtr);
2707
20.2k
}
2708
2709
static enum XML_Error PTRCALL
2710
externalEntityInitProcessor2(XML_Parser parser, const char *start,
2711
22.8k
                             const char *end, const char **endPtr) {
2712
22.8k
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
2713
22.8k
  int tok = XmlContentTok(parser->m_encoding, start, end, &next);
2714
22.8k
  switch (tok) {
2715
3.58k
  case XML_TOK_BOM:
2716
3.58k
#if XML_GE == 1
2717
3.58k
    if (! accountingDiffTolerated(parser, tok, start, next, __LINE__,
2718
3.58k
                                  XML_ACCOUNT_DIRECT)) {
2719
5
      accountingOnAbort(parser);
2720
5
      return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
2721
5
    }
2722
3.57k
#endif /* XML_GE == 1 */
2723
2724
    /* If we are at the end of the buffer, this would cause the next stage,
2725
       i.e. externalEntityInitProcessor3, to pass control directly to
2726
       doContent (by detecting XML_TOK_NONE) without processing any xml text
2727
       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2728
    */
2729
3.57k
    if (next == end && ! parser->m_parsingStatus.finalBuffer) {
2730
3
      *endPtr = next;
2731
3
      return XML_ERROR_NONE;
2732
3
    }
2733
3.57k
    start = next;
2734
3.57k
    break;
2735
2.40k
  case XML_TOK_PARTIAL:
2736
2.40k
    if (! parser->m_parsingStatus.finalBuffer) {
2737
2.20k
      *endPtr = start;
2738
2.20k
      return XML_ERROR_NONE;
2739
2.20k
    }
2740
202
    parser->m_eventPtr = start;
2741
202
    return XML_ERROR_UNCLOSED_TOKEN;
2742
465
  case XML_TOK_PARTIAL_CHAR:
2743
465
    if (! parser->m_parsingStatus.finalBuffer) {
2744
403
      *endPtr = start;
2745
403
      return XML_ERROR_NONE;
2746
403
    }
2747
62
    parser->m_eventPtr = start;
2748
62
    return XML_ERROR_PARTIAL_CHAR;
2749
22.8k
  }
2750
19.9k
  parser->m_processor = externalEntityInitProcessor3;
2751
19.9k
  return externalEntityInitProcessor3(parser, start, end, endPtr);
2752
22.8k
}
2753
2754
static enum XML_Error PTRCALL
2755
externalEntityInitProcessor3(XML_Parser parser, const char *start,
2756
20.2k
                             const char *end, const char **endPtr) {
2757
20.2k
  int tok;
2758
20.2k
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
2759
20.2k
  parser->m_eventPtr = start;
2760
20.2k
  tok = XmlContentTok(parser->m_encoding, start, end, &next);
2761
  /* Note: These bytes are accounted later in:
2762
           - processXmlDecl
2763
           - externalEntityContentProcessor
2764
  */
2765
20.2k
  parser->m_eventEndPtr = next;
2766
2767
20.2k
  switch (tok) {
2768
415
  case XML_TOK_XML_DECL: {
2769
415
    enum XML_Error result;
2770
415
    result = processXmlDecl(parser, 1, start, next);
2771
415
    if (result != XML_ERROR_NONE)
2772
269
      return result;
2773
146
    switch (parser->m_parsingStatus.parsing) {
2774
0
    case XML_SUSPENDED:
2775
0
      *endPtr = next;
2776
0
      return XML_ERROR_NONE;
2777
0
    case XML_FINISHED:
2778
0
      return XML_ERROR_ABORTED;
2779
146
    default:
2780
146
      start = next;
2781
146
    }
2782
146
  } break;
2783
253
  case XML_TOK_PARTIAL:
2784
253
    if (! parser->m_parsingStatus.finalBuffer) {
2785
241
      *endPtr = start;
2786
241
      return XML_ERROR_NONE;
2787
241
    }
2788
12
    return XML_ERROR_UNCLOSED_TOKEN;
2789
70
  case XML_TOK_PARTIAL_CHAR:
2790
70
    if (! parser->m_parsingStatus.finalBuffer) {
2791
69
      *endPtr = start;
2792
69
      return XML_ERROR_NONE;
2793
69
    }
2794
1
    return XML_ERROR_PARTIAL_CHAR;
2795
20.2k
  }
2796
19.6k
  parser->m_processor = externalEntityContentProcessor;
2797
19.6k
  parser->m_tagLevel = 1;
2798
19.6k
  return externalEntityContentProcessor(parser, start, end, endPtr);
2799
20.2k
}
2800
2801
static enum XML_Error PTRCALL
2802
externalEntityContentProcessor(XML_Parser parser, const char *start,
2803
25.6k
                               const char *end, const char **endPtr) {
2804
25.6k
  enum XML_Error result
2805
25.6k
      = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
2806
25.6k
                  (XML_Bool)! parser->m_parsingStatus.finalBuffer,
2807
25.6k
                  XML_ACCOUNT_ENTITY_EXPANSION);
2808
25.6k
  if (result == XML_ERROR_NONE) {
2809
8.18k
    if (! storeRawNames(parser))
2810
0
      return XML_ERROR_NO_MEMORY;
2811
8.18k
  }
2812
25.6k
  return result;
2813
25.6k
}
2814
2815
static enum XML_Error
2816
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
2817
          const char *s, const char *end, const char **nextPtr,
2818
1.70M
          XML_Bool haveMore, enum XML_Account account) {
2819
  /* save one level of indirection */
2820
1.70M
  DTD *const dtd = parser->m_dtd;
2821
2822
1.70M
  const char **eventPP;
2823
1.70M
  const char **eventEndPP;
2824
1.70M
  if (enc == parser->m_encoding) {
2825
47.1k
    eventPP = &parser->m_eventPtr;
2826
47.1k
    eventEndPP = &parser->m_eventEndPtr;
2827
1.65M
  } else {
2828
1.65M
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
2829
1.65M
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
2830
1.65M
  }
2831
1.70M
  *eventPP = s;
2832
2833
28.3M
  for (;;) {
2834
28.3M
    const char *next = s; /* XmlContentTok doesn't always set the last arg */
2835
28.3M
    int tok = XmlContentTok(enc, s, end, &next);
2836
28.3M
#if XML_GE == 1
2837
28.3M
    const char *accountAfter
2838
28.3M
        = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR))
2839
28.3M
              ? (haveMore ? s /* i.e. 0 bytes */ : end)
2840
28.3M
              : next;
2841
28.3M
    if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__,
2842
28.3M
                                  account)) {
2843
7
      accountingOnAbort(parser);
2844
7
      return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
2845
7
    }
2846
28.3M
#endif
2847
28.3M
    *eventEndPP = next;
2848
28.3M
    switch (tok) {
2849
344
    case XML_TOK_TRAILING_CR:
2850
344
      if (haveMore) {
2851
187
        *nextPtr = s;
2852
187
        return XML_ERROR_NONE;
2853
187
      }
2854
157
      *eventEndPP = end;
2855
157
      if (parser->m_characterDataHandler) {
2856
157
        XML_Char c = 0xA;
2857
157
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
2858
157
      } else if (parser->m_defaultHandler)
2859
0
        reportDefault(parser, enc, s, end);
2860
      /* We are at the end of the final buffer, should we check for
2861
         XML_SUSPENDED, XML_FINISHED?
2862
      */
2863
157
      if (startTagLevel == 0)
2864
42
        return XML_ERROR_NO_ELEMENTS;
2865
115
      if (parser->m_tagLevel != startTagLevel)
2866
45
        return XML_ERROR_ASYNC_ENTITY;
2867
70
      *nextPtr = end;
2868
70
      return XML_ERROR_NONE;
2869
1.66M
    case XML_TOK_NONE:
2870
1.66M
      if (haveMore) {
2871
5.57k
        *nextPtr = s;
2872
5.57k
        return XML_ERROR_NONE;
2873
5.57k
      }
2874
1.66M
      if (startTagLevel > 0) {
2875
1.65M
        if (parser->m_tagLevel != startTagLevel)
2876
1.75k
          return XML_ERROR_ASYNC_ENTITY;
2877
1.65M
        *nextPtr = s;
2878
1.65M
        return XML_ERROR_NONE;
2879
1.65M
      }
2880
2.95k
      return XML_ERROR_NO_ELEMENTS;
2881
20.9k
    case XML_TOK_INVALID:
2882
20.9k
      *eventPP = next;
2883
20.9k
      return XML_ERROR_INVALID_TOKEN;
2884
6.77k
    case XML_TOK_PARTIAL:
2885
6.77k
      if (haveMore) {
2886
5.93k
        *nextPtr = s;
2887
5.93k
        return XML_ERROR_NONE;
2888
5.93k
      }
2889
843
      return XML_ERROR_UNCLOSED_TOKEN;
2890
2.01k
    case XML_TOK_PARTIAL_CHAR:
2891
2.01k
      if (haveMore) {
2892
1.39k
        *nextPtr = s;
2893
1.39k
        return XML_ERROR_NONE;
2894
1.39k
      }
2895
620
      return XML_ERROR_PARTIAL_CHAR;
2896
1.68M
    case XML_TOK_ENTITY_REF: {
2897
1.68M
      const XML_Char *name;
2898
1.68M
      ENTITY *entity;
2899
1.68M
      XML_Char ch = (XML_Char)XmlPredefinedEntityName(
2900
1.68M
          enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
2901
1.68M
      if (ch) {
2902
9.49k
#if XML_GE == 1
2903
        /* NOTE: We are replacing 4-6 characters original input for 1 character
2904
         *       so there is no amplification and hence recording without
2905
         *       protection. */
2906
9.49k
        accountingDiffTolerated(parser, tok, (char *)&ch,
2907
9.49k
                                ((char *)&ch) + sizeof(XML_Char), __LINE__,
2908
9.49k
                                XML_ACCOUNT_ENTITY_EXPANSION);
2909
9.49k
#endif /* XML_GE == 1 */
2910
9.49k
        if (parser->m_characterDataHandler)
2911
9.49k
          parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
2912
0
        else if (parser->m_defaultHandler)
2913
0
          reportDefault(parser, enc, s, next);
2914
9.49k
        break;
2915
9.49k
      }
2916
1.67M
      name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
2917
1.67M
                             next - enc->minBytesPerChar);
2918
1.67M
      if (! name)
2919
0
        return XML_ERROR_NO_MEMORY;
2920
1.67M
      entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2921
1.67M
      poolDiscard(&dtd->pool);
2922
      /* First, determine if a check for an existing declaration is needed;
2923
         if yes, check that the entity exists, and that it is internal,
2924
         otherwise call the skipped entity or default handler.
2925
      */
2926
1.67M
      if (! dtd->hasParamEntityRefs || dtd->standalone) {
2927
1.64M
        if (! entity)
2928
538
          return XML_ERROR_UNDEFINED_ENTITY;
2929
1.64M
        else if (! entity->is_internal)
2930
0
          return XML_ERROR_ENTITY_DECLARED_IN_PE;
2931
1.64M
      } else if (! entity) {
2932
15.6k
        if (parser->m_skippedEntityHandler)
2933
0
          parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
2934
15.6k
        else if (parser->m_defaultHandler)
2935
0
          reportDefault(parser, enc, s, next);
2936
15.6k
        break;
2937
15.6k
      }
2938
1.65M
      if (entity->open)
2939
22
        return XML_ERROR_RECURSIVE_ENTITY_REF;
2940
1.65M
      if (entity->notation)
2941
3
        return XML_ERROR_BINARY_ENTITY_REF;
2942
1.65M
      if (entity->textPtr) {
2943
1.65M
        enum XML_Error result;
2944
1.65M
        if (! parser->m_defaultExpandInternalEntities) {
2945
0
          if (parser->m_skippedEntityHandler)
2946
0
            parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
2947
0
                                           0);
2948
0
          else if (parser->m_defaultHandler)
2949
0
            reportDefault(parser, enc, s, next);
2950
0
          break;
2951
0
        }
2952
1.65M
        result = processInternalEntity(parser, entity, XML_FALSE);
2953
1.65M
        if (result != XML_ERROR_NONE)
2954
1.93k
          return result;
2955
1.65M
      } else if (parser->m_externalEntityRefHandler) {
2956
0
        const XML_Char *context;
2957
0
        entity->open = XML_TRUE;
2958
0
        context = getContext(parser);
2959
0
        entity->open = XML_FALSE;
2960
0
        if (! context)
2961
0
          return XML_ERROR_NO_MEMORY;
2962
0
        if (! parser->m_externalEntityRefHandler(
2963
0
                parser->m_externalEntityRefHandlerArg, context, entity->base,
2964
0
                entity->systemId, entity->publicId))
2965
0
          return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2966
0
        poolDiscard(&parser->m_tempPool);
2967
66
      } else if (parser->m_defaultHandler)
2968
0
        reportDefault(parser, enc, s, next);
2969
1.65M
      break;
2970
1.65M
    }
2971
2.61M
    case XML_TOK_START_TAG_NO_ATTS:
2972
      /* fall through */
2973
2.65M
    case XML_TOK_START_TAG_WITH_ATTS: {
2974
2.65M
      TAG *tag;
2975
2.65M
      enum XML_Error result;
2976
2.65M
      XML_Char *toPtr;
2977
2.65M
      if (parser->m_freeTagList) {
2978
13.5k
        tag = parser->m_freeTagList;
2979
13.5k
        parser->m_freeTagList = parser->m_freeTagList->parent;
2980
2.64M
      } else {
2981
2.64M
        tag = (TAG *)MALLOC(parser, sizeof(TAG));
2982
2.64M
        if (! tag)
2983
0
          return XML_ERROR_NO_MEMORY;
2984
2.64M
        tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
2985
2.64M
        if (! tag->buf) {
2986
0
          FREE(parser, tag);
2987
0
          return XML_ERROR_NO_MEMORY;
2988
0
        }
2989
2.64M
        tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2990
2.64M
      }
2991
2.65M
      tag->bindings = NULL;
2992
2.65M
      tag->parent = parser->m_tagStack;
2993
2.65M
      parser->m_tagStack = tag;
2994
2.65M
      tag->name.localPart = NULL;
2995
2.65M
      tag->name.prefix = NULL;
2996
2.65M
      tag->rawName = s + enc->minBytesPerChar;
2997
2.65M
      tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2998
2.65M
      ++parser->m_tagLevel;
2999
2.65M
      {
3000
2.65M
        const char *rawNameEnd = tag->rawName + tag->rawNameLength;
3001
2.65M
        const char *fromPtr = tag->rawName;
3002
2.65M
        toPtr = (XML_Char *)tag->buf;
3003
2.66M
        for (;;) {
3004
2.66M
          int bufSize;
3005
2.66M
          int convLen;
3006
2.66M
          const enum XML_Convert_Result convert_res
3007
2.66M
              = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,
3008
2.66M
                           (ICHAR *)tag->bufEnd - 1);
3009
2.66M
          convLen = (int)(toPtr - (XML_Char *)tag->buf);
3010
2.66M
          if ((fromPtr >= rawNameEnd)
3011
2.66M
              || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
3012
2.65M
            tag->name.strLen = convLen;
3013
2.65M
            break;
3014
2.65M
          }
3015
7.21k
          bufSize = (int)(tag->bufEnd - tag->buf) << 1;
3016
7.21k
          {
3017
7.21k
            char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
3018
7.21k
            if (temp == NULL)
3019
0
              return XML_ERROR_NO_MEMORY;
3020
7.21k
            tag->buf = temp;
3021
7.21k
            tag->bufEnd = temp + bufSize;
3022
7.21k
            toPtr = (XML_Char *)temp + convLen;
3023
7.21k
          }
3024
7.21k
        }
3025
2.65M
      }
3026
2.65M
      tag->name.str = (XML_Char *)tag->buf;
3027
2.65M
      *toPtr = XML_T('\0');
3028
2.65M
      result
3029
2.65M
          = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account);
3030
2.65M
      if (result)
3031
859
        return result;
3032
2.65M
      if (parser->m_startElementHandler)
3033
2.65M
        parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
3034
2.65M
                                      (const XML_Char **)parser->m_atts);
3035
0
      else if (parser->m_defaultHandler)
3036
0
        reportDefault(parser, enc, s, next);
3037
2.65M
      poolClear(&parser->m_tempPool);
3038
2.65M
      break;
3039
2.65M
    }
3040
747k
    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
3041
      /* fall through */
3042
897k
    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: {
3043
897k
      const char *rawName = s + enc->minBytesPerChar;
3044
897k
      enum XML_Error result;
3045
897k
      BINDING *bindings = NULL;
3046
897k
      XML_Bool noElmHandlers = XML_TRUE;
3047
897k
      TAG_NAME name;
3048
897k
      name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
3049
897k
                                 rawName + XmlNameLength(enc, rawName));
3050
897k
      if (! name.str)
3051
0
        return XML_ERROR_NO_MEMORY;
3052
897k
      poolFinish(&parser->m_tempPool);
3053
897k
      result = storeAtts(parser, enc, s, &name, &bindings,
3054
897k
                         XML_ACCOUNT_NONE /* token spans whole start tag */);
3055
897k
      if (result != XML_ERROR_NONE) {
3056
152
        freeBindings(parser, bindings);
3057
152
        return result;
3058
152
      }
3059
897k
      poolFinish(&parser->m_tempPool);
3060
897k
      if (parser->m_startElementHandler) {
3061
897k
        parser->m_startElementHandler(parser->m_handlerArg, name.str,
3062
897k
                                      (const XML_Char **)parser->m_atts);
3063
897k
        noElmHandlers = XML_FALSE;
3064
897k
      }
3065
897k
      if (parser->m_endElementHandler) {
3066
897k
        if (parser->m_startElementHandler)
3067
897k
          *eventPP = *eventEndPP;
3068
897k
        parser->m_endElementHandler(parser->m_handlerArg, name.str);
3069
897k
        noElmHandlers = XML_FALSE;
3070
897k
      }
3071
897k
      if (noElmHandlers && parser->m_defaultHandler)
3072
0
        reportDefault(parser, enc, s, next);
3073
897k
      poolClear(&parser->m_tempPool);
3074
897k
      freeBindings(parser, bindings);
3075
897k
    }
3076
897k
      if ((parser->m_tagLevel == 0)
3077
897k
          && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
3078
727
        if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
3079
0
          parser->m_processor = epilogProcessor;
3080
727
        else
3081
727
          return epilogProcessor(parser, next, end, nextPtr);
3082
727
      }
3083
896k
      break;
3084
896k
    case XML_TOK_END_TAG:
3085
14.5k
      if (parser->m_tagLevel == startTagLevel)
3086
26
        return XML_ERROR_ASYNC_ENTITY;
3087
14.5k
      else {
3088
14.5k
        int len;
3089
14.5k
        const char *rawName;
3090
14.5k
        TAG *tag = parser->m_tagStack;
3091
14.5k
        rawName = s + enc->minBytesPerChar * 2;
3092
14.5k
        len = XmlNameLength(enc, rawName);
3093
14.5k
        if (len != tag->rawNameLength
3094
14.5k
            || memcmp(tag->rawName, rawName, len) != 0) {
3095
346
          *eventPP = rawName;
3096
346
          return XML_ERROR_TAG_MISMATCH;
3097
346
        }
3098
14.1k
        parser->m_tagStack = tag->parent;
3099
14.1k
        tag->parent = parser->m_freeTagList;
3100
14.1k
        parser->m_freeTagList = tag;
3101
14.1k
        --parser->m_tagLevel;
3102
14.1k
        if (parser->m_endElementHandler) {
3103
14.1k
          const XML_Char *localPart;
3104
14.1k
          const XML_Char *prefix;
3105
14.1k
          XML_Char *uri;
3106
14.1k
          localPart = tag->name.localPart;
3107
14.1k
          if (parser->m_ns && localPart) {
3108
            /* localPart and prefix may have been overwritten in
3109
               tag->name.str, since this points to the binding->uri
3110
               buffer which gets reused; so we have to add them again
3111
            */
3112
736
            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
3113
            /* don't need to check for space - already done in storeAtts() */
3114
1.72k
            while (*localPart)
3115
985
              *uri++ = *localPart++;
3116
736
            prefix = tag->name.prefix;
3117
736
            if (parser->m_ns_triplets && prefix) {
3118
0
              *uri++ = parser->m_namespaceSeparator;
3119
0
              while (*prefix)
3120
0
                *uri++ = *prefix++;
3121
0
            }
3122
736
            *uri = XML_T('\0');
3123
736
          }
3124
14.1k
          parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
3125
14.1k
        } else if (parser->m_defaultHandler)
3126
0
          reportDefault(parser, enc, s, next);
3127
15.4k
        while (tag->bindings) {
3128
1.26k
          BINDING *b = tag->bindings;
3129
1.26k
          if (parser->m_endNamespaceDeclHandler)
3130
0
            parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
3131
0
                                              b->prefix->name);
3132
1.26k
          tag->bindings = tag->bindings->nextTagBinding;
3133
1.26k
          b->nextTagBinding = parser->m_freeBindingList;
3134
1.26k
          parser->m_freeBindingList = b;
3135
1.26k
          b->prefix->binding = b->prevPrefixBinding;
3136
1.26k
        }
3137
14.1k
        if ((parser->m_tagLevel == 0)
3138
14.1k
            && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
3139
61
          if (parser->m_parsingStatus.parsing == XML_SUSPENDED)
3140
0
            parser->m_processor = epilogProcessor;
3141
61
          else
3142
61
            return epilogProcessor(parser, next, end, nextPtr);
3143
61
        }
3144
14.1k
      }
3145
14.1k
      break;
3146
14.1k
    case XML_TOK_CHAR_REF: {
3147
12.1k
      int n = XmlCharRefNumber(enc, s);
3148
12.1k
      if (n < 0)
3149
343
        return XML_ERROR_BAD_CHAR_REF;
3150
11.7k
      if (parser->m_characterDataHandler) {
3151
11.7k
        XML_Char buf[XML_ENCODE_MAX];
3152
11.7k
        parser->m_characterDataHandler(parser->m_handlerArg, buf,
3153
11.7k
                                       XmlEncode(n, (ICHAR *)buf));
3154
11.7k
      } else if (parser->m_defaultHandler)
3155
0
        reportDefault(parser, enc, s, next);
3156
11.7k
    } break;
3157
91
    case XML_TOK_XML_DECL:
3158
91
      return XML_ERROR_MISPLACED_XML_PI;
3159
13.2M
    case XML_TOK_DATA_NEWLINE:
3160
13.2M
      if (parser->m_characterDataHandler) {
3161
13.2M
        XML_Char c = 0xA;
3162
13.2M
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
3163
13.2M
      } else if (parser->m_defaultHandler)
3164
0
        reportDefault(parser, enc, s, next);
3165
13.2M
      break;
3166
746k
    case XML_TOK_CDATA_SECT_OPEN: {
3167
746k
      enum XML_Error result;
3168
746k
      if (parser->m_startCdataSectionHandler)
3169
0
        parser->m_startCdataSectionHandler(parser->m_handlerArg);
3170
      /* BEGIN disabled code */
3171
      /* Suppose you doing a transformation on a document that involves
3172
         changing only the character data.  You set up a defaultHandler
3173
         and a characterDataHandler.  The defaultHandler simply copies
3174
         characters through.  The characterDataHandler does the
3175
         transformation and writes the characters out escaping them as
3176
         necessary.  This case will fail to work if we leave out the
3177
         following two lines (because & and < inside CDATA sections will
3178
         be incorrectly escaped).
3179
3180
         However, now we have a start/endCdataSectionHandler, so it seems
3181
         easier to let the user deal with this.
3182
      */
3183
746k
      else if ((0) && parser->m_characterDataHandler)
3184
0
        parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3185
0
                                       0);
3186
      /* END disabled code */
3187
746k
      else if (parser->m_defaultHandler)
3188
0
        reportDefault(parser, enc, s, next);
3189
746k
      result
3190
746k
          = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account);
3191
746k
      if (result != XML_ERROR_NONE)
3192
550
        return result;
3193
746k
      else if (! next) {
3194
1.04k
        parser->m_processor = cdataSectionProcessor;
3195
1.04k
        return result;
3196
1.04k
      }
3197
746k
    } break;
3198
744k
    case XML_TOK_TRAILING_RSQB:
3199
799
      if (haveMore) {
3200
182
        *nextPtr = s;
3201
182
        return XML_ERROR_NONE;
3202
182
      }
3203
617
      if (parser->m_characterDataHandler) {
3204
617
        if (MUST_CONVERT(enc, s)) {
3205
95
          ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3206
95
          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3207
95
          parser->m_characterDataHandler(
3208
95
              parser->m_handlerArg, parser->m_dataBuf,
3209
95
              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3210
95
        } else
3211
522
          parser->m_characterDataHandler(
3212
522
              parser->m_handlerArg, (const XML_Char *)s,
3213
522
              (int)((const XML_Char *)end - (const XML_Char *)s));
3214
617
      } else if (parser->m_defaultHandler)
3215
0
        reportDefault(parser, enc, s, end);
3216
      /* We are at the end of the final buffer, should we check for
3217
         XML_SUSPENDED, XML_FINISHED?
3218
      */
3219
617
      if (startTagLevel == 0) {
3220
64
        *eventPP = end;
3221
64
        return XML_ERROR_NO_ELEMENTS;
3222
64
      }
3223
553
      if (parser->m_tagLevel != startTagLevel) {
3224
57
        *eventPP = end;
3225
57
        return XML_ERROR_ASYNC_ENTITY;
3226
57
      }
3227
496
      *nextPtr = end;
3228
496
      return XML_ERROR_NONE;
3229
7.29M
    case XML_TOK_DATA_CHARS: {
3230
7.29M
      XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3231
7.29M
      if (charDataHandler) {
3232
7.29M
        if (MUST_CONVERT(enc, s)) {
3233
258k
          for (;;) {
3234
258k
            ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3235
258k
            const enum XML_Convert_Result convert_res = XmlConvert(
3236
258k
                enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3237
258k
            *eventEndPP = s;
3238
258k
            charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3239
258k
                            (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3240
258k
            if ((convert_res == XML_CONVERT_COMPLETED)
3241
258k
                || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3242
238k
              break;
3243
20.2k
            *eventPP = s;
3244
20.2k
          }
3245
238k
        } else
3246
7.05M
          charDataHandler(parser->m_handlerArg, (const XML_Char *)s,
3247
7.05M
                          (int)((const XML_Char *)next - (const XML_Char *)s));
3248
7.29M
      } else if (parser->m_defaultHandler)
3249
0
        reportDefault(parser, enc, s, next);
3250
7.29M
    } break;
3251
73.0k
    case XML_TOK_PI:
3252
73.0k
      if (! reportProcessingInstruction(parser, enc, s, next))
3253
0
        return XML_ERROR_NO_MEMORY;
3254
73.0k
      break;
3255
73.0k
    case XML_TOK_COMMENT:
3256
1.36k
      if (! reportComment(parser, enc, s, next))
3257
0
        return XML_ERROR_NO_MEMORY;
3258
1.36k
      break;
3259
1.36k
    default:
3260
      /* All of the tokens produced by XmlContentTok() have their own
3261
       * explicit cases, so this default is not strictly necessary.
3262
       * However it is a useful safety net, so we retain the code and
3263
       * simply exclude it from the coverage tests.
3264
       *
3265
       * LCOV_EXCL_START
3266
       */
3267
0
      if (parser->m_defaultHandler)
3268
0
        reportDefault(parser, enc, s, next);
3269
0
      break;
3270
      /* LCOV_EXCL_STOP */
3271
28.3M
    }
3272
26.6M
    *eventPP = s = next;
3273
26.6M
    switch (parser->m_parsingStatus.parsing) {
3274
178
    case XML_SUSPENDED:
3275
178
      *nextPtr = next;
3276
178
      return XML_ERROR_NONE;
3277
13
    case XML_FINISHED:
3278
13
      return XML_ERROR_ABORTED;
3279
26.6M
    default:;
3280
26.6M
    }
3281
26.6M
  }
3282
  /* not reached */
3283
1.70M
}
3284
3285
/* This function does not call free() on the allocated memory, merely
3286
 * moving it to the parser's m_freeBindingList where it can be freed or
3287
 * reused as appropriate.
3288
 */
3289
static void
3290
897k
freeBindings(XML_Parser parser, BINDING *bindings) {
3291
899k
  while (bindings) {
3292
1.98k
    BINDING *b = bindings;
3293
3294
    /* m_startNamespaceDeclHandler will have been called for this
3295
     * binding in addBindings(), so call the end handler now.
3296
     */
3297
1.98k
    if (parser->m_endNamespaceDeclHandler)
3298
0
      parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
3299
3300
1.98k
    bindings = bindings->nextTagBinding;
3301
1.98k
    b->nextTagBinding = parser->m_freeBindingList;
3302
1.98k
    parser->m_freeBindingList = b;
3303
1.98k
    b->prefix->binding = b->prevPrefixBinding;
3304
1.98k
  }
3305
897k
}
3306
3307
/* Precondition: all arguments must be non-NULL;
3308
   Purpose:
3309
   - normalize attributes
3310
   - check attributes for well-formedness
3311
   - generate namespace aware attribute names (URI, prefix)
3312
   - build list of attributes for startElementHandler
3313
   - default attributes
3314
   - process namespace declarations (check and report them)
3315
   - generate namespace aware element name (URI, prefix)
3316
*/
3317
static enum XML_Error
3318
storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
3319
          TAG_NAME *tagNamePtr, BINDING **bindingsPtr,
3320
3.55M
          enum XML_Account account) {
3321
3.55M
  DTD *const dtd = parser->m_dtd; /* save one level of indirection */
3322
3.55M
  ELEMENT_TYPE *elementType;
3323
3.55M
  int nDefaultAtts;
3324
3.55M
  const XML_Char **appAtts; /* the attribute list for the application */
3325
3.55M
  int attIndex = 0;
3326
3.55M
  int prefixLen;
3327
3.55M
  int i;
3328
3.55M
  int n;
3329
3.55M
  XML_Char *uri;
3330
3.55M
  int nPrefixes = 0;
3331
3.55M
  BINDING *binding;
3332
3.55M
  const XML_Char *localPart;
3333
3334
  /* lookup the element type name */
3335
3.55M
  elementType
3336
3.55M
      = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
3337
3.55M
  if (! elementType) {
3338
24.9k
    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
3339
24.9k
    if (! name)
3340
0
      return XML_ERROR_NO_MEMORY;
3341
24.9k
    elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
3342
24.9k
                                         sizeof(ELEMENT_TYPE));
3343
24.9k
    if (! elementType)
3344
0
      return XML_ERROR_NO_MEMORY;
3345
24.9k
    if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
3346
0
      return XML_ERROR_NO_MEMORY;
3347
24.9k
  }
3348
3.55M
  nDefaultAtts = elementType->nDefaultAtts;
3349
3350
  /* get the attributes from the tokenizer */
3351
3.55M
  n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
3352
3353
  /* Detect and prevent integer overflow */
3354
3.55M
  if (n > INT_MAX - nDefaultAtts) {
3355
0
    return XML_ERROR_NO_MEMORY;
3356
0
  }
3357
3358
3.55M
  if (n + nDefaultAtts > parser->m_attsSize) {
3359
678
    int oldAttsSize = parser->m_attsSize;
3360
678
    ATTRIBUTE *temp;
3361
#ifdef XML_ATTR_INFO
3362
    XML_AttrInfo *temp2;
3363
#endif
3364
3365
    /* Detect and prevent integer overflow */
3366
678
    if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
3367
678
        || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
3368
0
      return XML_ERROR_NO_MEMORY;
3369
0
    }
3370
3371
678
    parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
3372
3373
    /* Detect and prevent integer overflow.
3374
     * The preprocessor guard addresses the "always false" warning
3375
     * from -Wtype-limits on platforms where
3376
     * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3377
#if UINT_MAX >= SIZE_MAX
3378
    if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
3379
      parser->m_attsSize = oldAttsSize;
3380
      return XML_ERROR_NO_MEMORY;
3381
    }
3382
#endif
3383
3384
678
    temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts,
3385
678
                                parser->m_attsSize * sizeof(ATTRIBUTE));
3386
678
    if (temp == NULL) {
3387
0
      parser->m_attsSize = oldAttsSize;
3388
0
      return XML_ERROR_NO_MEMORY;
3389
0
    }
3390
678
    parser->m_atts = temp;
3391
#ifdef XML_ATTR_INFO
3392
    /* Detect and prevent integer overflow.
3393
     * The preprocessor guard addresses the "always false" warning
3394
     * from -Wtype-limits on platforms where
3395
     * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3396
#  if UINT_MAX >= SIZE_MAX
3397
    if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) {
3398
      parser->m_attsSize = oldAttsSize;
3399
      return XML_ERROR_NO_MEMORY;
3400
    }
3401
#  endif
3402
3403
    temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo,
3404
                                    parser->m_attsSize * sizeof(XML_AttrInfo));
3405
    if (temp2 == NULL) {
3406
      parser->m_attsSize = oldAttsSize;
3407
      return XML_ERROR_NO_MEMORY;
3408
    }
3409
    parser->m_attInfo = temp2;
3410
#endif
3411
678
    if (n > oldAttsSize)
3412
656
      XmlGetAttributes(enc, attStr, n, parser->m_atts);
3413
678
  }
3414
3415
3.55M
  appAtts = (const XML_Char **)parser->m_atts;
3416
4.00M
  for (i = 0; i < n; i++) {
3417
449k
    ATTRIBUTE *currAtt = &parser->m_atts[i];
3418
#ifdef XML_ATTR_INFO
3419
    XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
3420
#endif
3421
    /* add the name and value to the attribute list */
3422
449k
    ATTRIBUTE_ID *attId
3423
449k
        = getAttributeId(parser, enc, currAtt->name,
3424
449k
                         currAtt->name + XmlNameLength(enc, currAtt->name));
3425
449k
    if (! attId)
3426
0
      return XML_ERROR_NO_MEMORY;
3427
#ifdef XML_ATTR_INFO
3428
    currAttInfo->nameStart
3429
        = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
3430
    currAttInfo->nameEnd
3431
        = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name);
3432
    currAttInfo->valueStart = parser->m_parseEndByteIndex
3433
                              - (parser->m_parseEndPtr - currAtt->valuePtr);
3434
    currAttInfo->valueEnd = parser->m_parseEndByteIndex
3435
                            - (parser->m_parseEndPtr - currAtt->valueEnd);
3436
#endif
3437
    /* Detect duplicate attributes by their QNames. This does not work when
3438
       namespace processing is turned on and different prefixes for the same
3439
       namespace are used. For this case we have a check further down.
3440
    */
3441
449k
    if ((attId->name)[-1]) {
3442
651
      if (enc == parser->m_encoding)
3443
648
        parser->m_eventPtr = parser->m_atts[i].name;
3444
651
      return XML_ERROR_DUPLICATE_ATTRIBUTE;
3445
651
    }
3446
449k
    (attId->name)[-1] = 1;
3447
449k
    appAtts[attIndex++] = attId->name;
3448
449k
    if (! parser->m_atts[i].normalized) {
3449
16.8k
      enum XML_Error result;
3450
16.8k
      XML_Bool isCdata = XML_TRUE;
3451
3452
      /* figure out whether declared as other than CDATA */
3453
16.8k
      if (attId->maybeTokenized) {
3454
2.08k
        int j;
3455
106k
        for (j = 0; j < nDefaultAtts; j++) {
3456
106k
          if (attId == elementType->defaultAtts[j].id) {
3457
1.81k
            isCdata = elementType->defaultAtts[j].isCdata;
3458
1.81k
            break;
3459
1.81k
          }
3460
106k
        }
3461
2.08k
      }
3462
3463
      /* normalize the attribute value */
3464
16.8k
      result = storeAttributeValue(
3465
16.8k
          parser, enc, isCdata, parser->m_atts[i].valuePtr,
3466
16.8k
          parser->m_atts[i].valueEnd, &parser->m_tempPool, account);
3467
16.8k
      if (result)
3468
187
        return result;
3469
16.6k
      appAtts[attIndex] = poolStart(&parser->m_tempPool);
3470
16.6k
      poolFinish(&parser->m_tempPool);
3471
432k
    } else {
3472
      /* the value did not need normalizing */
3473
432k
      appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
3474
432k
                                          parser->m_atts[i].valuePtr,
3475
432k
                                          parser->m_atts[i].valueEnd);
3476
432k
      if (appAtts[attIndex] == 0)
3477
0
        return XML_ERROR_NO_MEMORY;
3478
432k
      poolFinish(&parser->m_tempPool);
3479
432k
    }
3480
    /* handle prefixed attribute names */
3481
448k
    if (attId->prefix) {
3482
107k
      if (attId->xmlns) {
3483
        /* deal with namespace declarations here */
3484
7.79k
        enum XML_Error result = addBinding(parser, attId->prefix, attId,
3485
7.79k
                                           appAtts[attIndex], bindingsPtr);
3486
7.79k
        if (result)
3487
26
          return result;
3488
7.77k
        --attIndex;
3489
100k
      } else {
3490
        /* deal with other prefixed names later */
3491
100k
        attIndex++;
3492
100k
        nPrefixes++;
3493
100k
        (attId->name)[-1] = 2;
3494
100k
      }
3495
107k
    } else
3496
341k
      attIndex++;
3497
448k
  }
3498
3499
  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
3500
3.55M
  parser->m_nSpecifiedAtts = attIndex;
3501
3.55M
  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3502
1.67k
    for (i = 0; i < attIndex; i += 2)
3503
1.67k
      if (appAtts[i] == elementType->idAtt->name) {
3504
1.09k
        parser->m_idAttIndex = i;
3505
1.09k
        break;
3506
1.09k
      }
3507
1.09k
  } else
3508
3.54M
    parser->m_idAttIndex = -1;
3509
3510
  /* do attribute defaulting */
3511
4.18M
  for (i = 0; i < nDefaultAtts; i++) {
3512
633k
    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
3513
633k
    if (! (da->id->name)[-1] && da->value) {
3514
971
      if (da->id->prefix) {
3515
158
        if (da->id->xmlns) {
3516
83
          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3517
83
                                             da->value, bindingsPtr);
3518
83
          if (result)
3519
1
            return result;
3520
83
        } else {
3521
75
          (da->id->name)[-1] = 2;
3522
75
          nPrefixes++;
3523
75
          appAtts[attIndex++] = da->id->name;
3524
75
          appAtts[attIndex++] = da->value;
3525
75
        }
3526
813
      } else {
3527
813
        (da->id->name)[-1] = 1;
3528
813
        appAtts[attIndex++] = da->id->name;
3529
813
        appAtts[attIndex++] = da->value;
3530
813
      }
3531
971
    }
3532
633k
  }
3533
3.55M
  appAtts[attIndex] = 0;
3534
3535
  /* expand prefixed attribute names, check for duplicates,
3536
     and clear flags that say whether attributes were specified */
3537
3.55M
  i = 0;
3538
3.55M
  if (nPrefixes) {
3539
51.4k
    int j; /* hash table index */
3540
51.4k
    unsigned long version = parser->m_nsAttsVersion;
3541
3542
    /* Detect and prevent invalid shift */
3543
51.4k
    if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) {
3544
0
      return XML_ERROR_NO_MEMORY;
3545
0
    }
3546
3547
51.4k
    unsigned int nsAttsSize = 1u << parser->m_nsAttsPower;
3548
51.4k
    unsigned char oldNsAttsPower = parser->m_nsAttsPower;
3549
    /* size of hash table must be at least 2 * (# of prefixed attributes) */
3550
51.4k
    if ((nPrefixes << 1)
3551
51.4k
        >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */
3552
316
      NS_ATT *temp;
3553
      /* hash table size must also be a power of 2 and >= 8 */
3554
808
      while (nPrefixes >> parser->m_nsAttsPower++)
3555
492
        ;
3556
316
      if (parser->m_nsAttsPower < 3)
3557
163
        parser->m_nsAttsPower = 3;
3558
3559
      /* Detect and prevent invalid shift */
3560
316
      if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) {
3561
        /* Restore actual size of memory in m_nsAtts */
3562
0
        parser->m_nsAttsPower = oldNsAttsPower;
3563
0
        return XML_ERROR_NO_MEMORY;
3564
0
      }
3565
3566
316
      nsAttsSize = 1u << parser->m_nsAttsPower;
3567
3568
      /* Detect and prevent integer overflow.
3569
       * The preprocessor guard addresses the "always false" warning
3570
       * from -Wtype-limits on platforms where
3571
       * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3572
#if UINT_MAX >= SIZE_MAX
3573
      if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) {
3574
        /* Restore actual size of memory in m_nsAtts */
3575
        parser->m_nsAttsPower = oldNsAttsPower;
3576
        return XML_ERROR_NO_MEMORY;
3577
      }
3578
#endif
3579
3580
316
      temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts,
3581
316
                               nsAttsSize * sizeof(NS_ATT));
3582
316
      if (! temp) {
3583
        /* Restore actual size of memory in m_nsAtts */
3584
0
        parser->m_nsAttsPower = oldNsAttsPower;
3585
0
        return XML_ERROR_NO_MEMORY;
3586
0
      }
3587
316
      parser->m_nsAtts = temp;
3588
316
      version = 0; /* force re-initialization of m_nsAtts hash table */
3589
316
    }
3590
    /* using a version flag saves us from initializing m_nsAtts every time */
3591
51.4k
    if (! version) { /* initialize version flags when version wraps around */
3592
316
      version = INIT_ATTS_VERSION;
3593
3.20k
      for (j = nsAttsSize; j != 0;)
3594
2.88k
        parser->m_nsAtts[--j].version = version;
3595
316
    }
3596
51.4k
    parser->m_nsAttsVersion = --version;
3597
3598
    /* expand prefixed names and check for duplicates */
3599
147k
    for (; i < attIndex; i += 2) {
3600
147k
      const XML_Char *s = appAtts[i];
3601
147k
      if (s[-1] == 2) { /* prefixed */
3602
100k
        ATTRIBUTE_ID *id;
3603
100k
        const BINDING *b;
3604
100k
        unsigned long uriHash;
3605
100k
        struct siphash sip_state;
3606
100k
        struct sipkey sip_key;
3607
3608
100k
        copy_salt_to_sipkey(parser, &sip_key);
3609
100k
        sip24_init(&sip_state, &sip_key);
3610
3611
100k
        ((XML_Char *)s)[-1] = 0; /* clear flag */
3612
100k
        id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
3613
100k
        if (! id || ! id->prefix) {
3614
          /* This code is walking through the appAtts array, dealing
3615
           * with (in this case) a prefixed attribute name.  To be in
3616
           * the array, the attribute must have already been bound, so
3617
           * has to have passed through the hash table lookup once
3618
           * already.  That implies that an entry for it already
3619
           * exists, so the lookup above will return a pointer to
3620
           * already allocated memory.  There is no opportunaity for
3621
           * the allocator to fail, so the condition above cannot be
3622
           * fulfilled.
3623
           *
3624
           * Since it is difficult to be certain that the above
3625
           * analysis is complete, we retain the test and merely
3626
           * remove the code from coverage tests.
3627
           */
3628
0
          return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
3629
0
        }
3630
100k
        b = id->prefix->binding;
3631
100k
        if (! b)
3632
84
          return XML_ERROR_UNBOUND_PREFIX;
3633
3634
180M
        for (j = 0; j < b->uriLen; j++) {
3635
180M
          const XML_Char c = b->uri[j];
3636
180M
          if (! poolAppendChar(&parser->m_tempPool, c))
3637
0
            return XML_ERROR_NO_MEMORY;
3638
180M
        }
3639
3640
99.9k
        sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3641
3642
392k
        while (*s++ != XML_T(ASCII_COLON))
3643
292k
          ;
3644
3645
99.9k
        sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3646
3647
585k
        do { /* copies null terminator */
3648
585k
          if (! poolAppendChar(&parser->m_tempPool, *s))
3649
0
            return XML_ERROR_NO_MEMORY;
3650
585k
        } while (*s++);
3651
3652
99.9k
        uriHash = (unsigned long)sip24_final(&sip_state);
3653
3654
99.9k
        { /* Check hash table for duplicate of expanded name (uriName).
3655
             Derived from code in lookup(parser, HASH_TABLE *table, ...).
3656
          */
3657
99.9k
          unsigned char step = 0;
3658
99.9k
          unsigned long mask = nsAttsSize - 1;
3659
99.9k
          j = uriHash & mask; /* index into hash table */
3660
108k
          while (parser->m_nsAtts[j].version == version) {
3661
            /* for speed we compare stored hash values first */
3662
8.85k
            if (uriHash == parser->m_nsAtts[j].hash) {
3663
0
              const XML_Char *s1 = poolStart(&parser->m_tempPool);
3664
0
              const XML_Char *s2 = parser->m_nsAtts[j].uriName;
3665
              /* s1 is null terminated, but not s2 */
3666
0
              for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
3667
0
                ;
3668
0
              if (*s1 == 0)
3669
0
                return XML_ERROR_DUPLICATE_ATTRIBUTE;
3670
0
            }
3671
8.85k
            if (! step)
3672
8.54k
              step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
3673
8.85k
            j < step ? (j += nsAttsSize - step) : (j -= step);
3674
8.85k
          }
3675
99.9k
        }
3676
3677
99.9k
        if (parser->m_ns_triplets) { /* append namespace separator and prefix */
3678
0
          parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
3679
0
          s = b->prefix->name;
3680
0
          do {
3681
0
            if (! poolAppendChar(&parser->m_tempPool, *s))
3682
0
              return XML_ERROR_NO_MEMORY;
3683
0
          } while (*s++);
3684
0
        }
3685
3686
        /* store expanded name in attribute list */
3687
99.9k
        s = poolStart(&parser->m_tempPool);
3688
99.9k
        poolFinish(&parser->m_tempPool);
3689
99.9k
        appAtts[i] = s;
3690
3691
        /* fill empty slot with new version, uriName and hash value */
3692
99.9k
        parser->m_nsAtts[j].version = version;
3693
99.9k
        parser->m_nsAtts[j].hash = uriHash;
3694
99.9k
        parser->m_nsAtts[j].uriName = s;
3695
3696
99.9k
        if (! --nPrefixes) {
3697
51.3k
          i += 2;
3698
51.3k
          break;
3699
51.3k
        }
3700
99.9k
      } else                     /* not prefixed */
3701
47.2k
        ((XML_Char *)s)[-1] = 0; /* clear flag */
3702
147k
    }
3703
51.4k
  }
3704
  /* clear flags for the remaining attributes */
3705
3.84M
  for (; i < attIndex; i += 2)
3706
293k
    ((XML_Char *)(appAtts[i]))[-1] = 0;
3707
3.55M
  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3708
7.80k
    binding->attId->name[-1] = 0;
3709
3710
3.55M
  if (! parser->m_ns)
3711
2.67M
    return XML_ERROR_NONE;
3712
3713
  /* expand the element type name */
3714
873k
  if (elementType->prefix) {
3715
3.51k
    binding = elementType->prefix->binding;
3716
3.51k
    if (! binding)
3717
62
      return XML_ERROR_UNBOUND_PREFIX;
3718
3.45k
    localPart = tagNamePtr->str;
3719
13.8k
    while (*localPart++ != XML_T(ASCII_COLON))
3720
10.3k
      ;
3721
870k
  } else if (dtd->defaultPrefix.binding) {
3722
6.16k
    binding = dtd->defaultPrefix.binding;
3723
6.16k
    localPart = tagNamePtr->str;
3724
6.16k
  } else
3725
864k
    return XML_ERROR_NONE;
3726
9.61k
  prefixLen = 0;
3727
9.61k
  if (parser->m_ns_triplets && binding->prefix->name) {
3728
0
    for (; binding->prefix->name[prefixLen++];)
3729
0
      ; /* prefixLen includes null terminator */
3730
0
  }
3731
9.61k
  tagNamePtr->localPart = localPart;
3732
9.61k
  tagNamePtr->uriLen = binding->uriLen;
3733
9.61k
  tagNamePtr->prefix = binding->prefix->name;
3734
9.61k
  tagNamePtr->prefixLen = prefixLen;
3735
5.85M
  for (i = 0; localPart[i++];)
3736
5.84M
    ; /* i includes null terminator */
3737
3738
  /* Detect and prevent integer overflow */
3739
9.61k
  if (binding->uriLen > INT_MAX - prefixLen
3740
9.61k
      || i > INT_MAX - (binding->uriLen + prefixLen)) {
3741
0
    return XML_ERROR_NO_MEMORY;
3742
0
  }
3743
3744
9.61k
  n = i + binding->uriLen + prefixLen;
3745
9.61k
  if (n > binding->uriAlloc) {
3746
767
    TAG *p;
3747
3748
    /* Detect and prevent integer overflow */
3749
767
    if (n > INT_MAX - EXPAND_SPARE) {
3750
0
      return XML_ERROR_NO_MEMORY;
3751
0
    }
3752
    /* Detect and prevent integer overflow.
3753
     * The preprocessor guard addresses the "always false" warning
3754
     * from -Wtype-limits on platforms where
3755
     * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
3756
#if UINT_MAX >= SIZE_MAX
3757
    if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
3758
      return XML_ERROR_NO_MEMORY;
3759
    }
3760
#endif
3761
3762
767
    uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
3763
767
    if (! uri)
3764
0
      return XML_ERROR_NO_MEMORY;
3765
767
    binding->uriAlloc = n + EXPAND_SPARE;
3766
767
    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3767
227k
    for (p = parser->m_tagStack; p; p = p->parent)
3768
227k
      if (p->name.str == binding->uri)
3769
1.05k
        p->name.str = uri;
3770
767
    FREE(parser, binding->uri);
3771
767
    binding->uri = uri;
3772
767
  }
3773
  /* if m_namespaceSeparator != '\0' then uri includes it already */
3774
9.61k
  uri = binding->uri + binding->uriLen;
3775
9.61k
  memcpy(uri, localPart, i * sizeof(XML_Char));
3776
  /* we always have a namespace separator between localPart and prefix */
3777
9.61k
  if (prefixLen) {
3778
0
    uri += i - 1;
3779
0
    *uri = parser->m_namespaceSeparator; /* replace null terminator */
3780
0
    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3781
0
  }
3782
9.61k
  tagNamePtr->str = binding->uri;
3783
9.61k
  return XML_ERROR_NONE;
3784
9.61k
}
3785
3786
static XML_Bool
3787
3.01M
is_rfc3986_uri_char(XML_Char candidate) {
3788
  // For the RFC 3986 ANBF grammar see
3789
  // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A
3790
3791
3.01M
  switch (candidate) {
3792
  // From rule "ALPHA" (uppercase half)
3793
0
  case 'A':
3794
0
  case 'B':
3795
0
  case 'C':
3796
0
  case 'D':
3797
0
  case 'E':
3798
0
  case 'F':
3799
0
  case 'G':
3800
0
  case 'H':
3801
0
  case 'I':
3802
0
  case 'J':
3803
0
  case 'K':
3804
0
  case 'L':
3805
0
  case 'M':
3806
0
  case 'N':
3807
0
  case 'O':
3808
0
  case 'P':
3809
0
  case 'Q':
3810
0
  case 'R':
3811
0
  case 'S':
3812
0
  case 'T':
3813
0
  case 'U':
3814
0
  case 'V':
3815
0
  case 'W':
3816
0
  case 'X':
3817
0
  case 'Y':
3818
0
  case 'Z':
3819
3820
  // From rule "ALPHA" (lowercase half)
3821
0
  case 'a':
3822
0
  case 'b':
3823
0
  case 'c':
3824
0
  case 'd':
3825
0
  case 'e':
3826
0
  case 'f':
3827
0
  case 'g':
3828
0
  case 'h':
3829
0
  case 'i':
3830
0
  case 'j':
3831
0
  case 'k':
3832
0
  case 'l':
3833
0
  case 'm':
3834
0
  case 'n':
3835
0
  case 'o':
3836
0
  case 'p':
3837
0
  case 'q':
3838
0
  case 'r':
3839
0
  case 's':
3840
0
  case 't':
3841
0
  case 'u':
3842
0
  case 'v':
3843
0
  case 'w':
3844
0
  case 'x':
3845
0
  case 'y':
3846
0
  case 'z':
3847
3848
  // From rule "DIGIT"
3849
0
  case '0':
3850
0
  case '1':
3851
0
  case '2':
3852
0
  case '3':
3853
0
  case '4':
3854
0
  case '5':
3855
0
  case '6':
3856
0
  case '7':
3857
0
  case '8':
3858
0
  case '9':
3859
3860
  // From rule "pct-encoded"
3861
0
  case '%':
3862
3863
  // From rule "unreserved"
3864
0
  case '-':
3865
0
  case '.':
3866
0
  case '_':
3867
0
  case '~':
3868
3869
  // From rule "gen-delims"
3870
0
  case ':':
3871
0
  case '/':
3872
0
  case '?':
3873
0
  case '#':
3874
0
  case '[':
3875
0
  case ']':
3876
0
  case '@':
3877
3878
  // From rule "sub-delims"
3879
3.01M
  case '!':
3880
3.01M
  case '$':
3881
3.01M
  case '&':
3882
3.01M
  case '\'':
3883
3.01M
  case '(':
3884
3.01M
  case ')':
3885
3.01M
  case '*':
3886
3.01M
  case '+':
3887
3.01M
  case ',':
3888
3.01M
  case ';':
3889
3.01M
  case '=':
3890
3.01M
    return XML_TRUE;
3891
3892
0
  default:
3893
0
    return XML_FALSE;
3894
3.01M
  }
3895
3.01M
}
3896
3897
/* addBinding() overwrites the value of prefix->binding without checking.
3898
   Therefore one must keep track of the old value outside of addBinding().
3899
*/
3900
static enum XML_Error
3901
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3902
28.0k
           const XML_Char *uri, BINDING **bindingsPtr) {
3903
  // "http://www.w3.org/XML/1998/namespace"
3904
28.0k
  static const XML_Char xmlNamespace[]
3905
28.0k
      = {ASCII_h,      ASCII_t,     ASCII_t,     ASCII_p,      ASCII_COLON,
3906
28.0k
         ASCII_SLASH,  ASCII_SLASH, ASCII_w,     ASCII_w,      ASCII_w,
3907
28.0k
         ASCII_PERIOD, ASCII_w,     ASCII_3,     ASCII_PERIOD, ASCII_o,
3908
28.0k
         ASCII_r,      ASCII_g,     ASCII_SLASH, ASCII_X,      ASCII_M,
3909
28.0k
         ASCII_L,      ASCII_SLASH, ASCII_1,     ASCII_9,      ASCII_9,
3910
28.0k
         ASCII_8,      ASCII_SLASH, ASCII_n,     ASCII_a,      ASCII_m,
3911
28.0k
         ASCII_e,      ASCII_s,     ASCII_p,     ASCII_a,      ASCII_c,
3912
28.0k
         ASCII_e,      '\0'};
3913
28.0k
  static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
3914
  // "http://www.w3.org/2000/xmlns/"
3915
28.0k
  static const XML_Char xmlnsNamespace[]
3916
28.0k
      = {ASCII_h,     ASCII_t,      ASCII_t, ASCII_p, ASCII_COLON,  ASCII_SLASH,
3917
28.0k
         ASCII_SLASH, ASCII_w,      ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w,
3918
28.0k
         ASCII_3,     ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,      ASCII_SLASH,
3919
28.0k
         ASCII_2,     ASCII_0,      ASCII_0, ASCII_0, ASCII_SLASH,  ASCII_x,
3920
28.0k
         ASCII_m,     ASCII_l,      ASCII_n, ASCII_s, ASCII_SLASH,  '\0'};
3921
28.0k
  static const int xmlnsLen
3922
28.0k
      = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
3923
3924
28.0k
  XML_Bool mustBeXML = XML_FALSE;
3925
28.0k
  XML_Bool isXML = XML_TRUE;
3926
28.0k
  XML_Bool isXMLNS = XML_TRUE;
3927
3928
28.0k
  BINDING *b;
3929
28.0k
  int len;
3930
3931
  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3932
28.0k
  if (*uri == XML_T('\0') && prefix->name)
3933
3
    return XML_ERROR_UNDECLARING_PREFIX;
3934
3935
28.0k
  if (prefix->name && prefix->name[0] == XML_T(ASCII_x)
3936
28.0k
      && prefix->name[1] == XML_T(ASCII_m)
3937
28.0k
      && prefix->name[2] == XML_T(ASCII_l)) {
3938
    /* Not allowed to bind xmlns */
3939
21.3k
    if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s)
3940
21.3k
        && prefix->name[5] == XML_T('\0'))
3941
1
      return XML_ERROR_RESERVED_PREFIX_XMLNS;
3942
3943
21.3k
    if (prefix->name[3] == XML_T('\0'))
3944
20.2k
      mustBeXML = XML_TRUE;
3945
21.3k
  }
3946
3947
257M
  for (len = 0; uri[len]; len++) {
3948
257M
    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3949
6.04k
      isXML = XML_FALSE;
3950
3951
257M
    if (! mustBeXML && isXMLNS
3952
257M
        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3953
6.02k
      isXMLNS = XML_FALSE;
3954
3955
    // NOTE: While Expat does not validate namespace URIs against RFC 3986
3956
    //       today (and is not REQUIRED to do so with regard to the XML 1.0
3957
    //       namespaces specification) we have to at least make sure, that
3958
    //       the application on top of Expat (that is likely splitting expanded
3959
    //       element names ("qualified names") of form
3960
    //       "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces
3961
    //       in its element handler code) cannot be confused by an attacker
3962
    //       putting additional namespace separator characters into namespace
3963
    //       declarations.  That would be ambiguous and not to be expected.
3964
    //
3965
    //       While the HTML API docs of function XML_ParserCreateNS have been
3966
    //       advising against use of a namespace separator character that can
3967
    //       appear in a URI for >20 years now, some widespread applications
3968
    //       are using URI characters (':' (colon) in particular) for a
3969
    //       namespace separator, in practice.  To keep these applications
3970
    //       functional, we only reject namespaces URIs containing the
3971
    //       application-chosen namespace separator if the chosen separator
3972
    //       is a non-URI character with regard to RFC 3986.
3973
257M
    if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)
3974
257M
        && ! is_rfc3986_uri_char(uri[len])) {
3975
0
      return XML_ERROR_SYNTAX;
3976
0
    }
3977
257M
  }
3978
28.0k
  isXML = isXML && len == xmlLen;
3979
28.0k
  isXMLNS = isXMLNS && len == xmlnsLen;
3980
3981
28.0k
  if (mustBeXML != isXML)
3982
23
    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3983
23
                     : XML_ERROR_RESERVED_NAMESPACE_URI;
3984
3985
28.0k
  if (isXMLNS)
3986
0
    return XML_ERROR_RESERVED_NAMESPACE_URI;
3987
3988
28.0k
  if (parser->m_namespaceSeparator)
3989
28.0k
    len++;
3990
28.0k
  if (parser->m_freeBindingList) {
3991
3.05k
    b = parser->m_freeBindingList;
3992
3.05k
    if (len > b->uriAlloc) {
3993
      /* Detect and prevent integer overflow */
3994
556
      if (len > INT_MAX - EXPAND_SPARE) {
3995
0
        return XML_ERROR_NO_MEMORY;
3996
0
      }
3997
3998
      /* Detect and prevent integer overflow.
3999
       * The preprocessor guard addresses the "always false" warning
4000
       * from -Wtype-limits on platforms where
4001
       * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
4002
#if UINT_MAX >= SIZE_MAX
4003
      if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
4004
        return XML_ERROR_NO_MEMORY;
4005
      }
4006
#endif
4007
4008
556
      XML_Char *temp = (XML_Char *)REALLOC(
4009
556
          parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
4010
556
      if (temp == NULL)
4011
0
        return XML_ERROR_NO_MEMORY;
4012
556
      b->uri = temp;
4013
556
      b->uriAlloc = len + EXPAND_SPARE;
4014
556
    }
4015
3.05k
    parser->m_freeBindingList = b->nextTagBinding;
4016
25.0k
  } else {
4017
25.0k
    b = (BINDING *)MALLOC(parser, sizeof(BINDING));
4018
25.0k
    if (! b)
4019
0
      return XML_ERROR_NO_MEMORY;
4020
4021
    /* Detect and prevent integer overflow */
4022
25.0k
    if (len > INT_MAX - EXPAND_SPARE) {
4023
0
      return XML_ERROR_NO_MEMORY;
4024
0
    }
4025
    /* Detect and prevent integer overflow.
4026
     * The preprocessor guard addresses the "always false" warning
4027
     * from -Wtype-limits on platforms where
4028
     * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
4029
#if UINT_MAX >= SIZE_MAX
4030
    if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
4031
      return XML_ERROR_NO_MEMORY;
4032
    }
4033
#endif
4034
4035
25.0k
    b->uri
4036
25.0k
        = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
4037
25.0k
    if (! b->uri) {
4038
0
      FREE(parser, b);
4039
0
      return XML_ERROR_NO_MEMORY;
4040
0
    }
4041
25.0k
    b->uriAlloc = len + EXPAND_SPARE;
4042
25.0k
  }
4043
28.0k
  b->uriLen = len;
4044
28.0k
  memcpy(b->uri, uri, len * sizeof(XML_Char));
4045
28.0k
  if (parser->m_namespaceSeparator)
4046
28.0k
    b->uri[len - 1] = parser->m_namespaceSeparator;
4047
28.0k
  b->prefix = prefix;
4048
28.0k
  b->attId = attId;
4049
28.0k
  b->prevPrefixBinding = prefix->binding;
4050
  /* NULL binding when default namespace undeclared */
4051
28.0k
  if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
4052
651
    prefix->binding = NULL;
4053
27.4k
  else
4054
27.4k
    prefix->binding = b;
4055
28.0k
  b->nextTagBinding = *bindingsPtr;
4056
28.0k
  *bindingsPtr = b;
4057
  /* if attId == NULL then we are not starting a namespace scope */
4058
28.0k
  if (attId && parser->m_startNamespaceDeclHandler)
4059
0
    parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
4060
0
                                        prefix->binding ? uri : 0);
4061
28.0k
  return XML_ERROR_NONE;
4062
28.0k
}
4063
4064
/* The idea here is to avoid using stack for each CDATA section when
4065
   the whole file is parsed with one call.
4066
*/
4067
static enum XML_Error PTRCALL
4068
cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
4069
1.01k
                      const char **endPtr) {
4070
1.01k
  enum XML_Error result = doCdataSection(
4071
1.01k
      parser, parser->m_encoding, &start, end, endPtr,
4072
1.01k
      (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
4073
1.01k
  if (result != XML_ERROR_NONE)
4074
950
    return result;
4075
61
  if (start) {
4076
55
    if (parser->m_parentParser) { /* we are parsing an external entity */
4077
18
      parser->m_processor = externalEntityContentProcessor;
4078
18
      return externalEntityContentProcessor(parser, start, end, endPtr);
4079
37
    } else {
4080
37
      parser->m_processor = contentProcessor;
4081
37
      return contentProcessor(parser, start, end, endPtr);
4082
37
    }
4083
55
  }
4084
6
  return result;
4085
61
}
4086
4087
/* startPtr gets set to non-null if the section is closed, and to null if
4088
   the section is not yet closed.
4089
*/
4090
static enum XML_Error
4091
doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
4092
               const char *end, const char **nextPtr, XML_Bool haveMore,
4093
747k
               enum XML_Account account) {
4094
747k
  const char *s = *startPtr;
4095
747k
  const char **eventPP;
4096
747k
  const char **eventEndPP;
4097
747k
  if (enc == parser->m_encoding) {
4098
4.10k
    eventPP = &parser->m_eventPtr;
4099
4.10k
    *eventPP = s;
4100
4.10k
    eventEndPP = &parser->m_eventEndPtr;
4101
743k
  } else {
4102
743k
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4103
743k
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
4104
743k
  }
4105
747k
  *eventPP = s;
4106
747k
  *startPtr = NULL;
4107
4108
4.03M
  for (;;) {
4109
4.03M
    const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
4110
4.03M
    int tok = XmlCdataSectionTok(enc, s, end, &next);
4111
4.03M
#if XML_GE == 1
4112
4.03M
    if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
4113
1
      accountingOnAbort(parser);
4114
1
      return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4115
1
    }
4116
#else
4117
    UNUSED_P(account);
4118
#endif
4119
4.03M
    *eventEndPP = next;
4120
4.03M
    switch (tok) {
4121
745k
    case XML_TOK_CDATA_SECT_CLOSE:
4122
745k
      if (parser->m_endCdataSectionHandler)
4123
0
        parser->m_endCdataSectionHandler(parser->m_handlerArg);
4124
      /* BEGIN disabled code */
4125
      /* see comment under XML_TOK_CDATA_SECT_OPEN */
4126
745k
      else if ((0) && parser->m_characterDataHandler)
4127
0
        parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
4128
0
                                       0);
4129
      /* END disabled code */
4130
745k
      else if (parser->m_defaultHandler)
4131
0
        reportDefault(parser, enc, s, next);
4132
745k
      *startPtr = next;
4133
745k
      *nextPtr = next;
4134
745k
      if (parser->m_parsingStatus.parsing == XML_FINISHED)
4135
0
        return XML_ERROR_ABORTED;
4136
745k
      else
4137
745k
        return XML_ERROR_NONE;
4138
3.04M
    case XML_TOK_DATA_NEWLINE:
4139
3.04M
      if (parser->m_characterDataHandler) {
4140
3.04M
        XML_Char c = 0xA;
4141
3.04M
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
4142
3.04M
      } else if (parser->m_defaultHandler)
4143
0
        reportDefault(parser, enc, s, next);
4144
3.04M
      break;
4145
237k
    case XML_TOK_DATA_CHARS: {
4146
237k
      XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
4147
237k
      if (charDataHandler) {
4148
237k
        if (MUST_CONVERT(enc, s)) {
4149
89.9k
          for (;;) {
4150
89.9k
            ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
4151
89.9k
            const enum XML_Convert_Result convert_res = XmlConvert(
4152
89.9k
                enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
4153
89.9k
            *eventEndPP = next;
4154
89.9k
            charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
4155
89.9k
                            (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
4156
89.9k
            if ((convert_res == XML_CONVERT_COMPLETED)
4157
89.9k
                || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
4158
81.5k
              break;
4159
8.33k
            *eventPP = s;
4160
8.33k
          }
4161
81.5k
        } else
4162
156k
          charDataHandler(parser->m_handlerArg, (const XML_Char *)s,
4163
156k
                          (int)((const XML_Char *)next - (const XML_Char *)s));
4164
237k
      } else if (parser->m_defaultHandler)
4165
0
        reportDefault(parser, enc, s, next);
4166
237k
    } break;
4167
353
    case XML_TOK_INVALID:
4168
353
      *eventPP = next;
4169
353
      return XML_ERROR_INVALID_TOKEN;
4170
356
    case XML_TOK_PARTIAL_CHAR:
4171
356
      if (haveMore) {
4172
203
        *nextPtr = s;
4173
203
        return XML_ERROR_NONE;
4174
203
      }
4175
153
      return XML_ERROR_PARTIAL_CHAR;
4176
424
    case XML_TOK_PARTIAL:
4177
1.77k
    case XML_TOK_NONE:
4178
1.77k
      if (haveMore) {
4179
808
        *nextPtr = s;
4180
808
        return XML_ERROR_NONE;
4181
808
      }
4182
964
      return XML_ERROR_UNCLOSED_CDATA_SECTION;
4183
0
    default:
4184
      /* Every token returned by XmlCdataSectionTok() has its own
4185
       * explicit case, so this default case will never be executed.
4186
       * We retain it as a safety net and exclude it from the coverage
4187
       * statistics.
4188
       *
4189
       * LCOV_EXCL_START
4190
       */
4191
0
      *eventPP = next;
4192
0
      return XML_ERROR_UNEXPECTED_STATE;
4193
      /* LCOV_EXCL_STOP */
4194
4.03M
    }
4195
4196
3.28M
    *eventPP = s = next;
4197
3.28M
    switch (parser->m_parsingStatus.parsing) {
4198
35
    case XML_SUSPENDED:
4199
35
      *nextPtr = next;
4200
35
      return XML_ERROR_NONE;
4201
29
    case XML_FINISHED:
4202
29
      return XML_ERROR_ABORTED;
4203
3.28M
    default:;
4204
3.28M
    }
4205
3.28M
  }
4206
  /* not reached */
4207
747k
}
4208
4209
#ifdef XML_DTD
4210
4211
/* The idea here is to avoid using stack for each IGNORE section when
4212
   the whole file is parsed with one call.
4213
*/
4214
static enum XML_Error PTRCALL
4215
ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
4216
473
                       const char **endPtr) {
4217
473
  enum XML_Error result
4218
473
      = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
4219
473
                        (XML_Bool)! parser->m_parsingStatus.finalBuffer);
4220
473
  if (result != XML_ERROR_NONE)
4221
459
    return result;
4222
14
  if (start) {
4223
14
    parser->m_processor = prologProcessor;
4224
14
    return prologProcessor(parser, start, end, endPtr);
4225
14
  }
4226
0
  return result;
4227
14
}
4228
4229
/* startPtr gets set to non-null is the section is closed, and to null
4230
   if the section is not yet closed.
4231
*/
4232
static enum XML_Error
4233
doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
4234
1.56k
                const char *end, const char **nextPtr, XML_Bool haveMore) {
4235
1.56k
  const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
4236
1.56k
  int tok;
4237
1.56k
  const char *s = *startPtr;
4238
1.56k
  const char **eventPP;
4239
1.56k
  const char **eventEndPP;
4240
1.56k
  if (enc == parser->m_encoding) {
4241
1.56k
    eventPP = &parser->m_eventPtr;
4242
1.56k
    *eventPP = s;
4243
1.56k
    eventEndPP = &parser->m_eventEndPtr;
4244
1.56k
  } else {
4245
    /* It's not entirely clear, but it seems the following two lines
4246
     * of code cannot be executed.  The only occasions on which 'enc'
4247
     * is not 'encoding' are when this function is called
4248
     * from the internal entity processing, and IGNORE sections are an
4249
     * error in internal entities.
4250
     *
4251
     * Since it really isn't clear that this is true, we keep the code
4252
     * and just remove it from our coverage tests.
4253
     *
4254
     * LCOV_EXCL_START
4255
     */
4256
0
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4257
0
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
4258
    /* LCOV_EXCL_STOP */
4259
0
  }
4260
1.56k
  *eventPP = s;
4261
1.56k
  *startPtr = NULL;
4262
1.56k
  tok = XmlIgnoreSectionTok(enc, s, end, &next);
4263
1.56k
#  if XML_GE == 1
4264
1.56k
  if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
4265
1.56k
                                XML_ACCOUNT_DIRECT)) {
4266
0
    accountingOnAbort(parser);
4267
0
    return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4268
0
  }
4269
1.56k
#  endif
4270
1.56k
  *eventEndPP = next;
4271
1.56k
  switch (tok) {
4272
547
  case XML_TOK_IGNORE_SECT:
4273
547
    if (parser->m_defaultHandler)
4274
0
      reportDefault(parser, enc, s, next);
4275
547
    *startPtr = next;
4276
547
    *nextPtr = next;
4277
547
    if (parser->m_parsingStatus.parsing == XML_FINISHED)
4278
0
      return XML_ERROR_ABORTED;
4279
547
    else
4280
547
      return XML_ERROR_NONE;
4281
135
  case XML_TOK_INVALID:
4282
135
    *eventPP = next;
4283
135
    return XML_ERROR_INVALID_TOKEN;
4284
91
  case XML_TOK_PARTIAL_CHAR:
4285
91
    if (haveMore) {
4286
56
      *nextPtr = s;
4287
56
      return XML_ERROR_NONE;
4288
56
    }
4289
35
    return XML_ERROR_PARTIAL_CHAR;
4290
794
  case XML_TOK_PARTIAL:
4291
794
  case XML_TOK_NONE:
4292
794
    if (haveMore) {
4293
417
      *nextPtr = s;
4294
417
      return XML_ERROR_NONE;
4295
417
    }
4296
377
    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
4297
0
  default:
4298
    /* All of the tokens that XmlIgnoreSectionTok() returns have
4299
     * explicit cases to handle them, so this default case is never
4300
     * executed.  We keep it as a safety net anyway, and remove it
4301
     * from our test coverage statistics.
4302
     *
4303
     * LCOV_EXCL_START
4304
     */
4305
0
    *eventPP = next;
4306
0
    return XML_ERROR_UNEXPECTED_STATE;
4307
    /* LCOV_EXCL_STOP */
4308
1.56k
  }
4309
  /* not reached */
4310
1.56k
}
4311
4312
#endif /* XML_DTD */
4313
4314
static enum XML_Error
4315
80.8k
initializeEncoding(XML_Parser parser) {
4316
80.8k
  const char *s;
4317
#ifdef XML_UNICODE
4318
  char encodingBuf[128];
4319
  /* See comments about `protocolEncodingName` in parserInit() */
4320
  if (! parser->m_protocolEncodingName)
4321
    s = NULL;
4322
  else {
4323
    int i;
4324
    for (i = 0; parser->m_protocolEncodingName[i]; i++) {
4325
      if (i == sizeof(encodingBuf) - 1
4326
          || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
4327
        encodingBuf[0] = '\0';
4328
        break;
4329
      }
4330
      encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
4331
    }
4332
    encodingBuf[i] = '\0';
4333
    s = encodingBuf;
4334
  }
4335
#else
4336
80.8k
  s = parser->m_protocolEncodingName;
4337
80.8k
#endif
4338
80.8k
  if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
4339
80.8k
          &parser->m_initEncoding, &parser->m_encoding, s))
4340
80.8k
    return XML_ERROR_NONE;
4341
0
  return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
4342
80.8k
}
4343
4344
static enum XML_Error
4345
processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
4346
1.36k
               const char *next) {
4347
1.36k
  const char *encodingName = NULL;
4348
1.36k
  const XML_Char *storedEncName = NULL;
4349
1.36k
  const ENCODING *newEncoding = NULL;
4350
1.36k
  const char *version = NULL;
4351
1.36k
  const char *versionend = NULL;
4352
1.36k
  const XML_Char *storedversion = NULL;
4353
1.36k
  int standalone = -1;
4354
4355
1.36k
#if XML_GE == 1
4356
1.36k
  if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__,
4357
1.36k
                                XML_ACCOUNT_DIRECT)) {
4358
0
    accountingOnAbort(parser);
4359
0
    return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4360
0
  }
4361
1.36k
#endif
4362
4363
1.36k
  if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
4364
1.36k
          isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
4365
1.36k
          &version, &versionend, &encodingName, &newEncoding, &standalone)) {
4366
760
    if (isGeneralTextEntity)
4367
466
      return XML_ERROR_TEXT_DECL;
4368
294
    else
4369
294
      return XML_ERROR_XML_DECL;
4370
760
  }
4371
602
  if (! isGeneralTextEntity && standalone == 1) {
4372
39
    parser->m_dtd->standalone = XML_TRUE;
4373
39
#ifdef XML_DTD
4374
39
    if (parser->m_paramEntityParsing
4375
39
        == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
4376
0
      parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
4377
39
#endif /* XML_DTD */
4378
39
  }
4379
602
  if (parser->m_xmlDeclHandler) {
4380
0
    if (encodingName != NULL) {
4381
0
      storedEncName = poolStoreString(
4382
0
          &parser->m_temp2Pool, parser->m_encoding, encodingName,
4383
0
          encodingName + XmlNameLength(parser->m_encoding, encodingName));
4384
0
      if (! storedEncName)
4385
0
        return XML_ERROR_NO_MEMORY;
4386
0
      poolFinish(&parser->m_temp2Pool);
4387
0
    }
4388
0
    if (version) {
4389
0
      storedversion
4390
0
          = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
4391
0
                            versionend - parser->m_encoding->minBytesPerChar);
4392
0
      if (! storedversion)
4393
0
        return XML_ERROR_NO_MEMORY;
4394
0
    }
4395
0
    parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
4396
0
                             standalone);
4397
602
  } else if (parser->m_defaultHandler)
4398
0
    reportDefault(parser, parser->m_encoding, s, next);
4399
602
  if (parser->m_protocolEncodingName == NULL) {
4400
549
    if (newEncoding) {
4401
      /* Check that the specified encoding does not conflict with what
4402
       * the parser has already deduced.  Do we have the same number
4403
       * of bytes in the smallest representation of a character?  If
4404
       * this is UTF-16, is it the same endianness?
4405
       */
4406
421
      if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
4407
421
          || (newEncoding->minBytesPerChar == 2
4408
416
              && newEncoding != parser->m_encoding)) {
4409
5
        parser->m_eventPtr = encodingName;
4410
5
        return XML_ERROR_INCORRECT_ENCODING;
4411
5
      }
4412
416
      parser->m_encoding = newEncoding;
4413
416
    } else if (encodingName) {
4414
92
      enum XML_Error result;
4415
92
      if (! storedEncName) {
4416
92
        storedEncName = poolStoreString(
4417
92
            &parser->m_temp2Pool, parser->m_encoding, encodingName,
4418
92
            encodingName + XmlNameLength(parser->m_encoding, encodingName));
4419
92
        if (! storedEncName)
4420
0
          return XML_ERROR_NO_MEMORY;
4421
92
      }
4422
92
      result = handleUnknownEncoding(parser, storedEncName);
4423
92
      poolClear(&parser->m_temp2Pool);
4424
92
      if (result == XML_ERROR_UNKNOWN_ENCODING)
4425
92
        parser->m_eventPtr = encodingName;
4426
92
      return result;
4427
92
    }
4428
549
  }
4429
4430
505
  if (storedEncName || storedversion)
4431
0
    poolClear(&parser->m_temp2Pool);
4432
4433
505
  return XML_ERROR_NONE;
4434
602
}
4435
4436
static enum XML_Error
4437
92
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
4438
92
  if (parser->m_unknownEncodingHandler) {
4439
0
    XML_Encoding info;
4440
0
    int i;
4441
0
    for (i = 0; i < 256; i++)
4442
0
      info.map[i] = -1;
4443
0
    info.convert = NULL;
4444
0
    info.data = NULL;
4445
0
    info.release = NULL;
4446
0
    if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData,
4447
0
                                         encodingName, &info)) {
4448
0
      ENCODING *enc;
4449
0
      parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
4450
0
      if (! parser->m_unknownEncodingMem) {
4451
0
        if (info.release)
4452
0
          info.release(info.data);
4453
0
        return XML_ERROR_NO_MEMORY;
4454
0
      }
4455
0
      enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
4456
0
          parser->m_unknownEncodingMem, info.map, info.convert, info.data);
4457
0
      if (enc) {
4458
0
        parser->m_unknownEncodingData = info.data;
4459
0
        parser->m_unknownEncodingRelease = info.release;
4460
0
        parser->m_encoding = enc;
4461
0
        return XML_ERROR_NONE;
4462
0
      }
4463
0
    }
4464
0
    if (info.release != NULL)
4465
0
      info.release(info.data);
4466
0
  }
4467
92
  return XML_ERROR_UNKNOWN_ENCODING;
4468
92
}
4469
4470
static enum XML_Error PTRCALL
4471
prologInitProcessor(XML_Parser parser, const char *s, const char *end,
4472
40.4k
                    const char **nextPtr) {
4473
40.4k
  enum XML_Error result = initializeEncoding(parser);
4474
40.4k
  if (result != XML_ERROR_NONE)
4475
0
    return result;
4476
40.4k
  parser->m_processor = prologProcessor;
4477
40.4k
  return prologProcessor(parser, s, end, nextPtr);
4478
40.4k
}
4479
4480
#ifdef XML_DTD
4481
4482
static enum XML_Error PTRCALL
4483
externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
4484
20.2k
                            const char **nextPtr) {
4485
20.2k
  enum XML_Error result = initializeEncoding(parser);
4486
20.2k
  if (result != XML_ERROR_NONE)
4487
0
    return result;
4488
4489
  /* we know now that XML_Parse(Buffer) has been called,
4490
     so we consider the external parameter entity read */
4491
20.2k
  parser->m_dtd->paramEntityRead = XML_TRUE;
4492
4493
20.2k
  if (parser->m_prologState.inEntityValue) {
4494
0
    parser->m_processor = entityValueInitProcessor;
4495
0
    return entityValueInitProcessor(parser, s, end, nextPtr);
4496
20.2k
  } else {
4497
20.2k
    parser->m_processor = externalParEntProcessor;
4498
20.2k
    return externalParEntProcessor(parser, s, end, nextPtr);
4499
20.2k
  }
4500
20.2k
}
4501
4502
static enum XML_Error PTRCALL
4503
entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
4504
0
                         const char **nextPtr) {
4505
0
  int tok;
4506
0
  const char *start = s;
4507
0
  const char *next = start;
4508
0
  parser->m_eventPtr = start;
4509
4510
0
  for (;;) {
4511
0
    tok = XmlPrologTok(parser->m_encoding, start, end, &next);
4512
    /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in:
4513
             - storeEntityValue
4514
             - processXmlDecl
4515
    */
4516
0
    parser->m_eventEndPtr = next;
4517
0
    if (tok <= 0) {
4518
0
      if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
4519
0
        *nextPtr = s;
4520
0
        return XML_ERROR_NONE;
4521
0
      }
4522
0
      switch (tok) {
4523
0
      case XML_TOK_INVALID:
4524
0
        return XML_ERROR_INVALID_TOKEN;
4525
0
      case XML_TOK_PARTIAL:
4526
0
        return XML_ERROR_UNCLOSED_TOKEN;
4527
0
      case XML_TOK_PARTIAL_CHAR:
4528
0
        return XML_ERROR_PARTIAL_CHAR;
4529
0
      case XML_TOK_NONE: /* start == end */
4530
0
      default:
4531
0
        break;
4532
0
      }
4533
      /* found end of entity value - can store it now */
4534
0
      return storeEntityValue(parser, parser->m_encoding, s, end,
4535
0
                              XML_ACCOUNT_DIRECT);
4536
0
    } else if (tok == XML_TOK_XML_DECL) {
4537
0
      enum XML_Error result;
4538
0
      result = processXmlDecl(parser, 0, start, next);
4539
0
      if (result != XML_ERROR_NONE)
4540
0
        return result;
4541
      /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED.  For
4542
       * that to happen, a parameter entity parsing handler must have attempted
4543
       * to suspend the parser, which fails and raises an error.  The parser can
4544
       * be aborted, but can't be suspended.
4545
       */
4546
0
      if (parser->m_parsingStatus.parsing == XML_FINISHED)
4547
0
        return XML_ERROR_ABORTED;
4548
0
      *nextPtr = next;
4549
      /* stop scanning for text declaration - we found one */
4550
0
      parser->m_processor = entityValueProcessor;
4551
0
      return entityValueProcessor(parser, next, end, nextPtr);
4552
0
    }
4553
    /* XmlPrologTok has now set the encoding based on the BOM it found, and we
4554
       must move s and nextPtr forward to consume the BOM.
4555
4556
       If we didn't, and got XML_TOK_NONE from the next XmlPrologTok call, we
4557
       would leave the BOM in the buffer and return. On the next call to this
4558
       function, our XmlPrologTok call would return XML_TOK_INVALID, since it
4559
       is not valid to have multiple BOMs.
4560
    */
4561
0
    else if (tok == XML_TOK_BOM) {
4562
0
#  if XML_GE == 1
4563
0
      if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
4564
0
                                    XML_ACCOUNT_DIRECT)) {
4565
0
        accountingOnAbort(parser);
4566
0
        return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4567
0
      }
4568
0
#  endif
4569
4570
0
      *nextPtr = next;
4571
0
      s = next;
4572
0
    }
4573
    /* If we get this token, we have the start of what might be a
4574
       normal tag, but not a declaration (i.e. it doesn't begin with
4575
       "<!").  In a DTD context, that isn't legal.
4576
    */
4577
0
    else if (tok == XML_TOK_INSTANCE_START) {
4578
0
      *nextPtr = next;
4579
0
      return XML_ERROR_SYNTAX;
4580
0
    }
4581
0
    start = next;
4582
0
    parser->m_eventPtr = start;
4583
0
  }
4584
0
}
4585
4586
static enum XML_Error PTRCALL
4587
externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
4588
21.9k
                        const char **nextPtr) {
4589
21.9k
  const char *next = s;
4590
21.9k
  int tok;
4591
4592
21.9k
  tok = XmlPrologTok(parser->m_encoding, s, end, &next);
4593
21.9k
  if (tok <= 0) {
4594
6.06k
    if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
4595
1.70k
      *nextPtr = s;
4596
1.70k
      return XML_ERROR_NONE;
4597
1.70k
    }
4598
4.36k
    switch (tok) {
4599
3.91k
    case XML_TOK_INVALID:
4600
3.91k
      return XML_ERROR_INVALID_TOKEN;
4601
175
    case XML_TOK_PARTIAL:
4602
175
      return XML_ERROR_UNCLOSED_TOKEN;
4603
86
    case XML_TOK_PARTIAL_CHAR:
4604
86
      return XML_ERROR_PARTIAL_CHAR;
4605
0
    case XML_TOK_NONE: /* start == end */
4606
189
    default:
4607
189
      break;
4608
4.36k
    }
4609
4.36k
  }
4610
  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
4611
     However, when parsing an external subset, doProlog will not accept a BOM
4612
     as valid, and report a syntax error, so we have to skip the BOM, and
4613
     account for the BOM bytes.
4614
  */
4615
15.8k
  else if (tok == XML_TOK_BOM) {
4616
3.58k
    if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
4617
3.58k
                                  XML_ACCOUNT_DIRECT)) {
4618
5
      accountingOnAbort(parser);
4619
5
      return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4620
5
    }
4621
4622
3.57k
    s = next;
4623
3.57k
    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
4624
3.57k
  }
4625
4626
16.0k
  parser->m_processor = prologProcessor;
4627
16.0k
  return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4628
16.0k
                  (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
4629
16.0k
                  XML_ACCOUNT_DIRECT);
4630
21.9k
}
4631
4632
static enum XML_Error PTRCALL
4633
entityValueProcessor(XML_Parser parser, const char *s, const char *end,
4634
0
                     const char **nextPtr) {
4635
0
  const char *start = s;
4636
0
  const char *next = s;
4637
0
  const ENCODING *enc = parser->m_encoding;
4638
0
  int tok;
4639
4640
0
  for (;;) {
4641
0
    tok = XmlPrologTok(enc, start, end, &next);
4642
    /* Note: These bytes are accounted later in:
4643
             - storeEntityValue
4644
    */
4645
0
    if (tok <= 0) {
4646
0
      if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
4647
0
        *nextPtr = s;
4648
0
        return XML_ERROR_NONE;
4649
0
      }
4650
0
      switch (tok) {
4651
0
      case XML_TOK_INVALID:
4652
0
        return XML_ERROR_INVALID_TOKEN;
4653
0
      case XML_TOK_PARTIAL:
4654
0
        return XML_ERROR_UNCLOSED_TOKEN;
4655
0
      case XML_TOK_PARTIAL_CHAR:
4656
0
        return XML_ERROR_PARTIAL_CHAR;
4657
0
      case XML_TOK_NONE: /* start == end */
4658
0
      default:
4659
0
        break;
4660
0
      }
4661
      /* found end of entity value - can store it now */
4662
0
      return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT);
4663
0
    }
4664
0
    start = next;
4665
0
  }
4666
0
}
4667
4668
#endif /* XML_DTD */
4669
4670
static enum XML_Error PTRCALL
4671
prologProcessor(XML_Parser parser, const char *s, const char *end,
4672
50.3k
                const char **nextPtr) {
4673
50.3k
  const char *next = s;
4674
50.3k
  int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
4675
50.3k
  return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
4676
50.3k
                  (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE,
4677
50.3k
                  XML_ACCOUNT_DIRECT);
4678
50.3k
}
4679
4680
static enum XML_Error
4681
doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
4682
         int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
4683
66.3k
         XML_Bool allowClosingDoctype, enum XML_Account account) {
4684
66.3k
#ifdef XML_DTD
4685
66.3k
  static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'};
4686
66.3k
#endif /* XML_DTD */
4687
66.3k
  static const XML_Char atypeCDATA[]
4688
66.3k
      = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'};
4689
66.3k
  static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'};
4690
66.3k
  static const XML_Char atypeIDREF[]
4691
66.3k
      = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'};
4692
66.3k
  static const XML_Char atypeIDREFS[]
4693
66.3k
      = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'};
4694
66.3k
  static const XML_Char atypeENTITY[]
4695
66.3k
      = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'};
4696
66.3k
  static const XML_Char atypeENTITIES[]
4697
66.3k
      = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T,
4698
66.3k
         ASCII_I, ASCII_E, ASCII_S, '\0'};
4699
66.3k
  static const XML_Char atypeNMTOKEN[]
4700
66.3k
      = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'};
4701
66.3k
  static const XML_Char atypeNMTOKENS[]
4702
66.3k
      = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K,
4703
66.3k
         ASCII_E, ASCII_N, ASCII_S, '\0'};
4704
66.3k
  static const XML_Char notationPrefix[]
4705
66.3k
      = {ASCII_N, ASCII_O, ASCII_T, ASCII_A,      ASCII_T,
4706
66.3k
         ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'};
4707
66.3k
  static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'};
4708
66.3k
  static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'};
4709
4710
#ifndef XML_DTD
4711
  UNUSED_P(account);
4712
#endif
4713
4714
  /* save one level of indirection */
4715
66.3k
  DTD *const dtd = parser->m_dtd;
4716
4717
66.3k
  const char **eventPP;
4718
66.3k
  const char **eventEndPP;
4719
66.3k
  enum XML_Content_Quant quant;
4720
4721
66.3k
  if (enc == parser->m_encoding) {
4722
66.3k
    eventPP = &parser->m_eventPtr;
4723
66.3k
    eventEndPP = &parser->m_eventEndPtr;
4724
66.3k
  } else {
4725
0
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4726
0
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
4727
0
  }
4728
4729
8.19M
  for (;;) {
4730
8.19M
    int role;
4731
8.19M
    XML_Bool handleDefault = XML_TRUE;
4732
8.19M
    *eventPP = s;
4733
8.19M
    *eventEndPP = next;
4734
8.19M
    if (tok <= 0) {
4735
31.5k
      if (haveMore && tok != XML_TOK_INVALID) {
4736
9.90k
        *nextPtr = s;
4737
9.90k
        return XML_ERROR_NONE;
4738
9.90k
      }
4739
21.6k
      switch (tok) {
4740
18.9k
      case XML_TOK_INVALID:
4741
18.9k
        *eventPP = next;
4742
18.9k
        return XML_ERROR_INVALID_TOKEN;
4743
901
      case XML_TOK_PARTIAL:
4744
901
        return XML_ERROR_UNCLOSED_TOKEN;
4745
208
      case XML_TOK_PARTIAL_CHAR:
4746
208
        return XML_ERROR_PARTIAL_CHAR;
4747
124
      case -XML_TOK_PROLOG_S:
4748
124
        tok = -tok;
4749
124
        break;
4750
643
      case XML_TOK_NONE:
4751
643
#ifdef XML_DTD
4752
        /* for internal PE NOT referenced between declarations */
4753
643
        if (enc != parser->m_encoding
4754
643
            && ! parser->m_openInternalEntities->betweenDecl) {
4755
0
          *nextPtr = s;
4756
0
          return XML_ERROR_NONE;
4757
0
        }
4758
        /* WFC: PE Between Declarations - must check that PE contains
4759
           complete markup, not only for external PEs, but also for
4760
           internal PEs if the reference occurs between declarations.
4761
        */
4762
643
        if (parser->m_isParamEntity || enc != parser->m_encoding) {
4763
352
          if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
4764
352
              == XML_ROLE_ERROR)
4765
86
            return XML_ERROR_INCOMPLETE_PE;
4766
266
          *nextPtr = s;
4767
266
          return XML_ERROR_NONE;
4768
352
        }
4769
291
#endif /* XML_DTD */
4770
291
        return XML_ERROR_NO_ELEMENTS;
4771
771
      default:
4772
771
        tok = -tok;
4773
771
        next = end;
4774
771
        break;
4775
21.6k
      }
4776
21.6k
    }
4777
8.16M
    role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
4778
8.16M
#if XML_GE == 1
4779
8.16M
    switch (role) {
4780
14.2k
    case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor
4781
14.7k
    case XML_ROLE_XML_DECL:       // bytes accounted in processXmlDecl
4782
14.7k
#  ifdef XML_DTD
4783
15.1k
    case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl
4784
15.1k
#  endif
4785
15.1k
      break;
4786
8.14M
    default:
4787
8.14M
      if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
4788
1
        accountingOnAbort(parser);
4789
1
        return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4790
1
      }
4791
8.16M
    }
4792
8.16M
#endif
4793
8.16M
    switch (role) {
4794
532
    case XML_ROLE_XML_DECL: {
4795
532
      enum XML_Error result = processXmlDecl(parser, 0, s, next);
4796
532
      if (result != XML_ERROR_NONE)
4797
319
        return result;
4798
213
      enc = parser->m_encoding;
4799
213
      handleDefault = XML_FALSE;
4800
213
    } break;
4801
7.61k
    case XML_ROLE_DOCTYPE_NAME:
4802
7.61k
      if (parser->m_startDoctypeDeclHandler) {
4803
0
        parser->m_doctypeName
4804
0
            = poolStoreString(&parser->m_tempPool, enc, s, next);
4805
0
        if (! parser->m_doctypeName)
4806
0
          return XML_ERROR_NO_MEMORY;
4807
0
        poolFinish(&parser->m_tempPool);
4808
0
        parser->m_doctypePubid = NULL;
4809
0
        handleDefault = XML_FALSE;
4810
0
      }
4811
7.61k
      parser->m_doctypeSysid = NULL; /* always initialize to NULL */
4812
7.61k
      break;
4813
6.48k
    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
4814
6.48k
      if (parser->m_startDoctypeDeclHandler) {
4815
0
        parser->m_startDoctypeDeclHandler(
4816
0
            parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4817
0
            parser->m_doctypePubid, 1);
4818
0
        parser->m_doctypeName = NULL;
4819
0
        poolClear(&parser->m_tempPool);
4820
0
        handleDefault = XML_FALSE;
4821
0
      }
4822
6.48k
      break;
4823
0
#ifdef XML_DTD
4824
415
    case XML_ROLE_TEXT_DECL: {
4825
415
      enum XML_Error result = processXmlDecl(parser, 1, s, next);
4826
415
      if (result != XML_ERROR_NONE)
4827
269
        return result;
4828
146
      enc = parser->m_encoding;
4829
146
      handleDefault = XML_FALSE;
4830
146
    } break;
4831
0
#endif /* XML_DTD */
4832
996
    case XML_ROLE_DOCTYPE_PUBLIC_ID:
4833
996
#ifdef XML_DTD
4834
996
      parser->m_useForeignDTD = XML_FALSE;
4835
996
      parser->m_declEntity = (ENTITY *)lookup(
4836
996
          parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
4837
996
      if (! parser->m_declEntity)
4838
0
        return XML_ERROR_NO_MEMORY;
4839
996
#endif /* XML_DTD */
4840
996
      dtd->hasParamEntityRefs = XML_TRUE;
4841
996
      if (parser->m_startDoctypeDeclHandler) {
4842
0
        XML_Char *pubId;
4843
0
        if (! XmlIsPublicId(enc, s, next, eventPP))
4844
0
          return XML_ERROR_PUBLICID;
4845
0
        pubId = poolStoreString(&parser->m_tempPool, enc,
4846
0
                                s + enc->minBytesPerChar,
4847
0
                                next - enc->minBytesPerChar);
4848
0
        if (! pubId)
4849
0
          return XML_ERROR_NO_MEMORY;
4850
0
        normalizePublicId(pubId);
4851
0
        poolFinish(&parser->m_tempPool);
4852
0
        parser->m_doctypePubid = pubId;
4853
0
        handleDefault = XML_FALSE;
4854
0
        goto alreadyChecked;
4855
0
      }
4856
      /* fall through */
4857
4.96k
    case XML_ROLE_ENTITY_PUBLIC_ID:
4858
4.96k
      if (! XmlIsPublicId(enc, s, next, eventPP))
4859
548
        return XML_ERROR_PUBLICID;
4860
4.41k
    alreadyChecked:
4861
4.41k
      if (dtd->keepProcessing && parser->m_declEntity) {
4862
1.07k
        XML_Char *tem
4863
1.07k
            = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
4864
1.07k
                              next - enc->minBytesPerChar);
4865
1.07k
        if (! tem)
4866
0
          return XML_ERROR_NO_MEMORY;
4867
1.07k
        normalizePublicId(tem);
4868
1.07k
        parser->m_declEntity->publicId = tem;
4869
1.07k
        poolFinish(&dtd->pool);
4870
        /* Don't suppress the default handler if we fell through from
4871
         * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
4872
         */
4873
1.07k
        if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
4874
0
          handleDefault = XML_FALSE;
4875
1.07k
      }
4876
4.41k
      break;
4877
4.41k
    case XML_ROLE_DOCTYPE_CLOSE:
4878
3.42k
      if (allowClosingDoctype != XML_TRUE) {
4879
        /* Must not close doctype from within expanded parameter entities */
4880
0
        return XML_ERROR_INVALID_TOKEN;
4881
0
      }
4882
4883
3.42k
      if (parser->m_doctypeName) {
4884
0
        parser->m_startDoctypeDeclHandler(
4885
0
            parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4886
0
            parser->m_doctypePubid, 0);
4887
0
        poolClear(&parser->m_tempPool);
4888
0
        handleDefault = XML_FALSE;
4889
0
      }
4890
      /* parser->m_doctypeSysid will be non-NULL in the case of a previous
4891
         XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
4892
         was not set, indicating an external subset
4893
      */
4894
3.42k
#ifdef XML_DTD
4895
3.42k
      if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
4896
15
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4897
15
        dtd->hasParamEntityRefs = XML_TRUE;
4898
15
        if (parser->m_paramEntityParsing
4899
15
            && parser->m_externalEntityRefHandler) {
4900
0
          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4901
0
                                            externalSubsetName, sizeof(ENTITY));
4902
0
          if (! entity) {
4903
            /* The external subset name "#" will have already been
4904
             * inserted into the hash table at the start of the
4905
             * external entity parsing, so no allocation will happen
4906
             * and lookup() cannot fail.
4907
             */
4908
0
            return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4909
0
          }
4910
0
          if (parser->m_useForeignDTD)
4911
0
            entity->base = parser->m_curBase;
4912
0
          dtd->paramEntityRead = XML_FALSE;
4913
0
          if (! parser->m_externalEntityRefHandler(
4914
0
                  parser->m_externalEntityRefHandlerArg, 0, entity->base,
4915
0
                  entity->systemId, entity->publicId))
4916
0
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4917
0
          if (dtd->paramEntityRead) {
4918
0
            if (! dtd->standalone && parser->m_notStandaloneHandler
4919
0
                && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
4920
0
              return XML_ERROR_NOT_STANDALONE;
4921
0
          }
4922
          /* if we didn't read the foreign DTD then this means that there
4923
             is no external subset and we must reset dtd->hasParamEntityRefs
4924
          */
4925
0
          else if (! parser->m_doctypeSysid)
4926
0
            dtd->hasParamEntityRefs = hadParamEntityRefs;
4927
          /* end of DTD - no need to update dtd->keepProcessing */
4928
0
        }
4929
15
        parser->m_useForeignDTD = XML_FALSE;
4930
15
      }
4931
3.42k
#endif /* XML_DTD */
4932
3.42k
      if (parser->m_endDoctypeDeclHandler) {
4933
0
        parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
4934
0
        handleDefault = XML_FALSE;
4935
0
      }
4936
3.42k
      break;
4937
14.2k
    case XML_ROLE_INSTANCE_START:
4938
14.2k
#ifdef XML_DTD
4939
      /* if there is no DOCTYPE declaration then now is the
4940
         last chance to read the foreign DTD
4941
      */
4942
14.2k
      if (parser->m_useForeignDTD) {
4943
0
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4944
0
        dtd->hasParamEntityRefs = XML_TRUE;
4945
0
        if (parser->m_paramEntityParsing
4946
0
            && parser->m_externalEntityRefHandler) {
4947
0
          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4948
0
                                            externalSubsetName, sizeof(ENTITY));
4949
0
          if (! entity)
4950
0
            return XML_ERROR_NO_MEMORY;
4951
0
          entity->base = parser->m_curBase;
4952
0
          dtd->paramEntityRead = XML_FALSE;
4953
0
          if (! parser->m_externalEntityRefHandler(
4954
0
                  parser->m_externalEntityRefHandlerArg, 0, entity->base,
4955
0
                  entity->systemId, entity->publicId))
4956
0
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4957
0
          if (dtd->paramEntityRead) {
4958
0
            if (! dtd->standalone && parser->m_notStandaloneHandler
4959
0
                && ! parser->m_notStandaloneHandler(parser->m_handlerArg))
4960
0
              return XML_ERROR_NOT_STANDALONE;
4961
0
          }
4962
          /* if we didn't read the foreign DTD then this means that there
4963
             is no external subset and we must reset dtd->hasParamEntityRefs
4964
          */
4965
0
          else
4966
0
            dtd->hasParamEntityRefs = hadParamEntityRefs;
4967
          /* end of DTD - no need to update dtd->keepProcessing */
4968
0
        }
4969
0
      }
4970
14.2k
#endif /* XML_DTD */
4971
14.2k
      parser->m_processor = contentProcessor;
4972
14.2k
      return contentProcessor(parser, s, end, nextPtr);
4973
10.3k
    case XML_ROLE_ATTLIST_ELEMENT_NAME:
4974
10.3k
      parser->m_declElementType = getElementType(parser, enc, s, next);
4975
10.3k
      if (! parser->m_declElementType)
4976
0
        return XML_ERROR_NO_MEMORY;
4977
10.3k
      goto checkAttListDeclHandler;
4978
76.5k
    case XML_ROLE_ATTRIBUTE_NAME:
4979
76.5k
      parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
4980
76.5k
      if (! parser->m_declAttributeId)
4981
0
        return XML_ERROR_NO_MEMORY;
4982
76.5k
      parser->m_declAttributeIsCdata = XML_FALSE;
4983
76.5k
      parser->m_declAttributeType = NULL;
4984
76.5k
      parser->m_declAttributeIsId = XML_FALSE;
4985
76.5k
      goto checkAttListDeclHandler;
4986
272
    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4987
272
      parser->m_declAttributeIsCdata = XML_TRUE;
4988
272
      parser->m_declAttributeType = atypeCDATA;
4989
272
      goto checkAttListDeclHandler;
4990
3.88k
    case XML_ROLE_ATTRIBUTE_TYPE_ID:
4991
3.88k
      parser->m_declAttributeIsId = XML_TRUE;
4992
3.88k
      parser->m_declAttributeType = atypeID;
4993
3.88k
      goto checkAttListDeclHandler;
4994
1.32k
    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4995
1.32k
      parser->m_declAttributeType = atypeIDREF;
4996
1.32k
      goto checkAttListDeclHandler;
4997
698
    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4998
698
      parser->m_declAttributeType = atypeIDREFS;
4999
698
      goto checkAttListDeclHandler;
5000
343
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
5001
343
      parser->m_declAttributeType = atypeENTITY;
5002
343
      goto checkAttListDeclHandler;
5003
3.68k
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
5004
3.68k
      parser->m_declAttributeType = atypeENTITIES;
5005
3.68k
      goto checkAttListDeclHandler;
5006
20
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
5007
20
      parser->m_declAttributeType = atypeNMTOKEN;
5008
20
      goto checkAttListDeclHandler;
5009
34
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
5010
34
      parser->m_declAttributeType = atypeNMTOKENS;
5011
97.1k
    checkAttListDeclHandler:
5012
97.1k
      if (dtd->keepProcessing && parser->m_attlistDeclHandler)
5013
0
        handleDefault = XML_FALSE;
5014
97.1k
      break;
5015
123k
    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
5016
124k
    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
5017
124k
      if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
5018
0
        const XML_Char *prefix;
5019
0
        if (parser->m_declAttributeType) {
5020
0
          prefix = enumValueSep;
5021
0
        } else {
5022
0
          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
5023
0
                                                              : enumValueStart);
5024
0
        }
5025
0
        if (! poolAppendString(&parser->m_tempPool, prefix))
5026
0
          return XML_ERROR_NO_MEMORY;
5027
0
        if (! poolAppend(&parser->m_tempPool, enc, s, next))
5028
0
          return XML_ERROR_NO_MEMORY;
5029
0
        parser->m_declAttributeType = parser->m_tempPool.start;
5030
0
        handleDefault = XML_FALSE;
5031
0
      }
5032
124k
      break;
5033
124k
    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
5034
64.1k
    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
5035
64.1k
      if (dtd->keepProcessing) {
5036
63.9k
        if (! defineAttribute(parser->m_declElementType,
5037
63.9k
                              parser->m_declAttributeId,
5038
63.9k
                              parser->m_declAttributeIsCdata,
5039
63.9k
                              parser->m_declAttributeIsId, 0, parser))
5040
0
          return XML_ERROR_NO_MEMORY;
5041
63.9k
        if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
5042
0
          if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
5043
0
              || (*parser->m_declAttributeType == XML_T(ASCII_N)
5044
0
                  && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
5045
            /* Enumerated or Notation type */
5046
0
            if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
5047
0
                || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')))
5048
0
              return XML_ERROR_NO_MEMORY;
5049
0
            parser->m_declAttributeType = parser->m_tempPool.start;
5050
0
            poolFinish(&parser->m_tempPool);
5051
0
          }
5052
0
          *eventEndPP = s;
5053
0
          parser->m_attlistDeclHandler(
5054
0
              parser->m_handlerArg, parser->m_declElementType->name,
5055
0
              parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
5056
0
              role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
5057
0
          handleDefault = XML_FALSE;
5058
0
        }
5059
63.9k
      }
5060
64.1k
      poolClear(&parser->m_tempPool);
5061
64.1k
      break;
5062
10.5k
    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
5063
11.6k
    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
5064
11.6k
      if (dtd->keepProcessing) {
5065
11.5k
        const XML_Char *attVal;
5066
11.5k
        enum XML_Error result = storeAttributeValue(
5067
11.5k
            parser, enc, parser->m_declAttributeIsCdata,
5068
11.5k
            s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool,
5069
11.5k
            XML_ACCOUNT_NONE);
5070
11.5k
        if (result)
5071
67
          return result;
5072
11.4k
        attVal = poolStart(&dtd->pool);
5073
11.4k
        poolFinish(&dtd->pool);
5074
        /* ID attributes aren't allowed to have a default */
5075
11.4k
        if (! defineAttribute(
5076
11.4k
                parser->m_declElementType, parser->m_declAttributeId,
5077
11.4k
                parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
5078
0
          return XML_ERROR_NO_MEMORY;