GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libexpat/lib/xmlparse.c Lines: 3248 3422 94.9 %
Date: 2017-11-13 Branches: 1997 2372 84.2 %

Line Branch Exec Source
1
/* 4b74aa710b4ed5ce464b0ce544852cb47bf905c85a49c7bae2749f5885cb966d (2.2.5+)
2
                            __  __            _
3
                         ___\ \/ /_ __   __ _| |_
4
                        / _ \\  /| '_ \ / _` | __|
5
                       |  __//  \| |_) | (_| | |_
6
                        \___/_/\_\ .__/ \__,_|\__|
7
                                 |_| XML parser
8
9
   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10
   Copyright (c) 2000-2017 Expat development team
11
   Licensed under the MIT license:
12
13
   Permission is  hereby granted,  free of charge,  to any  person obtaining
14
   a  copy  of  this  software   and  associated  documentation  files  (the
15
   "Software"),  to  deal in  the  Software  without restriction,  including
16
   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
17
   distribute, sublicense, and/or sell copies of the Software, and to permit
18
   persons  to whom  the Software  is  furnished to  do so,  subject to  the
19
   following conditions:
20
21
   The above copyright  notice and this permission notice  shall be included
22
   in all copies or substantial portions of the Software.
23
24
   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
25
   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
26
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
27
   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
28
   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
29
   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
30
   USE OR OTHER DEALINGS IN THE SOFTWARE.
31
*/
32
33
#if !defined(_GNU_SOURCE)
34
# define _GNU_SOURCE 1                  /* syscall prototype */
35
#endif
36
37
#include <stddef.h>
38
#include <string.h>                     /* memset(), memcpy() */
39
#include <assert.h>
40
#include <limits.h>                     /* UINT_MAX */
41
#include <stdio.h>                      /* fprintf */
42
#include <stdlib.h>                     /* getenv */
43
44
#ifdef _WIN32
45
#define getpid GetCurrentProcessId
46
#else
47
#include <sys/time.h>                   /* gettimeofday() */
48
#include <sys/types.h>                  /* getpid() */
49
#include <unistd.h>                     /* getpid() */
50
#include <fcntl.h>                      /* O_RDONLY */
51
#include <errno.h>
52
#endif
53
54
#define XML_BUILDING_EXPAT 1
55
56
#ifdef _WIN32
57
#include "winconfig.h"
58
#elif defined(HAVE_EXPAT_CONFIG_H)
59
#include <expat_config.h>
60
#endif /* ndef _WIN32 */
61
62
#include "ascii.h"
63
#include "expat.h"
64
#include "siphash.h"
65
66
#ifdef XML_UNICODE
67
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
68
#define XmlConvert XmlUtf16Convert
69
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
70
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
71
#define XmlEncode XmlUtf16Encode
72
/* Using pointer subtraction to convert to integer type. */
73
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
74
typedef unsigned short ICHAR;
75
#else
76
#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
77
#define XmlConvert XmlUtf8Convert
78
#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
79
#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
80
#define XmlEncode XmlUtf8Encode
81
#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
82
typedef char ICHAR;
83
#endif
84
85
86
#ifndef XML_NS
87
88
#define XmlInitEncodingNS XmlInitEncoding
89
#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
90
#undef XmlGetInternalEncodingNS
91
#define XmlGetInternalEncodingNS XmlGetInternalEncoding
92
#define XmlParseXmlDeclNS XmlParseXmlDecl
93
94
#endif
95
96
#ifdef XML_UNICODE
97
98
#ifdef XML_UNICODE_WCHAR_T
99
#define XML_T(x) (const wchar_t)x
100
#define XML_L(x) L ## x
101
#else
102
#define XML_T(x) (const unsigned short)x
103
#define XML_L(x) x
104
#endif
105
106
#else
107
108
#define XML_T(x) x
109
#define XML_L(x) x
110
111
#endif
112
113
/* Round up n to be a multiple of sz, where sz is a power of 2. */
114
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
115
116
/* Handle the case where memmove() doesn't exist. */
117
#ifndef HAVE_MEMMOVE
118
#ifdef HAVE_BCOPY
119
#define memmove(d,s,l) bcopy((s),(d),(l))
120
#else
121
#error memmove does not exist on this platform, nor is a substitute available
122
#endif /* HAVE_BCOPY */
123
#endif /* HAVE_MEMMOVE */
124
125
#include "internal.h"
126
#include "xmltok.h"
127
#include "xmlrole.h"
128
129
typedef const XML_Char *KEY;
130
131
typedef struct {
132
  KEY name;
133
} NAMED;
134
135
typedef struct {
136
  NAMED **v;
137
  unsigned char power;
138
  size_t size;
139
  size_t used;
140
  const XML_Memory_Handling_Suite *mem;
141
} HASH_TABLE;
142
143
static size_t
144
keylen(KEY s);
145
146
static void
147
copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
148
149
/* For probing (after a collision) we need a step size relative prime
150
   to the hash table size, which is a power of 2. We use double-hashing,
151
   since we can calculate a second hash value cheaply by taking those bits
152
   of the first hash value that were discarded (masked out) when the table
153
   index was calculated: index = hash & mask, where mask = table->size - 1.
154
   We limit the maximum step size to table->size / 4 (mask >> 2) and make
155
   it odd, since odd numbers are always relative prime to a power of 2.
156
*/
157
#define SECOND_HASH(hash, mask, power) \
158
  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
159
#define PROBE_STEP(hash, mask, power) \
160
  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
161
162
typedef struct {
163
  NAMED **p;
164
  NAMED **end;
165
} HASH_TABLE_ITER;
166
167
#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
168
#define INIT_DATA_BUF_SIZE 1024
169
#define INIT_ATTS_SIZE 16
170
#define INIT_ATTS_VERSION 0xFFFFFFFF
171
#define INIT_BLOCK_SIZE 1024
172
#define INIT_BUFFER_SIZE 1024
173
174
#define EXPAND_SPARE 24
175
176
typedef struct binding {
177
  struct prefix *prefix;
178
  struct binding *nextTagBinding;
179
  struct binding *prevPrefixBinding;
180
  const struct attribute_id *attId;
181
  XML_Char *uri;
182
  int uriLen;
183
  int uriAlloc;
184
} BINDING;
185
186
typedef struct prefix {
187
  const XML_Char *name;
188
  BINDING *binding;
189
} PREFIX;
190
191
typedef struct {
192
  const XML_Char *str;
193
  const XML_Char *localPart;
194
  const XML_Char *prefix;
195
  int strLen;
196
  int uriLen;
197
  int prefixLen;
198
} TAG_NAME;
199
200
/* TAG represents an open element.
201
   The name of the element is stored in both the document and API
202
   encodings.  The memory buffer 'buf' is a separately-allocated
203
   memory area which stores the name.  During the XML_Parse()/
204
   XMLParseBuffer() when the element is open, the memory for the 'raw'
205
   version of the name (in the document encoding) is shared with the
206
   document buffer.  If the element is open across calls to
207
   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
208
   contain the 'raw' name as well.
209
210
   A parser re-uses these structures, maintaining a list of allocated
211
   TAG objects in a free list.
212
*/
213
typedef struct tag {
214
  struct tag *parent;           /* parent of this element */
215
  const char *rawName;          /* tagName in the original encoding */
216
  int rawNameLength;
217
  TAG_NAME name;                /* tagName in the API encoding */
218
  char *buf;                    /* buffer for name components */
219
  char *bufEnd;                 /* end of the buffer */
220
  BINDING *bindings;
221
} TAG;
222
223
typedef struct {
224
  const XML_Char *name;
225
  const XML_Char *textPtr;
226
  int textLen;                  /* length in XML_Chars */
227
  int processed;                /* # of processed bytes - when suspended */
228
  const XML_Char *systemId;
229
  const XML_Char *base;
230
  const XML_Char *publicId;
231
  const XML_Char *notation;
232
  XML_Bool open;
233
  XML_Bool is_param;
234
  XML_Bool is_internal; /* true if declared in internal subset outside PE */
235
} ENTITY;
236
237
typedef struct {
238
  enum XML_Content_Type         type;
239
  enum XML_Content_Quant        quant;
240
  const XML_Char *              name;
241
  int                           firstchild;
242
  int                           lastchild;
243
  int                           childcnt;
244
  int                           nextsib;
245
} CONTENT_SCAFFOLD;
246
247
#define INIT_SCAFFOLD_ELEMENTS 32
248
249
typedef struct block {
250
  struct block *next;
251
  int size;
252
  XML_Char s[1];
253
} BLOCK;
254
255
typedef struct {
256
  BLOCK *blocks;
257
  BLOCK *freeBlocks;
258
  const XML_Char *end;
259
  XML_Char *ptr;
260
  XML_Char *start;
261
  const XML_Memory_Handling_Suite *mem;
262
} STRING_POOL;
263
264
/* The XML_Char before the name is used to determine whether
265
   an attribute has been specified. */
266
typedef struct attribute_id {
267
  XML_Char *name;
268
  PREFIX *prefix;
269
  XML_Bool maybeTokenized;
270
  XML_Bool xmlns;
271
} ATTRIBUTE_ID;
272
273
typedef struct {
274
  const ATTRIBUTE_ID *id;
275
  XML_Bool isCdata;
276
  const XML_Char *value;
277
} DEFAULT_ATTRIBUTE;
278
279
typedef struct {
280
  unsigned long version;
281
  unsigned long hash;
282
  const XML_Char *uriName;
283
} NS_ATT;
284
285
typedef struct {
286
  const XML_Char *name;
287
  PREFIX *prefix;
288
  const ATTRIBUTE_ID *idAtt;
289
  int nDefaultAtts;
290
  int allocDefaultAtts;
291
  DEFAULT_ATTRIBUTE *defaultAtts;
292
} ELEMENT_TYPE;
293
294
typedef struct {
295
  HASH_TABLE generalEntities;
296
  HASH_TABLE elementTypes;
297
  HASH_TABLE attributeIds;
298
  HASH_TABLE prefixes;
299
  STRING_POOL pool;
300
  STRING_POOL entityValuePool;
301
  /* false once a parameter entity reference has been skipped */
302
  XML_Bool keepProcessing;
303
  /* true once an internal or external PE reference has been encountered;
304
     this includes the reference to an external subset */
305
  XML_Bool hasParamEntityRefs;
306
  XML_Bool standalone;
307
#ifdef XML_DTD
308
  /* indicates if external PE has been read */
309
  XML_Bool paramEntityRead;
310
  HASH_TABLE paramEntities;
311
#endif /* XML_DTD */
312
  PREFIX defaultPrefix;
313
  /* === scaffolding for building content model === */
314
  XML_Bool in_eldecl;
315
  CONTENT_SCAFFOLD *scaffold;
316
  unsigned contentStringLen;
317
  unsigned scaffSize;
318
  unsigned scaffCount;
319
  int scaffLevel;
320
  int *scaffIndex;
321
} DTD;
322
323
typedef struct open_internal_entity {
324
  const char *internalEventPtr;
325
  const char *internalEventEndPtr;
326
  struct open_internal_entity *next;
327
  ENTITY *entity;
328
  int startTagLevel;
329
  XML_Bool betweenDecl; /* WFC: PE Between Declarations */
330
} OPEN_INTERNAL_ENTITY;
331
332
typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
333
                                         const char *start,
334
                                         const char *end,
335
                                         const char **endPtr);
336
337
static Processor prologProcessor;
338
static Processor prologInitProcessor;
339
static Processor contentProcessor;
340
static Processor cdataSectionProcessor;
341
#ifdef XML_DTD
342
static Processor ignoreSectionProcessor;
343
static Processor externalParEntProcessor;
344
static Processor externalParEntInitProcessor;
345
static Processor entityValueProcessor;
346
static Processor entityValueInitProcessor;
347
#endif /* XML_DTD */
348
static Processor epilogProcessor;
349
static Processor errorProcessor;
350
static Processor externalEntityInitProcessor;
351
static Processor externalEntityInitProcessor2;
352
static Processor externalEntityInitProcessor3;
353
static Processor externalEntityContentProcessor;
354
static Processor internalEntityProcessor;
355
356
static enum XML_Error
357
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
358
static enum XML_Error
359
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
360
               const char *s, const char *next);
361
static enum XML_Error
362
initializeEncoding(XML_Parser parser);
363
static enum XML_Error
364
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
365
         const char *end, int tok, const char *next, const char **nextPtr,
366
         XML_Bool haveMore);
367
static enum XML_Error
368
processInternalEntity(XML_Parser parser, ENTITY *entity,
369
                      XML_Bool betweenDecl);
370
static enum XML_Error
371
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
372
          const char *start, const char *end, const char **endPtr,
373
          XML_Bool haveMore);
374
static enum XML_Error
375
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
376
               const char *end, const char **nextPtr, XML_Bool haveMore);
377
#ifdef XML_DTD
378
static enum XML_Error
379
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
380
                const char *end, const char **nextPtr, XML_Bool haveMore);
381
#endif /* XML_DTD */
382
383
static void
384
freeBindings(XML_Parser parser, BINDING *bindings);
385
static enum XML_Error
386
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
387
          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
388
static enum XML_Error
389
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
390
           const XML_Char *uri, BINDING **bindingsPtr);
391
static int
392
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
393
                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
394
static enum XML_Error
395
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
396
                    const char *, const char *, STRING_POOL *);
397
static enum XML_Error
398
appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
399
                     const char *, const char *, STRING_POOL *);
400
static ATTRIBUTE_ID *
401
getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
402
               const char *end);
403
static int
404
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
405
static enum XML_Error
406
storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
407
                 const char *end);
408
static int
409
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
410
                            const char *start, const char *end);
411
static int
412
reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
413
              const char *end);
414
static void
415
reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
416
              const char *end);
417
418
static const XML_Char * getContext(XML_Parser parser);
419
static XML_Bool
420
setContext(XML_Parser parser, const XML_Char *context);
421
422
static void FASTCALL normalizePublicId(XML_Char *s);
423
424
static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
425
/* do not call if m_parentParser != NULL */
426
static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
427
static void
428
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
429
static int
430
dtdCopy(XML_Parser oldParser,
431
        DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
432
static int
433
copyEntityTable(XML_Parser oldParser,
434
                HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
435
static NAMED *
436
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
437
static void FASTCALL
438
hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
439
static void FASTCALL hashTableClear(HASH_TABLE *);
440
static void FASTCALL hashTableDestroy(HASH_TABLE *);
441
static void FASTCALL
442
hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
443
static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
444
445
static void FASTCALL
446
poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
447
static void FASTCALL poolClear(STRING_POOL *);
448
static void FASTCALL poolDestroy(STRING_POOL *);
449
static XML_Char *
450
poolAppend(STRING_POOL *pool, const ENCODING *enc,
451
           const char *ptr, const char *end);
452
static XML_Char *
453
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
454
                const char *ptr, const char *end);
455
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
456
static const XML_Char * FASTCALL
457
poolCopyString(STRING_POOL *pool, const XML_Char *s);
458
static const XML_Char *
459
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
460
static const XML_Char * FASTCALL
461
poolAppendString(STRING_POOL *pool, const XML_Char *s);
462
463
static int FASTCALL nextScaffoldPart(XML_Parser parser);
464
static XML_Content * build_model(XML_Parser parser);
465
static ELEMENT_TYPE *
466
getElementType(XML_Parser parser, const ENCODING *enc,
467
               const char *ptr, const char *end);
468
469
static XML_Char *copyString(const XML_Char *s,
470
                            const XML_Memory_Handling_Suite *memsuite);
471
472
static unsigned long generate_hash_secret_salt(XML_Parser parser);
473
static XML_Bool startParsing(XML_Parser parser);
474
475
static XML_Parser
476
parserCreate(const XML_Char *encodingName,
477
             const XML_Memory_Handling_Suite *memsuite,
478
             const XML_Char *nameSep,
479
             DTD *dtd);
480
481
static void
482
parserInit(XML_Parser parser, const XML_Char *encodingName);
483
484
#define poolStart(pool) ((pool)->start)
485
#define poolEnd(pool) ((pool)->ptr)
486
#define poolLength(pool) ((pool)->ptr - (pool)->start)
487
#define poolChop(pool) ((void)--(pool->ptr))
488
#define poolLastChar(pool) (((pool)->ptr)[-1])
489
#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
490
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
491
#define poolAppendChar(pool, c) \
492
  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
493
   ? 0 \
494
   : ((*((pool)->ptr)++ = c), 1))
495
496
struct XML_ParserStruct {
497
  /* The first member must be m_userData so that the XML_GetUserData
498
     macro works. */
499
  void *m_userData;
500
  void *m_handlerArg;
501
  char *m_buffer;
502
  const XML_Memory_Handling_Suite m_mem;
503
  /* first character to be parsed */
504
  const char *m_bufferPtr;
505
  /* past last character to be parsed */
506
  char *m_bufferEnd;
507
  /* allocated end of m_buffer */
508
  const char *m_bufferLim;
509
  XML_Index m_parseEndByteIndex;
510
  const char *m_parseEndPtr;
511
  XML_Char *m_dataBuf;
512
  XML_Char *m_dataBufEnd;
513
  XML_StartElementHandler m_startElementHandler;
514
  XML_EndElementHandler m_endElementHandler;
515
  XML_CharacterDataHandler m_characterDataHandler;
516
  XML_ProcessingInstructionHandler m_processingInstructionHandler;
517
  XML_CommentHandler m_commentHandler;
518
  XML_StartCdataSectionHandler m_startCdataSectionHandler;
519
  XML_EndCdataSectionHandler m_endCdataSectionHandler;
520
  XML_DefaultHandler m_defaultHandler;
521
  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
522
  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
523
  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
524
  XML_NotationDeclHandler m_notationDeclHandler;
525
  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
526
  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
527
  XML_NotStandaloneHandler m_notStandaloneHandler;
528
  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
529
  XML_Parser m_externalEntityRefHandlerArg;
530
  XML_SkippedEntityHandler m_skippedEntityHandler;
531
  XML_UnknownEncodingHandler m_unknownEncodingHandler;
532
  XML_ElementDeclHandler m_elementDeclHandler;
533
  XML_AttlistDeclHandler m_attlistDeclHandler;
534
  XML_EntityDeclHandler m_entityDeclHandler;
535
  XML_XmlDeclHandler m_xmlDeclHandler;
536
  const ENCODING *m_encoding;
537
  INIT_ENCODING m_initEncoding;
538
  const ENCODING *m_internalEncoding;
539
  const XML_Char *m_protocolEncodingName;
540
  XML_Bool m_ns;
541
  XML_Bool m_ns_triplets;
542
  void *m_unknownEncodingMem;
543
  void *m_unknownEncodingData;
544
  void *m_unknownEncodingHandlerData;
545
  void (XMLCALL *m_unknownEncodingRelease)(void *);
546
  PROLOG_STATE m_prologState;
547
  Processor *m_processor;
548
  enum XML_Error m_errorCode;
549
  const char *m_eventPtr;
550
  const char *m_eventEndPtr;
551
  const char *m_positionPtr;
552
  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
553
  OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
554
  XML_Bool m_defaultExpandInternalEntities;
555
  int m_tagLevel;
556
  ENTITY *m_declEntity;
557
  const XML_Char *m_doctypeName;
558
  const XML_Char *m_doctypeSysid;
559
  const XML_Char *m_doctypePubid;
560
  const XML_Char *m_declAttributeType;
561
  const XML_Char *m_declNotationName;
562
  const XML_Char *m_declNotationPublicId;
563
  ELEMENT_TYPE *m_declElementType;
564
  ATTRIBUTE_ID *m_declAttributeId;
565
  XML_Bool m_declAttributeIsCdata;
566
  XML_Bool m_declAttributeIsId;
567
  DTD *m_dtd;
568
  const XML_Char *m_curBase;
569
  TAG *m_tagStack;
570
  TAG *m_freeTagList;
571
  BINDING *m_inheritedBindings;
572
  BINDING *m_freeBindingList;
573
  int m_attsSize;
574
  int m_nSpecifiedAtts;
575
  int m_idAttIndex;
576
  ATTRIBUTE *m_atts;
577
  NS_ATT *m_nsAtts;
578
  unsigned long m_nsAttsVersion;
579
  unsigned char m_nsAttsPower;
580
#ifdef XML_ATTR_INFO
581
  XML_AttrInfo *m_attInfo;
582
#endif
583
  POSITION m_position;
584
  STRING_POOL m_tempPool;
585
  STRING_POOL m_temp2Pool;
586
  char *m_groupConnector;
587
  unsigned int m_groupSize;
588
  XML_Char m_namespaceSeparator;
589
  XML_Parser m_parentParser;
590
  XML_ParsingStatus m_parsingStatus;
591
#ifdef XML_DTD
592
  XML_Bool m_isParamEntity;
593
  XML_Bool m_useForeignDTD;
594
  enum XML_ParamEntityParsing m_paramEntityParsing;
595
#endif
596
  unsigned long m_hash_secret_salt;
597
};
598
599
#define MALLOC(parser, s)      (parser->m_mem.malloc_fcn((s)))
600
#define REALLOC(parser, p, s)  (parser->m_mem.realloc_fcn((p),(s)))
601
#define FREE(parser, p)        (parser->m_mem.free_fcn((p)))
602
603
604
XML_Parser XMLCALL
605
XML_ParserCreate(const XML_Char *encodingName)
606
{
607
2550
  return XML_ParserCreate_MM(encodingName, NULL, NULL);
608
}
609
610
XML_Parser XMLCALL
611
XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
612
{
613
384
  XML_Char tmp[2];
614
192
  *tmp = nsSep;
615
384
  return XML_ParserCreate_MM(encodingName, NULL, tmp);
616
192
}
617
618
static const XML_Char implicitContext[] = {
619
  ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
620
  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
621
  ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
622
  ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
623
  ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
624
  ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
625
};
626
627
static unsigned long
628
generate_hash_secret_salt(XML_Parser parser)
629
{
630
77166
  unsigned long entropy;
631
  (void)parser;
632
633
  /* "Failproof" high quality providers: */
634
38583
  arc4random_buf(&entropy, sizeof(entropy));
635
77166
  return entropy;
636
38583
}
637
638
static unsigned long
639
get_hash_secret_salt(XML_Parser parser) {
640
27806894
  if (parser->m_parentParser != NULL)
641
2631
    return get_hash_secret_salt(parser->m_parentParser);
642
13900816
  return parser->m_hash_secret_salt;
643
13903447
}
644
645
static XML_Bool  /* only valid for root parser */
646
startParsing(XML_Parser parser)
647
{
648
    /* hash functions must be initialized before setContext() is called */
649
77214
    if (parser->m_hash_secret_salt == 0)
650
38583
      parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
651
38607
    if (parser->m_ns) {
652
      /* implicit context only set for root parser, since child
653
         parsers (i.e. external entity parsers) will inherit it
654
      */
655
2844
      return setContext(parser, implicitContext);
656
    }
657
35763
    return XML_TRUE;
658
38607
}
659
660
XML_Parser XMLCALL
661
XML_ParserCreate_MM(const XML_Char *encodingName,
662
                    const XML_Memory_Handling_Suite *memsuite,
663
                    const XML_Char *nameSep)
664
{
665
14808
  return parserCreate(encodingName, memsuite, nameSep, NULL);
666
}
667
668
static XML_Parser
669
parserCreate(const XML_Char *encodingName,
670
             const XML_Memory_Handling_Suite *memsuite,
671
             const XML_Char *nameSep,
672
             DTD *dtd)
673
{
674
  XML_Parser parser;
675
676
21498
  if (memsuite) {
677
    XML_Memory_Handling_Suite *mtemp;
678
9282
    parser = (XML_Parser)
679
9282
      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
680
9282
    if (parser != NULL) {
681
9150
      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
682
9150
      mtemp->malloc_fcn = memsuite->malloc_fcn;
683
9150
      mtemp->realloc_fcn = memsuite->realloc_fcn;
684
9150
      mtemp->free_fcn = memsuite->free_fcn;
685
9150
    }
686
9282
  }
687
  else {
688
    XML_Memory_Handling_Suite *mtemp;
689
1467
    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
690
1467
    if (parser != NULL) {
691
1467
      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
692
1467
      mtemp->malloc_fcn = malloc;
693
1467
      mtemp->realloc_fcn = realloc;
694
1467
      mtemp->free_fcn = free;
695
1467
    }
696
  }
697
698
10749
  if (!parser)
699
132
    return parser;
700
701
10617
  parser->m_buffer = NULL;
702
10617
  parser->m_bufferLim = NULL;
703
704
10617
  parser->m_attsSize = INIT_ATTS_SIZE;
705
10617
  parser->m_atts = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
706
10617
  if (parser->m_atts == NULL) {
707
132
    FREE(parser, parser);
708
132
    return NULL;
709
  }
710
#ifdef XML_ATTR_INFO
711
  parser->m_attInfo = (XML_AttrInfo*)MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo));
712
  if (parser->m_attInfo == NULL) {
713
    FREE(parser, parser->m_atts);
714
    FREE(parser, parser);
715
    return NULL;
716
  }
717
#endif
718
10485
  parser->m_dataBuf = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
719
10485
  if (parser->m_dataBuf == NULL) {
720
132
    FREE(parser, parser->m_atts);
721
#ifdef XML_ATTR_INFO
722
    FREE(parser, parser->m_attInfo);
723
#endif
724
132
    FREE(parser, parser);
725
132
    return NULL;
726
  }
727
10353
  parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;
728
729
10353
  if (dtd)
730
1734
    parser->m_dtd = dtd;
731
  else {
732
8619
    parser->m_dtd = dtdCreate(&parser->m_mem);
733
8619
    if (parser->m_dtd == NULL) {
734
78
      FREE(parser, parser->m_dataBuf);
735
78
      FREE(parser, parser->m_atts);
736
#ifdef XML_ATTR_INFO
737
      FREE(parser, parser->m_attInfo);
738
#endif
739
78
      FREE(parser, parser);
740
78
      return NULL;
741
    }
742
  }
743
744
10275
  parser->m_freeBindingList = NULL;
745
10275
  parser->m_freeTagList = NULL;
746
10275
  parser->m_freeInternalEntities = NULL;
747
748
10275
  parser->m_groupSize = 0;
749
10275
  parser->m_groupConnector = NULL;
750
751
10275
  parser->m_unknownEncodingHandler = NULL;
752
10275
  parser->m_unknownEncodingHandlerData = NULL;
753
754
10275
  parser->m_namespaceSeparator = ASCII_EXCL;
755
10275
  parser->m_ns = XML_FALSE;
756
10275
  parser->m_ns_triplets = XML_FALSE;
757
758
10275
  parser->m_nsAtts = NULL;
759
10275
  parser->m_nsAttsVersion = 0;
760
10275
  parser->m_nsAttsPower = 0;
761
762
10275
  parser->m_protocolEncodingName = NULL;
763
764
10275
  poolInit(&parser->m_tempPool, &(parser->m_mem));
765
10275
  poolInit(&parser->m_temp2Pool, &(parser->m_mem));
766
10275
  parserInit(parser, encodingName);
767
768

10299
  if (encodingName && !parser->m_protocolEncodingName) {
769
6
    XML_ParserFree(parser);
770
6
    return NULL;
771
  }
772
773
10269
  if (nameSep) {
774
4026
    parser->m_ns = XML_TRUE;
775
4026
    parser->m_internalEncoding = XmlGetInternalEncodingNS();
776
4026
    parser->m_namespaceSeparator = *nameSep;
777
4026
  }
778
  else {
779
6243
    parser->m_internalEncoding = XmlGetInternalEncoding();
780
  }
781
782
10269
  return parser;
783
10749
}
784
785
static void
786
parserInit(XML_Parser parser, const XML_Char *encodingName)
787
{
788
83310
  parser->m_processor = prologInitProcessor;
789
41655
  XmlPrologStateInit(&parser->m_prologState);
790
41655
  if (encodingName != NULL) {
791
24
    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
792
24
  }
793
41655
  parser->m_curBase = NULL;
794
41655
  XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
795
41655
  parser->m_userData = NULL;
796
41655
  parser->m_handlerArg = NULL;
797
41655
  parser->m_startElementHandler = NULL;
798
41655
  parser->m_endElementHandler = NULL;
799
41655
  parser->m_characterDataHandler = NULL;
800
41655
  parser->m_processingInstructionHandler = NULL;
801
41655
  parser->m_commentHandler = NULL;
802
41655
  parser->m_startCdataSectionHandler = NULL;
803
41655
  parser->m_endCdataSectionHandler = NULL;
804
41655
  parser->m_defaultHandler = NULL;
805
41655
  parser->m_startDoctypeDeclHandler = NULL;
806
41655
  parser->m_endDoctypeDeclHandler = NULL;
807
41655
  parser->m_unparsedEntityDeclHandler = NULL;
808
41655
  parser->m_notationDeclHandler = NULL;
809
41655
  parser->m_startNamespaceDeclHandler = NULL;
810
41655
  parser->m_endNamespaceDeclHandler = NULL;
811
41655
  parser->m_notStandaloneHandler = NULL;
812
41655
  parser->m_externalEntityRefHandler = NULL;
813
41655
  parser->m_externalEntityRefHandlerArg = parser;
814
41655
  parser->m_skippedEntityHandler = NULL;
815
41655
  parser->m_elementDeclHandler = NULL;
816
41655
  parser->m_attlistDeclHandler = NULL;
817
41655
  parser->m_entityDeclHandler = NULL;
818
41655
  parser->m_xmlDeclHandler = NULL;
819
41655
  parser->m_bufferPtr = parser->m_buffer;
820
41655
  parser->m_bufferEnd = parser->m_buffer;
821
41655
  parser->m_parseEndByteIndex = 0;
822
41655
  parser->m_parseEndPtr = NULL;
823
41655
  parser->m_declElementType = NULL;
824
41655
  parser->m_declAttributeId = NULL;
825
41655
  parser->m_declEntity = NULL;
826
41655
  parser->m_doctypeName = NULL;
827
41655
  parser->m_doctypeSysid = NULL;
828
41655
  parser->m_doctypePubid = NULL;
829
41655
  parser->m_declAttributeType = NULL;
830
41655
  parser->m_declNotationName = NULL;
831
41655
  parser->m_declNotationPublicId = NULL;
832
41655
  parser->m_declAttributeIsCdata = XML_FALSE;
833
41655
  parser->m_declAttributeIsId = XML_FALSE;
834
41655
  memset(&parser->m_position, 0, sizeof(POSITION));
835
41655
  parser->m_errorCode = XML_ERROR_NONE;
836
41655
  parser->m_eventPtr = NULL;
837
41655
  parser->m_eventEndPtr = NULL;
838
41655
  parser->m_positionPtr = NULL;
839
41655
  parser->m_openInternalEntities = NULL;
840
41655
  parser->m_defaultExpandInternalEntities = XML_TRUE;
841
41655
  parser->m_tagLevel = 0;
842
41655
  parser->m_tagStack = NULL;
843
41655
  parser->m_inheritedBindings = NULL;
844
41655
  parser->m_nSpecifiedAtts = 0;
845
41655
  parser->m_unknownEncodingMem = NULL;
846
41655
  parser->m_unknownEncodingRelease = NULL;
847
41655
  parser->m_unknownEncodingData = NULL;
848
41655
  parser->m_parentParser = NULL;
849
41655
  parser->m_parsingStatus.parsing = XML_INITIALIZED;
850
#ifdef XML_DTD
851
41655
  parser->m_isParamEntity = XML_FALSE;
852
41655
  parser->m_useForeignDTD = XML_FALSE;
853
41655
  parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
854
#endif
855
41655
  parser->m_hash_secret_salt = 0;
856
41655
}
857
858
/* moves list of bindings to m_freeBindingList */
859
static void FASTCALL
860
moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
861
{
862
97614
  while (bindings) {
863
    BINDING *b = bindings;
864
36
    bindings = bindings->nextTagBinding;
865
36
    b->nextTagBinding = parser->m_freeBindingList;
866
36
    parser->m_freeBindingList = b;
867
  }
868
32514
}
869
870
XML_Bool XMLCALL
871
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
872
{
873
  TAG *tStk;
874
  OPEN_INTERNAL_ENTITY *openEntityList;
875
876
62772
  if (parser == NULL)
877
      return XML_FALSE;
878
879
31386
  if (parser->m_parentParser)
880
6
    return XML_FALSE;
881
  /* move m_tagStack to m_freeTagList */
882
31380
  tStk = parser->m_tagStack;
883
65028
  while (tStk) {
884
    TAG *tag = tStk;
885
1134
    tStk = tStk->parent;
886
1134
    tag->parent = parser->m_freeTagList;
887
1134
    moveToFreeBindingList(parser, tag->bindings);
888
1134
    tag->bindings = NULL;
889
1134
    parser->m_freeTagList = tag;
890
  }
891
  /* move m_openInternalEntities to m_freeInternalEntities */
892
31380
  openEntityList = parser->m_openInternalEntities;
893
62772
  while (openEntityList) {
894
    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
895
6
    openEntityList = openEntity->next;
896
6
    openEntity->next = parser->m_freeInternalEntities;
897
6
    parser->m_freeInternalEntities = openEntity;
898
  }
899
31380
  moveToFreeBindingList(parser, parser->m_inheritedBindings);
900
31380
  FREE(parser, parser->m_unknownEncodingMem);
901
31380
  if (parser->m_unknownEncodingRelease)
902
    parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
903
31380
  poolClear(&parser->m_tempPool);
904
31380
  poolClear(&parser->m_temp2Pool);
905
31380
  FREE(parser, (void *)parser->m_protocolEncodingName);
906
31380
  parser->m_protocolEncodingName = NULL;
907
31380
  parserInit(parser, encodingName);
908
31380
  dtdReset(parser->m_dtd, &parser->m_mem);
909
31380
  return XML_TRUE;
910
31386
}
911
912
enum XML_Status XMLCALL
913
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
914
{
915
252
  if (parser == NULL)
916
      return XML_STATUS_ERROR;
917
  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
918
     XXX There's no way for the caller to determine which of the
919
     XXX possible error cases caused the XML_STATUS_ERROR return.
920
  */
921

246
  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
922
6
    return XML_STATUS_ERROR;
923
924
  /* Get rid of any previous encoding name */
925
120
  FREE(parser, (void *)parser->m_protocolEncodingName);
926
927
120
  if (encodingName == NULL)
928
    /* No new encoding name */
929
12
    parser->m_protocolEncodingName = NULL;
930
  else {
931
    /* Copy the new encoding name into allocated memory */
932
108
    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
933
108
    if (!parser->m_protocolEncodingName)
934
12
      return XML_STATUS_ERROR;
935
  }
936
108
  return XML_STATUS_OK;
937
126
}
938
939
XML_Parser XMLCALL
940
XML_ExternalEntityParserCreate(XML_Parser oldParser,
941
                               const XML_Char *context,
942
                               const XML_Char *encodingName)
943
{
944
  XML_Parser parser = oldParser;
945
  DTD *newDtd = NULL;
946
  DTD *oldDtd;
947
  XML_StartElementHandler oldStartElementHandler;
948
  XML_EndElementHandler oldEndElementHandler;
949
  XML_CharacterDataHandler oldCharacterDataHandler;
950
  XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
951
  XML_CommentHandler oldCommentHandler;
952
  XML_StartCdataSectionHandler oldStartCdataSectionHandler;
953
  XML_EndCdataSectionHandler oldEndCdataSectionHandler;
954
  XML_DefaultHandler oldDefaultHandler;
955
  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
956
  XML_NotationDeclHandler oldNotationDeclHandler;
957
  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
958
  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
959
  XML_NotStandaloneHandler oldNotStandaloneHandler;
960
  XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
961
  XML_SkippedEntityHandler oldSkippedEntityHandler;
962
  XML_UnknownEncodingHandler oldUnknownEncodingHandler;
963
  XML_ElementDeclHandler oldElementDeclHandler;
964
  XML_AttlistDeclHandler oldAttlistDeclHandler;
965
  XML_EntityDeclHandler oldEntityDeclHandler;
966
  XML_XmlDeclHandler oldXmlDeclHandler;
967
  ELEMENT_TYPE * oldDeclElementType;
968
969
  void *oldUserData;
970
  void *oldHandlerArg;
971
  XML_Bool oldDefaultExpandInternalEntities;
972
  XML_Parser oldExternalEntityRefHandlerArg;
973
#ifdef XML_DTD
974
  enum XML_ParamEntityParsing oldParamEntityParsing;
975
  int oldInEntityValue;
976
#endif
977
  XML_Bool oldns_triplets;
978
  /* Note that the new parser shares the same hash secret as the old
979
     parser, so that dtdCopy and copyEntityTable can lookup values
980
     from hash tables associated with either parser without us having
981
     to worry which hash secrets each table has.
982
  */
983
  unsigned long oldhash_secret_salt;
984
985
  /* Validate the oldParser parameter before we pull everything out of it */
986
6690
  if (oldParser == NULL)
987
    return NULL;
988
989
  /* Stash the original parser contents on the stack */
990
3345
  oldDtd = parser->m_dtd;
991
3345
  oldStartElementHandler = parser->m_startElementHandler;
992
3345
  oldEndElementHandler = parser->m_endElementHandler;
993
3345
  oldCharacterDataHandler = parser->m_characterDataHandler;
994
3345
  oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
995
3345
  oldCommentHandler = parser->m_commentHandler;
996
3345
  oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
997
3345
  oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
998
3345
  oldDefaultHandler = parser->m_defaultHandler;
999
3345
  oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1000
3345
  oldNotationDeclHandler = parser->m_notationDeclHandler;
1001
3345
  oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1002
3345
  oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1003
3345
  oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1004
3345
  oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1005
3345
  oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1006
3345
  oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1007
3345
  oldElementDeclHandler = parser->m_elementDeclHandler;
1008
3345
  oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1009
3345
  oldEntityDeclHandler = parser->m_entityDeclHandler;
1010
3345
  oldXmlDeclHandler = parser->m_xmlDeclHandler;
1011
3345
  oldDeclElementType = parser->m_declElementType;
1012
1013
3345
  oldUserData = parser->m_userData;
1014
3345
  oldHandlerArg = parser->m_handlerArg;
1015
3345
  oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1016
3345
  oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1017
#ifdef XML_DTD
1018
3345
  oldParamEntityParsing = parser->m_paramEntityParsing;
1019
3345
  oldInEntityValue = parser->m_prologState.inEntityValue;
1020
#endif
1021
3345
  oldns_triplets = parser->m_ns_triplets;
1022
  /* Note that the new parser shares the same hash secret as the old
1023
     parser, so that dtdCopy and copyEntityTable can lookup values
1024
     from hash tables associated with either parser without us having
1025
     to worry which hash secrets each table has.
1026
  */
1027
3345
  oldhash_secret_salt = parser->m_hash_secret_salt;
1028
1029
#ifdef XML_DTD
1030
3345
  if (!context)
1031
1914
    newDtd = oldDtd;
1032
#endif /* XML_DTD */
1033
1034
  /* Note that the magical uses of the pre-processor to make field
1035
     access look more like C++ require that `parser' be overwritten
1036
     here.  This makes this function more painful to follow than it
1037
     would be otherwise.
1038
  */
1039
3345
  if (parser->m_ns) {
1040
1368
    XML_Char tmp[2];
1041
1368
    *tmp = parser->m_namespaceSeparator;
1042
1368
    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1043
1368
  }
1044
  else {
1045
1977
    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1046
  }
1047
1048
3345
  if (!parser)
1049
426
    return NULL;
1050
1051
2919
  parser->m_startElementHandler = oldStartElementHandler;
1052
2919
  parser->m_endElementHandler = oldEndElementHandler;
1053
2919
  parser->m_characterDataHandler = oldCharacterDataHandler;
1054
2919
  parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1055
2919
  parser->m_commentHandler = oldCommentHandler;
1056
2919
  parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1057
2919
  parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1058
2919
  parser->m_defaultHandler = oldDefaultHandler;
1059
2919
  parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1060
2919
  parser->m_notationDeclHandler = oldNotationDeclHandler;
1061
2919
  parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1062
2919
  parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1063
2919
  parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1064
2919
  parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1065
2919
  parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1066
2919
  parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1067
2919
  parser->m_elementDeclHandler = oldElementDeclHandler;
1068
2919
  parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1069
2919
  parser->m_entityDeclHandler = oldEntityDeclHandler;
1070
2919
  parser->m_xmlDeclHandler = oldXmlDeclHandler;
1071
2919
  parser->m_declElementType = oldDeclElementType;
1072
2919
  parser->m_userData = oldUserData;
1073
2919
  if (oldUserData == oldHandlerArg)
1074
2913
    parser->m_handlerArg = parser->m_userData;
1075
  else
1076
6
    parser->m_handlerArg = parser;
1077
2919
  if (oldExternalEntityRefHandlerArg != oldParser)
1078
6
    parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1079
2919
  parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1080
2919
  parser->m_ns_triplets = oldns_triplets;
1081
2919
  parser->m_hash_secret_salt = oldhash_secret_salt;
1082
2919
  parser->m_parentParser = oldParser;
1083
#ifdef XML_DTD
1084
2919
  parser->m_paramEntityParsing = oldParamEntityParsing;
1085
2919
  parser->m_prologState.inEntityValue = oldInEntityValue;
1086
2919
  if (context) {
1087
#endif /* XML_DTD */
1088
1743
    if (!dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
1089
1743
      || !setContext(parser, context)) {
1090
784
      XML_ParserFree(parser);
1091
784
      return NULL;
1092
    }
1093
    parser->m_processor = externalEntityInitProcessor;
1094
#ifdef XML_DTD
1095
401
  }
1096
  else {
1097
    /* The DTD instance referenced by parser->m_dtd is shared between the document's
1098
       root parser and external PE parsers, therefore one does not need to
1099
       call setContext. In addition, one also *must* not call setContext,
1100
       because this would overwrite existing prefix->binding pointers in
1101
       parser->m_dtd with ones that get destroyed with the external PE parser.
1102
       This would leave those prefixes with dangling pointers.
1103
    */
1104
1734
    parser->m_isParamEntity = XML_TRUE;
1105
1734
    XmlPrologStateInitExternalEntity(&parser->m_prologState);
1106
    parser->m_processor = externalParEntInitProcessor;
1107
  }
1108
#endif /* XML_DTD */
1109
2135
  return parser;
1110
3345
}
1111
1112
static void FASTCALL
1113
destroyBindings(BINDING *bindings, XML_Parser parser)
1114
{
1115
52636
  for (;;) {
1116
    BINDING *b = bindings;
1117
28162
    if (!b)
1118
24474
      break;
1119
3688
    bindings = b->nextTagBinding;
1120
3688
    FREE(parser, b->uri);
1121
3688
    FREE(parser, b);
1122
3688
  }
1123
24474
}
1124
1125
void XMLCALL
1126
XML_ParserFree(XML_Parser parser)
1127
{
1128
  TAG *tagList;
1129
  OPEN_INTERNAL_ENTITY *entityList;
1130
20562
  if (parser == NULL)
1131
6
    return;
1132
  /* free m_tagStack and m_freeTagList */
1133
10275
  tagList = parser->m_tagStack;
1134
14199
  for (;;) {
1135
    TAG *p;
1136
14199
    if (tagList == NULL) {
1137
11352
      if (parser->m_freeTagList == NULL)
1138
10275
        break;
1139
      tagList = parser->m_freeTagList;
1140
1077
      parser->m_freeTagList = NULL;
1141
1077
    }
1142
    p = tagList;
1143
3924
    tagList = tagList->parent;
1144
3924
    FREE(parser, p->buf);
1145
3924
    destroyBindings(p->bindings, parser);
1146
3924
    FREE(parser, p);
1147
3924
  }
1148
  /* free m_openInternalEntities and m_freeInternalEntities */
1149
10275
  entityList = parser->m_openInternalEntities;
1150
10389
  for (;;) {
1151
    OPEN_INTERNAL_ENTITY *openEntity;
1152
10389
    if (entityList == NULL) {
1153
10365
      if (parser->m_freeInternalEntities == NULL)
1154
10275
        break;
1155
      entityList = parser->m_freeInternalEntities;
1156
90
      parser->m_freeInternalEntities = NULL;
1157
90
    }
1158
    openEntity = entityList;
1159
114
    entityList = entityList->next;
1160
114
    FREE(parser, openEntity);
1161
114
  }
1162
1163
10275
  destroyBindings(parser->m_freeBindingList, parser);
1164
10275
  destroyBindings(parser->m_inheritedBindings, parser);
1165
10275
  poolDestroy(&parser->m_tempPool);
1166
10275
  poolDestroy(&parser->m_temp2Pool);
1167
10275
  FREE(parser, (void *)parser->m_protocolEncodingName);
1168
#ifdef XML_DTD
1169
  /* external parameter entity parsers share the DTD structure
1170
     parser->m_dtd with the root parser, so we must not destroy it
1171
  */
1172

18816
  if (!parser->m_isParamEntity && parser->m_dtd)
1173
#else
1174
  if (parser->m_dtd)
1175
#endif /* XML_DTD */
1176
8541
    dtdDestroy(parser->m_dtd, (XML_Bool)!parser->m_parentParser, &parser->m_mem);
1177
10275
  FREE(parser, (void *)parser->m_atts);
1178
#ifdef XML_ATTR_INFO
1179
  FREE(parser, (void *)parser->m_attInfo);
1180
#endif
1181
10275
  FREE(parser, parser->m_groupConnector);
1182
10275
  FREE(parser, parser->m_buffer);
1183
10275
  FREE(parser, parser->m_dataBuf);
1184
10275
  FREE(parser, parser->m_nsAtts);
1185
10275
  FREE(parser, parser->m_unknownEncodingMem);
1186
10275
  if (parser->m_unknownEncodingRelease)
1187
60
    parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1188
10275
  FREE(parser, parser);
1189
20556
}
1190
1191
void XMLCALL
1192
XML_UseParserAsHandlerArg(XML_Parser parser)
1193
{
1194
24
  if (parser != NULL)
1195
12
    parser->m_handlerArg = parser;
1196
12
}
1197
1198
enum XML_Error XMLCALL
1199
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1200
{
1201
264
  if (parser == NULL)
1202
    return XML_ERROR_INVALID_ARGUMENT;
1203
#ifdef XML_DTD
1204
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1205

252
  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1206
12
    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1207
120
  parser->m_useForeignDTD = useDTD;
1208
120
  return XML_ERROR_NONE;
1209
#else
1210
  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1211
#endif
1212
132
}
1213
1214
void XMLCALL
1215
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1216
{
1217
684
  if (parser == NULL)
1218
    return;
1219
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1220

672
  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1221
    return;
1222
330
  parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1223
672
}
1224
1225
void XMLCALL
1226
XML_SetUserData(XML_Parser parser, void *p)
1227
{
1228
8646
  if (parser == NULL)
1229
    return;
1230
4323
  if (parser->m_handlerArg == parser->m_userData)
1231
4317
    parser->m_handlerArg = parser->m_userData = p;
1232
  else
1233
    parser->m_userData = p;
1234
4323
}
1235
1236
enum XML_Status XMLCALL
1237
XML_SetBase(XML_Parser parser, const XML_Char *p)
1238
{
1239
324
  if (parser == NULL)
1240
    return XML_STATUS_ERROR;
1241
162
  if (p) {
1242
150
    p = poolCopyString(&parser->m_dtd->pool, p);
1243
150
    if (!p)
1244
12
      return XML_STATUS_ERROR;
1245
    parser->m_curBase = p;
1246
138
  }
1247
  else
1248
    parser->m_curBase = NULL;
1249
150
  return XML_STATUS_OK;
1250
162
}
1251
1252
const XML_Char * XMLCALL
1253
XML_GetBase(XML_Parser parser)
1254
{
1255
36
  if (parser == NULL)
1256
    return NULL;
1257
18
  return parser->m_curBase;
1258
18
}
1259
1260
int XMLCALL
1261
XML_GetSpecifiedAttributeCount(XML_Parser parser)
1262
{
1263
24
  if (parser == NULL)
1264
    return -1;
1265
12
  return parser->m_nSpecifiedAtts;
1266
12
}
1267
1268
int XMLCALL
1269
XML_GetIdAttributeIndex(XML_Parser parser)
1270
{
1271
24
  if (parser == NULL)
1272
    return -1;
1273
12
  return parser->m_idAttIndex;
1274
12
}
1275
1276
#ifdef XML_ATTR_INFO
1277
const XML_AttrInfo * XMLCALL
1278
XML_GetAttributeInfo(XML_Parser parser)
1279
{
1280
  if (parser == NULL)
1281
    return NULL;
1282
  return parser->m_attInfo;
1283
}
1284
#endif
1285
1286
void XMLCALL
1287
XML_SetElementHandler(XML_Parser parser,
1288
                      XML_StartElementHandler start,
1289
                      XML_EndElementHandler end)
1290
{
1291
672
  if (parser == NULL)
1292
    return;
1293
336
  parser->m_startElementHandler = start;
1294
336
  parser->m_endElementHandler = end;
1295
672
}
1296
1297
void XMLCALL
1298
XML_SetStartElementHandler(XML_Parser parser,
1299
                           XML_StartElementHandler start) {
1300
528
  if (parser != NULL)
1301
264
    parser->m_startElementHandler = start;
1302
264
}
1303
1304
void XMLCALL
1305
XML_SetEndElementHandler(XML_Parser parser,
1306
                         XML_EndElementHandler end) {
1307
72
  if (parser != NULL)
1308
36
    parser->m_endElementHandler = end;
1309
36
}
1310
1311
void XMLCALL
1312
XML_SetCharacterDataHandler(XML_Parser parser,
1313
                            XML_CharacterDataHandler handler)
1314
{
1315
1200
  if (parser != NULL)
1316
600
    parser->m_characterDataHandler = handler;
1317
600
}
1318
1319
void XMLCALL
1320
XML_SetProcessingInstructionHandler(XML_Parser parser,
1321
                                    XML_ProcessingInstructionHandler handler)
1322
{
1323
660
  if (parser != NULL)
1324
330
    parser->m_processingInstructionHandler = handler;
1325
330
}
1326
1327
void XMLCALL
1328
XML_SetCommentHandler(XML_Parser parser,
1329
                      XML_CommentHandler handler)
1330
{
1331
552
  if (parser != NULL)
1332
276
    parser->m_commentHandler = handler;
1333
276
}
1334
1335
void XMLCALL
1336
XML_SetCdataSectionHandler(XML_Parser parser,
1337
                           XML_StartCdataSectionHandler start,
1338
                           XML_EndCdataSectionHandler end)
1339
{
1340
216
  if (parser == NULL)
1341
    return;
1342
108
  parser->m_startCdataSectionHandler = start;
1343
108
  parser->m_endCdataSectionHandler = end;
1344
216
}
1345
1346
void XMLCALL
1347
XML_SetStartCdataSectionHandler(XML_Parser parser,
1348
                                XML_StartCdataSectionHandler start) {
1349
24
  if (parser != NULL)
1350
12
    parser->m_startCdataSectionHandler = start;
1351
12
}
1352
1353
void XMLCALL
1354
XML_SetEndCdataSectionHandler(XML_Parser parser,
1355
                              XML_EndCdataSectionHandler end) {
1356
24
  if (parser != NULL)
1357
12
    parser->m_endCdataSectionHandler = end;
1358
12
}
1359
1360
void XMLCALL
1361
XML_SetDefaultHandler(XML_Parser parser,
1362
                      XML_DefaultHandler handler)
1363
{
1364
768
  if (parser == NULL)
1365
    return;
1366
384
  parser->m_defaultHandler = handler;
1367
384
  parser->m_defaultExpandInternalEntities = XML_FALSE;
1368
768
}
1369
1370
void XMLCALL
1371
XML_SetDefaultHandlerExpand(XML_Parser parser,
1372
                            XML_DefaultHandler handler)
1373
{
1374
24
  if (parser == NULL)
1375
    return;
1376
12
  parser->m_defaultHandler = handler;
1377
12
  parser->m_defaultExpandInternalEntities = XML_TRUE;
1378
24
}
1379
1380
void XMLCALL
1381
XML_SetDoctypeDeclHandler(XML_Parser parser,
1382
                          XML_StartDoctypeDeclHandler start,
1383
                          XML_EndDoctypeDeclHandler end)
1384
{
1385
504
  if (parser == NULL)
1386
    return;
1387
252
  parser->m_startDoctypeDeclHandler = start;
1388
252
  parser->m_endDoctypeDeclHandler = end;
1389
504
}
1390
1391
void XMLCALL
1392
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1393
                               XML_StartDoctypeDeclHandler start) {
1394
48
  if (parser != NULL)
1395
24
    parser->m_startDoctypeDeclHandler = start;
1396
24
}
1397
1398
void XMLCALL
1399
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1400
                             XML_EndDoctypeDeclHandler end) {
1401
48
  if (parser != NULL)
1402
24
    parser->m_endDoctypeDeclHandler = end;
1403
24
}
1404
1405
void XMLCALL
1406
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1407
                                 XML_UnparsedEntityDeclHandler handler)
1408
{
1409
216
  if (parser != NULL)
1410
108
    parser->m_unparsedEntityDeclHandler = handler;
1411
108
}
1412
1413
void XMLCALL
1414
XML_SetNotationDeclHandler(XML_Parser parser,
1415
                           XML_NotationDeclHandler handler)
1416
{
1417
576
  if (parser != NULL)
1418
288
    parser->m_notationDeclHandler = handler;
1419
288
}
1420
1421
void XMLCALL
1422
XML_SetNamespaceDeclHandler(XML_Parser parser,
1423
                            XML_StartNamespaceDeclHandler start,
1424
                            XML_EndNamespaceDeclHandler end)
1425
{
1426
24
  if (parser == NULL)
1427
    return;
1428
12
  parser->m_startNamespaceDeclHandler = start;
1429
12
  parser->m_endNamespaceDeclHandler = end;
1430
24
}
1431
1432
void XMLCALL
1433
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1434
                                 XML_StartNamespaceDeclHandler start) {
1435
24
  if (parser != NULL)
1436
12
    parser->m_startNamespaceDeclHandler = start;
1437
12
}
1438
1439
void XMLCALL
1440
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1441
                               XML_EndNamespaceDeclHandler end) {
1442
24
  if (parser != NULL)
1443
12
    parser->m_endNamespaceDeclHandler = end;
1444
12
}
1445
1446
void XMLCALL
1447
XML_SetNotStandaloneHandler(XML_Parser parser,
1448
                            XML_NotStandaloneHandler handler)
1449
{
1450
84
  if (parser != NULL)
1451
42
    parser->m_notStandaloneHandler = handler;
1452
42
}
1453
1454
void XMLCALL
1455
XML_SetExternalEntityRefHandler(XML_Parser parser,
1456
                                XML_ExternalEntityRefHandler handler)
1457
{
1458
6522
  if (parser != NULL)
1459
3261
    parser->m_externalEntityRefHandler = handler;
1460
3261
}
1461
1462
void XMLCALL
1463
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1464
{
1465
24
  if (parser == NULL)
1466
    return;
1467
24
  if (arg)
1468
12
    parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
1469
  else
1470
    parser->m_externalEntityRefHandlerArg = parser;
1471
24
}
1472
1473
void XMLCALL
1474
XML_SetSkippedEntityHandler(XML_Parser parser,
1475
                            XML_SkippedEntityHandler handler)
1476
{
1477
36
  if (parser != NULL)
1478
18
    parser->m_skippedEntityHandler = handler;
1479
18
}
1480
1481
void XMLCALL
1482
XML_SetUnknownEncodingHandler(XML_Parser parser,
1483
                              XML_UnknownEncodingHandler handler,
1484
                              void *data)
1485
{
1486
528
  if (parser == NULL)
1487
    return;
1488
264
  parser->m_unknownEncodingHandler = handler;
1489
264
  parser->m_unknownEncodingHandlerData = data;
1490
528
}
1491
1492
void XMLCALL
1493
XML_SetElementDeclHandler(XML_Parser parser,
1494
                          XML_ElementDeclHandler eldecl)
1495
{
1496
1128
  if (parser != NULL)
1497
564
    parser->m_elementDeclHandler = eldecl;
1498
564
}
1499
1500
void XMLCALL
1501
XML_SetAttlistDeclHandler(XML_Parser parser,
1502
                          XML_AttlistDeclHandler attdecl)
1503
{
1504
600
  if (parser != NULL)
1505
300
    parser->m_attlistDeclHandler = attdecl;
1506
300
}
1507
1508
void XMLCALL
1509
XML_SetEntityDeclHandler(XML_Parser parser,
1510
                         XML_EntityDeclHandler handler)
1511
{
1512
744
  if (parser != NULL)
1513
372
    parser->m_entityDeclHandler = handler;
1514
372
}
1515
1516
void XMLCALL
1517
XML_SetXmlDeclHandler(XML_Parser parser,
1518
                      XML_XmlDeclHandler handler) {
1519
408
  if (parser != NULL)
1520
204
    parser->m_xmlDeclHandler = handler;
1521
204
}
1522
1523
int XMLCALL
1524
XML_SetParamEntityParsing(XML_Parser parser,
1525
                          enum XML_ParamEntityParsing peParsing)
1526
{
1527
6018
  if (parser == NULL)
1528
    return 0;
1529
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1530

6012
  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1531
6
    return 0;
1532
#ifdef XML_DTD
1533
3003
  parser->m_paramEntityParsing = peParsing;
1534
3003
  return 1;
1535
#else
1536
  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1537
#endif
1538
3009
}
1539
1540
int XMLCALL
1541
XML_SetHashSalt(XML_Parser parser,
1542
                unsigned long hash_salt)
1543
{
1544
60
  if (parser == NULL)
1545
    return 0;
1546
30
  if (parser->m_parentParser)
1547
    return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1548
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1549

48
  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
1550
12
    return 0;
1551
18
  parser->m_hash_secret_salt = hash_salt;
1552
18
  return 1;
1553
30
}
1554
1555
enum XML_Status XMLCALL
1556
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1557
{
1558

13283385
  if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1559
    if (parser != NULL)
1560
      parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
1561
    return XML_STATUS_ERROR;
1562
  }
1563

4467937
  switch (parser->m_parsingStatus.parsing) {
1564
  case XML_SUSPENDED:
1565
12
    parser->m_errorCode = XML_ERROR_SUSPENDED;
1566
12
    return XML_STATUS_ERROR;
1567
  case XML_FINISHED:
1568
6
    parser->m_errorCode = XML_ERROR_FINISHED;
1569
6
    return XML_STATUS_ERROR;
1570
  case XML_INITIALIZED:
1571

79091
    if (parser->m_parentParser == NULL && !startParsing(parser)) {
1572
432
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
1573
432
      return XML_STATUS_ERROR;
1574
    }
1575
  default:
1576
4427345
    parser->m_parsingStatus.parsing = XML_PARSING;
1577
  }
1578
1579
4427345
  if (len == 0) {
1580
30
    parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
1581
30
    if (!isFinal)
1582
6
      return XML_STATUS_OK;
1583
24
    parser->m_positionPtr = parser->m_bufferPtr;
1584
24
    parser->m_parseEndPtr = parser->m_bufferEnd;
1585
1586
    /* If data are left over from last buffer, and we now know that these
1587
       data are the final chunk of input, then we have to check them again
1588
       to detect errors based on that fact.
1589
    */
1590
24
    parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
1591
1592
24
    if (parser->m_errorCode == XML_ERROR_NONE) {
1593

12
      switch (parser->m_parsingStatus.parsing) {
1594
      case XML_SUSPENDED:
1595
        /* It is hard to be certain, but it seems that this case
1596
         * cannot occur.  This code is cleaning up a previous parse
1597
         * with no new data (since len == 0).  Changing the parsing
1598
         * state requires getting to execute a handler function, and
1599
         * there doesn't seem to be an opportunity for that while in
1600
         * this circumstance.
1601
         *
1602
         * Given the uncertainty, we retain the code but exclude it
1603
         * from coverage tests.
1604
         *
1605
         * LCOV_EXCL_START
1606
         */
1607
        XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
1608
        parser->m_positionPtr = parser->m_bufferPtr;
1609
        return XML_STATUS_SUSPENDED;
1610
        /* LCOV_EXCL_STOP */
1611
      case XML_INITIALIZED:
1612
      case XML_PARSING:
1613
6
        parser->m_parsingStatus.parsing = XML_FINISHED;
1614
        /* fall through */
1615
      default:
1616
6
        return XML_STATUS_OK;
1617
      }
1618
    }
1619
18
    parser->m_eventEndPtr = parser->m_eventPtr;
1620
18
    parser->m_processor = errorProcessor;
1621
18
    return XML_STATUS_ERROR;
1622
  }
1623
#ifndef XML_CONTEXT_BYTES
1624
  else if (parser->m_bufferPtr == parser->m_bufferEnd) {
1625
    const char *end;
1626
    int nLeftOver;
1627
    enum XML_Status result;
1628
    /* Detect overflow (a+b > MAX <==> b > MAX-a) */
1629
    if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
1630
       parser->m_errorCode = XML_ERROR_NO_MEMORY;
1631
       parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1632
       parser->m_processor = errorProcessor;
1633
       return XML_STATUS_ERROR;
1634
    }
1635
    parser->m_parseEndByteIndex += len;
1636
    parser->m_positionPtr = s;
1637
    parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
1638
1639
    parser->m_errorCode = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);
1640
1641
    if (parser->m_errorCode != XML_ERROR_NONE) {
1642
      parser->m_eventEndPtr = parser->m_eventPtr;
1643
      parser->m_processor = errorProcessor;
1644
      return XML_STATUS_ERROR;
1645
    }
1646
    else {
1647
      switch (parser->m_parsingStatus.parsing) {
1648
      case XML_SUSPENDED:
1649
        result = XML_STATUS_SUSPENDED;
1650
        break;
1651
      case XML_INITIALIZED:
1652
      case XML_PARSING:
1653
        if (isFinal) {
1654
          parser->m_parsingStatus.parsing = XML_FINISHED;
1655
          return XML_STATUS_OK;
1656
        }
1657
      /* fall through */
1658
      default:
1659
        result = XML_STATUS_OK;
1660
      }
1661
    }
1662
1663
    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position);
1664
    nLeftOver = s + len - end;
1665
    if (nLeftOver) {
1666
      if (parser->m_buffer == NULL || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
1667
        /* avoid _signed_ integer overflow */
1668
        char *temp = NULL;
1669
        const int bytesToAllocate = (int)((unsigned)len * 2U);
1670
        if (bytesToAllocate > 0) {
1671
          temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
1672
        }
1673
        if (temp == NULL) {
1674
          parser->m_errorCode = XML_ERROR_NO_MEMORY;
1675
          parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1676
          parser->m_processor = errorProcessor;
1677
          return XML_STATUS_ERROR;
1678
        }
1679
        parser->m_buffer = temp;
1680
        parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
1681
      }
1682
      memcpy(parser->m_buffer, end, nLeftOver);
1683
    }
1684
    parser->m_bufferPtr = parser->m_buffer;
1685
    parser->m_bufferEnd = parser->m_buffer + nLeftOver;
1686
    parser->m_positionPtr = parser->m_bufferPtr;
1687
    parser->m_parseEndPtr = parser->m_bufferEnd;
1688
    parser->m_eventPtr = parser->m_bufferPtr;
1689
    parser->m_eventEndPtr = parser->m_bufferPtr;
1690
    return result;
1691
  }
1692
#endif  /* not defined XML_CONTEXT_BYTES */
1693
  else {
1694
4427315
    void *buff = XML_GetBuffer(parser, len);
1695
4427315
    if (buff == NULL)
1696
425
      return XML_STATUS_ERROR;
1697
    else {
1698
4426890
      memcpy(buff, s, len);
1699
4426890
      return XML_ParseBuffer(parser, len, isFinal);
1700
    }
1701
  }
1702
4427795
}
1703
1704
enum XML_Status XMLCALL
1705
XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1706
{
1707
  const char *start;
1708
  enum XML_Status result = XML_STATUS_OK;
1709
1710
8854164
  if (parser == NULL)
1711
    return XML_STATUS_ERROR;
1712

4427232
  switch (parser->m_parsingStatus.parsing) {
1713
  case XML_SUSPENDED:
1714
6
    parser->m_errorCode = XML_ERROR_SUSPENDED;
1715
6
    return XML_STATUS_ERROR;
1716
  case XML_FINISHED:
1717
6
    parser->m_errorCode = XML_ERROR_FINISHED;
1718
6
    return XML_STATUS_ERROR;
1719
  case XML_INITIALIZED:
1720

246
    if (parser->m_parentParser == NULL && !startParsing(parser)) {
1721
6
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
1722
6
      return XML_STATUS_ERROR;
1723
    }
1724
  default:
1725
4427064
    parser->m_parsingStatus.parsing = XML_PARSING;
1726
  }
1727
1728
4427064
  start = parser->m_bufferPtr;
1729
4427064
  parser->m_positionPtr = start;
1730
4427064
  parser->m_bufferEnd += len;
1731
4427064
  parser->m_parseEndPtr = parser->m_bufferEnd;
1732
4427064
  parser->m_parseEndByteIndex += len;
1733
4427064
  parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
1734
1735
4427064
  parser->m_errorCode = parser->m_processor(parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);
1736
1737
4427064
  if (parser->m_errorCode != XML_ERROR_NONE) {
1738
6939
    parser->m_eventEndPtr = parser->m_eventPtr;
1739
6939
    parser->m_processor = errorProcessor;
1740
6939
    return XML_STATUS_ERROR;
1741
  }
1742
  else {
1743

8807454
    switch (parser->m_parsingStatus.parsing) {
1744
    case XML_SUSPENDED:
1745
      result = XML_STATUS_SUSPENDED;
1746
90
      break;
1747
    case XML_INITIALIZED:
1748
    case XML_PARSING:
1749
4420035
      if (isFinal) {
1750
32796
        parser->m_parsingStatus.parsing = XML_FINISHED;
1751
32796
        return result;
1752
      }
1753
    default: ;  /* should not happen */
1754
    }
1755
  }
1756
1757
4387329
  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
1758
4387329
  parser->m_positionPtr = parser->m_bufferPtr;
1759
4387329
  return result;
1760
4427082
}
1761
1762
void * XMLCALL
1763
XML_GetBuffer(XML_Parser parser, int len)
1764
{
1765
8855014
  if (parser == NULL)
1766
    return NULL;
1767
4427507
  if (len < 0) {
1768
6
    parser->m_errorCode = XML_ERROR_NO_MEMORY;
1769
6
    return NULL;
1770
  }
1771
4427501
  switch (parser->m_parsingStatus.parsing) {
1772
  case XML_SUSPENDED:
1773
6
    parser->m_errorCode = XML_ERROR_SUSPENDED;
1774
6
    return NULL;
1775
  case XML_FINISHED:
1776
6
    parser->m_errorCode = XML_ERROR_FINISHED;
1777
6
    return NULL;
1778
  default: ;
1779
  }
1780
1781
4427489
  if (len > parser->m_bufferLim - parser->m_bufferEnd) {
1782
#ifdef XML_CONTEXT_BYTES
1783
    int keep;
1784
#endif  /* defined XML_CONTEXT_BYTES */
1785
    /* Do not invoke signed arithmetic overflow: */
1786
10313
    int neededSize = (int) ((unsigned)len + (unsigned)(parser->m_bufferEnd - parser->m_bufferPtr));
1787
10313
    if (neededSize < 0) {
1788
6
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
1789
6
      return NULL;
1790
    }
1791
#ifdef XML_CONTEXT_BYTES
1792
10307
    keep = (int)(parser->m_bufferPtr - parser->m_buffer);
1793
10307
    if (keep > XML_CONTEXT_BYTES)
1794
      keep = XML_CONTEXT_BYTES;
1795
10307
    neededSize += keep;
1796
#endif  /* defined XML_CONTEXT_BYTES */
1797
10307
    if (neededSize  <= parser->m_bufferLim - parser->m_buffer) {
1798
#ifdef XML_CONTEXT_BYTES
1799
396
      if (keep < parser->m_bufferPtr - parser->m_buffer) {
1800
396
        int offset = (int)(parser->m_bufferPtr - parser->m_buffer) - keep;
1801
396
        memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep);
1802
396
        parser->m_bufferEnd -= offset;
1803
396
        parser->m_bufferPtr -= offset;
1804
396
      }
1805
#else
1806
      memmove(parser->m_buffer, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr);
1807
      parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr);
1808
      parser->m_bufferPtr = parser->m_buffer;
1809
#endif  /* not defined XML_CONTEXT_BYTES */
1810
    }
1811
    else {
1812
      char *newBuf;
1813
9911
      int bufferSize = (int)(parser->m_bufferLim - parser->m_bufferPtr);
1814
9911
      if (bufferSize == 0)
1815
        bufferSize = INIT_BUFFER_SIZE;
1816
9911
      do {
1817
        /* Do not invoke signed arithmetic overflow: */
1818
10403
        bufferSize = (int) (2U * (unsigned) bufferSize);
1819
10403
      } while (bufferSize < neededSize && bufferSize > 0);
1820
9911
      if (bufferSize <= 0) {
1821
6
        parser->m_errorCode = XML_ERROR_NO_MEMORY;
1822
6
        return NULL;
1823
      }
1824
9905
      newBuf = (char *)MALLOC(parser, bufferSize);
1825
9905
      if (newBuf == 0) {
1826
425
        parser->m_errorCode = XML_ERROR_NO_MEMORY;
1827
425
        return NULL;
1828
      }
1829
9480
      parser->m_bufferLim = newBuf + bufferSize;
1830
#ifdef XML_CONTEXT_BYTES
1831
9480
      if (parser->m_bufferPtr) {
1832
876
        int keep = (int)(parser->m_bufferPtr - parser->m_buffer);
1833
876
        if (keep > XML_CONTEXT_BYTES)
1834
          keep = XML_CONTEXT_BYTES;
1835
876
        memcpy(newBuf, &parser->m_bufferPtr[-keep], parser->m_bufferEnd - parser->m_bufferPtr + keep);
1836
876
        FREE(parser, parser->m_buffer);
1837
876
        parser->m_buffer = newBuf;
1838
876
        parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr) + keep;
1839
876
        parser->m_bufferPtr = parser->m_buffer + keep;
1840
876
      }
1841
      else {
1842
8604
        parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr);
1843
8604
        parser->m_bufferPtr = parser->m_buffer = newBuf;
1844
      }
1845
#else
1846
      if (parser->m_bufferPtr) {
1847
        memcpy(newBuf, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr);
1848
        FREE(parser, parser->m_buffer);
1849
      }
1850
      parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr);
1851
      parser->m_bufferPtr = parser->m_buffer = newBuf;
1852
#endif  /* not defined XML_CONTEXT_BYTES */
1853
9480
    }
1854
9876
    parser->m_eventPtr = parser->m_eventEndPtr = NULL;
1855
9876
    parser->m_positionPtr = NULL;
1856
9876
  }
1857
4427052
  return parser->m_bufferEnd;
1858
4427507
}
1859
1860
enum XML_Status XMLCALL
1861
XML_StopParser(XML_Parser parser, XML_Bool resumable)
1862
{
1863
372
  if (parser == NULL)
1864
    return XML_STATUS_ERROR;
1865
186
  switch (parser->m_parsingStatus.parsing) {
1866
  case XML_SUSPENDED:
1867
12
    if (resumable) {
1868
6
      parser->m_errorCode = XML_ERROR_SUSPENDED;
1869
6
      return XML_STATUS_ERROR;
1870
    }
1871
    parser->m_parsingStatus.parsing = XML_FINISHED;
1872
    break;
1873
  case XML_FINISHED:
1874
6
    parser->m_errorCode = XML_ERROR_FINISHED;
1875
6
    return XML_STATUS_ERROR;
1876
  default:
1877
168
    if (resumable) {
1878
#ifdef XML_DTD
1879
114
      if (parser->m_isParamEntity) {
1880
6
        parser->m_errorCode = XML_ERROR_SUSPEND_PE;
1881
6
        return XML_STATUS_ERROR;
1882
      }
1883
#endif
1884
      parser->m_parsingStatus.parsing = XML_SUSPENDED;
1885
    }
1886
    else
1887
      parser->m_parsingStatus.parsing = XML_FINISHED;
1888
  }
1889
168
  return XML_STATUS_OK;
1890
186
}
1891
1892
enum XML_Status XMLCALL
1893
XML_ResumeParser(XML_Parser parser)
1894
{
1895
  enum XML_Status result = XML_STATUS_OK;
1896
1897
132
  if (parser == NULL)
1898
    return XML_STATUS_ERROR;
1899
66
  if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
1900
6
    parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
1901
6
    return XML_STATUS_ERROR;
1902
  }
1903
60
  parser->m_parsingStatus.parsing = XML_PARSING;
1904
1905
60
  parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
1906
1907
60
  if (parser->m_errorCode != XML_ERROR_NONE) {
1908
12
    parser->m_eventEndPtr = parser->m_eventPtr;
1909
12
    parser->m_processor = errorProcessor;
1910
12
    return XML_STATUS_ERROR;
1911
  }
1912
  else {
1913

72
    switch (parser->m_parsingStatus.parsing) {
1914
    case XML_SUSPENDED:
1915
      result = XML_STATUS_SUSPENDED;
1916
12
      break;
1917
    case XML_INITIALIZED:
1918
    case XML_PARSING:
1919
36
      if (parser->m_parsingStatus.finalBuffer) {
1920
24
        parser->m_parsingStatus.parsing = XML_FINISHED;
1921
24
        return result;
1922
      }
1923
    default: ;
1924
    }
1925
  }
1926
1927
24
  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
1928
24
  parser->m_positionPtr = parser->m_bufferPtr;
1929
24
  return result;
1930
66
}
1931
1932
void XMLCALL
1933
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1934
{
1935
120
  if (parser == NULL)
1936
    return;
1937
60
  assert(status != NULL);
1938
60
  *status = parser->m_parsingStatus;
1939
120
}
1940
1941
enum XML_Error XMLCALL
1942
XML_GetErrorCode(XML_Parser parser)
1943
{
1944
3960
  if (parser == NULL)
1945
    return XML_ERROR_INVALID_ARGUMENT;
1946
1980
  return parser->m_errorCode;
1947
1980
}
1948
1949
XML_Index XMLCALL
1950
XML_GetCurrentByteIndex(XML_Parser parser)
1951
{
1952
36
  if (parser == NULL)
1953
    return -1;
1954
18
  if (parser->m_eventPtr)
1955
12
    return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr));
1956
6
  return -1;
1957
18
}
1958
1959
int XMLCALL
1960
XML_GetCurrentByteCount(XML_Parser parser)
1961
{
1962
36
  if (parser == NULL)
1963
    return 0;
1964

24
  if (parser->m_eventEndPtr && parser->m_eventPtr)
1965
6
    return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
1966
12
  return 0;
1967
18
}
1968
1969
const char * XMLCALL
1970
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1971
{
1972
#ifdef XML_CONTEXT_BYTES
1973
12
  if (parser == NULL)
1974
    return NULL;
1975

6
  if (parser->m_eventPtr && parser->m_buffer) {
1976
    if (offset != NULL)
1977
      *offset = (int)(parser->m_eventPtr - parser->m_buffer);
1978
    if (size != NULL)
1979
      *size   = (int)(parser->m_bufferEnd - parser->m_buffer);
1980
    return parser->m_buffer;
1981
  }
1982
#else
1983
  (void)parser;
1984
  (void)offset;
1985
  (void)size;
1986
#endif /* defined XML_CONTEXT_BYTES */
1987
6
  return (char *) 0;
1988
6
}
1989
1990
XML_Size XMLCALL
1991
XML_GetCurrentLineNumber(XML_Parser parser)
1992
{
1993
144
  if (parser == NULL)
1994
    return 0;
1995

144
  if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
1996
72
    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position);
1997
72
    parser->m_positionPtr = parser->m_eventPtr;
1998
72
  }
1999
72
  return parser->m_position.lineNumber + 1;
2000
72
}
2001
2002
XML_Size XMLCALL
2003
XML_GetCurrentColumnNumber(XML_Parser parser)
2004
{
2005
144
  if (parser == NULL)
2006
    return 0;
2007

144
  if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
2008
72
    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position);
2009
72
    parser->m_positionPtr = parser->m_eventPtr;
2010
72
  }
2011
72
  return parser->m_position.columnNumber;
2012
72
}
2013
2014
void XMLCALL
2015
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
2016
{
2017
396
  if (parser != NULL)
2018
198
    FREE(parser, model);
2019
198
}
2020
2021
void * XMLCALL
2022
XML_MemMalloc(XML_Parser parser, size_t size)
2023
{
2024
12
  if (parser == NULL)
2025
    return NULL;
2026
6
  return MALLOC(parser, size);
2027
6
}
2028
2029
void * XMLCALL
2030
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
2031
{
2032
12
  if (parser == NULL)
2033
    return NULL;
2034
6
  return REALLOC(parser, ptr, size);
2035
6
}
2036
2037
void XMLCALL
2038
XML_MemFree(XML_Parser parser, void *ptr)
2039
{
2040
12
  if (parser != NULL)
2041
6
    FREE(parser, ptr);
2042
6
}
2043
2044
void XMLCALL
2045
XML_DefaultCurrent(XML_Parser parser)
2046
{
2047
72
  if (parser == NULL)
2048
    return;
2049
36
  if (parser->m_defaultHandler) {
2050
36
    if (parser->m_openInternalEntities)
2051
6
      reportDefault(parser,
2052
6
                    parser->m_internalEncoding,
2053
6
                    parser->m_openInternalEntities->internalEventPtr,
2054
6
                    parser->m_openInternalEntities->internalEventEndPtr);
2055
    else
2056
30
      reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr);
2057
  }
2058
36
}
2059
2060
const XML_LChar * XMLCALL
2061
XML_ErrorString(enum XML_Error code)
2062
{
2063










24
  switch (code) {
2064
  case XML_ERROR_NONE:
2065
    return NULL;
2066
  case XML_ERROR_NO_MEMORY:
2067
    return XML_L("out of memory");
2068
  case XML_ERROR_SYNTAX:
2069
    return XML_L("syntax error");
2070
  case XML_ERROR_NO_ELEMENTS:
2071
    return XML_L("no element found");
2072
  case XML_ERROR_INVALID_TOKEN:
2073
    return XML_L("not well-formed (invalid token)");
2074
  case XML_ERROR_UNCLOSED_TOKEN:
2075
    return XML_L("unclosed token");
2076
  case XML_ERROR_PARTIAL_CHAR:
2077
    return XML_L("partial character");
2078
  case XML_ERROR_TAG_MISMATCH:
2079
    return XML_L("mismatched tag");
2080
  case XML_ERROR_DUPLICATE_ATTRIBUTE:
2081
    return XML_L("duplicate attribute");
2082
  case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
2083
    return XML_L("junk after document element");
2084
  case XML_ERROR_PARAM_ENTITY_REF:
2085
    return XML_L("illegal parameter entity reference");
2086
  case XML_ERROR_UNDEFINED_ENTITY:
2087
    return XML_L("undefined entity");
2088
  case XML_ERROR_RECURSIVE_ENTITY_REF:
2089
    return XML_L("recursive entity reference");
2090
  case XML_ERROR_ASYNC_ENTITY:
2091
    return XML_L("asynchronous entity");
2092
  case XML_ERROR_BAD_CHAR_REF:
2093
    return XML_L("reference to invalid character number");
2094
  case XML_ERROR_BINARY_ENTITY_REF:
2095
    return XML_L("reference to binary entity");
2096
  case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
2097
    return XML_L("reference to external entity in attribute");
2098
  case XML_ERROR_MISPLACED_XML_PI:
2099
    return XML_L("XML or text declaration not at start of entity");
2100
  case XML_ERROR_UNKNOWN_ENCODING:
2101
    return XML_L("unknown encoding");
2102
  case XML_ERROR_INCORRECT_ENCODING:
2103
    return XML_L("encoding specified in XML declaration is incorrect");
2104
  case XML_ERROR_UNCLOSED_CDATA_SECTION:
2105
    return XML_L("unclosed CDATA section");
2106
  case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
2107
    return XML_L("error in processing external entity reference");
2108
  case XML_ERROR_NOT_STANDALONE:
2109
    return XML_L("document is not standalone");
2110
  case XML_ERROR_UNEXPECTED_STATE:
2111
    return XML_L("unexpected parser state - please send a bug report");
2112
  case XML_ERROR_ENTITY_DECLARED_IN_PE:
2113
    return XML_L("entity declared in parameter entity");
2114
  case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
2115
    return XML_L("requested feature requires XML_DTD support in Expat");
2116
  case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
2117
    return XML_L("cannot change setting once parsing has begun");
2118
  /* Added in 1.95.7. */
2119
  case XML_ERROR_UNBOUND_PREFIX:
2120
    return XML_L("unbound prefix");
2121
  /* Added in 1.95.8. */
2122
  case XML_ERROR_UNDECLARING_PREFIX:
2123
    return XML_L("must not undeclare prefix");
2124
  case XML_ERROR_INCOMPLETE_PE:
2125
    return XML_L("incomplete markup in parameter entity");
2126
  case XML_ERROR_XML_DECL:
2127
    return XML_L("XML declaration not well-formed");
2128
  case XML_ERROR_TEXT_DECL:
2129
    return XML_L("text declaration not well-formed");
2130
  case XML_ERROR_PUBLICID:
2131
    return XML_L("illegal character(s) in public id");
2132
  case XML_ERROR_SUSPENDED:
2133
    return XML_L("parser suspended");
2134
  case XML_ERROR_NOT_SUSPENDED:
2135
    return XML_L("parser not suspended");
2136
  case XML_ERROR_ABORTED:
2137
    return XML_L("parsing aborted");
2138
  case XML_ERROR_FINISHED:
2139
    return XML_L("parsing finished");
2140
  case XML_ERROR_SUSPEND_PE:
2141
    return XML_L("cannot suspend in external parameter entity");
2142
  /* Added in 2.0.0. */
2143
  case XML_ERROR_RESERVED_PREFIX_XML:
2144
    return XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name");
2145
  case XML_ERROR_RESERVED_PREFIX_XMLNS:
2146
    return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
2147
  case XML_ERROR_RESERVED_NAMESPACE_URI:
2148
    return XML_L("prefix must not be bound to one of the reserved namespace names");
2149
  /* Added in 2.2.5. */
2150
  case XML_ERROR_INVALID_ARGUMENT:  /* Constant added in 2.2.1, already */
2151
    return XML_L("invalid argument");
2152
  }
2153
12
  return NULL;
2154
12
}
2155
2156
const XML_LChar * XMLCALL
2157
XML_ExpatVersion(void) {
2158
2159
  /* V1 is used to string-ize the version number. However, it would
2160
     string-ize the actual version macro *names* unless we get them
2161
     substituted before being passed to V1. CPP is defined to expand
2162
     a macro, then rescan for more expansions. Thus, we use V2 to expand
2163
     the version macros, then CPP will expand the resulting V1() macro
2164
     with the correct numerals. */
2165
  /* ### I'm assuming cpp is portable in this respect... */
2166
2167
#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
2168
#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
2169
2170
24
  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2171
2172
#undef V1
2173
#undef V2
2174
}
2175
2176
XML_Expat_Version XMLCALL
2177
XML_ExpatVersionInfo(void)
2178
{
2179
  XML_Expat_Version version;
2180
2181
  version.major = XML_MAJOR_VERSION;
2182
  version.minor = XML_MINOR_VERSION;
2183
  version.micro = XML_MICRO_VERSION;
2184
2185
  return version;
2186
12
}
2187
2188
const XML_Feature * XMLCALL
2189
XML_GetFeatureList(void)
2190
{
2191
  static const XML_Feature features[] = {
2192
    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
2193
     sizeof(XML_Char)},
2194
    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2195
     sizeof(XML_LChar)},
2196
#ifdef XML_UNICODE
2197
    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
2198
#endif
2199
#ifdef XML_UNICODE_WCHAR_T
2200
    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
2201
#endif
2202
#ifdef XML_DTD
2203
    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
2204
#endif
2205
#ifdef XML_CONTEXT_BYTES
2206
    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
2207
     XML_CONTEXT_BYTES},
2208
#endif
2209
#ifdef XML_MIN_SIZE
2210
    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
2211
#endif
2212
#ifdef XML_NS
2213
    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
2214
#endif
2215
#ifdef XML_LARGE_SIZE
2216
    {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
2217
#endif
2218
#ifdef XML_ATTR_INFO
2219
    {XML_FEATURE_ATTR_INFO,        XML_L("XML_ATTR_INFO"), 0},
2220
#endif
2221
    {XML_FEATURE_END,              NULL, 0}
2222
  };
2223
2224
24
  return features;
2225
}
2226
2227
/* Initially tag->rawName always points into the parse buffer;
2228
   for those TAG instances opened while the current parse buffer was
2229
   processed, and not yet closed, we need to store tag->rawName in a more
2230
   permanent location, since the parse buffer is about to be discarded.
2231
*/
2232
static XML_Bool
2233
storeRawNames(XML_Parser parser)
2234
{
2235
4568094
  TAG *tag = parser->m_tagStack;
2236
4575936
  while (tag) {
2237
    int bufSize;
2238
220386
    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2239
220386
    char *rawNameBuf = tag->buf + nameLen;
2240
    /* Stop if already stored.  Since m_tagStack is a stack, we can stop
2241
       at the first entry that has already been copied; everything
2242
       below it in the stack is already been accounted for in a
2243
       previous call to this function.
2244
    */
2245
220386
    if (tag->rawName == rawNameBuf)
2246
216435
      break;
2247
    /* For re-use purposes we need to ensure that the
2248
       size of tag->buf is a multiple of sizeof(XML_Char).
2249
    */
2250
3951
    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2251
3951
    if (bufSize > tag->bufEnd - tag->buf) {
2252
210
      char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2253
210
      if (temp == NULL)
2254
30
        return XML_FALSE;
2255
      /* if tag->name.str points to tag->buf (only when namespace
2256
         processing is off) then we have to update it
2257
      */
2258
180
      if (tag->name.str == (XML_Char *)tag->buf)
2259
36
        tag->name.str = (XML_Char *)temp;
2260
      /* if tag->name.localPart is set (when namespace processing is on)
2261
         then update it as well, since it will always point into tag->buf
2262
      */
2263
180
      if (tag->name.localPart)
2264
144
        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2265
144
                                                  (XML_Char *)tag->buf);
2266
180
      tag->buf = temp;
2267
180
      tag->bufEnd = temp + bufSize;
2268
180
      rawNameBuf = temp + nameLen;
2269
180
    }
2270
3921
    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2271
3921
    tag->rawName = rawNameBuf;
2272
3921
    tag = tag->parent;
2273
3921
  }
2274
2284017
  return XML_TRUE;
2275
2284047
}
2276
2277
static enum XML_Error PTRCALL
2278
contentProcessor(XML_Parser parser,
2279
                 const char *start,
2280
                 const char *end,
2281
                 const char **endPtr)
2282
{
2283
6862860
  enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end,
2284
2287620
                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
2285
2287620
  if (result == XML_ERROR_NONE) {
2286
2283201
    if (!storeRawNames(parser))
2287
24
      return XML_ERROR_NO_MEMORY;
2288
  }
2289
2287596
  return result;
2290
2287620
}
2291
2292
static enum XML_Error PTRCALL
2293
externalEntityInitProcessor(XML_Parser parser,
2294
                            const char *start,
2295
                            const char *end,
2296
                            const char **endPtr)
2297
{
2298
672
  enum XML_Error result = initializeEncoding(parser);
2299
336
  if (result != XML_ERROR_NONE)
2300
6
    return result;
2301
330
  parser->m_processor = externalEntityInitProcessor2;
2302
330
  return externalEntityInitProcessor2(parser, start, end, endPtr);
2303
336
}
2304
2305
static enum XML_Error PTRCALL
2306
externalEntityInitProcessor2(XML_Parser parser,
2307
                             const char *start,
2308
                             const char *end,
2309
                             const char **endPtr)
2310
{
2311
5376
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
2312
2688
  int tok = XmlContentTok(parser->m_encoding, start, end, &next);
2313

2688
  switch (tok) {
2314
  case XML_TOK_BOM:
2315
    /* If we are at the end of the buffer, this would cause the next stage,
2316
       i.e. externalEntityInitProcessor3, to pass control directly to
2317
       doContent (by detecting XML_TOK_NONE) without processing any xml text
2318
       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2319
    */
2320

12
    if (next == end && !parser->m_parsingStatus.finalBuffer) {
2321
6
      *endPtr = next;
2322
6
      return XML_ERROR_NONE;
2323
    }
2324
    start = next;
2325
    break;
2326
  case XML_TOK_PARTIAL:
2327
2352
    if (!parser->m_parsingStatus.finalBuffer) {
2328
2346
      *endPtr = start;
2329
2346
      return XML_ERROR_NONE;
2330
    }
2331
6
    parser->m_eventPtr = start;
2332
6
    return XML_ERROR_UNCLOSED_TOKEN;
2333
  case XML_TOK_PARTIAL_CHAR:
2334
12
    if (!parser->m_parsingStatus.finalBuffer) {
2335
6
      *endPtr = start;
2336
6
      return XML_ERROR_NONE;
2337
    }
2338
6
    parser->m_eventPtr = start;
2339
6
    return XML_ERROR_PARTIAL_CHAR;
2340
  }
2341
318
  parser->m_processor = externalEntityInitProcessor3;
2342
318
  return externalEntityInitProcessor3(parser, start, end, endPtr);
2343
2688
}
2344
2345
static enum XML_Error PTRCALL
2346
externalEntityInitProcessor3(XML_Parser parser,
2347
                             const char *start,
2348
                             const char *end,
2349
                             const char **endPtr)
2350
{
2351
  int tok;
2352
684
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
2353
342
  parser->m_eventPtr = start;
2354
342
  tok = XmlContentTok(parser->m_encoding, start, end, &next);
2355
342
  parser->m_eventEndPtr = next;
2356
2357

342
  switch (tok) {
2358
  case XML_TOK_XML_DECL:
2359
    {
2360
      enum XML_Error result;
2361
66
      result = processXmlDecl(parser, 1, start, next);
2362
66
      if (result != XML_ERROR_NONE)
2363
        return result;
2364
66
      switch (parser->m_parsingStatus.parsing) {
2365
      case XML_SUSPENDED:
2366
18
        *endPtr = next;
2367
18
        return XML_ERROR_NONE;
2368
      case XML_FINISHED:
2369
6
        return XML_ERROR_ABORTED;
2370
      default:
2371
42
        start = next;
2372
      }
2373
42
    }
2374
    break;
2375
  case XML_TOK_PARTIAL:
2376
12
    if (!parser->m_parsingStatus.finalBuffer) {
2377
6
      *endPtr = start;
2378
6
      return XML_ERROR_NONE;
2379
    }
2380
6
    return XML_ERROR_UNCLOSED_TOKEN;
2381
  case XML_TOK_PARTIAL_CHAR:
2382
12
    if (!parser->m_parsingStatus.finalBuffer) {
2383
6
      *endPtr = start;
2384
6
      return XML_ERROR_NONE;
2385
    }
2386
6
    return XML_ERROR_PARTIAL_CHAR;
2387
  }
2388
294
  parser->m_processor = externalEntityContentProcessor;
2389
294
  parser->m_tagLevel = 1;
2390
294
  return externalEntityContentProcessor(parser, start, end, endPtr);
2391
342
}
2392
2393
static enum XML_Error PTRCALL
2394
externalEntityContentProcessor(XML_Parser parser,
2395
                               const char *start,
2396
                               const char *end,
2397
                               const char **endPtr)
2398
{
2399
2808
  enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end,
2400
936
                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
2401
936
  if (result == XML_ERROR_NONE) {
2402
846
    if (!storeRawNames(parser))
2403
6
      return XML_ERROR_NO_MEMORY;
2404
  }
2405
930
  return result;
2406
936
}
2407
2408
static enum XML_Error
2409
doContent(XML_Parser parser,
2410
          int startTagLevel,
2411
          const ENCODING *enc,
2412
          const char *s,
2413
          const char *end,
2414
          const char **nextPtr,
2415
          XML_Bool haveMore)
2416
{
2417
  /* save one level of indirection */
2418
2288646
  DTD * const dtd = parser->m_dtd;
2419
2420
  const char **eventPP;
2421
  const char **eventEndPP;
2422
2288646
  if (enc == parser->m_encoding) {
2423
2288562
    eventPP = &parser->m_eventPtr;
2424
2288562
    eventEndPP = &parser->m_eventEndPtr;
2425
2288562
  }
2426
  else {
2427
84
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
2428
84
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
2429
  }
2430
2288646
  *eventPP = s;
2431
2432
76615059
  for (;;) {
2433
76615059
    const char *next = s; /* XmlContentTok doesn't always set the last arg */
2434
76615059
    int tok = XmlContentTok(enc, s, end, &next);
2435
76615059
    *eventEndPP = next;
2436





76615059
    switch (tok) {
2437
    case XML_TOK_TRAILING_CR:
2438
36
      if (haveMore) {
2439
12
        *nextPtr = s;
2440
12
        return XML_ERROR_NONE;
2441
      }
2442
24
      *eventEndPP = end;
2443
24
      if (parser->m_characterDataHandler) {
2444
18
        XML_Char c = 0xA;
2445
18
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
2446
18
      }
2447
6
      else if (parser->m_defaultHandler)
2448
6
        reportDefault(parser, enc, s, end);
2449
      /* We are at the end of the final buffer, should we check for
2450
         XML_SUSPENDED, XML_FINISHED?
2451
      */
2452
24
      if (startTagLevel == 0)
2453
12
        return XML_ERROR_NO_ELEMENTS;
2454
12
      if (parser->m_tagLevel != startTagLevel)
2455
6
        return XML_ERROR_ASYNC_ENTITY;
2456
6
      *nextPtr = end;
2457
6
      return XML_ERROR_NONE;
2458
    case XML_TOK_NONE:
2459
16293
      if (haveMore) {
2460
16059
        *nextPtr = s;
2461
16059
        return XML_ERROR_NONE;
2462
      }
2463
234
      if (startTagLevel > 0) {
2464
228
        if (parser->m_tagLevel != startTagLevel)
2465
          return XML_ERROR_ASYNC_ENTITY;
2466
228
        *nextPtr = s;
2467
228
        return XML_ERROR_NONE;
2468
      }
2469
6
      return XML_ERROR_NO_ELEMENTS;
2470
    case XML_TOK_INVALID:
2471
882
      *eventPP = next;
2472
882
      return XML_ERROR_INVALID_TOKEN;
2473
    case XML_TOK_PARTIAL:
2474
2235678
      if (haveMore) {
2475
2235510
        *nextPtr = s;
2476
2235510
        return XML_ERROR_NONE;
2477
      }
2478
168
      return XML_ERROR_UNCLOSED_TOKEN;
2479
    case XML_TOK_PARTIAL_CHAR:
2480
636
      if (haveMore) {
2481
630
        *nextPtr = s;
2482
630
        return XML_ERROR_NONE;
2483
      }
2484
6
      return XML_ERROR_PARTIAL_CHAR;
2485
    case XML_TOK_ENTITY_REF:
2486
      {
2487
        const XML_Char *name;
2488
        ENTITY *entity;
2489
3001761
        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2490
                                              s + enc->minBytesPerChar,
2491
                                              next - enc->minBytesPerChar);
2492
3001761
        if (ch) {
2493
3000066
          if (parser->m_characterDataHandler)
2494
36
            parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
2495
3000030
          else if (parser->m_defaultHandler)
2496
30
            reportDefault(parser, enc, s, next);
2497
3000066
          break;
2498
        }
2499
3390
        name = poolStoreString(&dtd->pool, enc,
2500
1695
                                s + enc->minBytesPerChar,
2501
1695
                                next - enc->minBytesPerChar);
2502
1695
        if (!name)
2503
6
          return XML_ERROR_NO_MEMORY;
2504
1689
        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2505
1689
        poolDiscard(&dtd->pool);
2506
        /* First, determine if a check for an existing declaration is needed;
2507
           if yes, check that the entity exists, and that it is internal,
2508
           otherwise call the skipped entity or default handler.
2509
        */
2510

2475
        if (!dtd->hasParamEntityRefs || dtd->standalone) {
2511
921
          if (!entity)
2512
60
            return XML_ERROR_UNDEFINED_ENTITY;
2513
861
          else if (!entity->is_internal)
2514
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
2515
        }
2516
768
        else if (!entity) {
2517
90
          if (parser->m_skippedEntityHandler)
2518
6
            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
2519
84
          else if (parser->m_defaultHandler)
2520
24
            reportDefault(parser, enc, s, next);
2521
90
          break;
2522
        }
2523
1539
        if (entity->open)
2524
6
          return XML_ERROR_RECURSIVE_ENTITY_REF;
2525
1533
        if (entity->notation)
2526
          return XML_ERROR_BINARY_ENTITY_REF;
2527
1533
        if (entity->textPtr) {
2528
          enum XML_Error result;
2529
90
          if (!parser->m_defaultExpandInternalEntities) {
2530
24
            if (parser->m_skippedEntityHandler)
2531
6
              parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0);
2532
18
            else if (parser->m_defaultHandler)
2533
18
              reportDefault(parser, enc, s, next);
2534
24
            break;
2535
          }
2536
66
          result = processInternalEntity(parser, entity, XML_FALSE);
2537
66
          if (result != XML_ERROR_NONE)
2538
12
            return result;
2539
54
        }
2540
1443
        else if (parser->m_externalEntityRefHandler) {
2541
          const XML_Char *context;
2542
1437
          entity->open = XML_TRUE;
2543
1437
          context = getContext(parser);
2544
1437
          entity->open = XML_FALSE;
2545
1437
          if (!context)
2546
78
            return XML_ERROR_NO_MEMORY;
2547
2718
          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
2548
                                        context,
2549
1359
                                        entity->base,
2550
1359
                                        entity->systemId,
2551
1359
                                        entity->publicId))
2552
1137
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2553
222
          poolDiscard(&parser->m_tempPool);
2554
222
        }
2555
6
        else if (parser->m_defaultHandler)
2556
6
          reportDefault(parser, enc, s, next);
2557
282
        break;
2558
3001761
      }
2559
    case XML_TOK_START_TAG_NO_ATTS:
2560
      /* fall through */
2561
    case XML_TOK_START_TAG_WITH_ATTS:
2562
      {
2563
        TAG *tag;
2564
        enum XML_Error result;
2565
9755661
        XML_Char *toPtr;
2566
9755661
        if (parser->m_freeTagList) {
2567
          tag = parser->m_freeTagList;
2568
9751293
          parser->m_freeTagList = parser->m_freeTagList->parent;
2569
9751293
        }
2570
        else {
2571
4368
          tag = (TAG *)MALLOC(parser, sizeof(TAG));
2572
4368
          if (!tag)
2573
222
            return XML_ERROR_NO_MEMORY;
2574
4146
          tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
2575
4146
          if (!tag->buf) {
2576
222
            FREE(parser, tag);
2577
222
            return XML_ERROR_NO_MEMORY;
2578
          }
2579
3924
          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2580
        }
2581
9755217
        tag->bindings = NULL;
2582
9755217
        tag->parent = parser->m_tagStack;
2583
9755217
        parser->m_tagStack = tag;
2584
9755217
        tag->name.localPart = NULL;
2585
9755217
        tag->name.prefix = NULL;
2586
9755217
        tag->rawName = s + enc->minBytesPerChar;
2587
9755217
        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2588
9755217
        ++parser->m_tagLevel;
2589
        {
2590
9755217
          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2591
9755217
          const char *fromPtr = tag->rawName;
2592
9755217
          toPtr = (XML_Char *)tag->buf;
2593
9758133
          for (;;) {
2594
            int bufSize;
2595
            int convLen;
2596
9758133
            const enum XML_Convert_Result convert_res = XmlConvert(enc,
2597
                       &fromPtr, rawNameEnd,
2598
                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2599
9758133
            convLen = (int)(toPtr - (XML_Char *)tag->buf);
2600
9758133
            if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2601
9755037
              tag->name.strLen = convLen;
2602
9755037
              break;
2603
            }
2604
3096
            bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2605
            {
2606
3096
              char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
2607
3096
              if (temp == NULL)
2608
180
                return XML_ERROR_NO_MEMORY;
2609
2916
              tag->buf = temp;
2610
2916
              tag->bufEnd = temp + bufSize;
2611
2916
              toPtr = (XML_Char *)temp + convLen;
2612
2916
            }
2613
2916
          }
2614
19510254
        }
2615
9755037
        tag->name.str = (XML_Char *)tag->buf;
2616
9755037
        *toPtr = XML_T('\0');
2617
9755037
        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2618
9755037
        if (result)
2619
1044
          return result;
2620
9753993
        if (parser->m_startElementHandler)
2621
456
          parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
2622
228
                              (const XML_Char **)parser->m_atts);
2623
9753765
        else if (parser->m_defaultHandler)
2624
144
          reportDefault(parser, enc, s, next);
2625
9753993
        poolClear(&parser->m_tempPool);
2626
9753993
        break;
2627
9755661
      }
2628
    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2629
      /* fall through */
2630
    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2631
      {
2632
1062
        const char *rawName = s + enc->minBytesPerChar;
2633
        enum XML_Error result;
2634
1062
        BINDING *bindings = NULL;
2635
        XML_Bool noElmHandlers = XML_TRUE;
2636
1062
        TAG_NAME name;
2637
2124
        name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
2638
1062
                                   rawName + XmlNameLength(enc, rawName));
2639
1062
        if (!name.str)
2640
42
          return XML_ERROR_NO_MEMORY;
2641
1020
        poolFinish(&parser->m_tempPool);
2642
1020
        result = storeAtts(parser, enc, s, &name, &bindings);
2643
1020
        if (result != XML_ERROR_NONE) {
2644
336
          freeBindings(parser, bindings);
2645
336
          return result;
2646
        }
2647
684
        poolFinish(&parser->m_tempPool);
2648
684
        if (parser->m_startElementHandler) {
2649
108
          parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts);
2650
          noElmHandlers = XML_FALSE;
2651
108
        }
2652
684
        if (parser->m_endElementHandler) {
2653
54
          if (parser->m_startElementHandler)
2654
36
            *eventPP = *eventEndPP;
2655
54
          parser->m_endElementHandler(parser->m_handlerArg, name.str);
2656
          noElmHandlers = XML_FALSE;
2657
54
        }
2658

1242
        if (noElmHandlers && parser->m_defaultHandler)
2659
24
          reportDefault(parser, enc, s, next);
2660
684
        poolClear(&parser->m_tempPool);
2661
684
        freeBindings(parser, bindings);
2662
1746
      }
2663

966
      if ((parser->m_tagLevel == 0) &&
2664
570
          !((parser->m_parsingStatus.parsing == XML_FINISHED) || (parser->m_parsingStatus.parsing == XML_SUSPENDED))) {
2665
282
        return epilogProcessor(parser, next, end, nextPtr);
2666
      }
2667
      break;
2668
    case XML_TOK_END_TAG:
2669
9751326
      if (parser->m_tagLevel == startTagLevel)
2670
        return XML_ERROR_ASYNC_ENTITY;
2671
      else {
2672
        int len;
2673
        const char *rawName;
2674
9751326
        TAG *tag = parser->m_tagStack;
2675
9751326
        parser->m_tagStack = tag->parent;
2676
9751326
        tag->parent = parser->m_freeTagList;
2677
9751326
        parser->m_freeTagList = tag;
2678
9751326
        rawName = s + enc->minBytesPerChar*2;
2679
9751326
        len = XmlNameLength(enc, rawName);
2680
19502640
        if (len != tag->rawNameLength
2681
19502640
            || memcmp(tag->rawName, rawName, len) != 0) {
2682
24
          *eventPP = rawName;
2683
24
          return XML_ERROR_TAG_MISMATCH;
2684
        }
2685
9751302
        --parser->m_tagLevel;
2686
9751302
        if (parser->m_endElementHandler) {
2687
          const XML_Char *localPart;
2688
          const XML_Char *prefix;
2689
          XML_Char *uri;
2690
120
          localPart = tag->name.localPart;
2691
120
          if (parser->m_ns && localPart) {
2692
            /* localPart and prefix may have been overwritten in
2693
               tag->name.str, since this points to the binding->uri
2694
               buffer which gets re-used; so we have to add them again
2695
            */
2696
42
            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2697
            /* don't need to check for space - already done in storeAtts() */
2698
1344
            while (*localPart) *uri++ = *localPart++;
2699
42
            prefix = (XML_Char *)tag->name.prefix;
2700
42
            if (parser->m_ns_triplets && prefix) {
2701
36
              *uri++ = parser->m_namespaceSeparator;
2702
264
              while (*prefix) *uri++ = *prefix++;
2703
             }
2704
42
            *uri = XML_T('\0');
2705
42
          }
2706
120
          parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
2707
120
        }
2708
9751182
        else if (parser->m_defaultHandler)
2709
120
          reportDefault(parser, enc, s, next);
2710
19503144
        while (tag->bindings) {
2711
          BINDING *b = tag->bindings;
2712
270
          if (parser->m_endNamespaceDeclHandler)
2713
36
            parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
2714
270
          tag->bindings = tag->bindings->nextTagBinding;
2715
270
          b->nextTagBinding = parser->m_freeBindingList;
2716
270
          parser->m_freeBindingList = b;
2717
270
          b->prefix->binding = b->prevPrefixBinding;
2718
        }
2719
9751302
        if (parser->m_tagLevel == 0)
2720
31158
          return epilogProcessor(parser, next, end, nextPtr);
2721
9720144
      }
2722
      break;
2723
    case XML_TOK_CHAR_REF:
2724
      {
2725
222
        int n = XmlCharRefNumber(enc, s);
2726
222
        if (n < 0)
2727
6
          return XML_ERROR_BAD_CHAR_REF;
2728
216
        if (parser->m_characterDataHandler) {
2729
144
          XML_Char buf[XML_ENCODE_MAX];
2730
144
          parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2731
144
        }
2732
72
        else if (parser->m_defaultHandler)
2733
36
          reportDefault(parser, enc, s, next);
2734
216
      }
2735
      break;
2736
    case XML_TOK_XML_DECL:
2737
      return XML_ERROR_MISPLACED_XML_PI;
2738
    case XML_TOK_DATA_NEWLINE:
2739
21391086
      if (parser->m_characterDataHandler) {
2740
18
        XML_Char c = 0xA;
2741
18
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
2742
18
      }
2743
21391068
      else if (parser->m_defaultHandler)
2744
30
        reportDefault(parser, enc, s, next);
2745
      break;
2746
    case XML_TOK_CDATA_SECT_OPEN:
2747
      {
2748
        enum XML_Error result;
2749
162
        if (parser->m_startCdataSectionHandler)
2750
12
          parser->m_startCdataSectionHandler(parser->m_handlerArg);
2751
#if 0
2752
        /* Suppose you doing a transformation on a document that involves
2753
           changing only the character data.  You set up a defaultHandler
2754
           and a characterDataHandler.  The defaultHandler simply copies
2755
           characters through.  The characterDataHandler does the
2756
           transformation and writes the characters out escaping them as
2757
           necessary.  This case will fail to work if we leave out the
2758
           following two lines (because & and < inside CDATA sections will
2759
           be incorrectly escaped).
2760
2761
           However, now we have a start/endCdataSectionHandler, so it seems
2762
           easier to let the user deal with this.
2763
        */
2764
        else if (parser->m_characterDataHandler)
2765
          parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0);
2766
#endif
2767
150
        else if (parser->m_defaultHandler)
2768
12
          reportDefault(parser, enc, s, next);
2769
162
        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2770
162
        if (result != XML_ERROR_NONE)
2771
12
          return result;
2772
150
        else if (!next) {
2773
144
          parser->m_processor = cdataSectionProcessor;
2774
144
          return result;
2775
        }
2776
6
      }
2777
      break;
2778
    case XML_TOK_TRAILING_RSQB:
2779
36
      if (haveMore) {
2780
12
        *nextPtr = s;
2781
12
        return XML_ERROR_NONE;
2782
      }
2783
24
      if (parser->m_characterDataHandler) {
2784
18
        if (MUST_CONVERT(enc, s)) {
2785
6
          ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2786
6
          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
2787
12
          parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2788
6
                               (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2789
6
        }
2790
        else
2791
24
          parser->m_characterDataHandler(parser->m_handlerArg,
2792
12
                               (XML_Char *)s,
2793
12
                               (int)((XML_Char *)end - (XML_Char *)s));
2794
      }
2795
6
      else if (parser->m_defaultHandler)
2796
6
        reportDefault(parser, enc, s, end);
2797
      /* We are at the end of the final buffer, should we check for
2798
         XML_SUSPENDED, XML_FINISHED?
2799
      */
2800
24
      if (startTagLevel == 0) {
2801
18
        *eventPP = end;
2802
18
        return XML_ERROR_NO_ELEMENTS;
2803
      }
2804
6
      if (parser->m_tagLevel != startTagLevel) {
2805
6
        *eventPP = end;
2806
6
        return XML_ERROR_ASYNC_ENTITY;
2807
      }
2808
      *nextPtr = end;
2809
      return XML_ERROR_NONE;
2810
    case XML_TOK_DATA_CHARS:
2811
      {
2812
30430188
        XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
2813
30430188
        if (charDataHandler) {
2814
984
          if (MUST_CONVERT(enc, s)) {
2815
654
            for (;;) {
2816
654
              ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
2817
654
              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
2818
654
              *eventEndPP = s;
2819
1308
              charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
2820
654
                              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
2821
654
              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
2822
648
                break;
2823
6
              *eventPP = s;
2824
660
            }
2825
          }
2826
          else
2827
672
            charDataHandler(parser->m_handlerArg,
2828
336
                            (XML_Char *)s,
2829
336
                            (int)((XML_Char *)next - (XML_Char *)s));
2830
        }
2831
30429204
        else if (parser->m_defaultHandler)
2832
126
          reportDefault(parser, enc, s, next);
2833
      }
2834
30430188
      break;
2835
    case XML_TOK_PI:
2836
12
      if (!reportProcessingInstruction(parser, enc, s, next))
2837
6
        return XML_ERROR_NO_MEMORY;
2838
      break;
2839
    case XML_TOK_COMMENT:
2840
30018
      if (!reportComment(parser, enc, s, next))
2841
6
        return XML_ERROR_NO_MEMORY;
2842
      break;
2843
    default:
2844
      /* All of the tokens produced by XmlContentTok() have their own
2845
       * explicit cases, so this default is not strictly necessary.
2846
       * However it is a useful safety net, so we retain the code and
2847
       * simply exclude it from the coverage tests.
2848
       *
2849
       * LCOV_EXCL_START
2850
       */
2851
      if (parser->m_defaultHandler)
2852
        reportDefault(parser, enc, s, next);
2853
      break;
2854
      /* LCOV_EXCL_STOP */
2855
    }
2856
74326515
    *eventPP = s = next;
2857
74326515
    switch (parser->m_parsingStatus.parsing) {
2858
    case XML_SUSPENDED:
2859
78
      *nextPtr = next;
2860
78
      return XML_ERROR_NONE;
2861
    case XML_FINISHED:
2862
24
      return XML_ERROR_ABORTED;
2863
    default: ;
2864
    }
2865
150941472
  }
2866
  /* not reached */
2867
2288646
}
2868
2869
/* This function does not call free() on the allocated memory, merely
2870
 * moving it to the parser's m_freeBindingList where it can be freed or
2871
 * reused as appropriate.
2872
 */
2873
static void
2874
freeBindings(XML_Parser parser, BINDING *bindings)
2875
{
2876
3228
  while (bindings) {
2877
    BINDING *b = bindings;
2878
2879
    /* m_startNamespaceDeclHandler will have been called for this
2880
     * binding in addBindings(), so call the end handler now.
2881
     */
2882
84
    if (parser->m_endNamespaceDeclHandler)
2883
6
        parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
2884
2885
84
    bindings = bindings->nextTagBinding;
2886
84
    b->nextTagBinding = parser->m_freeBindingList;
2887
84
    parser->m_freeBindingList = b;
2888
84
    b->prefix->binding = b->prevPrefixBinding;
2889
  }
2890
1020
}
2891
2892
/* Precondition: all arguments must be non-NULL;
2893
   Purpose:
2894
   - normalize attributes
2895
   - check attributes for well-formedness
2896
   - generate namespace aware attribute names (URI, prefix)
2897
   - build list of attributes for startElementHandler
2898
   - default attributes
2899
   - process namespace declarations (check and report them)
2900
   - generate namespace aware element name (URI, prefix)
2901
*/
2902
static enum XML_Error
2903
storeAtts(XML_Parser parser, const ENCODING *enc,
2904
          const char *attStr, TAG_NAME *tagNamePtr,
2905
          BINDING **bindingsPtr)
2906
{
2907
19512114
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
2908
  ELEMENT_TYPE *elementType;
2909
  int nDefaultAtts;
2910
  const XML_Char **appAtts;   /* the attribute list for the application */
2911
  int attIndex = 0;
2912
  int prefixLen;
2913
  int i;
2914
  int n;
2915
  XML_Char *uri;
2916
  int nPrefixes = 0;
2917
  BINDING *binding;
2918
  const XML_Char *localPart;
2919
2920
  /* lookup the element type name */
2921
9756057
  elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
2922
9756057
  if (!elementType) {
2923
1235247
    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2924
1235247
    if (!name)
2925
132
      return XML_ERROR_NO_MEMORY;
2926
1235115
    elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
2927
                                         sizeof(ELEMENT_TYPE));
2928
1235115
    if (!elementType)
2929
474
      return XML_ERROR_NO_MEMORY;
2930

1236069
    if (parser->m_ns && !setElementTypePrefix(parser, elementType))
2931
84
      return XML_ERROR_NO_MEMORY;
2932
1234557
  }
2933
9755367
  nDefaultAtts = elementType->nDefaultAtts;
2934
2935
  /* get the attributes from the tokenizer */
2936
9755367
  n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
2937
9755367
  if (n + nDefaultAtts > parser->m_attsSize) {
2938
    int oldAttsSize = parser->m_attsSize;
2939
    ATTRIBUTE *temp;
2940
#ifdef XML_ATTR_INFO
2941
    XML_AttrInfo *temp2;
2942
#endif
2943
12
    parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2944
12
    temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE));
2945
12
    if (temp == NULL) {
2946
6
      parser->m_attsSize = oldAttsSize;
2947
6
      return XML_ERROR_NO_MEMORY;
2948
    }
2949
6
    parser->m_atts = temp;
2950
#ifdef XML_ATTR_INFO
2951
    temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo));
2952
    if (temp2 == NULL) {
2953
      parser->m_attsSize = oldAttsSize;
2954
      return XML_ERROR_NO_MEMORY;
2955
    }
2956
    parser->m_attInfo = temp2;
2957
#endif
2958
6
    if (n > oldAttsSize)
2959
6
      XmlGetAttributes(enc, attStr, n, parser->m_atts);
2960
6
  }
2961
2962
9755361
  appAtts = (const XML_Char **)parser->m_atts;
2963
25214886
  for (i = 0; i < n; i++) {
2964
2852700
    ATTRIBUTE *currAtt = &parser->m_atts[i];
2965
#ifdef XML_ATTR_INFO
2966
    XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
2967
#endif
2968
    /* add the name and value to the attribute list */
2969
5705400
    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
2970
                                         currAtt->name
2971
2852700
                                         + XmlNameLength(enc, currAtt->name));
2972
2852700
    if (!attId)
2973
336
      return XML_ERROR_NO_MEMORY;
2974
#ifdef XML_ATTR_INFO
2975
    currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
2976
    currAttInfo->nameEnd = currAttInfo->nameStart +
2977
                           XmlNameLength(enc, currAtt->name);
2978
    currAttInfo->valueStart = parser->m_parseEndByteIndex -
2979
                            (parser->m_parseEndPtr - currAtt->valuePtr);
2980
    currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd);
2981
#endif
2982
    /* Detect duplicate attributes by their QNames. This does not work when
2983
       namespace processing is turned on and different prefixes for the same
2984
       namespace are used. For this case we have a check further down.
2985
    */
2986
2852364
    if ((attId->name)[-1]) {
2987
      if (enc == parser->m_encoding)
2988
        parser->m_eventPtr = parser->m_atts[i].name;
2989
      return XML_ERROR_DUPLICATE_ATTRIBUTE;
2990
    }
2991
2852364
    (attId->name)[-1] = 1;
2992
2852364
    appAtts[attIndex++] = attId->name;
2993
2852364
    if (!parser->m_atts[i].normalized) {
2994
      enum XML_Error result;
2995
      XML_Bool isCdata = XML_TRUE;
2996
2997
      /* figure out whether declared as other than CDATA */
2998
126
      if (attId->maybeTokenized) {
2999
        int j;
3000
72
        for (j = 0; j < nDefaultAtts; j++) {
3001
36
          if (attId == elementType->defaultAtts[j].id) {
3002
18
            isCdata = elementType->defaultAtts[j].isCdata;
3003
18
            break;
3004
          }
3005
        }
3006
18
      }
3007
3008
      /* normalize the attribute value */
3009
126
      result = storeAttributeValue(parser, enc, isCdata,
3010
126
                                   parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd,
3011
126
                                   &parser->m_tempPool);
3012
126
      if (result)
3013
30
        return result;
3014
96
      appAtts[attIndex] = poolStart(&parser->m_tempPool);
3015
96
      poolFinish(&parser->m_tempPool);
3016
96
    }
3017
    else {
3018
      /* the value did not need normalizing */
3019
5704476
      appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr,
3020
2852238
                                          parser->m_atts[i].valueEnd);
3021
2852238
      if (appAtts[attIndex] == 0)
3022
30
        return XML_ERROR_NO_MEMORY;
3023
2852208
      poolFinish(&parser->m_tempPool);
3024
    }
3025
    /* handle prefixed attribute names */
3026
2852304
    if (attId->prefix) {
3027
1554
      if (attId->xmlns) {
3028
        /* deal with namespace declarations here */
3029
1284
        enum XML_Error result = addBinding(parser, attId->prefix, attId,
3030
1284
                                           appAtts[attIndex], bindingsPtr);
3031
1284
        if (result)
3032
222
          return result;
3033
        --attIndex;
3034
1062
      }
3035
      else {
3036
        /* deal with other prefixed names later */
3037
270
        attIndex++;
3038
270
        nPrefixes++;
3039
270
        (attId->name)[-1] = 2;
3040
      }
3041
    }
3042
    else
3043
2850750
      attIndex++;
3044
2852082
  }
3045
3046
  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
3047
9754743
  parser->m_nSpecifiedAtts = attIndex;
3048

9755061
  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3049
636
    for (i = 0; i < attIndex; i += 2)
3050
318
      if (appAtts[i] == elementType->idAtt->name) {
3051
        parser->m_idAttIndex = i;
3052
312
        break;
3053
      }
3054
  }
3055
  else
3056
    parser->m_idAttIndex = -1;
3057
3058
  /* do attribute defaulting */
3059
29265597
  for (i = 0; i < nDefaultAtts; i++) {
3060
690
    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
3061

918
    if (!(da->id->name)[-1] && da->value) {
3062
150
      if (da->id->prefix) {
3063
18
        if (da->id->xmlns) {
3064
12
          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3065
                                             da->value, bindingsPtr);
3066
12
          if (result)
3067
6
            return result;
3068
6
        }
3069
        else {
3070
6
          (da->id->name)[-1] = 2;
3071
6
          nPrefixes++;
3072
6
          appAtts[attIndex++] = da->id->name;
3073
6
          appAtts[attIndex++] = da->value;
3074
        }
3075
      }
3076
      else {
3077
132
        (da->id->name)[-1] = 1;
3078
132
        appAtts[attIndex++] = da->id->name;
3079
132
        appAtts[attIndex++] = da->value;
3080
      }
3081
138
    }
3082
684
  }
3083
9754737
  appAtts[attIndex] = 0;
3084
3085
  /* expand prefixed attribute names, check for duplicates,
3086
     and clear flags that say whether attributes were specified */
3087
  i = 0;
3088
9754737
  if (nPrefixes) {
3089
    int j;  /* hash table index */
3090
174
    unsigned long version = parser->m_nsAttsVersion;
3091
174
    int nsAttsSize = (int)1 << parser->m_nsAttsPower;
3092
    unsigned char oldNsAttsPower = parser->m_nsAttsPower;
3093
    /* size of hash table must be at least 2 * (# of prefixed attributes) */
3094
174
    if ((nPrefixes << 1) >> parser->m_nsAttsPower) {  /* true for m_nsAttsPower = 0 */
3095
      NS_ATT *temp;
3096
      /* hash table size must also be a power of 2 and >= 8 */
3097
684
      while (nPrefixes >> parser->m_nsAttsPower++);
3098
162
      if (parser->m_nsAttsPower < 3)
3099
144
        parser->m_nsAttsPower = 3;
3100
162
      nsAttsSize = (int)1 << parser->m_nsAttsPower;
3101
162
      temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT));
3102
162
      if (!temp) {
3103
        /* Restore actual size of memory in m_nsAtts */
3104
6
        parser->m_nsAttsPower = oldNsAttsPower;
3105
6
        return XML_ERROR_NO_MEMORY;
3106
      }
3107
156
      parser->m_nsAtts = temp;
3108
      version = 0;  /* force re-initialization of m_nsAtts hash table */
3109
156
    }
3110
    /* using a version flag saves us from initializing m_nsAtts every time */
3111
168
    if (!version) {  /* initialize version flags when version wraps around */
3112
      version = INIT_ATTS_VERSION;
3113
2808
      for (j = nsAttsSize; j != 0; )
3114
1248
        parser->m_nsAtts[--j].version = version;
3115
    }
3116
168
    parser->m_nsAttsVersion = --version;
3117
3118
    /* expand prefixed names and check for duplicates */
3119
372
    for (; i < attIndex; i += 2) {
3120
186
      const XML_Char *s = appAtts[i];
3121
186
      if (s[-1] == 2) {  /* prefixed */
3122
        ATTRIBUTE_ID *id;
3123
        const BINDING *b;
3124
        unsigned long uriHash;
3125
180
        struct siphash sip_state;
3126
180
        struct sipkey sip_key;
3127
3128
180
        copy_salt_to_sipkey(parser, &sip_key);
3129
180
        sip24_init(&sip_state, &sip_key);
3130
3131
180
        ((XML_Char *)s)[-1] = 0;  /* clear flag */
3132
180
        id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
3133

360
        if (!id || !id->prefix) {
3134
          /* This code is walking through the appAtts array, dealing
3135
           * with (in this case) a prefixed attribute name.  To be in
3136
           * the array, the attribute must have already been bound, so
3137
           * has to have passed through the hash table lookup once
3138
           * already.  That implies that an entry for it already
3139
           * exists, so the lookup above will return a pointer to
3140
           * already allocated memory.  There is no opportunaity for
3141
           * the allocator to fail, so the condition above cannot be
3142
           * fulfilled.
3143
           *
3144
           * Since it is difficult to be certain that the above
3145
           * analysis is complete, we retain the test and merely
3146
           * remove the code from coverage tests.
3147
           */
3148
          return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
3149
        }
3150
180
        b = id->prefix->binding;
3151
180
        if (!b)
3152
18
          return XML_ERROR_UNBOUND_PREFIX;
3153
3154
30564
        for (j = 0; j < b->uriLen; j++) {
3155
15126
          const XML_Char c = b->uri[j];
3156

30264
          if (!poolAppendChar(&parser->m_tempPool, c))
3157
6
            return XML_ERROR_NO_MEMORY;
3158
15120
        }
3159
3160
156
        sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3161
3162
68400
        while (*s++ != XML_T(ASCII_COLON))
3163
          ;
3164
3165
156
        sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3166
3167
156
        do {  /* copies null terminator */
3168

24732
          if (!poolAppendChar(&parser->m_tempPool, *s))
3169
6
            return XML_ERROR_NO_MEMORY;
3170
12354
        } while (*s++);
3171
3172
150
        uriHash = (unsigned long)sip24_final(&sip_state);
3173
3174
        { /* Check hash table for duplicate of expanded name (uriName).
3175
             Derived from code in lookup(parser, HASH_TABLE *table, ...).
3176
          */
3177
          unsigned char step = 0;
3178
150
          unsigned long mask = nsAttsSize - 1;
3179
150
          j = uriHash & mask;  /* index into hash table */
3180
300
          while (parser->m_nsAtts[j].version == version) {
3181
            /* for speed we compare stored hash values first */
3182
6
            if (uriHash == parser->m_nsAtts[j].hash) {
3183
6
              const XML_Char *s1 = poolStart(&parser->m_tempPool);
3184
6
              const XML_Char *s2 = parser->m_nsAtts[j].uriName;
3185
              /* s1 is null terminated, but not s2 */
3186

414
              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
3187
6
              if (*s1 == 0)
3188
6
                return XML_ERROR_DUPLICATE_ATTRIBUTE;
3189
            }
3190
            if (!step)
3191
              step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
3192
            j < step ? (j += nsAttsSize - step) : (j -= step);
3193
          }
3194
144
        }
3195
3196
144
        if (parser->m_ns_triplets) {  /* append namespace separator and prefix */
3197
54
          parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
3198
54
          s = b->prefix->name;
3199
54
          do {
3200

24120
            if (!poolAppendChar(&parser->m_tempPool, *s))
3201
6
              return XML_ERROR_NO_MEMORY;
3202
12048
          } while (*s++);
3203
        }
3204
3205
        /* store expanded name in attribute list */
3206
138
        s = poolStart(&parser->m_tempPool);
3207
138
        poolFinish(&parser->m_tempPool);
3208
138
        appAtts[i] = s;
3209
3210
        /* fill empty slot with new version, uriName and hash value */
3211
138
        parser->m_nsAtts[j].version = version;
3212
138
        parser->m_nsAtts[j].hash = uriHash;
3213
138
        parser->m_nsAtts[j].uriName = s;
3214
3215
138
        if (!--nPrefixes) {
3216
126
          i += 2;
3217
126
          break;
3218
        }
3219
192
      }
3220
      else  /* not prefixed */
3221
6
        ((XML_Char *)s)[-1] = 0;  /* clear flag */
3222
18
    }
3223
126
  }
3224
  /* clear flags for the remaining attributes */
3225
25211130
  for (; i < attIndex; i += 2)
3226
2850876
    ((XML_Char *)(appAtts[i]))[-1] = 0;
3227
19511046
  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3228
834
    binding->attId->name[-1] = 0;
3229
3230
9754689
  if (!parser->m_ns)
3231
9753531
    return XML_ERROR_NONE;
3232
3233
  /* expand the element type name */
3234
1158
  if (elementType->prefix) {
3235
462
    binding = elementType->prefix->binding;
3236
462
    if (!binding)
3237
6
      return XML_ERROR_UNBOUND_PREFIX;
3238
456
    localPart = tagNamePtr->str;
3239
284880
    while (*localPart++ != XML_T(ASCII_COLON))
3240
      ;
3241
  }
3242
696
  else if (dtd->defaultPrefix.binding) {
3243
    binding = dtd->defaultPrefix.binding;
3244
378
    localPart = tagNamePtr->str;
3245
  }
3246
  else
3247
318
    return XML_ERROR_NONE;
3248
  prefixLen = 0;
3249

894
  if (parser->m_ns_triplets && binding->prefix->name) {
3250
444
    for (; binding->prefix->name[prefixLen++];)
3251
      ;  /* prefixLen includes null terminator */
3252
  }
3253
834
  tagNamePtr->localPart = localPart;
3254
834
  tagNamePtr->uriLen = binding->uriLen;
3255
834
  tagNamePtr->prefix = binding->prefix->name;
3256
834
  tagNamePtr->prefixLen = prefixLen;
3257
9132
  for (i = 0; localPart[i++];)
3258
    ;  /* i includes null terminator */
3259
834
  n = i + binding->uriLen + prefixLen;
3260
834
  if (n > binding->uriAlloc) {
3261
    TAG *p;
3262
24
    uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char));
3263
24
    if (!uri)
3264
6
      return XML_ERROR_NO_MEMORY;
3265
18
    binding->uriAlloc = n + EXPAND_SPARE;
3266
18
    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3267
72
    for (p = parser->m_tagStack; p; p = p->parent)
3268
18
      if (p->name.str == binding->uri)
3269
6
        p->name.str = uri;
3270
18
    FREE(parser, binding->uri);
3271
18
    binding->uri = uri;
3272
18
  }
3273
  /* if m_namespaceSeparator != '\0' then uri includes it already */
3274
828
  uri = binding->uri + binding->uriLen;
3275
828
  memcpy(uri, localPart, i * sizeof(XML_Char));
3276
  /* we always have a namespace separator between localPart and prefix */
3277
828
  if (prefixLen) {
3278
54
    uri += i - 1;
3279
54
    *uri = parser->m_namespaceSeparator;  /* replace null terminator */
3280
54
    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3281
54
  }
3282
828
  tagNamePtr->str = binding->uri;
3283
828
  return XML_ERROR_NONE;
3284
9756057
}
3285
3286
/* addBinding() overwrites the value of prefix->binding without checking.
3287
   Therefore one must keep track of the old value outside of addBinding().
3288
*/
3289
static enum XML_Error
3290
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3291
           const XML_Char *uri, BINDING **bindingsPtr)
3292
{
3293
  static const XML_Char xmlNamespace[] = {
3294
    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3295
    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3296
    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
3297
    ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
3298
    ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3299
    ASCII_e, '\0'
3300
  };
3301
  static const int xmlLen =
3302
    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3303
  static const XML_Char xmlnsNamespace[] = {
3304
    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3305
    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3306
    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
3307
    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
3308
    ASCII_SLASH, '\0'
3309
  };
3310
  static const int xmlnsLen =
3311
    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3312
3313
  XML_Bool mustBeXML = XML_FALSE;
3314
  XML_Bool isXML = XML_TRUE;
3315
  XML_Bool isXMLNS = XML_TRUE;
3316
3317
  BINDING *b;
3318
  int len;
3319
3320
  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3321

8414
  if (*uri == XML_T('\0') && prefix->name)
3322
18
    return XML_ERROR_UNDECLARING_PREFIX;
3323
3324
6914
  if (prefix->name
3325
7832
      && prefix->name[0] == XML_T(ASCII_x)
3326
6422
      && prefix->name[1] == XML_T(ASCII_m)
3327
5504
      && prefix->name[2] == XML_T(ASCII_l)) {
3328
3329
    /* Not allowed to bind xmlns */
3330
2758
    if (prefix->name[3] == XML_T(ASCII_n)
3331
2758
        && prefix->name[4] == XML_T(ASCII_s)
3332
12
        && prefix->name[5] == XML_T('\0'))
3333
6
      return XML_ERROR_RESERVED_PREFIX_XMLNS;
3334
3335
2746
    if (prefix->name[3] == XML_T('\0'))
3336
2746
      mustBeXML = XML_TRUE;
3337
  }
3338
3339
1100636
  for (len = 0; uri[len]; len++) {
3340

764898
    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3341
1374
      isXML = XML_FALSE;
3342
3343

1004208
    if (!mustBeXML && isXMLNS
3344

468684
        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3345
1368
      isXMLNS = XML_FALSE;
3346
  }
3347
4156
  isXML = isXML && len == xmlLen;
3348
4156
  isXMLNS = isXMLNS && len == xmlnsLen;
3349
3350
4156
  if (mustBeXML != isXML)
3351
12
    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3352
                     : XML_ERROR_RESERVED_NAMESPACE_URI;
3353
3354
4144
  if (isXMLNS)
3355
6
    return XML_ERROR_RESERVED_NAMESPACE_URI;
3356
3357
4138
  if (parser->m_namespaceSeparator)
3358
4138
    len++;
3359
4138
  if (parser->m_freeBindingList) {
3360
    b = parser->m_freeBindingList;
3361
54
    if (len > b->uriAlloc) {
3362
12
      XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri,
3363
                          sizeof(XML_Char) * (len + EXPAND_SPARE));
3364
12
      if (temp == NULL)
3365
6
        return XML_ERROR_NO_MEMORY;
3366
6
      b->uri = temp;
3367
6
      b->uriAlloc = len + EXPAND_SPARE;
3368
6
    }
3369
48
    parser->m_freeBindingList = b->nextTagBinding;
3370
48
  }
3371
  else {
3372
4084
    b = (BINDING *)MALLOC(parser, sizeof(BINDING));
3373
4084
    if (!b)
3374
198
      return XML_ERROR_NO_MEMORY;
3375
3886
    b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
3376
3886
    if (!b->uri) {
3377
198
      FREE(parser, b);
3378
198
      return XML_ERROR_NO_MEMORY;
3379
    }
3380
3688
    b->uriAlloc = len + EXPAND_SPARE;
3381
  }
3382
3736
  b->uriLen = len;
3383
3736
  memcpy(b->uri, uri, len * sizeof(XML_Char));
3384
3736
  if (parser->m_namespaceSeparator)
3385
3736
    b->uri[len - 1] = parser->m_namespaceSeparator;
3386
3736
  b->prefix = prefix;
3387
3736
  b->attId = attId;
3388
3736
  b->prevPrefixBinding = prefix->binding;
3389
  /* NULL binding when default namespace undeclared */
3390

3760
  if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
3391
24
    prefix->binding = NULL;
3392
  else
3393
    prefix->binding = b;
3394
3736
  b->nextTagBinding = *bindingsPtr;
3395
3736
  *bindingsPtr = b;
3396
  /* if attId == NULL then we are not starting a namespace scope */
3397

4804
  if (attId && parser->m_startNamespaceDeclHandler)
3398
84
    parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
3399
42
                              prefix->binding ? uri : 0);
3400
3736
  return XML_ERROR_NONE;
3401
4180
}
3402
3403
/* The idea here is to avoid using stack for each CDATA section when
3404
   the whole file is parsed with one call.
3405
*/
3406
static enum XML_Error PTRCALL
3407
cdataSectionProcessor(XML_Parser parser,
3408
                      const char *start,
3409
                      const char *end,
3410
                      const char **endPtr)
3411
{
3412
3024
  enum XML_Error result = doCdataSection(parser, parser->m_encoding, &start, end,
3413
1512
                                         endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
3414
1512
  if (result != XML_ERROR_NONE)
3415
78
    return result;
3416
1434
  if (start) {
3417
60
    if (parser->m_parentParser) {  /* we are parsing an external entity */
3418
6
      parser->m_processor = externalEntityContentProcessor;
3419
6
      return externalEntityContentProcessor(parser, start, end, endPtr);
3420
    }
3421
    else {
3422
54
      parser->m_processor = contentProcessor;
3423
54
      return contentProcessor(parser, start, end, endPtr);
3424
    }
3425
  }
3426
1374
  return result;
3427
1512
}
3428
3429
/* startPtr gets set to non-null if the section is closed, and to null if
3430
   the section is not yet closed.
3431
*/
3432
static enum XML_Error
3433
doCdataSection(XML_Parser parser,
3434
               const ENCODING *enc,
3435
               const char **startPtr,
3436
               const char *end,
3437
               const char **nextPtr,
3438
               XML_Bool haveMore)
3439
{
3440
3348
  const char *s = *startPtr;
3441
  const char **eventPP;
3442
  const char **eventEndPP;
3443
1674
  if (enc == parser->m_encoding) {
3444
1674
    eventPP = &parser->m_eventPtr;
3445
1674
    *eventPP = s;
3446
1674
    eventEndPP = &parser->m_eventEndPtr;
3447
1674
  }
3448
  else {
3449
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3450
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
3451
  }
3452
1674
  *eventPP = s;
3453
1674
  *startPtr = NULL;
3454
3455
2700
  for (;;) {
3456
2700
    const char *next;
3457
2700
    int tok = XmlCdataSectionTok(enc, s, end, &next);
3458
2700
    *eventEndPP = next;
3459


2700
    switch (tok) {
3460
    case XML_TOK_CDATA_SECT_CLOSE:
3461
66
      if (parser->m_endCdataSectionHandler)
3462
12
        parser->m_endCdataSectionHandler(parser->m_handlerArg);
3463
#if 0
3464
      /* see comment under XML_TOK_CDATA_SECT_OPEN */
3465
      else if (parser->m_characterDataHandler)
3466
        parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0);
3467
#endif
3468
54
      else if (parser->m_defaultHandler)
3469
12
        reportDefault(parser, enc, s, next);
3470
66
      *startPtr = next;
3471
66
      *nextPtr = next;
3472
66
      if (parser->m_parsingStatus.parsing == XML_FINISHED)
3473
        return XML_ERROR_ABORTED;
3474
      else
3475
66
        return XML_ERROR_NONE;
3476
    case XML_TOK_DATA_NEWLINE:
3477
6
      if (parser->m_characterDataHandler) {
3478
        XML_Char c = 0xA;
3479
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
3480
      }
3481
6
      else if (parser->m_defaultHandler)
3482
6
        reportDefault(parser, enc, s, next);
3483
      break;
3484
    case XML_TOK_DATA_CHARS:
3485
      {
3486
1032
        XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3487
1032
        if (charDataHandler) {
3488
858
          if (MUST_CONVERT(enc, s)) {
3489
84
            for (;;) {
3490
84
              ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3491
84
              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
3492
84
              *eventEndPP = next;
3493
168
              charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3494
84
                              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3495
84
              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3496
78
                break;
3497
6
              *eventPP = s;
3498
90
            }
3499
          }
3500
          else
3501
1560
            charDataHandler(parser->m_handlerArg,
3502
780
                            (XML_Char *)s,
3503
780
                            (int)((XML_Char *)next - (XML_Char *)s));
3504
        }
3505
174
        else if (parser->m_defaultHandler)
3506
60
          reportDefault(parser, enc, s, next);
3507
      }
3508
1032
      break;
3509
    case XML_TOK_INVALID:
3510
6
      *eventPP = next;
3511
6
      return XML_ERROR_INVALID_TOKEN;
3512
    case XML_TOK_PARTIAL_CHAR:
3513
72
      if (haveMore) {
3514
60
        *nextPtr = s;
3515
60
        return XML_ERROR_NONE;
3516
      }
3517
12
      return XML_ERROR_PARTIAL_CHAR;
3518
    case XML_TOK_PARTIAL:
3519
    case XML_TOK_NONE:
3520
1518
      if (haveMore) {
3521
1452
        *nextPtr = s;
3522
1452
        return XML_ERROR_NONE;
3523
      }
3524
66
      return XML_ERROR_UNCLOSED_CDATA_SECTION;
3525
    default:
3526
      /* Every token returned by XmlCdataSectionTok() has its own
3527
       * explicit case, so this default case will never be executed.
3528
       * We retain it as a safety net and exclude it from the coverage
3529
       * statistics.
3530
       *
3531
       * LCOV_EXCL_START
3532
      */
3533
      *eventPP = next;
3534
      return XML_ERROR_UNEXPECTED_STATE;
3535
      /* LCOV_EXCL_STOP */
3536
    }
3537
3538
1038
    *eventPP = s = next;
3539
1038
    switch (parser->m_parsingStatus.parsing) {
3540
    case XML_SUSPENDED:
3541
6
      *nextPtr = next;
3542
6
      return XML_ERROR_NONE;
3543
    case XML_FINISHED:
3544
6
      return XML_ERROR_ABORTED;
3545
    default: ;
3546
    }
3547
3726
  }
3548
  /* not reached */
3549
1674
}
3550
3551
#ifdef XML_DTD
3552
3553
/* The idea here is to avoid using stack for each IGNORE section when
3554
   the whole file is parsed with one call.
3555
*/
3556
static enum XML_Error PTRCALL
3557
ignoreSectionProcessor(XML_Parser parser,
3558
                       const char *start,
3559
                       const char *end,
3560
                       const char **endPtr)
3561
{
3562
1812
  enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end,
3563
906
                                          endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
3564
906
  if (result != XML_ERROR_NONE)
3565
24
    return result;
3566
882
  if (start) {
3567
18
    parser->m_processor = prologProcessor;
3568
18
    return prologProcessor(parser, start, end, endPtr);
3569
  }
3570
864
  return result;
3571
906
}
3572
3573
/* startPtr gets set to non-null is the section is closed, and to null
3574
   if the section is not yet closed.
3575
*/
3576
static enum XML_Error
3577
doIgnoreSection(XML_Parser parser,
3578
                const ENCODING *enc,
3579
                const char **startPtr,
3580
                const char *end,
3581
                const char **nextPtr,
3582
                XML_Bool haveMore)
3583
{
3584
1896
  const char *next;
3585
  int tok;
3586
948
  const char *s = *startPtr;
3587
  const char **eventPP;
3588
  const char **eventEndPP;
3589
948
  if (enc == parser->m_encoding) {
3590
948
    eventPP = &parser->m_eventPtr;
3591
948
    *eventPP = s;
3592
948
    eventEndPP = &parser->m_eventEndPtr;
3593
948
  }
3594
  else {
3595
    /* It's not entirely clear, but it seems the following two lines
3596
     * of code cannot be executed.  The only occasions on which 'enc'
3597
     * is not 'encoding' are when this function is called
3598
     * from the internal entity processing, and IGNORE sections are an
3599
     * error in internal entities.
3600
     *
3601
     * Since it really isn't clear that this is true, we keep the code
3602
     * and just remove it from our coverage tests.
3603
     *
3604
     * LCOV_EXCL_START
3605
     */
3606
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3607
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
3608
    /* LCOV_EXCL_STOP */
3609
  }
3610
948
  *eventPP = s;
3611
948
  *startPtr = NULL;
3612
948
  tok = XmlIgnoreSectionTok(enc, s, end, &next);
3613
948
  *eventEndPP = next;
3614

948
  switch (tok) {
3615
  case XML_TOK_IGNORE_SECT:
3616
18
    if (parser->m_defaultHandler)
3617
18
      reportDefault(parser, enc, s, next);
3618
18
    *startPtr = next;
3619
18
    *nextPtr = next;
3620
18
    if (parser->m_parsingStatus.parsing == XML_FINISHED)
3621
      return XML_ERROR_ABORTED;
3622
    else
3623
18
      return XML_ERROR_NONE;
3624
  case XML_TOK_INVALID:
3625
12
    *eventPP = next;
3626
12
    return XML_ERROR_INVALID_TOKEN;
3627
  case XML_TOK_PARTIAL_CHAR:
3628
18
    if (haveMore) {
3629
12
      *nextPtr = s;
3630
12
      return XML_ERROR_NONE;
3631
    }
3632
6
    return XML_ERROR_PARTIAL_CHAR;
3633
  case XML_TOK_PARTIAL:
3634
  case XML_TOK_NONE:
3635
900
    if (haveMore) {
3636
894
      *nextPtr = s;
3637
894
      return XML_ERROR_NONE;
3638
    }
3639
6
    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3640
  default:
3641
    /* All of the tokens that XmlIgnoreSectionTok() returns have
3642
     * explicit cases to handle them, so this default case is never
3643
     * executed.  We keep it as a safety net anyway, and remove it
3644
     * from our test coverage statistics.
3645
     *
3646
     * LCOV_EXCL_START
3647
     */
3648
    *eventPP = next;
3649
    return XML_ERROR_UNEXPECTED_STATE;
3650
    /* LCOV_EXCL_STOP */
3651
  }
3652
  /* not reached */
3653
948
}
3654
3655
#endif /* XML_DTD */
3656
3657
static enum XML_Error
3658
initializeEncoding(XML_Parser parser)
3659
{
3660
  const char *s;
3661
#ifdef XML_UNICODE
3662
  char encodingBuf[128];
3663
  /* See comments abount `protoclEncodingName` in parserInit() */
3664
  if (!parser->m_protocolEncodingName)
3665
    s = NULL;
3666
  else {
3667
    int i;
3668
    for (i = 0; parser->m_protocolEncodingName[i]; i++) {
3669
      if (i == sizeof(encodingBuf) - 1
3670
          || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
3671
        encodingBuf[0] = '\0';
3672
        break;
3673
      }
3674
      encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
3675
    }
3676
    encodingBuf[i] = '\0';
3677
    s = encodingBuf;
3678
  }
3679
#else
3680
79818
  s = parser->m_protocolEncodingName;
3681
#endif
3682
39909
  if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(&parser->m_initEncoding, &parser->m_encoding, s))
3683
39885
    return XML_ERROR_NONE;
3684
24
  return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
3685
39909
}
3686
3687
static enum XML_Error
3688
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3689
               const char *s, const char *next)
3690
{
3691
63372
  const char *encodingName = NULL;
3692
  const XML_Char *storedEncName = NULL;
3693
31686
  const ENCODING *newEncoding = NULL;
3694
31686
  const char *version = NULL;
3695
31686
  const char *versionend;
3696
  const XML_Char *storedversion = NULL;
3697
31686
  int standalone = -1;
3698
63372
  if (!(parser->m_ns
3699
        ? XmlParseXmlDeclNS
3700
        : XmlParseXmlDecl)(isGeneralTextEntity,
3701
31686
                           parser->m_encoding,
3702
                           s,
3703
                           next,
3704
31686
                           &parser->m_eventPtr,
3705
                           &version,
3706
                           &versionend,
3707
                           &encodingName,
3708
                           &newEncoding,
3709
                           &standalone)) {
3710
30
    if (isGeneralTextEntity)
3711
6
      return XML_ERROR_TEXT_DECL;
3712
    else
3713
24
      return XML_ERROR_XML_DECL;
3714
  }
3715
31656
  if (!isGeneralTextEntity && standalone == 1) {
3716
30
    parser->m_dtd->standalone = XML_TRUE;
3717
#ifdef XML_DTD
3718
30
    if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3719
6
      parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3720
#endif /* XML_DTD */
3721
  }
3722
31656
  if (parser->m_xmlDeclHandler) {
3723
150
    if (encodingName != NULL) {
3724
300
      storedEncName = poolStoreString(&parser->m_temp2Pool,
3725
150
                                      parser->m_encoding,
3726
                                      encodingName,
3727
                                      encodingName
3728
150
                                      + XmlNameLength(parser->m_encoding, encodingName));
3729
150
      if (!storedEncName)
3730
12
              return XML_ERROR_NO_MEMORY;
3731
138
      poolFinish(&parser->m_temp2Pool);
3732
138
    }
3733
138
    if (version) {
3734
276
      storedversion = poolStoreString(&parser->m_temp2Pool,
3735
138
                                      parser->m_encoding,
3736
                                      version,
3737
138
                                      versionend - parser->m_encoding->minBytesPerChar);
3738
138
      if (!storedversion)
3739
6
        return XML_ERROR_NO_MEMORY;
3740
    }
3741
132
    parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone);
3742
132
  }
3743
31506
  else if (parser->m_defaultHandler)
3744
24
    reportDefault(parser, parser->m_encoding, s, next);
3745
31638
  if (parser->m_protocolEncodingName == NULL) {
3746
31614
    if (newEncoding) {
3747
      /* Check that the specified encoding does not conflict with what
3748
       * the parser has already deduced.  Do we have the same number
3749
       * of bytes in the smallest representation of a character?  If
3750
       * this is UTF-16, is it the same endianness?
3751
       */
3752
31170
      if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
3753

61974
          || (newEncoding->minBytesPerChar == 2 &&
3754
180
              newEncoding != parser->m_encoding)) {
3755
6
        parser->m_eventPtr = encodingName;
3756
6
        return XML_ERROR_INCORRECT_ENCODING;
3757
      }
3758
30984
      parser->m_encoding = newEncoding;
3759
30984
    }
3760
624
    else if (encodingName) {
3761
      enum XML_Error result;
3762
234
      if (!storedEncName) {
3763
192
        storedEncName = poolStoreString(
3764
192
          &parser->m_temp2Pool, parser->m_encoding, encodingName,
3765
192
          encodingName + XmlNameLength(parser->m_encoding, encodingName));
3766
192
        if (!storedEncName)
3767
6
          return XML_ERROR_NO_MEMORY;
3768
      }
3769
228
      result = handleUnknownEncoding(parser, storedEncName);
3770
228
      poolClear(&parser->m_temp2Pool);
3771
228
      if (result == XML_ERROR_UNKNOWN_ENCODING)
3772
36
        parser->m_eventPtr = encodingName;
3773
228
      return result;
3774
    }
3775
  }
3776
3777
31398
  if (storedEncName || storedversion)
3778
84
    poolClear(&parser->m_temp2Pool);
3779
3780
31398
  return XML_ERROR_NONE;
3781
31686
}
3782
3783
static enum XML_Error
3784
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3785
{
3786
504
  if (parser->m_unknownEncodingHandler) {
3787
234
    XML_Encoding info;
3788
    int i;
3789
120276
    for (i = 0; i < 256; i++)
3790
59904
      info.map[i] = -1;
3791
234
    info.convert = NULL;
3792
234
    info.data = NULL;
3793
234
    info.release = NULL;
3794
234
    if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName,
3795
                               &info)) {
3796
      ENCODING *enc;
3797
228
      parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
3798
228
      if (!parser->m_unknownEncodingMem) {
3799
12
        if (info.release)
3800
6
          info.release(info.data);
3801
12
        return XML_ERROR_NO_MEMORY;
3802
      }
3803
432
      enc = (parser->m_ns
3804
             ? XmlInitUnknownEncodingNS
3805
             : XmlInitUnknownEncoding)(parser->m_unknownEncodingMem,
3806
216
                                       info.map,
3807
216
                                       info.convert,
3808
216
                                       info.data);
3809
216
      if (enc) {
3810
186
        parser->m_unknownEncodingData = info.data;
3811
186
        parser->m_unknownEncodingRelease = info.release;
3812
186
        parser->m_encoding = enc;
3813
186
        return XML_ERROR_NONE;
3814
      }
3815
30
    }
3816
36
    if (info.release != NULL)
3817
6
      info.release(info.data);
3818
270
  }
3819
54
  return XML_ERROR_UNKNOWN_ENCODING;
3820
252
}
3821
3822
static enum XML_Error PTRCALL
3823
prologInitProcessor(XML_Parser parser,
3824
                    const char *s,
3825
                    const char *end,
3826
                    const char **nextPtr)
3827
{
3828
75798
  enum XML_Error result = initializeEncoding(parser);
3829
37899
  if (result != XML_ERROR_NONE)
3830
6
    return result;
3831
37893
  parser->m_processor = prologProcessor;
3832
37893
  return prologProcessor(parser, s, end, nextPtr);
3833
37899
}
3834
3835
#ifdef XML_DTD
3836
3837
static enum XML_Error PTRCALL
3838
externalParEntInitProcessor(XML_Parser parser,
3839
                            const char *s,
3840
                            const char *end,
3841
                            const char **nextPtr)
3842
{
3843
3348
  enum XML_Error result = initializeEncoding(parser);
3844
1674
  if (result != XML_ERROR_NONE)
3845
6
    return result;
3846
3847
  /* we know now that XML_Parse(Buffer) has been called,
3848
     so we consider the external parameter entity read */
3849
1668
  parser->m_dtd->paramEntityRead = XML_TRUE;
3850
3851
1668
  if (parser->m_prologState.inEntityValue) {
3852
150
    parser->m_processor = entityValueInitProcessor;
3853
150
    return entityValueInitProcessor(parser, s, end, nextPtr);
3854
  }
3855
  else {
3856
1518
    parser->m_processor = externalParEntProcessor;
3857
1518
    return externalParEntProcessor(parser, s, end, nextPtr);
3858
  }
3859
1674
}
3860
3861
static enum XML_Error PTRCALL
3862
entityValueInitProcessor(XML_Parser parser,
3863
                         const char *s,
3864
                         const char *end,
3865
                         const char **nextPtr)
3866
{
3867
  int tok;
3868
  const char *start = s;
3869
8016
  const char *next = start;
3870
  parser->m_eventPtr = start;
3871
3872
15012
  for (;;) {
3873
15012
    tok = XmlPrologTok(parser->m_encoding, start, end, &next);
3874
15012
    parser->m_eventEndPtr = next;
3875
15012
    if (tok <= 0) {
3876
3960
      if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
3877
3852
        *nextPtr = s;
3878
3852
        return XML_ERROR_NONE;
3879
      }
3880

108
      switch (tok) {
3881
      case XML_TOK_INVALID:
3882
6
        return XML_ERROR_INVALID_TOKEN;
3883
      case XML_TOK_PARTIAL:
3884
6
        return XML_ERROR_UNCLOSED_TOKEN;
3885
      case XML_TOK_PARTIAL_CHAR:
3886
6
        return XML_ERROR_PARTIAL_CHAR;
3887
      case XML_TOK_NONE:   /* start == end */
3888
      default:
3889
        break;
3890
      }
3891
      /* found end of entity value - can store it now */
3892
90
      return storeEntityValue(parser, parser->m_encoding, s, end);
3893
    }
3894
11052
    else if (tok == XML_TOK_XML_DECL) {
3895
      enum XML_Error result;
3896
36
      result = processXmlDecl(parser, 0, start, next);
3897
36
      if (result != XML_ERROR_NONE)
3898
6
        return result;
3899
      /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED.  For that
3900
       * to happen, a parameter entity parsing handler must have
3901
       * attempted to suspend the parser, which fails and raises an
3902
       * error.  The parser can be aborted, but can't be suspended.
3903
       */
3904
30
      if (parser->m_parsingStatus.parsing == XML_FINISHED)
3905
6
        return XML_ERROR_ABORTED;
3906
24
      *nextPtr = next;
3907
      /* stop scanning for text declaration - we found one */
3908
24
      parser->m_processor = entityValueProcessor;
3909
24
      return entityValueProcessor(parser, next, end, nextPtr);
3910
    }
3911
    /* If we are at the end of the buffer, this would cause XmlPrologTok to
3912
       return XML_TOK_NONE on the next call, which would then cause the
3913
       function to exit with *nextPtr set to s - that is what we want for other
3914
       tokens, but not for the BOM - we would rather like to skip it;
3915
       then, when this routine is entered the next time, XmlPrologTok will
3916
       return XML_TOK_INVALID, since the BOM is still in the buffer
3917
    */
3918

11028
    else if (tok == XML_TOK_BOM && next == end && !parser->m_parsingStatus.finalBuffer) {
3919
6
      *nextPtr = next;
3920
6
      return XML_ERROR_NONE;
3921
    }
3922
    /* If we get this token, we have the start of what might be a
3923
       normal tag, but not a declaration (i.e. it doesn't begin with
3924
       "<!").  In a DTD context, that isn't legal.
3925
    */
3926
11010
    else if (tok == XML_TOK_INSTANCE_START) {
3927
6
      *nextPtr = next;
3928
6
      return XML_ERROR_SYNTAX;
3929
    }
3930
    start = next;
3931
    parser->m_eventPtr = start;
3932
  }
3933
4008
}
3934
3935
static enum XML_Error PTRCALL
3936
externalParEntProcessor(XML_Parser parser,
3937
                        const char *s,
3938
                        const char *end,
3939
                        const char **nextPtr)
3940
{
3941
31308
  const char *next = s;
3942
  int tok;
3943
3944
15654
  tok = XmlPrologTok(parser->m_encoding, s, end, &next);
3945
15654
  if (tok <= 0) {
3946
14154
    if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
3947
14136
      *nextPtr = s;
3948
14136
      return XML_ERROR_NONE;
3949
    }
3950

318
    switch (tok) {
3951
    case XML_TOK_INVALID:
3952
6
      return XML_ERROR_INVALID_TOKEN;
3953
    case XML_TOK_PARTIAL:
3954
6
      return XML_ERROR_UNCLOSED_TOKEN;
3955
    case XML_TOK_PARTIAL_CHAR:
3956
6
      return XML_ERROR_PARTIAL_CHAR;
3957
    case XML_TOK_NONE:   /* start == end */
3958
    default:
3959
      break;
3960
    }
3961
  }
3962
  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3963
     However, when parsing an external subset, doProlog will not accept a BOM
3964
     as valid, and report a syntax error, so we have to skip the BOM
3965
  */
3966
1500
  else if (tok == XML_TOK_BOM) {
3967
6
    s = next;
3968
6
    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
3969
6
  }
3970
3971
1500
  parser->m_processor = prologProcessor;
3972
3000
  return doProlog(parser, parser->m_encoding, s, end, tok, next,
3973
1500
                  nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
3974
15654
}
3975
3976
static enum XML_Error PTRCALL
3977
entityValueProcessor(XML_Parser parser,
3978
                     const char *s,
3979
                     const char *end,
3980
                     const char **nextPtr)
3981
{
3982
  const char *start = s;
3983
216
  const char *next = s;
3984
108
  const ENCODING *enc = parser->m_encoding;
3985
  int tok;
3986
3987
192
  for (;;) {
3988
192
    tok = XmlPrologTok(enc, start, end, &next);
3989
192
    if (tok <= 0) {
3990
108
      if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
3991
84
        *nextPtr = s;
3992
84
        return XML_ERROR_NONE;
3993
      }
3994

24
      switch (tok) {
3995
      case XML_TOK_INVALID:
3996
6
        return XML_ERROR_INVALID_TOKEN;
3997
      case XML_TOK_PARTIAL:
3998
6
        return XML_ERROR_UNCLOSED_TOKEN;
3999
      case XML_TOK_PARTIAL_CHAR:
4000
6
        return XML_ERROR_PARTIAL_CHAR;
4001
      case XML_TOK_NONE:   /* start == end */
4002
      default:
4003
        break;
4004
      }
4005
      /* found end of entity value - can store it now */
4006
6
      return storeEntityValue(parser, enc, s, end);
4007
    }
4008
84
    start = next;
4009
  }
4010
108
}
4011
4012
#endif /* XML_DTD */
4013
4014
static enum XML_Error PTRCALL
4015
prologProcessor(XML_Parser parser,
4016
                const char *s,
4017
                const char *end,
4018
                const char **nextPtr)
4019
{
4020
4298634
  const char *next = s;
4021
2149317
  int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
4022
6447951
  return doProlog(parser, parser->m_encoding, s, end, tok, next,
4023
2149317
                  nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
4024
2149317
}
4025
4026
static enum XML_Error
4027
doProlog(XML_Parser parser,
4028
         const ENCODING *enc,
4029
         const char *s,
4030
         const char *end,
4031
         int tok,
4032
         const char *next,
4033
         const char **nextPtr,
4034
         XML_Bool haveMore)
4035
{
4036
#ifdef XML_DTD
4037
  static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
4038
#endif /* XML_DTD */
4039
  static const XML_Char atypeCDATA[] =
4040
      { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
4041
  static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
4042
  static const XML_Char atypeIDREF[] =
4043
      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
4044
  static const XML_Char atypeIDREFS[] =
4045
      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
4046
  static const XML_Char atypeENTITY[] =
4047
      { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
4048
  static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
4049
      ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
4050
  static const XML_Char atypeNMTOKEN[] = {
4051
      ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
4052
  static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
4053
      ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
4054
  static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
4055
      ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
4056
  static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
4057
  static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
4058
4059
  /* save one level of indirection */
4060
2150883
  DTD * const dtd = parser->m_dtd;
4061
4062
  const char **eventPP;
4063
  const char **eventEndPP;
4064
  enum XML_Content_Quant quant;
4065
4066
2150883
  if (enc == parser->m_encoding) {
4067
2150823
    eventPP = &parser->m_eventPtr;
4068
2150823
    eventEndPP = &parser->m_eventEndPtr;
4069
2150823
  }
4070
  else {
4071
60
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4072
60
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
4073
  }
4074
4075
2850000
  for (;;) {
4076
    int role;
4077
    XML_Bool handleDefault = XML_TRUE;
4078
2850000
    *eventPP = s;
4079
2850000
    *eventEndPP = next;
4080
2850000
    if (tok <= 0) {
4081
2112696
      if (haveMore && tok != XML_TOK_INVALID) {
4082
2111418
        *nextPtr = s;
4083
2111418
        return XML_ERROR_NONE;
4084
      }
4085

1278
      switch (tok) {
4086
      case XML_TOK_INVALID:
4087
54
        *eventPP = next;
4088
54
        return XML_ERROR_INVALID_TOKEN;
4089
      case XML_TOK_PARTIAL:
4090
6
        return XML_ERROR_UNCLOSED_TOKEN;
4091
      case XML_TOK_PARTIAL_CHAR:
4092
6
        return XML_ERROR_PARTIAL_CHAR;
4093
      case -XML_TOK_PROLOG_S:
4094
        tok = -tok;
4095
        break;
4096
      case XML_TOK_NONE:
4097
#ifdef XML_DTD
4098
        /* for internal PE NOT referenced between declarations */
4099

1260
        if (enc != parser->m_encoding && !parser->m_openInternalEntities->betweenDecl) {
4100
          *nextPtr = s;
4101
          return XML_ERROR_NONE;
4102
        }
4103
        /* WFC: PE Between Declarations - must check that PE contains
4104
           complete markup, not only for external PEs, but also for
4105
           internal PEs if the reference occurs between declarations.
4106
        */
4107

1236
        if (parser->m_isParamEntity || enc != parser->m_encoding) {
4108
2412
          if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
4109
1206
              == XML_ROLE_ERROR)
4110
            return XML_ERROR_INCOMPLETE_PE;
4111
1206
          *nextPtr = s;
4112
1206
          return XML_ERROR_NONE;
4113
        }
4114
#endif /* XML_DTD */
4115
6
        return XML_ERROR_NO_ELEMENTS;
4116
      default:
4117
        tok = -tok;
4118
        next = end;
4119
        break;
4120
      }
4121
    }
4122
1496985
    role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
4123















1496985
    switch (role) {
4124
    case XML_ROLE_XML_DECL:
4125
      {
4126
31548
        enum XML_Error result = processXmlDecl(parser, 0, s, next);
4127
31548
        if (result != XML_ERROR_NONE)
4128
96
          return result;
4129
31452
        enc = parser->m_encoding;
4130
        handleDefault = XML_FALSE;
4131
31452
      }
4132
      break;
4133
    case XML_ROLE_DOCTYPE_NAME:
4134
34251
      if (parser->m_startDoctypeDeclHandler) {
4135
258
        parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next);
4136
258
        if (!parser->m_doctypeName)
4137
18
          return XML_ERROR_NO_MEMORY;
4138
240
        poolFinish(&parser->m_tempPool);
4139
240
        parser->m_doctypePubid = NULL;
4140
        handleDefault = XML_FALSE;
4141
240
      }
4142
34233
      parser->m_doctypeSysid = NULL; /* always initialize to NULL */
4143
34233
      break;
4144
    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
4145
3381
      if (parser->m_startDoctypeDeclHandler) {
4146
204
        parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
4147
102
                                parser->m_doctypePubid, 1);
4148
102
        parser->m_doctypeName = NULL;
4149
102
        poolClear(&parser->m_tempPool);
4150
        handleDefault = XML_FALSE;
4151
102
      }
4152
      break;
4153
#ifdef XML_DTD
4154
    case XML_ROLE_TEXT_DECL:
4155
      {
4156
36
        enum XML_Error result = processXmlDecl(parser, 1, s, next);
4157
36
        if (result != XML_ERROR_NONE)
4158
6
          return result;
4159
30
        enc = parser->m_encoding;
4160
        handleDefault = XML_FALSE;
4161
30
      }
4162
      break;
4163
#endif /* XML_DTD */
4164
    case XML_ROLE_DOCTYPE_PUBLIC_ID:
4165
#ifdef XML_DTD
4166
30132
      parser->m_useForeignDTD = XML_FALSE;
4167
30132
      parser->m_declEntity = (ENTITY *)lookup(parser,
4168
30132
                                    &dtd->paramEntities,
4169
                                    externalSubsetName,
4170
                                    sizeof(ENTITY));
4171
30132
      if (!parser->m_declEntity)
4172
24
        return XML_ERROR_NO_MEMORY;
4173
#endif /* XML_DTD */
4174
30108
      dtd->hasParamEntityRefs = XML_TRUE;
4175
30108
      if (parser->m_startDoctypeDeclHandler) {
4176
        XML_Char *pubId;
4177
96
        if (!XmlIsPublicId(enc, s, next, eventPP))
4178
6
          return XML_ERROR_PUBLICID;
4179
180
        pubId = poolStoreString(&parser->m_tempPool, enc,
4180
90
                                s + enc->minBytesPerChar,
4181
90
                                next - enc->minBytesPerChar);
4182
90
        if (!pubId)
4183
6
          return XML_ERROR_NO_MEMORY;
4184
84
        normalizePublicId(pubId);
4185
84
        poolFinish(&parser->m_tempPool);
4186
84
        parser->m_doctypePubid = pubId;
4187
        handleDefault = XML_FALSE;
4188
84
        goto alreadyChecked;
4189
      }
4190
      /* fall through */
4191
    case XML_ROLE_ENTITY_PUBLIC_ID:
4192
30270
      if (!XmlIsPublicId(enc, s, next, eventPP))
4193
        return XML_ERROR_PUBLICID;
4194
    alreadyChecked:
4195

60708
      if (dtd->keepProcessing && parser->m_declEntity) {
4196
60708
        XML_Char *tem = poolStoreString(&dtd->pool,
4197
                                        enc,
4198
30354
                                        s + enc->minBytesPerChar,
4199
30354
                                        next - enc->minBytesPerChar);
4200
30354
        if (!tem)
4201
18
          return XML_ERROR_NO_MEMORY;
4202
30336
        normalizePublicId(tem);
4203
30336
        parser->m_declEntity->publicId = tem;
4204
30336
        poolFinish(&dtd->pool);
4205
        /* Don't suppress the default handler if we fell through from
4206
         * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
4207
         */
4208
30336
        if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
4209
120
          handleDefault = XML_FALSE;
4210
30336
      }
4211
      break;
4212
    case XML_ROLE_DOCTYPE_CLOSE:
4213
33057
      if (parser->m_doctypeName) {
4214
156
        parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName,
4215
78
                                parser->m_doctypeSysid, parser->m_doctypePubid, 0);
4216
78
        poolClear(&parser->m_tempPool);
4217
        handleDefault = XML_FALSE;
4218
78
      }
4219
      /* parser->m_doctypeSysid will be non-NULL in the case of a previous
4220
         XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
4221
         was not set, indicating an external subset
4222
      */
4223
#ifdef XML_DTD
4224

34530
      if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
4225
31596
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4226
31596
        dtd->hasParamEntityRefs = XML_TRUE;
4227

33102
        if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) {
4228
1506
          ENTITY *entity = (ENTITY *)lookup(parser,
4229
1506
                                            &dtd->paramEntities,
4230
                                            externalSubsetName,
4231
                                            sizeof(ENTITY));
4232
1506
          if (!entity) {
4233
            /* The external subset name "#" will have already been
4234
             * inserted into the hash table at the start of the
4235
             * external entity parsing, so no allocation will happen
4236
             * and lookup() cannot fail.
4237
             */
4238
            return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4239
          }
4240
1506
          if (parser->m_useForeignDTD)
4241
12
            entity->base = parser->m_curBase;
4242
1506
          dtd->paramEntityRead = XML_FALSE;
4243
3012
          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
4244
                                        0,
4245
1506
                                        entity->base,
4246
1506
                                        entity->systemId,
4247
1506
                                        entity->publicId))
4248
420
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4249
1086
          if (dtd->paramEntityRead) {
4250

1050
            if (!dtd->standalone &&
4251
1026
                parser->m_notStandaloneHandler &&
4252
12
                !parser->m_notStandaloneHandler(parser->m_handlerArg))
4253
6
              return XML_ERROR_NOT_STANDALONE;
4254
          }
4255
          /* if we didn't read the foreign DTD then this means that there
4256
             is no external subset and we must reset dtd->hasParamEntityRefs
4257
          */
4258
48
          else if (!parser->m_doctypeSysid)
4259
6
            dtd->hasParamEntityRefs = hadParamEntityRefs;
4260
          /* end of DTD - no need to update dtd->keepProcessing */
4261
1080
        }
4262
31170
        parser->m_useForeignDTD = XML_FALSE;
4263
31170
      }
4264
#endif /* XML_DTD */
4265
32631
      if (parser->m_endDoctypeDeclHandler) {
4266
102
        parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
4267
        handleDefault = XML_FALSE;
4268
102
      }
4269
      break;
4270
    case XML_ROLE_INSTANCE_START:
4271
#ifdef XML_DTD
4272
      /* if there is no DOCTYPE declaration then now is the
4273
         last chance to read the foreign DTD
4274
      */
4275
36093
      if (parser->m_useForeignDTD) {
4276
102
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4277
102
        dtd->hasParamEntityRefs = XML_TRUE;
4278

204
        if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) {
4279
102
          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4280
                                            externalSubsetName,
4281
                                            sizeof(ENTITY));
4282
102
          if (!entity)
4283
12
            return XML_ERROR_NO_MEMORY;
4284
90
          entity->base = parser->m_curBase;
4285
90
          dtd->paramEntityRead = XML_FALSE;
4286
180
          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
4287
                                        0,
4288
90
                                        entity->base,
4289
90
                                        entity->systemId,
4290
90
                                        entity->publicId))
4291
36
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4292
54
          if (dtd->paramEntityRead) {
4293

54
            if (!dtd->standalone &&
4294
48
                parser->m_notStandaloneHandler &&
4295
6
                !parser->m_notStandaloneHandler(parser->m_handlerArg))
4296
6
              return XML_ERROR_NOT_STANDALONE;
4297
          }
4298
          /* if we didn't read the foreign DTD then this means that there
4299
             is no external subset and we must reset dtd->hasParamEntityRefs
4300
          */
4301
          else
4302
6
            dtd->hasParamEntityRefs = hadParamEntityRefs;
4303
          /* end of DTD - no need to update dtd->keepProcessing */
4304
48
        }
4305
48
      }
4306
#endif /* XML_DTD */
4307
36039
      parser->m_processor = contentProcessor;
4308
36039
      return contentProcessor(parser, s, end, nextPtr);
4309
    case XML_ROLE_ATTLIST_ELEMENT_NAME:
4310
1302
      parser->m_declElementType = getElementType(parser, enc, s, next);
4311
1302
      if (!parser->m_declElementType)
4312
96
        return XML_ERROR_NO_MEMORY;
4313
      goto checkAttListDeclHandler;
4314
    case XML_ROLE_ATTRIBUTE_NAME:
4315
1320
      parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
4316
1320
      if (!parser->m_declAttributeId)
4317
96
        return XML_ERROR_NO_MEMORY;
4318
1224
      parser->m_declAttributeIsCdata = XML_FALSE;
4319
1224
      parser->m_declAttributeType = NULL;
4320
1224
      parser->m_declAttributeIsId = XML_FALSE;
4321
1224
      goto checkAttListDeclHandler;
4322
    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4323
534
      parser->m_declAttributeIsCdata = XML_TRUE;
4324
534
      parser->m_declAttributeType = atypeCDATA;
4325
534
      goto checkAttListDeclHandler;
4326
    case XML_ROLE_ATTRIBUTE_TYPE_ID:
4327
474
      parser->m_declAttributeIsId = XML_TRUE;
4328
474
      parser->m_declAttributeType = atypeID;
4329
474
      goto checkAttListDeclHandler;
4330
    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4331
12
      parser->m_declAttributeType = atypeIDREF;
4332
12
      goto checkAttListDeclHandler;
4333
    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4334
18
      parser->m_declAttributeType = atypeIDREFS;
4335
18
      goto checkAttListDeclHandler;
4336
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4337
12
      parser->m_declAttributeType = atypeENTITY;
4338
12
      goto checkAttListDeclHandler;
4339
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4340
18
      parser->m_declAttributeType = atypeENTITIES;
4341
18
      goto checkAttListDeclHandler;
4342
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4343
12
      parser->m_declAttributeType = atypeNMTOKEN;
4344
12
      goto checkAttListDeclHandler;
4345
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4346
18
      parser->m_declAttributeType = atypeNMTOKENS;
4347
    checkAttListDeclHandler:
4348

7056
      if (dtd->keepProcessing && parser->m_attlistDeclHandler)
4349
336
        handleDefault = XML_FALSE;
4350
      break;
4351
    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4352
    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4353

1536
      if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
4354
        const XML_Char *prefix;
4355
708
        if (parser->m_declAttributeType) {
4356
          prefix = enumValueSep;
4357
606
        }
4358
        else {
4359
102
          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4360
                    ? notationPrefix
4361
                    : enumValueStart);
4362
        }
4363
708
        if (!poolAppendString(&parser->m_tempPool, prefix))
4364
6
          return XML_ERROR_NO_MEMORY;
4365
702
        if (!poolAppend(&parser->m_tempPool, enc, s, next))
4366
6
          return XML_ERROR_NO_MEMORY;
4367
696
        parser->m_declAttributeType = parser->m_tempPool.start;
4368
        handleDefault = XML_FALSE;
4369
696
      }
4370
      break;
4371
    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4372
    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4373
780
      if (dtd->keepProcessing) {
4374
1560
        if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId,
4375
780
                             parser->m_declAttributeIsCdata, parser->m_declAttributeIsId,
4376
                             0, parser))
4377
30
          return XML_ERROR_NO_MEMORY;
4378

798
        if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4379
54
          if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4380
78
              || (*parser->m_declAttributeType == XML_T(ASCII_N)
4381
36
                  && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
4382
            /* Enumerated or Notation type */
4383

60
            if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4384

54
                || !poolAppendChar(&parser->m_tempPool, XML_T('\0')))
4385
6
              return XML_ERROR_NO_MEMORY;
4386
18
            parser->m_declAttributeType = parser->m_tempPool.start;
4387
18
            poolFinish(&parser->m_tempPool);
4388
18
          }
4389
42
          *eventEndPP = s;
4390
84
          parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name,
4391
42
                             parser->m_declAttributeId->name, parser->m_declAttributeType,
4392
42
                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4393
42
          poolClear(&parser->m_tempPool);
4394
          handleDefault = XML_FALSE;
4395
42
        }
4396
      }
4397
      break;
4398
    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4399
    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4400
420
      if (dtd->keepProcessing) {
4401
        const XML_Char *attVal;
4402
        enum XML_Error result =
4403
840
          storeAttributeValue(parser, enc, parser->m_declAttributeIsCdata,
4404
420
                              s + enc->minBytesPerChar,
4405
420
                              next - enc->minBytesPerChar,
4406
420
                              &dtd->pool);
4407
420
        if (result)
4408
24
          return result;
4409
396
        attVal = poolStart(&dtd->pool);
4410
396
        poolFinish(&dtd->pool);
4411
        /* ID attributes aren't allowed to have a default */
4412
792
        if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId,
4413
396
                             parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
4414
24
          return XML_ERROR_NO_MEMORY;
4415

438
        if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
4416
72
          if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
4417
78
              || (*parser->m_declAttributeType == XML_T(ASCII_N)
4418
18
                  && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
4419
            /* Enumerated or Notation type */
4420

132
            if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
4421

126
                || !poolAppendChar(&parser->m_tempPool, XML_T('\0')))
4422
6
              return XML_ERROR_NO_MEMORY;
4423
54
            parser->m_declAttributeType = parser->m_tempPool.start;
4424
54
            poolFinish(&parser->m_tempPool);
4425
54
          }
4426
60
          *eventEndPP = s;
4427
120
          parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name,
4428
60
                             parser->m_declAttributeId->name, parser->m_declAttributeType,
4429
                             attVal,
4430
60
                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4431
60
          poolClear(&parser->m_tempPool);
4432
          handleDefault = XML_FALSE;
4433
60
        }
4434
366
      }
4435
      break;
4436
    case XML_ROLE_ENTITY_VALUE:
4437
657
      if (dtd->keepProcessing) {
4438
651
        enum XML_Error result = storeEntityValue(parser, enc,
4439
651
                                            s + enc->minBytesPerChar,
4440
651
                                            next - enc->minBytesPerChar);
4441
651
        if (parser->m_declEntity) {
4442
645
          parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
4443
645
          parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4444
645
          poolFinish(&dtd->entityValuePool);
4445
645
          if (parser->m_entityDeclHandler) {
4446
126
            *eventEndPP = s;
4447
252
            parser->m_entityDeclHandler(parser->m_handlerArg,
4448
126
                              parser->m_declEntity->name,
4449
126
                              parser->m_declEntity->is_param,
4450
126
                              parser->m_declEntity->textPtr,
4451
126
                              parser->m_declEntity->textLen,
4452
126
                              parser->m_curBase, 0, 0, 0);
4453
            handleDefault = XML_FALSE;
4454
126
          }
4455
        }
4456
        else
4457
6
          poolDiscard(&dtd->entityValuePool);
4458
651
        if (result != XML_ERROR_NONE)
4459
96
          return result;
4460
555
      }
4461
      break;
4462
    case XML_ROLE_DOCTYPE_SYSTEM_ID:
4463
#ifdef XML_DTD
4464
31842
      parser->m_useForeignDTD = XML_FALSE;
4465
#endif /* XML_DTD */
4466
31842
      dtd->hasParamEntityRefs = XML_TRUE;
4467
31842
      if (parser->m_startDoctypeDeclHandler) {
4468
180
        parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
4469
90
                                       s + enc->minBytesPerChar,
4470
90
                                       next - enc->minBytesPerChar);
4471
90
        if (parser->m_doctypeSysid == NULL)
4472
6
          return XML_ERROR_NO_MEMORY;
4473
84
        poolFinish(&parser->m_tempPool);
4474
        handleDefault = XML_FALSE;
4475
84
      }
4476
#ifdef XML_DTD
4477
      else
4478
        /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
4479
           for the case where no parser->m_startDoctypeDeclHandler is set */
4480
31752
        parser->m_doctypeSysid = externalSubsetName;
4481
#endif /* XML_DTD */
4482
31848
      if (!dtd->standalone
4483
#ifdef XML_DTD
4484
63648
          && !parser->m_paramEntityParsing
4485
#endif /* XML_DTD */
4486
61908
          && parser->m_notStandaloneHandler
4487
30108
          && !parser->m_notStandaloneHandler(parser->m_handlerArg))
4488
6
        return XML_ERROR_NOT_STANDALONE;
4489
#ifndef XML_DTD
4490
      break;
4491
#else /* XML_DTD */
4492
31830
      if (!parser->m_declEntity) {
4493
1752
        parser->m_declEntity = (ENTITY *)lookup(parser,
4494
1752
                                      &dtd->paramEntities,
4495
                                      externalSubsetName,
4496
                                      sizeof(ENTITY));
4497
1752
        if (!parser->m_declEntity)
4498
84
          return XML_ERROR_NO_MEMORY;
4499
1668
        parser->m_declEntity->publicId = NULL;
4500
1668
      }
4501
      /* fall through */
4502
#endif /* XML_DTD */
4503
    case XML_ROLE_ENTITY_SYSTEM_ID:
4504

68502
      if (dtd->keepProcessing && parser->m_declEntity) {
4505
68502
        parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc,
4506
34251
                                               s + enc->minBytesPerChar,
4507
34251
                                               next - enc->minBytesPerChar);
4508
34251
        if (!parser->m_declEntity->systemId)
4509
36
          return XML_ERROR_NO_MEMORY;
4510
34215
        parser->m_declEntity->base = parser->m_curBase;
4511
34215
        poolFinish(&dtd->pool);
4512
        /* Don't suppress the default handler if we fell through from
4513
         * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
4514
         */
4515
34215
        if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
4516
306
          handleDefault = XML_FALSE;
4517
      }
4518
      break;
4519
    case XML_ROLE_ENTITY_COMPLETE:
4520

6687
      if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) {
4521
204
        *eventEndPP = s;
4522
408
        parser->m_entityDeclHandler(parser->m_handlerArg,
4523
204
                          parser->m_declEntity->name,
4524
204
                          parser->m_declEntity->is_param,
4525
                          0,0,
4526
204
                          parser->m_declEntity->base,
4527
204
                          parser->m_declEntity->systemId,
4528
204
                          parser->m_declEntity->publicId,
4529
                          0);
4530
        handleDefault = XML_FALSE;
4531
204
      }
4532
      break;
4533
    case XML_ROLE_ENTITY_NOTATION_NAME:
4534

516
      if (dtd->keepProcessing && parser->m_declEntity) {
4535
258
        parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4536
258
        if (!parser->m_declEntity->notation)
4537
12
          return XML_ERROR_NO_MEMORY;
4538
246
        poolFinish(&dtd->pool);
4539
246
        if (parser->m_unparsedEntityDeclHandler) {
4540
72
          *eventEndPP = s;
4541
144
          parser->m_unparsedEntityDeclHandler(parser->m_handlerArg,
4542
72
                                    parser->m_declEntity->name,
4543
72
                                    parser->m_declEntity->base,
4544
72
                                    parser->m_declEntity->systemId,
4545
72
                                    parser->m_declEntity->publicId,
4546
72
                                    parser->m_declEntity->notation);
4547
          handleDefault = XML_FALSE;
4548
72
        }
4549
174
        else if (parser->m_entityDeclHandler) {
4550
18
          *eventEndPP = s;
4551
36
          parser->m_entityDeclHandler(parser->m_handlerArg,
4552
18
                            parser->m_declEntity->name,
4553
                            0,0,0,
4554
18
                            parser->m_declEntity->base,
4555
18
                            parser->m_declEntity->systemId,
4556
18
                            parser->m_declEntity->publicId,
4557
18
                            parser->m_declEntity->notation);
4558
          handleDefault = XML_FALSE;
4559
18
        }
4560
      }
4561
      break;
4562
    case XML_ROLE_GENERAL_ENTITY_NAME:
4563
      {
4564
2916
        if (XmlPredefinedEntityName(enc, s, next)) {
4565
6
          parser->m_declEntity = NULL;
4566
6
          break;
4567
        }
4568
2910
        if (dtd->keepProcessing) {
4569
2904
          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4570
2904
          if (!name)
4571
66
            return XML_ERROR_NO_MEMORY;
4572
2838
          parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
4573
                                        sizeof(ENTITY));
4574
2838
          if (!parser->m_declEntity)
4575
210
            return XML_ERROR_NO_MEMORY;
4576
2628
          if (parser->m_declEntity->name != name) {
4577
            poolDiscard(&dtd->pool);
4578
            parser->m_declEntity = NULL;
4579
          }
4580
          else {
4581
2628
            poolFinish(&dtd->pool);
4582
2628
            parser->m_declEntity->publicId = NULL;
4583
2628
            parser->m_declEntity->is_param = XML_FALSE;
4584
            /* if we have a parent parser or are reading an internal parameter
4585
               entity, then the entity declaration is not considered "internal"
4586
            */
4587
7872
            parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities);
4588
2628
            if (parser->m_entityDeclHandler)
4589
192
              handleDefault = XML_FALSE;
4590
          }
4591
2628
        }
4592
        else {
4593
6
          poolDiscard(&dtd->pool);
4594
6
          parser->m_declEntity = NULL;
4595
        }
4596
      }
4597
      break;
4598
    case XML_ROLE_PARAM_ENTITY_NAME:
4599
#ifdef XML_DTD
4600
576
      if (dtd->keepProcessing) {
4601
576
        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4602
576
        if (!name)
4603
12
          return XML_ERROR_NO_MEMORY;
4604
564
        parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4605
                                           name, sizeof(ENTITY));
4606
564
        if (!parser->m_declEntity)
4607
12
          return XML_ERROR_NO_MEMORY;
4608
552
        if (parser->m_declEntity->name != name) {
4609
          poolDiscard(&dtd->pool);
4610
          parser->m_declEntity = NULL;
4611
        }
4612
        else {
4613
552
          poolFinish(&dtd->pool);
4614
552
          parser->m_declEntity->publicId = NULL;
4615
552
          parser->m_declEntity->is_param = XML_TRUE;
4616
          /* if we have a parent parser or are reading an internal parameter
4617
             entity, then the entity declaration is not considered "internal"
4618
          */
4619
1158
          parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities);
4620
552
          if (parser->m_entityDeclHandler)
4621
240
            handleDefault = XML_FALSE;
4622
        }
4623
552
      }
4624
      else {
4625
        poolDiscard(&dtd->pool);
4626
        parser->m_declEntity = NULL;
4627
      }
4628
#else /* not XML_DTD */
4629
      parser->m_declEntity = NULL;
4630
#endif /* XML_DTD */
4631
      break;
4632
    case XML_ROLE_NOTATION_NAME:
4633
402
      parser->m_declNotationPublicId = NULL;
4634
402
      parser->m_declNotationName = NULL;
4635
402
      if (parser->m_notationDeclHandler) {
4636
240
        parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next);
4637
240
        if (!parser->m_declNotationName)
4638
18
          return XML_ERROR_NO_MEMORY;
4639
222
        poolFinish(&parser->m_tempPool);
4640
        handleDefault = XML_FALSE;
4641
222
      }
4642
      break;
4643
    case XML_ROLE_NOTATION_PUBLIC_ID:
4644
48
      if (!XmlIsPublicId(enc, s, next, eventPP))
4645
        return XML_ERROR_PUBLICID;
4646
48
      if (parser->m_declNotationName) {  /* means m_notationDeclHandler != NULL */
4647
96
        XML_Char *tem = poolStoreString(&parser->m_tempPool,
4648
                                        enc,
4649
48
                                        s + enc->minBytesPerChar,
4650
48
                                        next - enc->minBytesPerChar);
4651
48
        if (!tem)
4652
6
          return XML_ERROR_NO_MEMORY;
4653
42
        normalizePublicId(tem);
4654
42
        parser->m_declNotationPublicId = tem;
4655
42
        poolFinish(&parser->m_tempPool);
4656
        handleDefault = XML_FALSE;
4657
42
      }
4658
      break;
4659
    case XML_ROLE_NOTATION_SYSTEM_ID:
4660

576
      if (parser->m_declNotationName && parser->m_notationDeclHandler) {
4661
        const XML_Char *systemId
4662
420
          = poolStoreString(&parser->m_tempPool, enc,
4663
210
                            s + enc->minBytesPerChar,
4664
210
                            next - enc->minBytesPerChar);
4665
210
        if (!systemId)
4666
6
          return XML_ERROR_NO_MEMORY;
4667
204
        *eventEndPP = s;
4668
408
        parser->m_notationDeclHandler(parser->m_handlerArg,
4669
204
                            parser->m_declNotationName,
4670
204
                            parser->m_curBase,
4671
                            systemId,
4672
204
                            parser->m_declNotationPublicId);
4673
        handleDefault = XML_FALSE;
4674
204
      }
4675
360
      poolClear(&parser->m_tempPool);
4676
360
      break;
4677
    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4678

12
      if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
4679
6
        *eventEndPP = s;
4680
12
        parser->m_notationDeclHandler(parser->m_handlerArg,
4681
6
                            parser->m_declNotationName,
4682
6
                            parser->m_curBase,
4683
                            0,
4684
6
                            parser->m_declNotationPublicId);
4685
        handleDefault = XML_FALSE;
4686
6
      }
4687
6
      poolClear(&parser->m_tempPool);
4688
6
      break;
4689
    case XML_ROLE_ERROR:
4690
78
      switch (tok) {
4691
      case XML_TOK_PARAM_ENTITY_REF:
4692
        /* PE references in internal subset are
4693
           not allowed within declarations. */
4694
        return XML_ERROR_PARAM_ENTITY_REF;
4695
      case XML_TOK_XML_DECL:
4696
6
        return XML_ERROR_MISPLACED_XML_PI;
4697
      default:
4698
72
        return XML_ERROR_SYNTAX;
4699
      }
4700
#ifdef XML_DTD
4701
    case XML_ROLE_IGNORE_SECT:
4702
      {
4703
        enum XML_Error result;
4704
42
        if (parser->m_defaultHandler)
4705
18
          reportDefault(parser, enc, s, next);
4706
        handleDefault = XML_FALSE;
4707
42
        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4708
42
        if (result != XML_ERROR_NONE)
4709
          return result;
4710
42
        else if (!next) {
4711
42
          parser->m_processor = ignoreSectionProcessor;
4712
42
          return result;
4713
        }
4714
      }
4715
      break;
4716
#endif /* XML_DTD */
4717
    case XML_ROLE_GROUP_OPEN:
4718
2808
      if (parser->m_prologState.level >= parser->m_groupSize) {
4719
900
        if (parser->m_groupSize) {
4720
60
          char *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2);
4721
60
          if (temp == NULL) {
4722
6
            parser->m_groupSize /= 2;
4723
6
            return XML_ERROR_NO_MEMORY;
4724
          }
4725
54
          parser->m_groupConnector = temp;
4726
54
          if (dtd->scaffIndex) {
4727
54
            int *temp = (int *)REALLOC(parser, dtd->scaffIndex,
4728
                          parser->m_groupSize * sizeof(int));
4729
54
            if (temp == NULL)
4730
6
              return XML_ERROR_NO_MEMORY;
4731
48
            dtd->scaffIndex = temp;
4732
48
          }
4733
48
        }
4734
        else {
4735
840
          parser->m_groupConnector = (char *)MALLOC(parser, parser->m_groupSize = 32);
4736
840
          if (!parser->m_groupConnector) {
4737
36
            parser->m_groupSize = 0;
4738
36
            return XML_ERROR_NO_MEMORY;
4739
          }
4740
        }
4741
      }
4742
2760
      parser->m_groupConnector[parser->m_prologState.level] = 0;
4743
2760
      if (dtd->in_eldecl) {
4744
2376
        int myindex = nextScaffoldPart(parser);
4745
2376
        if (myindex < 0)
4746
42
          return XML_ERROR_NO_MEMORY;
4747
2334
        dtd->scaffIndex[dtd->scaffLevel] = myindex;
4748
2334
        dtd->scaffLevel++;
4749
2334
        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4750
2334
        if (parser->m_elementDeclHandler)
4751
2334
          handleDefault = XML_FALSE;
4752
2334
      }
4753
      break;
4754
    case XML_ROLE_GROUP_SEQUENCE:
4755
1956
      if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
4756
        return XML_ERROR_SYNTAX;
4757
1956
      parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
4758

3912
      if (dtd->in_eldecl && parser->m_elementDeclHandler)
4759
1956
        handleDefault = XML_FALSE;
4760
      break;
4761
    case XML_ROLE_GROUP_CHOICE:
4762
4704
      if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
4763
        return XML_ERROR_SYNTAX;
4764
4950
      if (dtd->in_eldecl
4765
9408
          && !parser->m_groupConnector[parser->m_prologState.level]
4766
4950
          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4767
246
              != XML_CTYPE_MIXED)
4768
          ) {
4769
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4770
246
            = XML_CTYPE_CHOICE;
4771
246
        if (parser->m_elementDeclHandler)
4772
246
          handleDefault = XML_FALSE;
4773
      }
4774
4704
      parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
4775
4704
      break;
4776
    case XML_ROLE_PARAM_ENTITY_REF:
4777
#ifdef XML_DTD
4778
    case XML_ROLE_INNER_PARAM_ENTITY_REF:
4779
270
      dtd->hasParamEntityRefs = XML_TRUE;
4780
270
      if (!parser->m_paramEntityParsing)
4781
12
        dtd->keepProcessing = dtd->standalone;
4782
      else {
4783
        const XML_Char *name;
4784
        ENTITY *entity;
4785
516
        name = poolStoreString(&dtd->pool, enc,
4786
258
                                s + enc->minBytesPerChar,
4787
258
                                next - enc->minBytesPerChar);
4788
258
        if (!name)
4789
6
          return XML_ERROR_NO_MEMORY;
4790
252
        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
4791
252
        poolDiscard(&dtd->pool);
4792
        /* first, determine if a check for an existing declaration is needed;
4793
           if yes, check that the entity exists, and that it is internal,
4794
           otherwise call the skipped entity handler
4795
        */
4796

300
        if (parser->m_prologState.documentEntity &&
4797
42
            (dtd->standalone
4798
12
             ? !parser->m_openInternalEntities
4799
18
             : !dtd->hasParamEntityRefs)) {
4800
12
          if (!entity)
4801
            return XML_ERROR_UNDEFINED_ENTITY;
4802
12
          else if (!entity->is_internal) {
4803
            /* It's hard to exhaustively search the code to be sure,
4804
             * but there doesn't seem to be a way of executing the
4805
             * following line.  There are two cases:
4806
             *
4807
             * If 'standalone' is false, the DTD must have no
4808
             * parameter entities or we wouldn't have passed the outer
4809
             * 'if' statement.  That measn the only entity in the hash
4810
             * table is the external subset name "#" which cannot be
4811
             * given as a parameter entity name in XML syntax, so the
4812
             * lookup must have returned NULL and we don't even reach
4813
             * the test for an internal entity.
4814
             *
4815
             * If 'standalone' is true, it does not seem to be
4816
             * possible to create entities taking this code path that
4817
             * are not internal entities, so fail the test above.
4818
             *
4819
             * Because this analysis is very uncertain, the code is
4820
             * being left in place and merely removed from the
4821
             * coverage test statistics.
4822
             */
4823
            return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
4824
          }
4825
        }
4826
240
        else if (!entity) {
4827
6
          dtd->keepProcessing = dtd->standalone;
4828
          /* cannot report skipped entities in declarations */
4829

12
          if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) {
4830
6
            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
4831
            handleDefault = XML_FALSE;
4832
6
          }
4833
6
          break;
4834
        }
4835
246
        if (entity->open)
4836
12
          return XML_ERROR_RECURSIVE_ENTITY_REF;
4837
234
        if (entity->textPtr) {
4838
          enum XML_Error result;
4839
          XML_Bool betweenDecl =
4840
54
            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4841
54
          result = processInternalEntity(parser, entity, betweenDecl);
4842
54
          if (result != XML_ERROR_NONE)
4843
6
            return result;
4844
          handleDefault = XML_FALSE;
4845
48
          break;
4846
        }
4847
180
        if (parser->m_externalEntityRefHandler) {
4848
174
          dtd->paramEntityRead = XML_FALSE;
4849
174
          entity->open = XML_TRUE;
4850
348
          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
4851
                                        0,
4852
174
                                        entity->base,
4853
174
                                        entity->systemId,
4854
174
                                        entity->publicId)) {
4855
            entity->open = XML_FALSE;
4856
54
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4857
          }
4858
          entity->open = XML_FALSE;
4859
          handleDefault = XML_FALSE;
4860
120
          if (!dtd->paramEntityRead) {
4861
6
            dtd->keepProcessing = dtd->standalone;
4862
6
            break;
4863
          }
4864
        }
4865
        else {
4866
6
          dtd->keepProcessing = dtd->standalone;
4867
6
          break;
4868
        }
4869
114
      }
4870
#endif /* XML_DTD */
4871

132
      if (!dtd->standalone &&
4872
126
          parser->m_notStandaloneHandler &&
4873
6
          !parser->m_notStandaloneHandler(parser->m_handlerArg))
4874
6
        return XML_ERROR_NOT_STANDALONE;
4875
      break;
4876
4877
    /* Element declaration stuff */
4878
4879
    case XML_ROLE_ELEMENT_NAME:
4880
2178
      if (parser->m_elementDeclHandler) {
4881
558
        parser->m_declElementType = getElementType(parser, enc, s, next);
4882
558
        if (!parser->m_declElementType)
4883
48
          return XML_ERROR_NO_MEMORY;
4884
510
        dtd->scaffLevel = 0;
4885
510
        dtd->scaffCount = 0;
4886
510
        dtd->in_eldecl = XML_TRUE;
4887
        handleDefault = XML_FALSE;
4888
510
      }
4889
      break;
4890
4891
    case XML_ROLE_CONTENT_ANY:
4892
    case XML_ROLE_CONTENT_EMPTY:
4893
1278
      if (dtd->in_eldecl) {
4894
60
        if (parser->m_elementDeclHandler) {
4895
60
          XML_Content * content = (XML_Content *) MALLOC(parser, sizeof(XML_Content));
4896
60
          if (!content)
4897
6
            return XML_ERROR_NO_MEMORY;
4898
54
          content->quant = XML_CQUANT_NONE;
4899
54
          content->name = NULL;
4900
54
          content->numchildren = 0;
4901
54
          content->children = NULL;
4902
54
          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4903
                           XML_CTYPE_ANY :
4904
                           XML_CTYPE_EMPTY);
4905
54
          *eventEndPP = s;
4906
54
          parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, content);
4907
          handleDefault = XML_FALSE;
4908
54
        }
4909
54
        dtd->in_eldecl = XML_FALSE;
4910
54
      }
4911
      break;
4912
4913
    case XML_ROLE_CONTENT_PCDATA:
4914
276
      if (dtd->in_eldecl) {
4915
66
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4916
66
            = XML_CTYPE_MIXED;
4917
66
        if (parser->m_elementDeclHandler)
4918
66
          handleDefault = XML_FALSE;
4919
      }
4920
      break;
4921
4922
    case XML_ROLE_CONTENT_ELEMENT:
4923
      quant = XML_CQUANT_NONE;
4924
5124
      goto elementContent;
4925
    case XML_ROLE_CONTENT_ELEMENT_OPT:
4926
      quant = XML_CQUANT_OPT;
4927
1938
      goto elementContent;
4928
    case XML_ROLE_CONTENT_ELEMENT_REP:
4929
      quant = XML_CQUANT_REP;
4930
      goto elementContent;
4931
    case XML_ROLE_CONTENT_ELEMENT_PLUS:
4932
168
      quant = XML_CQUANT_PLUS;
4933
    elementContent:
4934
7230
      if (dtd->in_eldecl) {
4935
        ELEMENT_TYPE *el;
4936
        const XML_Char *name;
4937
        int nameLen;
4938
15882
        const char *nxt = (quant == XML_CQUANT_NONE
4939
                           ? next
4940
1938
                           : next - enc->minBytesPerChar);
4941
6972
        int myindex = nextScaffoldPart(parser);
4942
6972
        if (myindex < 0)
4943
6
          return XML_ERROR_NO_MEMORY;
4944
6966
        dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4945
6966
        dtd->scaffold[myindex].quant = quant;
4946
6966
        el = getElementType(parser, enc, s, nxt);
4947
6966
        if (!el)
4948
210
          return XML_ERROR_NO_MEMORY;
4949
6756
        name = el->name;
4950
6756
        dtd->scaffold[myindex].name = name;
4951
        nameLen = 0;
4952
36552
        for (; name[nameLen++]; );
4953
6756
        dtd->contentStringLen +=  nameLen;
4954
6756
        if (parser->m_elementDeclHandler)
4955
6756
          handleDefault = XML_FALSE;
4956
6756
      }
4957
      break;
4958
4959
    case XML_ROLE_GROUP_CLOSE:
4960
      quant = XML_CQUANT_NONE;
4961
1782
      goto closeGroup;
4962
    case XML_ROLE_GROUP_CLOSE_OPT:
4963
      quant = XML_CQUANT_OPT;
4964
      goto closeGroup;
4965
    case XML_ROLE_GROUP_CLOSE_REP:
4966
      quant = XML_CQUANT_REP;
4967
210
      goto closeGroup;
4968
    case XML_ROLE_GROUP_CLOSE_PLUS:
4969
42
      quant = XML_CQUANT_PLUS;
4970
    closeGroup:
4971
2034
      if (dtd->in_eldecl) {
4972
1650
        if (parser->m_elementDeclHandler)
4973
1650
          handleDefault = XML_FALSE;
4974
1650
        dtd->scaffLevel--;
4975
1650
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4976
1650
        if (dtd->scaffLevel == 0) {
4977
162
          if (!handleDefault) {
4978
162
            XML_Content *model = build_model(parser);
4979
162
            if (!model)
4980
18
              return XML_ERROR_NO_MEMORY;
4981
144
            *eventEndPP = s;
4982
144
            parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, model);
4983
144
          }
4984
144
          dtd->in_eldecl = XML_FALSE;
4985
144
          dtd->contentStringLen = 0;
4986
144
        }
4987
      }
4988
      break;
4989
      /* End element declaration stuff */
4990
4991
    case XML_ROLE_PI:
4992
30138
      if (!reportProcessingInstruction(parser, enc, s, next))
4993
18
        return XML_ERROR_NO_MEMORY;
4994
      handleDefault = XML_FALSE;
4995
30120
      break;
4996
    case XML_ROLE_COMMENT:
4997
60096
      if (!reportComment(parser, enc, s, next))
4998
6
        return XML_ERROR_NO_MEMORY;
4999
      handleDefault = XML_FALSE;
5000
60090
      break;
5001
    case XML_ROLE_NONE:
5002
169362
      switch (tok) {
5003
      case XML_TOK_BOM:
5004
        handleDefault = XML_FALSE;
5005
36
        break;
5006
      }
5007
      break;
5008
    case XML_ROLE_DOCTYPE_NONE:
5009
200124
      if (parser->m_startDoctypeDeclHandler)
5010
1128
        handleDefault = XML_FALSE;
5011
      break;
5012
    case XML_ROLE_ENTITY_NONE:
5013

36432
      if (dtd->keepProcessing && parser->m_entityDeclHandler)
5014
3150
        handleDefault = XML_FALSE;
5015
      break;
5016
    case XML_ROLE_NOTATION_NONE:
5017
2346
      if (parser->m_notationDeclHandler)
5018
1386
        handleDefault = XML_FALSE;
5019
      break;
5020
    case XML_ROLE_ATTLIST_NONE:
5021

19032
      if (dtd->keepProcessing && parser->m_attlistDeclHandler)
5022
1734
        handleDefault = XML_FALSE;
5023
      break;
5024
    case XML_ROLE_ELEMENT_NONE:
5025
8382
      if (parser->m_elementDeclHandler)
5026
1818
        handleDefault = XML_FALSE;
5027
      break;
5028
    } /* end of big switch */
5029
5030

1250172
    if (handleDefault && parser->m_defaultHandler)
5031
1356
      reportDefault(parser, enc, s, next);
5032
5033
699141
    switch (parser->m_parsingStatus.parsing) {
5034
    case XML_SUSPENDED:
5035
18
      *nextPtr = next;
5036
18
      return XML_ERROR_NONE;
5037
    case XML_FINISHED:
5038
6
      return XML_ERROR_ABORTED;
5039
    default:
5040
699117
      s = next;
5041
699117
      tok = XmlPrologTok(enc, s, end, &next);
5042
    }
5043
699117
  }
5044
  /* not reached */
5045
2150883
}
5046
5047
static enum XML_Error PTRCALL
5048
epilogProcessor(XML_Parser parser,
5049
                const char *s,
5050
                const char *end,
5051
                const char **nextPtr)
5052
{
5053
64404
  parser->m_processor = epilogProcessor;
5054
32202
  parser->m_eventPtr = s;
5055
182394
  for (;;) {
5056
182394
    const char *next = NULL;
5057
182394
    int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5058
182394
    parser->m_eventEndPtr = next;
5059


182394
    switch (tok) {
5060
    /* report partial linebreak - it might be the last token */
5061
    case -XML_TOK_PROLOG_S:
5062
18
      if (parser->m_defaultHandler) {
5063
6
        reportDefault(parser, parser->m_encoding, s, next);
5064
6
        if (parser->m_parsingStatus.parsing == XML_FINISHED)
5065
6
          return XML_ERROR_ABORTED;
5066
      }
5067
12
      *nextPtr = next;
5068
12
      return XML_ERROR_NONE;
5069
    case XML_TOK_NONE:
5070
31632
      *nextPtr = s;
5071
31632
      return XML_ERROR_NONE;
5072
    case XML_TOK_PROLOG_S:
5073
90192
      if (parser->m_defaultHandler)
5074
18
        reportDefault(parser, parser->m_encoding, s, next);
5075
      break;
5076
    case XML_TOK_PI:
5077
12
      if (!reportProcessingInstruction(parser, parser->m_encoding, s, next))
5078
6
        return XML_ERROR_NO_MEMORY;
5079
      break;
5080
    case XML_TOK_COMMENT:
5081
60012
      if (!reportComment(parser, parser->m_encoding, s, next))
5082
6
        return XML_ERROR_NO_MEMORY;
5083
      break;
5084
    case XML_TOK_INVALID:
5085
      parser->m_eventPtr = next;
5086
      return XML_ERROR_INVALID_TOKEN;
5087
    case XML_TOK_PARTIAL:
5088
510
      if (!parser->m_parsingStatus.finalBuffer) {
5089
504
        *nextPtr = s;
5090
504
        return XML_ERROR_NONE;
5091
      }
5092
6
      return XML_ERROR_UNCLOSED_TOKEN;
5093
    case XML_TOK_PARTIAL_CHAR:
5094
18
      if (!parser->m_parsingStatus.finalBuffer) {
5095
12
        *nextPtr = s;
5096
12
        return XML_ERROR_NONE;
5097
      }
5098
6
      return XML_ERROR_PARTIAL_CHAR;
5099
    default:
5100
      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5101
    }
5102
150204
    parser->m_eventPtr = s = next;
5103
150204
    switch (parser->m_parsingStatus.parsing) {
5104
    case XML_SUSPENDED:
5105
6
      *nextPtr = next;
5106
6
      return XML_ERROR_NONE;
5107
    case XML_FINISHED:
5108
6
      return XML_ERROR_ABORTED;
5109
    default: ;
5110
    }
5111
332586
  }
5112
32202
}
5113
5114
static enum XML_Error
5115
processInternalEntity(XML_Parser parser, ENTITY *entity,
5116
                      XML_Bool betweenDecl)
5117
{
5118
  const char *textStart, *textEnd;
5119
240
  const char *next;
5120
  enum XML_Error result;
5121
  OPEN_INTERNAL_ENTITY *openEntity;
5122
5123
120
  if (parser->m_freeInternalEntities) {
5124
    openEntity = parser->m_freeInternalEntities;
5125
6
    parser->m_freeInternalEntities = openEntity->next;
5126
6
  }
5127
  else {
5128
114
    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
5129
114
    if (!openEntity)
5130
      return XML_ERROR_NO_MEMORY;
5131
  }
5132
120
  entity->open = XML_TRUE;
5133
120
  entity->processed = 0;
5134
120
  openEntity->next = parser->m_openInternalEntities;
5135
120
  parser->m_openInternalEntities = openEntity;
5136
120
  openEntity->entity = entity;
5137
120
  openEntity->startTagLevel = parser->m_tagLevel;
5138
120
  openEntity->betweenDecl = betweenDecl;
5139
120
  openEntity->internalEventPtr = NULL;
5140
120
  openEntity->internalEventEndPtr = NULL;
5141
120
  textStart = (char *)entity->textPtr;
5142
120
  textEnd = (char *)(entity->textPtr + entity->textLen);
5143
  /* Set a safe default value in case 'next' does not get set */
5144
120
  next = textStart;
5145
5146
#ifdef XML_DTD
5147
120
  if (entity->is_param) {
5148
54
    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5149
108
    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
5150
54
                      next, &next, XML_FALSE);
5151
54
  }
5152
  else
5153
#endif /* XML_DTD */
5154
66
    result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart,
5155
                       textEnd, &next, XML_FALSE);
5156
5157
120
  if (result == XML_ERROR_NONE) {
5158

126
    if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
5159
24
      entity->processed = (int)(next - textStart);
5160
24
      parser->m_processor = internalEntityProcessor;
5161
24
    }
5162
    else {
5163
78
      entity->open = XML_FALSE;
5164
78
      parser->m_openInternalEntities = openEntity->next;
5165
      /* put openEntity back in list of free instances */
5166
78
      openEntity->next = parser->m_freeInternalEntities;
5167
78
      parser->m_freeInternalEntities = openEntity;
5168
    }
5169
  }
5170
120
  return result;
5171
120
}
5172
5173
static enum XML_Error PTRCALL
5174
internalEntityProcessor(XML_Parser parser,
5175
                        const char *s,
5176
                        const char *end,
5177
                        const char **nextPtr)
5178
{
5179
  ENTITY *entity;
5180
  const char *textStart, *textEnd;
5181
48
  const char *next;
5182
  enum XML_Error result;
5183
24
  OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
5184
24
  if (!openEntity)
5185
    return XML_ERROR_UNEXPECTED_STATE;
5186
5187
24
  entity = openEntity->entity;
5188
24
  textStart = ((char *)entity->textPtr) + entity->processed;
5189
24
  textEnd = (char *)(entity->textPtr + entity->textLen);
5190
  /* Set a safe default value in case 'next' does not get set */
5191
24
  next = textStart;
5192
5193
#ifdef XML_DTD
5194
24
  if (entity->is_param) {
5195
6
    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
5196
12
    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
5197
6
                      next, &next, XML_FALSE);
5198
6
  }
5199
  else
5200
#endif /* XML_DTD */
5201
18
    result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding,
5202
                       textStart, textEnd, &next, XML_FALSE);
5203
5204
24
  if (result != XML_ERROR_NONE)
5205
6
    return result;
5206

24
  else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
5207
6
    entity->processed = (int)(next - (char *)entity->textPtr);
5208
6
    return result;
5209
  }
5210
  else {
5211
12
    entity->open = XML_FALSE;
5212
12
    parser->m_openInternalEntities = openEntity->next;
5213
    /* put openEntity back in list of free instances */
5214
12
    openEntity->next = parser->m_freeInternalEntities;
5215
12
    parser->m_freeInternalEntities = openEntity;
5216
  }
5217
5218
#ifdef XML_DTD
5219
12
  if (entity->is_param) {
5220
    int tok;
5221
6
    parser->m_processor = prologProcessor;
5222
6
    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
5223
12
    return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
5224
6
                    (XML_Bool)!parser->m_parsingStatus.finalBuffer);
5225
  }
5226
  else
5227
#endif /* XML_DTD */
5228
  {
5229
6
    parser->m_processor = contentProcessor;
5230
    /* see externalEntityContentProcessor vs contentProcessor */
5231
12
    return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, s, end,
5232
6
                     nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
5233
  }
5234
24
}
5235
5236
static enum XML_Error PTRCALL
5237
errorProcessor(XML_Parser parser,
5238
               const char *UNUSED_P(s),
5239
               const char *UNUSED_P(end),
5240
               const char **UNUSED_P(nextPtr))
5241
{
5242
12
  return parser->m_errorCode;
5243
}
5244
5245
static enum XML_Error
5246
storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5247
                    const char *ptr, const char *end,
5248
                    STRING_POOL *pool)
5249
{
5250
1092
  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
5251
                                               end, pool);
5252
546
  if (result)
5253
48
    return result;
5254

690
  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
5255
18
    poolChop(pool);
5256

1164
  if (!poolAppendChar(pool, XML_T('\0')))
5257
6
    return XML_ERROR_NO_MEMORY;
5258
492
  return XML_ERROR_NONE;
5259
546
}
5260
5261
static enum XML_Error
5262
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5263
                     const char *ptr, const char *end,
5264
                     STRING_POOL *pool)
5265
{
5266
1176
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
5267
3696
  for (;;) {
5268
3702
    const char *next;
5269
3702
    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5270


3702
    switch (tok) {
5271
    case XML_TOK_NONE:
5272
534
      return XML_ERROR_NONE;
5273
    case XML_TOK_INVALID:
5274
6
      if (enc == parser->m_encoding)
5275
6
        parser->m_eventPtr = next;
5276
6
      return XML_ERROR_INVALID_TOKEN;
5277
    case XML_TOK_PARTIAL:
5278
6
      if (enc == parser->m_encoding)
5279
6
        parser->m_eventPtr = ptr;
5280
6
      return XML_ERROR_INVALID_TOKEN;
5281
    case XML_TOK_CHAR_REF:
5282
      {
5283
192
        XML_Char buf[XML_ENCODE_MAX];
5284
        int i;
5285
192
        int n = XmlCharRefNumber(enc, ptr);
5286
192
        if (n < 0) {
5287
          if (enc == parser->m_encoding)
5288
            parser->m_eventPtr = ptr;
5289
          return XML_ERROR_BAD_CHAR_REF;
5290
        }
5291
192
        if (!isCdata
5292
192
            && n == 0x20 /* space */
5293
            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5294
          break;
5295
192
        n = XmlEncode(n, (ICHAR *)buf);
5296
        /* The XmlEncode() functions can never return 0 here.  That
5297
         * error return happens if the code point passed in is either
5298
         * negative or greater than or equal to 0x110000.  The
5299
         * XmlCharRefNumber() functions will all return a number
5300
         * strictly less than 0x110000 or a negative value if an error
5301
         * occurred.  The negative value is intercepted above, so
5302
         * XmlEncode() is never passed a value it might return an
5303
         * error for.
5304
         */
5305
1092
        for (i = 0; i < n; i++) {
5306

750
          if (!poolAppendChar(pool, buf[i]))
5307
6
            return XML_ERROR_NO_MEMORY;
5308
        }
5309
564
      }
5310
      break;
5311
    case XML_TOK_DATA_CHARS:
5312
1434
      if (!poolAppend(pool, enc, ptr, next))
5313
12
        return XML_ERROR_NO_MEMORY;
5314
      break;
5315
    case XML_TOK_TRAILING_CR:
5316
6
      next = ptr + enc->minBytesPerChar;
5317
      /* fall through */
5318
    case XML_TOK_ATTRIBUTE_VALUE_S:
5319
    case XML_TOK_DATA_NEWLINE:
5320

1908
      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5321
        break;
5322

2562
      if (!poolAppendChar(pool, 0x20))
5323
6
        return XML_ERROR_NO_MEMORY;
5324
1272
      break;
5325
    case XML_TOK_ENTITY_REF:
5326
      {
5327
        const XML_Char *name;
5328
        ENTITY *entity;
5329
        char checkEntityDecl;
5330
60
        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
5331
                                              ptr + enc->minBytesPerChar,
5332
                                              next - enc->minBytesPerChar);
5333
60
        if (ch) {
5334

30
          if (!poolAppendChar(pool, ch))
5335
6
                return XML_ERROR_NO_MEMORY;
5336
6
          break;
5337
        }
5338
96
        name = poolStoreString(&parser->m_temp2Pool, enc,
5339
48
                               ptr + enc->minBytesPerChar,
5340
48
                               next - enc->minBytesPerChar);
5341
48
        if (!name)
5342
6
          return XML_ERROR_NO_MEMORY;
5343
42
        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5344
42
        poolDiscard(&parser->m_temp2Pool);
5345
        /* First, determine if a check for an existing declaration is needed;
5346
           if yes, check that the entity exists, and that it is internal.
5347
        */
5348
42
        if (pool == &dtd->pool)  /* are we called from prolog? */
5349
6
          checkEntityDecl =
5350
#ifdef XML_DTD
5351
12
              parser->m_prologState.documentEntity &&
5352
#endif /* XML_DTD */
5353
12
              (dtd->standalone
5354
6
               ? !parser->m_openInternalEntities
5355
               : !dtd->hasParamEntityRefs);
5356
        else /* if (pool == &parser->m_tempPool): we are called from content */
5357
72
          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
5358
42
        if (checkEntityDecl) {
5359
36
          if (!entity)
5360
            return XML_ERROR_UNDEFINED_ENTITY;
5361
36
          else if (!entity->is_internal)
5362
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
5363
        }
5364
6
        else if (!entity) {
5365
          /* Cannot report skipped entity here - see comments on
5366
             parser->m_skippedEntityHandler.
5367
          if (parser->m_skippedEntityHandler)
5368
            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5369
          */
5370
          /* Cannot call the default handler because this would be
5371
             out of sync with the call to the startElementHandler.
5372
          if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
5373
            reportDefault(parser, enc, ptr, next);
5374
          */
5375
          break;
5376
        }
5377
42
        if (entity->open) {
5378
          if (enc == parser->m_encoding) {
5379
            /* It does not appear that this line can be executed.
5380
             *
5381
             * The "if (entity->open)" check catches recursive entity
5382
             * definitions.  In order to be called with an open
5383
             * entity, it must have gone through this code before and
5384
             * been through the recursive call to
5385
             * appendAttributeValue() some lines below.  That call
5386
             * sets the local encoding ("enc") to the parser's
5387
             * internal encoding (internal_utf8 or internal_utf16),
5388
             * which can never be the same as the principle encoding.
5389
             * It doesn't appear there is another code path that gets
5390
             * here with entity->open being TRUE.
5391
             *
5392
             * Since it is not certain that this logic is watertight,
5393
             * we keep the line and merely exclude it from coverage
5394
             * tests.
5395
             */
5396
            parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
5397
          }
5398
          return XML_ERROR_RECURSIVE_ENTITY_REF;
5399
        }
5400
42
        if (entity->notation) {
5401
          if (enc == parser->m_encoding)
5402
            parser->m_eventPtr = ptr;
5403
          return XML_ERROR_BINARY_ENTITY_REF;
5404
        }
5405
42
        if (!entity->textPtr) {
5406
          if (enc == parser->m_encoding)
5407
            parser->m_eventPtr = ptr;
5408
          return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5409
        }
5410
        else {
5411
          enum XML_Error result;
5412
42
          const XML_Char *textEnd = entity->textPtr + entity->textLen;
5413
42
          entity->open = XML_TRUE;
5414
84
          result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata,
5415
42
                                        (char *)entity->textPtr,
5416
                                        (char *)textEnd, pool);
5417
42
          entity->open = XML_FALSE;
5418
42
          if (result)
5419
6
            return result;
5420
36
        }
5421
36
      }
5422
      break;
5423
    default:
5424
      /* The only token returned by XmlAttributeValueTok() that does
5425
       * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
5426
       * Getting that would require an entity name to contain an
5427
       * incomplete XML character (e.g. \xE2\x82); however previous
5428
       * tokenisers will have already recognised and rejected such
5429
       * names before XmlAttributeValueTok() gets a look-in.  This
5430
       * default case should be retained as a safety net, but the code
5431
       * excluded from coverage tests.
5432
       *
5433
       * LCOV_EXCL_START
5434
       */
5435
      if (enc == parser->m_encoding)
5436
        parser->m_eventPtr = ptr;
5437
      return XML_ERROR_UNEXPECTED_STATE;
5438
      /* LCOV_EXCL_STOP */
5439
    }
5440
3108
    ptr = next;
5441
6804
  }
5442
  /* not reached */
5443
588
}
5444
5445
static enum XML_Error
5446
storeEntityValue(XML_Parser parser,
5447
                 const ENCODING *enc,
5448
                 const char *entityTextPtr,
5449
                 const char *entityTextEnd)
5450
{
5451
1506
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
5452
753
  STRING_POOL *pool = &(dtd->entityValuePool);
5453
  enum XML_Error result = XML_ERROR_NONE;
5454
#ifdef XML_DTD
5455
753
  int oldInEntityValue = parser->m_prologState.inEntityValue;
5456
753
  parser->m_prologState.inEntityValue = 1;
5457
#endif /* XML_DTD */
5458
  /* never return Null for the value argument in EntityDeclHandler,
5459
     since this would indicate an external entity; therefore we
5460
     have to make sure that entityValuePool.start is not null */
5461
753
  if (!pool->blocks) {
5462
627
    if (!poolGrow(pool))
5463
24
      return XML_ERROR_NO_MEMORY;
5464
  }
5465
5466
1494
  for (;;) {
5467
1500
    const char *next;
5468
1500
    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5469


1500
    switch (tok) {
5470
    case XML_TOK_PARAM_ENTITY_REF:
5471
#ifdef XML_DTD
5472

210
      if (parser->m_isParamEntity || enc != parser->m_encoding) {
5473
        const XML_Char *name;
5474
        ENTITY *entity;
5475
420
        name = poolStoreString(&parser->m_tempPool, enc,
5476
210
                               entityTextPtr + enc->minBytesPerChar,
5477
210
                               next - enc->minBytesPerChar);
5478
210
        if (!name) {
5479
          result = XML_ERROR_NO_MEMORY;
5480
6
          goto endEntityValue;
5481
        }
5482
204
        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
5483
204
        poolDiscard(&parser->m_tempPool);
5484
204
        if (!entity) {
5485
          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5486
          /* cannot report skipped entity here - see comments on
5487
             parser->m_skippedEntityHandler
5488
          if (parser->m_skippedEntityHandler)
5489
            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
5490
          */
5491
6
          dtd->keepProcessing = dtd->standalone;
5492
6
          goto endEntityValue;
5493
        }
5494
198
        if (entity->open) {
5495
6
          if (enc == parser->m_encoding)
5496
6
            parser->m_eventPtr = entityTextPtr;
5497
          result = XML_ERROR_RECURSIVE_ENTITY_REF;
5498
6
          goto endEntityValue;
5499
        }
5500
192
        if (entity->systemId) {
5501
186
          if (parser->m_externalEntityRefHandler) {
5502
180
            dtd->paramEntityRead = XML_FALSE;
5503
180
            entity->open = XML_TRUE;
5504
360
            if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
5505
                                          0,
5506
180
                                          entity->base,
5507
180
                                          entity->systemId,
5508
180
                                          entity->publicId)) {
5509
              entity->open = XML_FALSE;
5510
              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5511
30
              goto endEntityValue;
5512
            }
5513
            entity->open = XML_FALSE;
5514
150
            if (!dtd->paramEntityRead)
5515
6
              dtd->keepProcessing = dtd->standalone;
5516
          }
5517
          else
5518
6
            dtd->keepProcessing = dtd->standalone;
5519
12
        }
5520
        else {
5521
6
          entity->open = XML_TRUE;
5522
6
          result = storeEntityValue(parser,
5523
6
                                    parser->m_internalEncoding,
5524
6
                                    (char *)entity->textPtr,
5525
                                    (char *)(entity->textPtr
5526
6
                                             + entity->textLen));
5527
6
          entity->open = XML_FALSE;
5528
6
          if (result)
5529
6
            goto endEntityValue;
5530
        }
5531
156
        break;
5532
      }
5533
#endif /* XML_DTD */
5534
      /* In the internal subset, PE references are not legal
5535
         within markup declarations, e.g entity values in this case. */
5536
      parser->m_eventPtr = entityTextPtr;
5537
      result = XML_ERROR_PARAM_ENTITY_REF;
5538
      goto endEntityValue;
5539
    case XML_TOK_NONE:
5540
      result = XML_ERROR_NONE;
5541
639
      goto endEntityValue;
5542
    case XML_TOK_ENTITY_REF:
5543
    case XML_TOK_DATA_CHARS:
5544
501
      if (!poolAppend(pool, enc, entityTextPtr, next)) {
5545
        result = XML_ERROR_NO_MEMORY;
5546
6
        goto endEntityValue;
5547
      }
5548
      break;
5549
    case XML_TOK_TRAILING_CR:
5550
6
      next = entityTextPtr + enc->minBytesPerChar;
5551
      /* fall through */
5552
    case XML_TOK_DATA_NEWLINE:
5553

90
      if (pool->end == pool->ptr && !poolGrow(pool)) {
5554
              result = XML_ERROR_NO_MEMORY;
5555
6
        goto endEntityValue;
5556
      }
5557
72
      *(pool->ptr)++ = 0xA;
5558
72
      break;
5559
    case XML_TOK_CHAR_REF:
5560
      {
5561
60
        XML_Char buf[XML_ENCODE_MAX];
5562
        int i;
5563
60
        int n = XmlCharRefNumber(enc, entityTextPtr);
5564
60
        if (n < 0) {
5565
12
          if (enc == parser->m_encoding)
5566
12
            parser->m_eventPtr = entityTextPtr;
5567
          result = XML_ERROR_BAD_CHAR_REF;
5568
12
          goto endEntityValue;
5569
        }
5570
48
        n = XmlEncode(n, (ICHAR *)buf);
5571
        /* The XmlEncode() functions can never return 0 here.  That
5572
         * error return happens if the code point passed in is either
5573
         * negative or greater than or equal to 0x110000.  The
5574
         * XmlCharRefNumber() functions will all return a number
5575
         * strictly less than 0x110000 or a negative value if an error
5576
         * occurred.  The negative value is intercepted above, so
5577
         * XmlEncode() is never passed a value it might return an
5578
         * error for.
5579
         */
5580
180
        for (i = 0; i < n; i++) {
5581

60
          if (pool->end == pool->ptr && !poolGrow(pool)) {
5582
            result = XML_ERROR_NO_MEMORY;
5583
6
            goto endEntityValue;
5584
          }
5585
42
          *(pool->ptr)++ = buf[i];
5586
        }
5587
102
      }
5588
      break;
5589
    case XML_TOK_PARTIAL:
5590
      if (enc == parser->m_encoding)
5591
        parser->m_eventPtr = entityTextPtr;
5592
      result = XML_ERROR_INVALID_TOKEN;
5593
      goto endEntityValue;
5594
    case XML_TOK_INVALID:
5595
6
      if (enc == parser->m_encoding)
5596
6
        parser->m_eventPtr = next;
5597
      result = XML_ERROR_INVALID_TOKEN;
5598
6
      goto endEntityValue;
5599
    default:
5600
      /* This default case should be unnecessary -- all the tokens
5601
       * that XmlEntityValueTok() can return have their own explicit
5602
       * cases -- but should be retained for safety.  We do however
5603
       * exclude it from the coverage statistics.
5604
       *
5605
       * LCOV_EXCL_START
5606
       */
5607
      if (enc == parser->m_encoding)
5608
        parser->m_eventPtr = entityTextPtr;
5609
      result = XML_ERROR_UNEXPECTED_STATE;
5610
      goto endEntityValue;
5611
      /* LCOV_EXCL_STOP */
5612
    }
5613
765
    entityTextPtr = next;
5614
3006
  }
5615
endEntityValue:
5616
#ifdef XML_DTD
5617
729
  parser->m_prologState.inEntityValue = oldInEntityValue;
5618
#endif /* XML_DTD */
5619
729
  return result;
5620
753
}
5621
5622
static void FASTCALL
5623
normalizeLines(XML_Char *s)
5624
{
5625
  XML_Char *p;
5626
27816
  for (;; s++) {
5627
27588
    if (*s == XML_T('\0'))
5628
228
      return;
5629
27360
    if (*s == 0xD)
5630
      break;
5631
  }
5632
  p = s;
5633
  do {
5634
    if (*s == 0xD) {
5635
      *p++ = 0xA;
5636
      if (*++s == 0xA)
5637
        s++;
5638
    }
5639
    else
5640
      *p++ = *s++;
5641
  } while (*s);
5642
  *p = XML_T('\0');
5643
228
}
5644
5645
static int
5646
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5647
                            const char *start, const char *end)
5648
{
5649
  const XML_Char *target;
5650
  XML_Char *data;
5651
  const char *tem;
5652
60324
  if (!parser->m_processingInstructionHandler) {
5653
30006
    if (parser->m_defaultHandler)
5654
6
      reportDefault(parser, enc, start, end);
5655
30006
    return 1;
5656
  }
5657
156
  start += enc->minBytesPerChar * 2;
5658
156
  tem = start + XmlNameLength(enc, start);
5659
156
  target = poolStoreString(&parser->m_tempPool, enc, start, tem);
5660
156
  if (!target)
5661
24
    return 0;
5662
132
  poolFinish(&parser->m_tempPool);
5663
132
  data = poolStoreString(&parser->m_tempPool, enc,
5664
132
                        XmlSkipS(enc, tem),
5665
132
                        end - enc->minBytesPerChar*2);
5666
132
  if (!data)
5667
6
    return 0;
5668
126
  normalizeLines(data);
5669
126
  parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
5670
126
  poolClear(&parser->m_tempPool);
5671
126
  return 1;
5672
30162
}
5673
5674
static int
5675
reportComment(XML_Parser parser, const ENCODING *enc,
5676
              const char *start, const char *end)
5677
{
5678
  XML_Char *data;
5679
300252
  if (!parser->m_commentHandler) {
5680
150006
    if (parser->m_defaultHandler)
5681
6
      reportDefault(parser, enc, start, end);
5682
150006
    return 1;
5683
  }
5684
240
  data = poolStoreString(&parser->m_tempPool,
5685
                         enc,
5686
120
                         start + enc->minBytesPerChar * 4,
5687
120
                         end - enc->minBytesPerChar * 3);
5688
120
  if (!data)
5689
18
    return 0;
5690
102
  normalizeLines(data);
5691
102
  parser->m_commentHandler(parser->m_handlerArg, data);
5692
102
  poolClear(&parser->m_tempPool);
5693
102
  return 1;
5694
150126
}
5695
5696
static void
5697
reportDefault(XML_Parser parser, const ENCODING *enc,
5698
              const char *s, const char *end)
5699
{
5700
2148
  if (MUST_CONVERT(enc, s)) {
5701
    enum XML_Convert_Result convert_res;
5702
    const char **eventPP;
5703
    const char **eventEndPP;
5704
228
    if (enc == parser->m_encoding) {
5705
228
      eventPP = &parser->m_eventPtr;
5706
228
      eventEndPP = &parser->m_eventEndPtr;
5707
228
    }
5708
    else {
5709
      /* To get here, two things must be true; the parser must be
5710
       * using a character encoding that is not the same as the
5711
       * encoding passed in, and the encoding passed in must need
5712
       * conversion to the internal format (UTF-8 unless XML_UNICODE
5713
       * is defined).  The only occasions on which the encoding passed
5714
       * in is not the same as the parser's encoding are when it is
5715
       * the internal encoding (e.g. a previously defined parameter
5716
       * entity, already converted to internal format).  This by
5717
       * definition doesn't need conversion, so the whole branch never
5718
       * gets executed.
5719
       *
5720
       * For safety's sake we don't delete these lines and merely
5721
       * exclude them from coverage statistics.
5722
       *
5723
       * LCOV_EXCL_START
5724
       */
5725
      eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5726
      eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5727
      /* LCOV_EXCL_STOP */
5728
    }
5729
228
    do {
5730
228
      ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
5731
228
      convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
5732
228
      *eventEndPP = s;
5733
228
      parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
5734
228
      *eventPP = s;
5735
228
    } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5736
228
  }
5737
  else
5738
1920
    parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5739
2148
}
5740
5741
5742
static int
5743
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5744
                XML_Bool isId, const XML_Char *value, XML_Parser parser)
5745
{
5746
  DEFAULT_ATTRIBUTE *att;
5747

3132
  if (value || isId) {
5748
    /* The handling of default attributes gets messed up if we have
5749
       a default which duplicates a non-default. */
5750
    int i;
5751
1908
    for (i = 0; i < type->nDefaultAtts; i++)
5752
84
      if (attId == type->defaultAtts[i].id)
5753
        return 1;
5754

1818
    if (isId && !type->idAtt && !attId->xmlns)
5755
474
      type->idAtt = attId;
5756
870
  }
5757
1176
  if (type->nDefaultAtts == type->allocDefaultAtts) {
5758
1050
    if (type->allocDefaultAtts == 0) {
5759
1038
      type->allocDefaultAtts = 8;
5760
1038
      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(parser, type->allocDefaultAtts
5761
                            * sizeof(DEFAULT_ATTRIBUTE));
5762
1038
      if (!type->defaultAtts) {
5763
48
        type->allocDefaultAtts = 0;
5764
48
        return 0;
5765
      }
5766
    }
5767
    else {
5768
      DEFAULT_ATTRIBUTE *temp;
5769
12
      int count = type->allocDefaultAtts * 2;
5770
12
      temp = (DEFAULT_ATTRIBUTE *)
5771
12
        REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5772
12
      if (temp == NULL)
5773
6
        return 0;
5774
6
      type->allocDefaultAtts = count;
5775
6
      type->defaultAtts = temp;
5776
6
    }
5777
  }
5778
1122
  att = type->defaultAtts + type->nDefaultAtts;
5779
1122
  att->id = attId;
5780
1122
  att->value = value;
5781
1122
  att->isCdata = isCdata;
5782
1122
  if (!isCdata)
5783
654
    attId->maybeTokenized = XML_TRUE;
5784
1122
  type->nDefaultAtts += 1;
5785
1122
  return 1;
5786
1176
}
5787
5788
static int
5789
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
5790
{
5791
15672
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
5792
  const XML_Char *name;
5793
691032
  for (name = elementType->name; *name; name++) {
5794
337770
    if (*name == XML_T(ASCII_COLON)) {
5795
      PREFIX *prefix;
5796
      const XML_Char *s;
5797
632244
      for (s = elementType->name; s != name; s++) {
5798

630474
        if (!poolAppendChar(&dtd->pool, *s))
5799
30
          return 0;
5800
      }
5801

2298
      if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5802
12
        return 0;
5803
1038
      prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5804
                                sizeof(PREFIX));
5805
1038
      if (!prefix)
5806
48
        return 0;
5807
990
      if (prefix->name == poolStart(&dtd->pool))
5808
918
        poolFinish(&dtd->pool);
5809
      else
5810
72
        poolDiscard(&dtd->pool);
5811
990
      elementType->prefix = prefix;
5812
5813
990
    }
5814
  }
5815
7746
  return 1;
5816
7836
}
5817
5818
static ATTRIBUTE_ID *
5819
getAttributeId(XML_Parser parser, const ENCODING *enc,
5820
               const char *start, const char *end)
5821
{
5822
5708040
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
5823
  ATTRIBUTE_ID *id;
5824
  const XML_Char *name;
5825

5708064
  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5826
6
    return NULL;
5827
2854014
  name = poolStoreString(&dtd->pool, enc, start, end);
5828
2854014
  if (!name)
5829
60
    return NULL;
5830
  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5831
2853954
  ++name;
5832
2853954
  id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
5833
2853954
  if (!id)
5834
324
    return NULL;
5835
2853630
  if (id->name != name)
5836
2580528
    poolDiscard(&dtd->pool);
5837
  else {
5838
273102
    poolFinish(&dtd->pool);
5839
273102
    if (!parser->m_ns)
5840
      ;
5841
3120
    else if (name[0] == XML_T(ASCII_x)
5842
3480
        && name[1] == XML_T(ASCII_m)
5843
2532
        && name[2] == XML_T(ASCII_l)
5844
2532
        && name[3] == XML_T(ASCII_n)
5845
2532
        && name[4] == XML_T(ASCII_s)
5846

3438
        && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
5847
1266
      if (name[5] == XML_T('\0'))
5848
360
        id->prefix = &dtd->defaultPrefix;
5849
      else
5850
906
        id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
5851
1266
      id->xmlns = XML_TRUE;
5852
1266
    }
5853
    else {
5854
      int i;
5855
166200
      for (i = 0; name[i]; i++) {
5856
        /* attributes without prefix are *not* in the default namespace */
5857
82470
        if (name[i] == XML_T(ASCII_COLON)) {
5858
          int j;
5859
161388
          for (j = 0; j < i; j++) {
5860

160830
            if (!poolAppendChar(&dtd->pool, name[j]))
5861
12
              return NULL;
5862
          }
5863

666
          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5864
6
            return NULL;
5865
300
          id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5866
                                        sizeof(PREFIX));
5867
300
          if (!id->prefix)
5868
24
            return NULL;
5869
276
          if (id->prefix->name == poolStart(&dtd->pool))
5870
192
            poolFinish(&dtd->pool);
5871
          else
5872
84
            poolDiscard(&dtd->pool);
5873
276
          break;
5874
        }
5875
      }
5876
906
    }
5877
  }
5878
2853588
  return id;
5879
2854020
}
5880
5881
#define CONTEXT_SEP XML_T(ASCII_FF)
5882
5883
static const XML_Char *
5884
getContext(XML_Parser parser)
5885
{
5886
2874
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
5887
1437
  HASH_TABLE_ITER iter;
5888
  XML_Bool needSep = XML_FALSE;
5889
5890
1437
  if (dtd->defaultPrefix.binding) {
5891
    int i;
5892
    int len;
5893

792
    if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
5894
      return NULL;
5895
264
    len = dtd->defaultPrefix.binding->uriLen;
5896
264
    if (parser->m_namespaceSeparator)
5897
264
      len--;
5898
478164
    for (i = 0; i < len; i++) {
5899

477636
      if (!poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) {
5900
        /* Because of memory caching, I don't believe this line can be
5901
         * executed.
5902
         *
5903
         * This is part of a loop copying the default prefix binding
5904
         * URI into the parser's temporary string pool.  Previously,
5905
         * that URI was copied into the same string pool, with a
5906
         * terminating NUL character, as part of setContext().  When
5907
         * the pool was cleared, that leaves a block definitely big
5908
         * enough to hold the URI on the free block list of the pool.
5909
         * The URI copy in getContext() therefore cannot run out of
5910
         * memory.
5911
         *
5912
         * If the pool is used between the setContext() and
5913
         * getContext() calls, the worst it can do is leave a bigger
5914
         * block on the front of the free list.  Given that this is
5915
         * all somewhat inobvious and program logic can be changed, we
5916
         * don't delete the line but we do exclude it from the test
5917
         * coverage statistics.
5918
         */
5919
        return NULL; /* LCOV_EXCL_LINE */
5920
      }
5921
    }
5922
    needSep = XML_TRUE;
5923
264
  }
5924
5925
1437
  hashTableIterInit(&iter, &(dtd->prefixes));
5926
2297
  for (;;) {
5927
    int i;
5928
    int len;
5929
    const XML_Char *s;
5930
2297
    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5931
2297
    if (!prefix)
5932
1407
      break;
5933
890
    if (!prefix->binding) {
5934
      /* This test appears to be (justifiable) paranoia.  There does
5935
       * not seem to be a way of injecting a prefix without a binding
5936
       * that doesn't get errored long before this function is called.
5937
       * The test should remain for safety's sake, so we instead
5938
       * exclude the following line from the coverage statistics.
5939
       */
5940
      continue; /* LCOV_EXCL_LINE */
5941
    }
5942

1950
    if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
5943
6
      return NULL;
5944
80384
    for (s = prefix->name; *s; s++)
5945

79091
      if (!poolAppendChar(&parser->m_tempPool, *s))
5946
8
        return NULL;
5947

1773
    if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
5948
10
      return NULL;
5949
866
    len = prefix->binding->uriLen;
5950
866
    if (parser->m_namespaceSeparator)
5951
866
      len--;
5952
56884
    for (i = 0; i < len; i++)
5953

55170
      if (!poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
5954
6
        return NULL;
5955
    needSep = XML_TRUE;
5956

860
  }
5957
5958
5959
1407
  hashTableIterInit(&iter, &(dtd->generalEntities));
5960
2772
  for (;;) {
5961
    const XML_Char *s;
5962
2946
    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5963
2946
    if (!e)
5964
1365
      break;
5965
1581
    if (!e->open)
5966
174
      continue;
5967

2757
    if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
5968
6
      return NULL;
5969
56274
    for (s = e->name; *s; s++)
5970

54267
      if (!poolAppendChar(&parser->m_tempPool, *s))
5971
36
        return 0;
5972
    needSep = XML_TRUE;
5973

1365
  }
5974
5975

2736
  if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
5976
6
    return NULL;
5977
1359
  return parser->m_tempPool.start;
5978
1437
}
5979
5980
static XML_Bool
5981
setContext(XML_Parser parser, const XML_Char *context)
5982
{
5983
6804
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
5984
  const XML_Char *s = context;
5985
5986
81686
  while (*context != XML_T('\0')) {
5987

76072
    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5988
      ENTITY *e;
5989

820
      if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
5990
6
        return XML_FALSE;
5991
401
      e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0);
5992
401
      if (e)
5993
401
        e->open = XML_TRUE;
5994
401
      if (*s != XML_T('\0'))
5995
        s++;
5996
      context = s;
5997
401
      poolDiscard(&parser->m_tempPool);
5998
401
    }
5999
37629
    else if (*s == XML_T(ASCII_EQUALS)) {
6000
      PREFIX *prefix;
6001
3118
      if (poolLength(&parser->m_tempPool) == 0)
6002
114
        prefix = &dtd->defaultPrefix;
6003
      else {
6004

6014
        if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
6005
6
          return XML_FALSE;
6006
2998
        prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&parser->m_tempPool),
6007
                                  sizeof(PREFIX));
6008
2998
        if (!prefix)
6009
144
          return XML_FALSE;
6010
2854
        if (prefix->name == poolStart(&parser->m_tempPool)) {
6011
2622
          prefix->name = poolCopyString(&dtd->pool, prefix->name);
6012
2622
          if (!prefix->name)
6013
72
            return XML_FALSE;
6014
        }
6015
2782
        poolDiscard(&parser->m_tempPool);
6016
      }
6017
388280
      for (context = s + 1;
6018
387940
           *context != CONTEXT_SEP && *context != XML_T('\0');
6019
191244
           context++)
6020

382608
        if (!poolAppendChar(&parser->m_tempPool, *context))
6021
6
          return XML_FALSE;
6022

5786
      if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
6023
6
        return XML_FALSE;
6024
8652
      if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
6025
5768
                     &parser->m_inheritedBindings) != XML_ERROR_NONE)
6026
216
        return XML_FALSE;
6027
2668
      poolDiscard(&parser->m_tempPool);
6028
2668
      if (*context != XML_T('\0'))
6029
262
        ++context;
6030
      s = context;
6031
2668
    }
6032
    else {
6033

72171
      if (!poolAppendChar(&parser->m_tempPool, *s))
6034
139
        return XML_FALSE;
6035
34372
      s++;
6036
    }
6037
  }
6038
2807
  return XML_TRUE;
6039
3402
}
6040
6041
static void FASTCALL
6042
normalizePublicId(XML_Char *publicId)
6043
{
6044
  XML_Char *p = publicId;
6045
  XML_Char *s;
6046
2566446
  for (s = publicId; *s; s++) {
6047

1237530
    switch (*s) {
6048
    case 0x20:
6049
    case 0xD:
6050
    case 0xA:
6051

180000
      if (p != publicId && p[-1] != 0x20)
6052
90000
        *p++ = 0x20;
6053
      break;
6054
    default:
6055
1147530
      *p++ = *s;
6056
1147530
    }
6057
  }
6058

60924
  if (p != publicId && p[-1] == 0x20)
6059
    --p;
6060
30462
  *p = XML_T('\0');
6061
30462
}
6062
6063
static DTD *
6064
dtdCreate(const XML_Memory_Handling_Suite *ms)
6065
{
6066
17238
  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
6067
8619
  if (p == NULL)
6068
78
    return p;
6069
8541
  poolInit(&(p->pool), ms);
6070
8541
  poolInit(&(p->entityValuePool), ms);
6071
8541
  hashTableInit(&(p->generalEntities), ms);
6072
8541
  hashTableInit(&(p->elementTypes), ms);
6073
8541
  hashTableInit(&(p->attributeIds), ms);
6074
8541
  hashTableInit(&(p->prefixes), ms);
6075
#ifdef XML_DTD
6076
8541
  p->paramEntityRead = XML_FALSE;
6077
8541
  hashTableInit(&(p->paramEntities), ms);
6078
#endif /* XML_DTD */
6079
8541
  p->defaultPrefix.name = NULL;
6080
8541
  p->defaultPrefix.binding = NULL;
6081
6082
8541
  p->in_eldecl = XML_FALSE;
6083
8541
  p->scaffIndex = NULL;
6084
8541
  p->scaffold = NULL;
6085
8541
  p->scaffLevel = 0;
6086
8541
  p->scaffSize = 0;
6087
8541
  p->scaffCount = 0;
6088
8541
  p->contentStringLen = 0;
6089
6090
8541
  p->keepProcessing = XML_TRUE;
6091
8541
  p->hasParamEntityRefs = XML_FALSE;
6092
8541
  p->standalone = XML_FALSE;
6093
8541
  return p;
6094
8619
}
6095
6096
static void
6097
dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
6098
{
6099
62760
  HASH_TABLE_ITER iter;
6100
31380
  hashTableIterInit(&iter, &(p->elementTypes));
6101
1262730
  for (;;) {
6102
1262730
    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6103
1262730
    if (!e)
6104
31380
      break;
6105
1231350
    if (e->allocDefaultAtts != 0)
6106
36
      ms->free_fcn(e->defaultAtts);
6107
1231350
  }
6108
31380
  hashTableClear(&(p->generalEntities));
6109
#ifdef XML_DTD
6110
31380
  p->paramEntityRead = XML_FALSE;
6111
31380
  hashTableClear(&(p->paramEntities));
6112
#endif /* XML_DTD */
6113
31380
  hashTableClear(&(p->elementTypes));
6114
31380
  hashTableClear(&(p->attributeIds));
6115
31380
  hashTableClear(&(p->prefixes));
6116
31380
  poolClear(&(p->pool));
6117
31380
  poolClear(&(p->entityValuePool));
6118
31380
  p->defaultPrefix.name = NULL;
6119
31380
  p->defaultPrefix.binding = NULL;
6120
6121
31380
  p->in_eldecl = XML_FALSE;
6122
6123
31380
  ms->free_fcn(p->scaffIndex);
6124
31380
  p->scaffIndex = NULL;
6125
31380
  ms->free_fcn(p->scaffold);
6126
31380
  p->scaffold = NULL;
6127
6128
31380
  p->scaffLevel = 0;
6129
31380
  p->scaffSize = 0;
6130
31380
  p->scaffCount = 0;
6131
31380
  p->contentStringLen = 0;
6132
6133
31380
  p->keepProcessing = XML_TRUE;
6134
31380
  p->hasParamEntityRefs = XML_FALSE;
6135
31380
  p->standalone = XML_FALSE;
6136
31380
}
6137
6138
static void
6139
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
6140
{
6141
17082
  HASH_TABLE_ITER iter;
6142
8541
  hashTableIterInit(&iter, &(p->elementTypes));
6143
19133
  for (;;) {
6144
19133
    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6145
19133
    if (!e)
6146
8541
      break;
6147
10592
    if (e->allocDefaultAtts != 0)
6148
1238
      ms->free_fcn(e->defaultAtts);
6149
10592
  }
6150
8541
  hashTableDestroy(&(p->generalEntities));
6151
#ifdef XML_DTD
6152
8541
  hashTableDestroy(&(p->paramEntities));
6153
#endif /* XML_DTD */
6154
8541
  hashTableDestroy(&(p->elementTypes));
6155
8541
  hashTableDestroy(&(p->attributeIds));
6156
8541
  hashTableDestroy(&(p->prefixes));
6157
8541
  poolDestroy(&(p->pool));
6158
8541
  poolDestroy(&(p->entityValuePool));
6159
8541
  if (isDocEntity) {
6160
7356
    ms->free_fcn(p->scaffIndex);
6161
7356
    ms->free_fcn(p->scaffold);
6162
7356
  }
6163
8541
  ms->free_fcn(p);
6164
8541
}
6165
6166
/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6167
   The new DTD has already been initialized.
6168
*/
6169
static int
6170
dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
6171
{
6172
2370
  HASH_TABLE_ITER iter;
6173
6174
  /* Copy the prefix table. */
6175
6176
1185
  hashTableIterInit(&iter, &(oldDtd->prefixes));
6177
1799
  for (;;) {
6178
    const XML_Char *name;
6179
1799
    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
6180
1799
    if (!oldP)
6181
1101
      break;
6182
698
    name = poolCopyString(&(newDtd->pool), oldP->name);
6183
698
    if (!name)
6184
30
      return 0;
6185
668
    if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
6186
54
      return 0;
6187
614
  }
6188
6189
1101
  hashTableIterInit(&iter, &(oldDtd->attributeIds));
6190
6191
  /* Copy the attribute id table. */
6192
6193
1755
  for (;;) {
6194
    ATTRIBUTE_ID *newA;
6195
    const XML_Char *name;
6196
1755
    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6197
6198
1755
    if (!oldA)
6199
1011
      break;
6200
    /* Remember to allocate the scratch byte before the name. */
6201

1632
    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
6202
12
      return 0;
6203
732
    name = poolCopyString(&(newDtd->pool), oldA->name);
6204
732
    if (!name)
6205
6
      return 0;
6206
726
    ++name;
6207
726
    newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
6208
                                  sizeof(ATTRIBUTE_ID));
6209
726
    if (!newA)
6210
72
      return 0;
6211
654
    newA->maybeTokenized = oldA->maybeTokenized;
6212
654
    if (oldA->prefix) {
6213
275
      newA->xmlns = oldA->xmlns;
6214
275
      if (oldA->prefix == &oldDtd->defaultPrefix)
6215
164
        newA->prefix = &newDtd->defaultPrefix;
6216
      else
6217
222
        newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
6218
111
                                        oldA->prefix->name, 0);
6219
275
    }
6220
654
  }
6221
6222
  /* Copy the element type table. */
6223
6224
1011
  hashTableIterInit(&iter, &(oldDtd->elementTypes));
6225
6226
1865
  for (;;) {
6227
    int i;
6228
    ELEMENT_TYPE *newE;
6229
    const XML_Char *name;
6230
1865
    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6231
1865
    if (!oldE)
6232
801
      break;
6233
1064
    name = poolCopyString(&(newDtd->pool), oldE->name);
6234
1064
    if (!name)
6235
36
      return 0;
6236
1028
    newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
6237
                                  sizeof(ELEMENT_TYPE));
6238
1028
    if (!newE)
6239
135
      return 0;
6240
893
    if (oldE->nDefaultAtts) {
6241
317
      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
6242
317
          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6243
317
      if (!newE->defaultAtts) {
6244
33
        return 0;
6245
      }
6246
    }
6247
860
    if (oldE->idAtt)
6248
144
      newE->idAtt = (ATTRIBUTE_ID *)
6249
144
          lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
6250
860
    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6251
860
    if (oldE->prefix)
6252
168
      newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
6253
84
                                      oldE->prefix->name, 0);
6254
2276
    for (i = 0; i < newE->nDefaultAtts; i++) {
6255
284
      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
6256
284
          lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
6257
284
      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6258
284
      if (oldE->defaultAtts[i].value) {
6259
50
        newE->defaultAtts[i].value
6260
100
            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
6261
50
        if (!newE->defaultAtts[i].value)
6262
6
          return 0;
6263
      }
6264
      else
6265
234
        newE->defaultAtts[i].value = NULL;
6266
    }
6267
854
  }
6268
6269
  /* Copy the entity tables. */
6270
801
  if (!copyEntityTable(oldParser,
6271
801
                       &(newDtd->generalEntities),
6272
801
                       &(newDtd->pool),
6273
801
                       &(oldDtd->generalEntities)))
6274
183
      return 0;
6275
6276
#ifdef XML_DTD
6277
618
  if (!copyEntityTable(oldParser,
6278
618
                       &(newDtd->paramEntities),
6279
                       &(newDtd->pool),
6280
618
                       &(oldDtd->paramEntities)))
6281
60
      return 0;
6282
558
  newDtd->paramEntityRead = oldDtd->paramEntityRead;
6283
#endif /* XML_DTD */
6284
6285
558
  newDtd->keepProcessing = oldDtd->keepProcessing;
6286
558
  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6287
558
  newDtd->standalone = oldDtd->standalone;
6288
6289
  /* Don't want deep copying for scaffolding */
6290
558
  newDtd->in_eldecl = oldDtd->in_eldecl;
6291
558
  newDtd->scaffold = oldDtd->scaffold;
6292
558
  newDtd->contentStringLen = oldDtd->contentStringLen;
6293
558
  newDtd->scaffSize = oldDtd->scaffSize;
6294
558
  newDtd->scaffLevel = oldDtd->scaffLevel;
6295
558
  newDtd->scaffIndex = oldDtd->scaffIndex;
6296
6297
558
  return 1;
6298
1185
}  /* End dtdCopy */
6299
6300
static int
6301
copyEntityTable(XML_Parser oldParser,
6302
                HASH_TABLE *newTable,
6303
                STRING_POOL *newPool,
6304
                const HASH_TABLE *oldTable)
6305
{
6306
2838
  HASH_TABLE_ITER iter;
6307
  const XML_Char *cachedOldBase = NULL;
6308
  const XML_Char *cachedNewBase = NULL;
6309
6310
1419
  hashTableIterInit(&iter, oldTable);
6311
6312
2331
  for (;;) {
6313
    ENTITY *newE;
6314
    const XML_Char *name;
6315
2331
    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
6316
2331
    if (!oldE)
6317
1176
      break;
6318
1155
    name = poolCopyString(newPool, oldE->name);
6319
1155
    if (!name)
6320
8
      return 0;
6321
1147
    newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
6322
1147
    if (!newE)
6323
206
      return 0;
6324
941
    if (oldE->systemId) {
6325
912
      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
6326
912
      if (!tem)
6327
6
        return 0;
6328
906
      newE->systemId = tem;
6329
906
      if (oldE->base) {
6330
24
        if (oldE->base == cachedOldBase)
6331
          newE->base = cachedNewBase;
6332
        else {
6333
          cachedOldBase = oldE->base;
6334
24
          tem = poolCopyString(newPool, cachedOldBase);
6335
24
          if (!tem)
6336
6
            return 0;
6337
18
          cachedNewBase = newE->base = tem;
6338
        }
6339
      }
6340
900
      if (oldE->publicId) {
6341
24
        tem = poolCopyString(newPool, oldE->publicId);
6342
24
        if (!tem)
6343
6
          return 0;
6344
18
        newE->publicId = tem;
6345
18
      }
6346
894
    }
6347
    else {
6348
58
      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
6349
29
                                            oldE->textLen);
6350
29
      if (!tem)
6351
6
        return 0;
6352
23
      newE->textPtr = tem;
6353
23
      newE->textLen = oldE->textLen;
6354
23
    }
6355
917
    if (oldE->notation) {
6356
25
      const XML_Char *tem = poolCopyString(newPool, oldE->notation);
6357
25
      if (!tem)
6358
5
        return 0;
6359
20
      newE->notation = tem;
6360
20
    }
6361
912
    newE->is_param = oldE->is_param;
6362
912
    newE->is_internal = oldE->is_internal;
6363
912
  }
6364
1176
  return 1;
6365
1419
}
6366
6367
#define INIT_POWER 6
6368
6369
static XML_Bool FASTCALL
6370
keyeq(KEY s1, KEY s2)
6371
{
6372
174055194
  for (; *s1 == *s2; s1++, s2++)
6373
78210752
    if (*s1 == 0)
6374
11109377
      return XML_TRUE;
6375
2174771
  return XML_FALSE;
6376
13284148
}
6377
6378
static size_t
6379
keylen(KEY s)
6380
{
6381
  size_t len = 0;
6382
219641342
  for (; *s; s++, len++);
6383
13900792
  return len;
6384
}
6385
6386
static void
6387
copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)
6388
{
6389
27801632
  key->k[0] = 0;
6390
13900816
  key->k[1] = get_hash_secret_salt(parser);
6391
13900816
}
6392
6393
static unsigned long FASTCALL
6394
hash(XML_Parser parser, KEY s)
6395
{
6396
27801272
  struct siphash state;
6397
13900636
  struct sipkey key;
6398
  (void)sip_tobin;
6399
  (void)sip24_valid;
6400
13900636
  copy_salt_to_sipkey(parser, &key);
6401
13900636
  sip24_init(&state, &key);
6402
13900636
  sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
6403
27801272
  return (unsigned long)sip24_final(&state);
6404
13900636
}
6405
6406
static NAMED *
6407
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
6408
{
6409
  size_t i;
6410
27806060
  if (table->size == 0) {
6411
    size_t tsize;
6412
20693
    if (!createSize)
6413
3378
      return NULL;
6414
17315
    table->power = INIT_POWER;
6415
    /* table->size is a power of 2 */
6416
17315
    table->size = (size_t)1 << INIT_POWER;
6417
    tsize = table->size * sizeof(NAMED *);
6418
17315
    table->v = (NAMED **)table->mem->malloc_fcn(tsize);
6419
17315
    if (!table->v) {
6420
840
      table->size = 0;
6421
840
      return NULL;
6422
    }
6423
16475
    memset(table->v, 0, tsize);
6424
16475
    i = hash(parser, name) & ((unsigned long)table->size - 1);
6425
16475
  }
6426
  else {
6427
13882337
    unsigned long h = hash(parser, name);
6428
13882337
    unsigned long mask = (unsigned long)table->size - 1;
6429
    unsigned char step = 0;
6430
13882337
    i = h & mask;
6431
32114216
    while (table->v[i]) {
6432
13284148
      if (keyeq(name, table->v[i]->name))
6433
11109377
        return table->v[i];
6434
2174771
      if (!step)
6435
1773133
        step = PROBE_STEP(h, mask, table->power);
6436
4349542
      i < step ? (i += table->size - step) : (i -= step);
6437
    }
6438
2772960
    if (!createSize)
6439
1232031
      return NULL;
6440
6441
    /* check for overflow (table is half full) */
6442
1540929
    if (table->used >> (table->power - 1)) {
6443
63
      unsigned char newPower = table->power + 1;
6444
63
      size_t newSize = (size_t)1 << newPower;
6445
63
      unsigned long newMask = (unsigned long)newSize - 1;
6446
63
      size_t tsize = newSize * sizeof(NAMED *);
6447
63
      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
6448
63
      if (!newV)
6449
6
        return NULL;
6450
57
      memset(newV, 0, tsize);
6451
7410
      for (i = 0; i < table->size; i++)
6452
3648
        if (table->v[i]) {
6453
1824
          unsigned long newHash = hash(parser, table->v[i]->name);
6454
1824
          size_t j = newHash & newMask;
6455
          step = 0;
6456
4124
          while (newV[j]) {
6457
238
            if (!step)
6458
195
              step = PROBE_STEP(newHash, newMask, newPower);
6459
476
            j < step ? (j += newSize - step) : (j -= step);
6460
          }
6461
1824
          newV[j] = table->v[i];
6462
1824
        }
6463
57
      table->mem->free_fcn(table->v);
6464
57
      table->v = newV;
6465
57
      table->power = newPower;
6466
57
      table->size = newSize;
6467
57
      i = h & newMask;
6468
      step = 0;
6469
132
      while (table->v[i]) {
6470
9
        if (!step)
6471
9
          step = PROBE_STEP(h, newMask, newPower);
6472
18
        i < step ? (i += newSize - step) : (i -= step);
6473
      }
6474
57
    }
6475
1540923
  }
6476
1557398
  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
6477
1557398
  if (!table->v[i])
6478
1307
    return NULL;
6479
1556091
  memset(table->v[i], 0, createSize);
6480
1556091
  table->v[i]->name = name;
6481
1556091
  (table->used)++;
6482
1556091
  return table->v[i];
6483
13903030
}
6484
6485
static void FASTCALL
6486
hashTableClear(HASH_TABLE *table)
6487
{
6488
  size_t i;
6489
16047276
  for (i = 0; i < table->size; i++) {
6490
7788288
    table->mem->free_fcn(table->v[i]);
6491
7788288
    table->v[i] = NULL;
6492
  }
6493
156900
  table->used = 0;
6494
156900
}
6495
6496
static void FASTCALL
6497
hashTableDestroy(HASH_TABLE *table)
6498
{
6499
  size_t i;
6500
2244211
  for (i = 0; i < table->size; i++)
6501
1058048
    table->mem->free_fcn(table->v[i]);
6502
42705
  table->mem->free_fcn(table->v);
6503
42705
}
6504
6505
static void FASTCALL
6506
hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
6507
{
6508
85410
  p->power = 0;
6509
42705
  p->size = 0;
6510
42705
  p->used = 0;
6511
42705
  p->v = NULL;
6512
42705
  p->mem = ms;
6513
42705
}
6514
6515
static void FASTCALL
6516
hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
6517
{
6518
94962
  iter->p = table->v;
6519
47481
  iter->end = iter->p + table->size;
6520
47481
}
6521
6522
static NAMED * FASTCALL
6523
hashTableIterNext(HASH_TABLE_ITER *iter)
6524
{
6525
10580882
  while (iter->p != iter->end) {
6526
4596231
    NAMED *tem = *(iter->p)++;
6527
4596231
    if (tem)
6528
1248074
      return tem;
6529
3348157
  }
6530
46782
  return NULL;
6531
1294856
}
6532
6533
static void FASTCALL
6534
poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
6535
{
6536
75264
  pool->blocks = NULL;
6537
37632
  pool->freeBlocks = NULL;
6538
37632
  pool->start = NULL;
6539
37632
  pool->ptr = NULL;
6540
37632
  pool->end = NULL;
6541
37632
  pool->mem = ms;
6542
37632
}
6543
6544
static void FASTCALL
6545
poolClear(STRING_POOL *pool)
6546
{
6547
19762770
  if (!pool->freeBlocks)
6548
2231109
    pool->freeBlocks = pool->blocks;
6549
  else {
6550
7650276
    BLOCK *p = pool->blocks;
6551
15300588
    while (p) {
6552
18
      BLOCK *tem = p->next;
6553
18
      p->next = pool->freeBlocks;
6554
18
      pool->freeBlocks = p;
6555
      p = tem;
6556
    }
6557
  }
6558
9881385
  pool->blocks = NULL;
6559
9881385
  pool->start = NULL;
6560
9881385
  pool->ptr = NULL;
6561
9881385
  pool->end = NULL;
6562
9881385
}
6563
6564
static void FASTCALL
6565
poolDestroy(STRING_POOL *pool)
6566
{
6567
75264
  BLOCK *p = pool->blocks;
6568
103198
  while (p) {
6569
13967
    BLOCK *tem = p->next;
6570
13967
    pool->mem->free_fcn(p);
6571
    p = tem;
6572
  }
6573
37632
  p = pool->freeBlocks;
6574
79068
  while (p) {
6575
1902
    BLOCK *tem = p->next;
6576
1902
    pool->mem->free_fcn(p);
6577
    p = tem;
6578
  }
6579
37632
}
6580
6581
static XML_Char *
6582
poolAppend(STRING_POOL *pool, const ENCODING *enc,
6583
           const char *ptr, const char *end)
6584
{
6585

7956360
  if (!pool->ptr && !poolGrow(pool))
6586
270
    return NULL;
6587
5792991
  for (;;) {
6588
5792991
    const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6589
5792991
    if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
6590
5790711
      break;
6591
2280
    if (!poolGrow(pool))
6592
174
      return NULL;
6593

2106
  }
6594
5790711
  return pool->start;
6595
5791155
}
6596
6597
static const XML_Char * FASTCALL
6598
poolCopyString(STRING_POOL *pool, const XML_Char *s)
6599
{
6600
2485406
  do {
6601

23682426
    if (!poolAppendChar(pool, *s))
6602
325
      return NULL;
6603
11837434
  } while (*s++);
6604
1242378
  s = pool->start;
6605
1242378
  poolFinish(pool);
6606
1242378
  return s;
6607
1242703
}
6608
6609
static const XML_Char *
6610
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
6611
{
6612

58
  if (!pool->ptr && !poolGrow(pool)) {
6613
    /* The following line is unreachable given the current usage of
6614
     * poolCopyStringN().  Currently it is called from exactly one
6615
     * place to copy the text of a simple general entity.  By that
6616
     * point, the name of the entity is already stored in the pool, so
6617
     * pool->ptr cannot be NULL.
6618
     *
6619
     * If poolCopyStringN() is used elsewhere as it well might be,
6620
     * this line may well become executable again.  Regardless, this
6621
     * sort of check shouldn't be removed lightly, so we just exclude
6622
     * it from the coverage statistics.
6623
     */
6624
    return NULL; /* LCOV_EXCL_LINE */
6625
  }
6626
59310
  for (; n > 0; --n, s++) {
6627

59287
    if (!poolAppendChar(pool, *s))
6628
6
      return NULL;
6629
  }
6630
23
  s = pool->start;
6631
23
  poolFinish(pool);
6632
23
  return s;
6633
29
}
6634
6635
static const XML_Char * FASTCALL
6636
poolAppendString(STRING_POOL *pool, const XML_Char *s)
6637
{
6638
3720
  while (*s) {
6639

1704
    if (!poolAppendChar(pool, *s))
6640
6
      return NULL;
6641
798
    s++;
6642
  }
6643
702
  return pool->start;
6644
708
}
6645
6646
static XML_Char *
6647
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6648
                const char *ptr, const char *end)
6649
{
6650
11577036
  if (!poolAppend(pool, enc, ptr, end))
6651
420
    return NULL;
6652

5788992
  if (pool->ptr == pool->end && !poolGrow(pool))
6653
30
    return NULL;
6654
5788068
  *(pool->ptr)++ = 0;
6655
5788068
  return pool->start;
6656
5788518
}
6657
6658
static size_t
6659
poolBytesToAllocateFor(int blockSize)
6660
{
6661
  /* Unprotected math would be:
6662
  ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
6663
  **
6664
  ** Detect overflow, avoiding _signed_ overflow undefined behavior
6665
  ** For a + b * c we check b * c in isolation first, so that addition of a
6666
  ** on top has no chance of making us accept a small non-negative number
6667
  */
6668
  const size_t stretch = sizeof(XML_Char);  /* can be 4 bytes */
6669
6670
39646
  if (blockSize <= 0)
6671
    return 0;
6672
6673
19823
  if (blockSize > (int)(INT_MAX / stretch))
6674
    return 0;
6675
6676
  {
6677
    const int stretchedBlockSize = blockSize * (int)stretch;
6678
19823
    const int bytesToAllocate = (int)(
6679
19823
        offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
6680
19823
    if (bytesToAllocate < 0)
6681
      return 0;
6682
6683
19823
    return (size_t)bytesToAllocate;
6684
  }
6685
19823
}
6686
6687
static XML_Bool FASTCALL
6688
poolGrow(STRING_POOL *pool)
6689
{
6690
4365490
  if (pool->freeBlocks) {
6691
2163072
    if (pool->start == 0) {
6692
2162922
      pool->blocks = pool->freeBlocks;
6693
2162922
      pool->freeBlocks = pool->freeBlocks->next;
6694
2162922
      pool->blocks->next = NULL;
6695
2162922
      pool->start = pool->blocks->s;
6696
2162922
      pool->end = pool->start + pool->blocks->size;
6697
2162922
      pool->ptr = pool->start;
6698
2162922
      return XML_TRUE;
6699
    }
6700
150
    if (pool->end - pool->start < pool->freeBlocks->size) {
6701
      BLOCK *tem = pool->freeBlocks->next;
6702
      pool->freeBlocks->next = pool->blocks;
6703
      pool->blocks = pool->freeBlocks;
6704
      pool->freeBlocks = tem;
6705
      memcpy(pool->blocks->s, pool->start,
6706
             (pool->end - pool->start) * sizeof(XML_Char));
6707
      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6708
      pool->start = pool->blocks->s;
6709
      pool->end = pool->start + pool->blocks->size;
6710
      return XML_TRUE;
6711
    }
6712
  }
6713

25720
  if (pool->blocks && pool->start == pool->blocks->s) {
6714
    BLOCK *temp;
6715
2956
    int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
6716
    size_t bytesToAllocate;
6717
6718
    /* NOTE: Needs to be calculated prior to calling `realloc`
6719
             to avoid dangling pointers: */
6720
2956
    const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;
6721
6722
2956
    if (blockSize < 0) {
6723
      /* This condition traps a situation where either more than
6724
       * INT_MAX/2 bytes have already been allocated.  This isn't
6725
       * readily testable, since it is unlikely that an average
6726
       * machine will have that much memory, so we exclude it from the
6727
       * coverage statistics.
6728
       */
6729
      return XML_FALSE; /* LCOV_EXCL_LINE */
6730
    }
6731
6732
2956
    bytesToAllocate = poolBytesToAllocateFor(blockSize);
6733
2956
    if (bytesToAllocate == 0)
6734
      return XML_FALSE;
6735
6736
2956
    temp = (BLOCK *)
6737
2956
      pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);
6738
2956
    if (temp == NULL)
6739
222
      return XML_FALSE;
6740
2734
    pool->blocks = temp;
6741
2734
    pool->blocks->size = blockSize;
6742
2734
    pool->ptr = pool->blocks->s + offsetInsideBlock;
6743
2734
    pool->start = pool->blocks->s;
6744
2734
    pool->end = pool->start + blockSize;
6745
2734
  }
6746
  else {
6747
    BLOCK *tem;
6748
16867
    int blockSize = (int)(pool->end - pool->start);
6749
    size_t bytesToAllocate;
6750
6751
16867
    if (blockSize < 0) {
6752
      /* This condition traps a situation where either more than
6753
       * INT_MAX bytes have already been allocated (which is prevented
6754
       * by various pieces of program logic, not least this one, never
6755
       * mind the unlikelihood of actually having that much memory) or
6756
       * the pool control fields have been corrupted (which could
6757
       * conceivably happen in an extremely buggy user handler
6758
       * function).  Either way it isn't readily testable, so we
6759
       * exclude it from the coverage statistics.
6760
       */
6761
      return XML_FALSE;  /* LCOV_EXCL_LINE */
6762
    }
6763
6764
16867
    if (blockSize < INIT_BLOCK_SIZE)
6765
16855
      blockSize = INIT_BLOCK_SIZE;
6766
    else {
6767
      /* Detect overflow, avoiding _signed_ overflow undefined behavior */
6768
12
      if ((int)((unsigned)blockSize * 2U) < 0) {
6769
        return XML_FALSE;
6770
      }
6771
      blockSize *= 2;
6772
    }
6773
6774
16867
    bytesToAllocate = poolBytesToAllocateFor(blockSize);
6775
16867
    if (bytesToAllocate == 0)
6776
      return XML_FALSE;
6777
6778
16867
    tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
6779
16867
    if (!tem)
6780
998
      return XML_FALSE;
6781
15869
    tem->size = blockSize;
6782
15869
    tem->next = pool->blocks;
6783
15869
    pool->blocks = tem;
6784
15869
    if (pool->ptr != pool->start)
6785
4932
      memcpy(tem->s, pool->start,
6786
2466
             (pool->ptr - pool->start) * sizeof(XML_Char));
6787
15869
    pool->ptr = tem->s + (pool->ptr - pool->start);
6788
15869
    pool->start = tem->s;
6789
15869
    pool->end = tem->s + blockSize;
6790
15869
  }
6791
18603
  return XML_TRUE;
6792
2182745
}
6793
6794
static int FASTCALL
6795
nextScaffoldPart(XML_Parser parser)
6796
{
6797
18696
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
6798
  CONTENT_SCAFFOLD * me;
6799
  int next;
6800
6801
9348
  if (!dtd->scaffIndex) {
6802
420
    dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
6803
420
    if (!dtd->scaffIndex)
6804
18
      return -1;
6805
402
    dtd->scaffIndex[0] = 0;
6806
402
  }
6807
6808
9330
  if (dtd->scaffCount >= dtd->scaffSize) {
6809
    CONTENT_SCAFFOLD *temp;
6810
528
    if (dtd->scaffold) {
6811
126
      temp = (CONTENT_SCAFFOLD *)
6812
126
        REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6813
126
      if (temp == NULL)
6814
12
        return -1;
6815
114
      dtd->scaffSize *= 2;
6816
114
    }
6817
    else {
6818
402
      temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
6819
                                        * sizeof(CONTENT_SCAFFOLD));
6820
402
      if (temp == NULL)
6821
18
        return -1;
6822
384
      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6823
    }
6824
498
    dtd->scaffold = temp;
6825
498
  }
6826
9300
  next = dtd->scaffCount++;
6827
9300
  me = &dtd->scaffold[next];
6828
9300
  if (dtd->scaffLevel) {
6829
8904
    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
6830
8904
    if (parent->lastchild) {
6831
6636
      dtd->scaffold[parent->lastchild].nextsib = next;
6832
6636
    }
6833
8904
    if (!parent->childcnt)
6834
2268
      parent->firstchild = next;
6835
8904
    parent->lastchild = next;
6836
8904
    parent->childcnt++;
6837
8904
  }
6838
9300
  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6839
9300
  return next;
6840
9348
}
6841
6842
static void
6843
build_node(XML_Parser parser,
6844
           int src_node,
6845
           XML_Content *dest,
6846
           XML_Content **contpos,
6847
           XML_Char **strpos)
6848
{
6849
7608
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
6850
3804
  dest->type = dtd->scaffold[src_node].type;
6851
3804
  dest->quant = dtd->scaffold[src_node].quant;
6852
3804
  if (dest->type == XML_CTYPE_NAME) {
6853
    const XML_Char *src;
6854
2358
    dest->name = *strpos;
6855
2358
    src = dtd->scaffold[src_node].name;
6856
5742
    for (;;) {
6857
5742
      *(*strpos)++ = *src;
6858
5742
      if (!*src)
6859
        break;
6860
3384
      src++;
6861
    }
6862
2358
    dest->numchildren = 0;
6863
2358
    dest->children = NULL;
6864
2358
  }
6865
  else {
6866
    unsigned int i;
6867
    int cn;
6868
1446
    dest->numchildren = dtd->scaffold[src_node].childcnt;
6869
1446
    dest->children = *contpos;
6870
1446
    *contpos += dest->numchildren;
6871
10212
    for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6872
5106
         i < dest->numchildren;
6873
3660
         i++, cn = dtd->scaffold[cn].nextsib) {
6874
3660
      build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6875
    }
6876
1446
    dest->name = NULL;
6877
  }
6878
3804
}
6879
6880
static XML_Content *
6881
build_model (XML_Parser parser)
6882
{
6883
324
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
6884
  XML_Content *ret;
6885
162
  XML_Content *cpos;
6886
162
  XML_Char * str;
6887
324
  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6888
162
                   + (dtd->contentStringLen * sizeof(XML_Char)));
6889
6890
162
  ret = (XML_Content *)MALLOC(parser, allocsize);
6891
162
  if (!ret)
6892
18
    return NULL;
6893
6894
144
  str =  (XML_Char *) (&ret[dtd->scaffCount]);
6895
144
  cpos = &ret[1];
6896
6897
144
  build_node(parser, 0, ret, &cpos, &str);
6898
144
  return ret;
6899
162
}
6900
6901
static ELEMENT_TYPE *
6902
getElementType(XML_Parser parser,
6903
               const ENCODING *enc,
6904
               const char *ptr,
6905
               const char *end)
6906
{
6907
17652
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
6908
8826
  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6909
  ELEMENT_TYPE *ret;
6910
6911
8826
  if (!name)
6912
18
    return NULL;
6913
8808
  ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6914
8808
  if (!ret)
6915
330
    return NULL;
6916
8478
  if (ret->name != name)
6917
2070
    poolDiscard(&dtd->pool);
6918
  else {
6919
6408
    poolFinish(&dtd->pool);
6920
6408
    if (!setElementTypePrefix(parser, ret))
6921
6
      return NULL;
6922
  }
6923
8472
  return ret;
6924
8826
}
6925
6926
static XML_Char *
6927
copyString(const XML_Char *s,
6928
           const XML_Memory_Handling_Suite *memsuite)
6929
{
6930
    int charsRequired = 0;
6931
    XML_Char *result;
6932
6933
    /* First determine how long the string is */
6934
2568
    while (s[charsRequired] != 0) {
6935
      charsRequired++;
6936
    }
6937
    /* Include the terminator */
6938
    charsRequired++;
6939
6940
    /* Now allocate space for the copy */
6941
132
    result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
6942
132
    if (result == NULL)
6943
18
        return NULL;
6944
    /* Copy the original into place */
6945
114
    memcpy(result, s, charsRequired * sizeof(XML_Char));
6946
114
    return result;
6947
132
}