Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/parser/expat/lib/xmlparse.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2
   See the file COPYING for copying permission.
3
*/
4
5
#include <stddef.h>
6
#include <string.h>                     /* memset(), memcpy() */
7
#include <assert.h>
8
9
#define XML_BUILDING_EXPAT 1
10
11
#ifdef COMPILED_FROM_DSP
12
#include "winconfig.h"
13
#elif defined(MACOS_CLASSIC)
14
#include "macconfig.h"
15
#elif defined(__amigaos4__)
16
#include "amigaconfig.h"
17
#elif defined(HAVE_EXPAT_CONFIG_H)
18
#include <expat_config.h>
19
#endif /* ndef COMPILED_FROM_DSP */
20
21
#include "expat.h"
22
23
#ifdef XML_UNICODE
24
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
25
0
#define XmlConvert XmlUtf16Convert
26
0
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
27
0
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
28
0
#define XmlEncode XmlUtf16Encode
29
30
/* Using pointer subtraction to convert to integer type. */
31
0
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
32
typedef unsigned short ICHAR;
33
#else
34
#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
35
#define XmlConvert XmlUtf8Convert
36
#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
37
#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
38
#define XmlEncode XmlUtf8Encode
39
#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
40
typedef char ICHAR;
41
#endif
42
43
44
#ifndef XML_NS
45
46
#define XmlInitEncodingNS XmlInitEncoding
47
#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
48
#undef XmlGetInternalEncodingNS
49
#define XmlGetInternalEncodingNS XmlGetInternalEncoding
50
#define XmlParseXmlDeclNS XmlParseXmlDecl
51
52
#endif
53
54
/* BEGIN MOZILLA CHANGE (typedef XML_Char to char16_t) */
55
#if 0
56
57
#ifdef XML_UNICODE
58
59
#ifdef XML_UNICODE_WCHAR_T
60
#define XML_T(x) (const wchar_t)x
61
#define XML_L(x) L ## x
62
#else
63
#define XML_T(x) (const unsigned short)x
64
#define XML_L(x) x
65
#endif
66
67
#else
68
69
#define XML_T(x) x
70
#define XML_L(x) x
71
72
#endif
73
74
#endif
75
/* END MOZILLA CHANGE */
76
77
/* Round up n to be a multiple of sz, where sz is a power of 2. */
78
0
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
79
80
/* Handle the case where memmove() doesn't exist. */
81
#ifndef HAVE_MEMMOVE
82
#ifdef HAVE_BCOPY
83
#define memmove(d,s,l) bcopy((s),(d),(l))
84
#else
85
#error memmove does not exist on this platform, nor is a substitute available
86
#endif /* HAVE_BCOPY */
87
#endif /* HAVE_MEMMOVE */
88
89
#include "internal.h"
90
#include "xmltok.h"
91
#include "xmlrole.h"
92
93
typedef const XML_Char *KEY;
94
95
typedef struct {
96
  KEY name;
97
} NAMED;
98
99
typedef struct {
100
  NAMED **v;
101
  unsigned char power;
102
  size_t size;
103
  size_t used;
104
  const XML_Memory_Handling_Suite *mem;
105
} HASH_TABLE;
106
107
/* Basic character hash algorithm, taken from Python's string hash:
108
   h = h * 1000003 ^ character, the constant being a prime number.
109
110
*/
111
#ifdef XML_UNICODE
112
#define CHAR_HASH(h, c) \
113
0
  (((h) * 0xF4243) ^ (unsigned short)(c))
114
#else
115
#define CHAR_HASH(h, c) \
116
  (((h) * 0xF4243) ^ (unsigned char)(c))
117
#endif
118
119
/* For probing (after a collision) we need a step size relative prime
120
   to the hash table size, which is a power of 2. We use double-hashing,
121
   since we can calculate a second hash value cheaply by taking those bits
122
   of the first hash value that were discarded (masked out) when the table
123
   index was calculated: index = hash & mask, where mask = table->size - 1.
124
   We limit the maximum step size to table->size / 4 (mask >> 2) and make
125
   it odd, since odd numbers are always relative prime to a power of 2.
126
*/
127
#define SECOND_HASH(hash, mask, power) \
128
0
  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
129
#define PROBE_STEP(hash, mask, power) \
130
0
  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
131
132
typedef struct {
133
  NAMED **p;
134
  NAMED **end;
135
} HASH_TABLE_ITER;
136
137
0
#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
138
0
#define INIT_DATA_BUF_SIZE 1024
139
0
#define INIT_ATTS_SIZE 16
140
0
#define INIT_ATTS_VERSION 0xFFFFFFFF
141
/* BEGIN MOZILLA CHANGE (Avoid slop in poolGrow() allocations) */
142
0
#define INIT_BLOCK_SIZE ((int)(1024 - (offsetof(BLOCK, s) / sizeof(XML_Char))))
143
/* END MOZILLA CHANGE */
144
0
#define INIT_BUFFER_SIZE 1024
145
146
0
#define EXPAND_SPARE 24
147
148
typedef struct binding {
149
  struct prefix *prefix;
150
  struct binding *nextTagBinding;
151
  struct binding *prevPrefixBinding;
152
  const struct attribute_id *attId;
153
  XML_Char *uri;
154
  int uriLen;
155
  int uriAlloc;
156
} BINDING;
157
158
typedef struct prefix {
159
  const XML_Char *name;
160
  BINDING *binding;
161
} PREFIX;
162
163
typedef struct {
164
  const XML_Char *str;
165
  const XML_Char *localPart;
166
  const XML_Char *prefix;
167
  int strLen;
168
  int uriLen;
169
  int prefixLen;
170
} TAG_NAME;
171
172
/* TAG represents an open element.
173
   The name of the element is stored in both the document and API
174
   encodings.  The memory buffer 'buf' is a separately-allocated
175
   memory area which stores the name.  During the XML_Parse()/
176
   XMLParseBuffer() when the element is open, the memory for the 'raw'
177
   version of the name (in the document encoding) is shared with the
178
   document buffer.  If the element is open across calls to
179
   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
180
   contain the 'raw' name as well.
181
182
   A parser re-uses these structures, maintaining a list of allocated
183
   TAG objects in a free list.
184
*/
185
typedef struct tag {
186
  struct tag *parent;           /* parent of this element */
187
  const char *rawName;          /* tagName in the original encoding */
188
  int rawNameLength;
189
  TAG_NAME name;                /* tagName in the API encoding */
190
  char *buf;                    /* buffer for name components */
191
  char *bufEnd;                 /* end of the buffer */
192
  BINDING *bindings;
193
} TAG;
194
195
typedef struct {
196
  const XML_Char *name;
197
  const XML_Char *textPtr;
198
  int textLen;                  /* length in XML_Chars */
199
  int processed;                /* # of processed bytes - when suspended */
200
  const XML_Char *systemId;
201
  const XML_Char *base;
202
  const XML_Char *publicId;
203
  const XML_Char *notation;
204
  XML_Bool open;
205
  XML_Bool is_param;
206
  XML_Bool is_internal; /* true if declared in internal subset outside PE */
207
} ENTITY;
208
209
typedef struct {
210
  enum XML_Content_Type         type;
211
  enum XML_Content_Quant        quant;
212
  const XML_Char *              name;
213
  int                           firstchild;
214
  int                           lastchild;
215
  int                           childcnt;
216
  int                           nextsib;
217
} CONTENT_SCAFFOLD;
218
219
0
#define INIT_SCAFFOLD_ELEMENTS 32
220
221
typedef struct block {
222
  struct block *next;
223
  int size;
224
  XML_Char s[1];
225
} BLOCK;
226
227
typedef struct {
228
  BLOCK *blocks;
229
  BLOCK *freeBlocks;
230
  const XML_Char *end;
231
  XML_Char *ptr;
232
  XML_Char *start;
233
  const XML_Memory_Handling_Suite *mem;
234
} STRING_POOL;
235
236
/* The XML_Char before the name is used to determine whether
237
   an attribute has been specified. */
238
typedef struct attribute_id {
239
  XML_Char *name;
240
  PREFIX *prefix;
241
  XML_Bool maybeTokenized;
242
  XML_Bool xmlns;
243
} ATTRIBUTE_ID;
244
245
typedef struct {
246
  const ATTRIBUTE_ID *id;
247
  XML_Bool isCdata;
248
  const XML_Char *value;
249
} DEFAULT_ATTRIBUTE;
250
251
typedef struct {
252
  unsigned long version;
253
  unsigned long hash;
254
  const XML_Char *uriName;
255
} NS_ATT;
256
257
typedef struct {
258
  const XML_Char *name;
259
  PREFIX *prefix;
260
  const ATTRIBUTE_ID *idAtt;
261
  int nDefaultAtts;
262
  int allocDefaultAtts;
263
  DEFAULT_ATTRIBUTE *defaultAtts;
264
} ELEMENT_TYPE;
265
266
typedef struct {
267
  HASH_TABLE generalEntities;
268
  HASH_TABLE elementTypes;
269
  HASH_TABLE attributeIds;
270
  HASH_TABLE prefixes;
271
  STRING_POOL pool;
272
  STRING_POOL entityValuePool;
273
  /* false once a parameter entity reference has been skipped */
274
  XML_Bool keepProcessing;
275
  /* true once an internal or external PE reference has been encountered;
276
     this includes the reference to an external subset */
277
  XML_Bool hasParamEntityRefs;
278
  XML_Bool standalone;
279
#ifdef XML_DTD
280
  /* indicates if external PE has been read */
281
  XML_Bool paramEntityRead;
282
  HASH_TABLE paramEntities;
283
#endif /* XML_DTD */
284
  PREFIX defaultPrefix;
285
  /* === scaffolding for building content model === */
286
  XML_Bool in_eldecl;
287
  CONTENT_SCAFFOLD *scaffold;
288
  unsigned contentStringLen;
289
  unsigned scaffSize;
290
  unsigned scaffCount;
291
  int scaffLevel;
292
  int *scaffIndex;
293
} DTD;
294
295
typedef struct open_internal_entity {
296
  const char *internalEventPtr;
297
  const char *internalEventEndPtr;
298
  struct open_internal_entity *next;
299
  ENTITY *entity;
300
  int startTagLevel;
301
  XML_Bool betweenDecl; /* WFC: PE Between Declarations */
302
} OPEN_INTERNAL_ENTITY;
303
304
typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
305
                                         const char *start,
306
                                         const char *end,
307
                                         const char **endPtr);
308
309
static Processor prologProcessor;
310
static Processor prologInitProcessor;
311
static Processor contentProcessor;
312
static Processor cdataSectionProcessor;
313
#ifdef XML_DTD
314
static Processor ignoreSectionProcessor;
315
static Processor externalParEntProcessor;
316
static Processor externalParEntInitProcessor;
317
static Processor entityValueProcessor;
318
static Processor entityValueInitProcessor;
319
#endif /* XML_DTD */
320
static Processor epilogProcessor;
321
static Processor errorProcessor;
322
static Processor externalEntityInitProcessor;
323
static Processor externalEntityInitProcessor2;
324
static Processor externalEntityInitProcessor3;
325
static Processor externalEntityContentProcessor;
326
static Processor internalEntityProcessor;
327
328
static enum XML_Error
329
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
330
static enum XML_Error
331
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
332
               const char *s, const char *next);
333
static enum XML_Error
334
initializeEncoding(XML_Parser parser);
335
static enum XML_Error
336
doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 
337
         const char *end, int tok, const char *next, const char **nextPtr, 
338
         XML_Bool haveMore);
339
static enum XML_Error
340
processInternalEntity(XML_Parser parser, ENTITY *entity, 
341
                      XML_Bool betweenDecl);
342
static enum XML_Error
343
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
344
          const char *start, const char *end, const char **endPtr, 
345
          XML_Bool haveMore);
346
static enum XML_Error
347
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
348
               const char *end, const char **nextPtr, XML_Bool haveMore);
349
#ifdef XML_DTD
350
static enum XML_Error
351
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
352
                const char *end, const char **nextPtr, XML_Bool haveMore);
353
#endif /* XML_DTD */
354
355
static enum XML_Error
356
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
357
          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
358
static enum XML_Error
359
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
360
           const XML_Char *uri, BINDING **bindingsPtr);
361
static int
362
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 
363
                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
364
static enum XML_Error
365
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
366
                    const char *, const char *, STRING_POOL *);
367
static enum XML_Error
368
appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
369
                     const char *, const char *, STRING_POOL *);
370
static ATTRIBUTE_ID *
371
getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
372
               const char *end);
373
static int
374
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
375
static enum XML_Error
376
storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
377
                 const char *end);
378
static int
379
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
380
                            const char *start, const char *end);
381
static int
382
reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
383
              const char *end);
384
static void
385
reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
386
              const char *end);
387
388
static const XML_Char * getContext(XML_Parser parser);
389
static XML_Bool
390
setContext(XML_Parser parser, const XML_Char *context);
391
392
static void FASTCALL normalizePublicId(XML_Char *s);
393
394
static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
395
/* BEGIN MOZILLA CHANGE (unused API) */
396
/* do not call if parentParser != NULL */
397
//static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
398
/* END MOZILLA CHANGE */
399
static void
400
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
401
static int
402
dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
403
static int
404
copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
405
406
static NAMED *
407
lookup(HASH_TABLE *table, KEY name, size_t createSize);
408
static void FASTCALL
409
hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
410
/* BEGIN MOZILLA CHANGE (unused API) */
411
//static void FASTCALL hashTableClear(HASH_TABLE *);
412
/* END MOZILLA CHANGE */
413
static void FASTCALL hashTableDestroy(HASH_TABLE *);
414
static void FASTCALL
415
hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
416
static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
417
418
static void FASTCALL
419
poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
420
static void FASTCALL poolClear(STRING_POOL *);
421
static void FASTCALL poolDestroy(STRING_POOL *);
422
static XML_Char *
423
poolAppend(STRING_POOL *pool, const ENCODING *enc,
424
           const char *ptr, const char *end);
425
static XML_Char *
426
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
427
                const char *ptr, const char *end);
428
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
429
static const XML_Char * FASTCALL
430
poolCopyString(STRING_POOL *pool, const XML_Char *s);
431
static const XML_Char *
432
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
433
static const XML_Char * FASTCALL
434
poolAppendString(STRING_POOL *pool, const XML_Char *s);
435
436
static int FASTCALL nextScaffoldPart(XML_Parser parser);
437
static XML_Content * build_model(XML_Parser parser);
438
static ELEMENT_TYPE *
439
getElementType(XML_Parser parser, const ENCODING *enc,
440
               const char *ptr, const char *end);
441
442
static XML_Parser
443
parserCreate(const XML_Char *encodingName,
444
             const XML_Memory_Handling_Suite *memsuite,
445
             const XML_Char *nameSep,
446
             DTD *dtd);
447
static void
448
parserInit(XML_Parser parser, const XML_Char *encodingName);
449
450
0
#define poolStart(pool) ((pool)->start)
451
#define poolEnd(pool) ((pool)->ptr)
452
0
#define poolLength(pool) ((pool)->ptr - (pool)->start)
453
0
#define poolChop(pool) ((void)--(pool->ptr))
454
0
#define poolLastChar(pool) (((pool)->ptr)[-1])
455
0
#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
456
0
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
457
#define poolAppendChar(pool, c) \
458
0
  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
459
0
   ? 0 \
460
0
   : ((*((pool)->ptr)++ = c), 1))
461
462
struct XML_ParserStruct {
463
  /* The first member must be userData so that the XML_GetUserData
464
     macro works. */
465
  void *m_userData;
466
  void *m_handlerArg;
467
  char *m_buffer;
468
  const XML_Memory_Handling_Suite m_mem;
469
  /* first character to be parsed */
470
  const char *m_bufferPtr;
471
  /* past last character to be parsed */
472
  char *m_bufferEnd;
473
  /* allocated end of buffer */
474
  const char *m_bufferLim;
475
  XML_Index m_parseEndByteIndex;
476
  const char *m_parseEndPtr;
477
  XML_Char *m_dataBuf;
478
  XML_Char *m_dataBufEnd;
479
  XML_StartElementHandler m_startElementHandler;
480
  XML_EndElementHandler m_endElementHandler;
481
  XML_CharacterDataHandler m_characterDataHandler;
482
  XML_ProcessingInstructionHandler m_processingInstructionHandler;
483
  XML_CommentHandler m_commentHandler;
484
  XML_StartCdataSectionHandler m_startCdataSectionHandler;
485
  XML_EndCdataSectionHandler m_endCdataSectionHandler;
486
  XML_DefaultHandler m_defaultHandler;
487
  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
488
  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
489
  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
490
  XML_NotationDeclHandler m_notationDeclHandler;
491
  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
492
  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
493
  XML_NotStandaloneHandler m_notStandaloneHandler;
494
  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
495
  XML_Parser m_externalEntityRefHandlerArg;
496
  XML_SkippedEntityHandler m_skippedEntityHandler;
497
  XML_UnknownEncodingHandler m_unknownEncodingHandler;
498
  XML_ElementDeclHandler m_elementDeclHandler;
499
  XML_AttlistDeclHandler m_attlistDeclHandler;
500
  XML_EntityDeclHandler m_entityDeclHandler;
501
  XML_XmlDeclHandler m_xmlDeclHandler;
502
  const ENCODING *m_encoding;
503
  INIT_ENCODING m_initEncoding;
504
  const ENCODING *m_internalEncoding;
505
  const XML_Char *m_protocolEncodingName;
506
  XML_Bool m_ns;
507
  XML_Bool m_ns_triplets;
508
  void *m_unknownEncodingMem;
509
  void *m_unknownEncodingData;
510
  void *m_unknownEncodingHandlerData;
511
  void (XMLCALL *m_unknownEncodingRelease)(void *);
512
  PROLOG_STATE m_prologState;
513
  Processor *m_processor;
514
  enum XML_Error m_errorCode;
515
  const char *m_eventPtr;
516
  const char *m_eventEndPtr;
517
  const char *m_positionPtr;
518
  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
519
  OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
520
  XML_Bool m_defaultExpandInternalEntities;
521
  int m_tagLevel;
522
  ENTITY *m_declEntity;
523
  const XML_Char *m_doctypeName;
524
  const XML_Char *m_doctypeSysid;
525
  const XML_Char *m_doctypePubid;
526
  const XML_Char *m_declAttributeType;
527
  const XML_Char *m_declNotationName;
528
  const XML_Char *m_declNotationPublicId;
529
  ELEMENT_TYPE *m_declElementType;
530
  ATTRIBUTE_ID *m_declAttributeId;
531
  XML_Bool m_declAttributeIsCdata;
532
  XML_Bool m_declAttributeIsId;
533
  DTD *m_dtd;
534
  const XML_Char *m_curBase;
535
  TAG *m_tagStack;
536
  TAG *m_freeTagList;
537
  BINDING *m_inheritedBindings;
538
  BINDING *m_freeBindingList;
539
  int m_attsSize;
540
  int m_nSpecifiedAtts;
541
  int m_idAttIndex;
542
  ATTRIBUTE *m_atts;
543
  NS_ATT *m_nsAtts;
544
  unsigned long m_nsAttsVersion;
545
  unsigned char m_nsAttsPower;
546
  POSITION m_position;
547
  STRING_POOL m_tempPool;
548
  STRING_POOL m_temp2Pool;
549
  char *m_groupConnector;
550
  unsigned int m_groupSize;
551
  XML_Char m_namespaceSeparator;
552
  XML_Parser m_parentParser;
553
  XML_ParsingStatus m_parsingStatus;
554
#ifdef XML_DTD
555
  XML_Bool m_isParamEntity;
556
  XML_Bool m_useForeignDTD;
557
  enum XML_ParamEntityParsing m_paramEntityParsing;
558
#endif
559
/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
560
  const XML_Char* m_mismatch;
561
/* END MOZILLA CHANGE */
562
};
563
564
0
#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
565
0
#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
566
0
#define FREE(p) (parser->m_mem.free_fcn((p)))
567
568
0
#define userData (parser->m_userData)
569
0
#define handlerArg (parser->m_handlerArg)
570
0
#define startElementHandler (parser->m_startElementHandler)
571
0
#define endElementHandler (parser->m_endElementHandler)
572
0
#define characterDataHandler (parser->m_characterDataHandler)
573
#define processingInstructionHandler \
574
0
        (parser->m_processingInstructionHandler)
575
0
#define commentHandler (parser->m_commentHandler)
576
#define startCdataSectionHandler \
577
0
        (parser->m_startCdataSectionHandler)
578
0
#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
579
0
#define defaultHandler (parser->m_defaultHandler)
580
0
#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
581
0
#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
582
#define unparsedEntityDeclHandler \
583
0
        (parser->m_unparsedEntityDeclHandler)
584
0
#define notationDeclHandler (parser->m_notationDeclHandler)
585
#define startNamespaceDeclHandler \
586
0
        (parser->m_startNamespaceDeclHandler)
587
0
#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
588
0
#define notStandaloneHandler (parser->m_notStandaloneHandler)
589
#define externalEntityRefHandler \
590
0
        (parser->m_externalEntityRefHandler)
591
#define externalEntityRefHandlerArg \
592
0
        (parser->m_externalEntityRefHandlerArg)
593
#define internalEntityRefHandler \
594
        (parser->m_internalEntityRefHandler)
595
0
#define skippedEntityHandler (parser->m_skippedEntityHandler)
596
0
#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
597
0
#define elementDeclHandler (parser->m_elementDeclHandler)
598
0
#define attlistDeclHandler (parser->m_attlistDeclHandler)
599
0
#define entityDeclHandler (parser->m_entityDeclHandler)
600
0
#define xmlDeclHandler (parser->m_xmlDeclHandler)
601
0
#define encoding (parser->m_encoding)
602
0
#define initEncoding (parser->m_initEncoding)
603
0
#define internalEncoding (parser->m_internalEncoding)
604
0
#define unknownEncodingMem (parser->m_unknownEncodingMem)
605
0
#define unknownEncodingData (parser->m_unknownEncodingData)
606
#define unknownEncodingHandlerData \
607
0
  (parser->m_unknownEncodingHandlerData)
608
0
#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
609
0
#define protocolEncodingName (parser->m_protocolEncodingName)
610
0
#define ns (parser->m_ns)
611
0
#define ns_triplets (parser->m_ns_triplets)
612
0
#define prologState (parser->m_prologState)
613
0
#define processor (parser->m_processor)
614
0
#define errorCode (parser->m_errorCode)
615
0
#define eventPtr (parser->m_eventPtr)
616
0
#define eventEndPtr (parser->m_eventEndPtr)
617
0
#define positionPtr (parser->m_positionPtr)
618
0
#define position (parser->m_position)
619
0
#define openInternalEntities (parser->m_openInternalEntities)
620
0
#define freeInternalEntities (parser->m_freeInternalEntities)
621
#define defaultExpandInternalEntities \
622
0
        (parser->m_defaultExpandInternalEntities)
623
0
#define tagLevel (parser->m_tagLevel)
624
0
#define buffer (parser->m_buffer)
625
0
#define bufferPtr (parser->m_bufferPtr)
626
0
#define bufferEnd (parser->m_bufferEnd)
627
0
#define parseEndByteIndex (parser->m_parseEndByteIndex)
628
0
#define parseEndPtr (parser->m_parseEndPtr)
629
0
#define bufferLim (parser->m_bufferLim)
630
0
#define dataBuf (parser->m_dataBuf)
631
0
#define dataBufEnd (parser->m_dataBufEnd)
632
0
#define _dtd (parser->m_dtd)
633
0
#define curBase (parser->m_curBase)
634
0
#define declEntity (parser->m_declEntity)
635
0
#define doctypeName (parser->m_doctypeName)
636
0
#define doctypeSysid (parser->m_doctypeSysid)
637
0
#define doctypePubid (parser->m_doctypePubid)
638
0
#define declAttributeType (parser->m_declAttributeType)
639
0
#define declNotationName (parser->m_declNotationName)
640
0
#define declNotationPublicId (parser->m_declNotationPublicId)
641
0
#define declElementType (parser->m_declElementType)
642
0
#define declAttributeId (parser->m_declAttributeId)
643
0
#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
644
0
#define declAttributeIsId (parser->m_declAttributeIsId)
645
0
#define freeTagList (parser->m_freeTagList)
646
0
#define freeBindingList (parser->m_freeBindingList)
647
0
#define inheritedBindings (parser->m_inheritedBindings)
648
0
#define tagStack (parser->m_tagStack)
649
0
#define atts (parser->m_atts)
650
0
#define attsSize (parser->m_attsSize)
651
0
#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
652
0
#define idAttIndex (parser->m_idAttIndex)
653
0
#define nsAtts (parser->m_nsAtts)
654
0
#define nsAttsVersion (parser->m_nsAttsVersion)
655
0
#define nsAttsPower (parser->m_nsAttsPower)
656
0
#define tempPool (parser->m_tempPool)
657
0
#define temp2Pool (parser->m_temp2Pool)
658
0
#define groupConnector (parser->m_groupConnector)
659
0
#define groupSize (parser->m_groupSize)
660
0
#define namespaceSeparator (parser->m_namespaceSeparator)
661
0
#define parentParser (parser->m_parentParser)
662
0
#define ps_parsing (parser->m_parsingStatus.parsing)
663
0
#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
664
#ifdef XML_DTD
665
0
#define isParamEntity (parser->m_isParamEntity)
666
0
#define useForeignDTD (parser->m_useForeignDTD)
667
0
#define paramEntityParsing (parser->m_paramEntityParsing)
668
#endif /* XML_DTD */
669
/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
670
0
#define mismatch (parser->m_mismatch)
671
/* END MOZILLA CHANGE */
672
673
/* BEGIN MOZILLA CHANGE (unused API) */
674
#if 0
675
XML_Parser XMLCALL
676
XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
677
{
678
  XML_Char tmp[2];
679
  *tmp = nsSep;
680
  return XML_ParserCreate_MM(encodingName, NULL, tmp);
681
}
682
#endif
683
/* END MOZILLA CHANGE */
684
685
static const XML_Char implicitContext[] = {
686
  'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
687
  'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
688
  'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
689
  'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
690
};
691
692
XML_Parser XMLCALL
693
XML_ParserCreate_MM(const XML_Char *encodingName,
694
                    const XML_Memory_Handling_Suite *memsuite,
695
                    const XML_Char *nameSep)
696
0
{
697
0
  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
698
0
  if (parser != NULL && ns) {
699
0
    /* implicit context only set for root parser, since child
700
0
       parsers (i.e. external entity parsers) will inherit it
701
0
    */
702
0
    if (!setContext(parser, implicitContext)) {
703
0
      XML_ParserFree(parser);
704
0
      return NULL;
705
0
    }
706
0
  }
707
0
  return parser;
708
0
}
709
710
static XML_Parser
711
parserCreate(const XML_Char *encodingName,
712
             const XML_Memory_Handling_Suite *memsuite,
713
             const XML_Char *nameSep,
714
             DTD *dtd)
715
0
{
716
0
  XML_Parser parser;
717
0
718
0
  if (memsuite) {
719
0
    XML_Memory_Handling_Suite *mtemp;
720
0
    parser = (XML_Parser)
721
0
      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
722
0
    if (parser != NULL) {
723
0
      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
724
0
      mtemp->malloc_fcn = memsuite->malloc_fcn;
725
0
      mtemp->realloc_fcn = memsuite->realloc_fcn;
726
0
      mtemp->free_fcn = memsuite->free_fcn;
727
0
    }
728
0
  }
729
0
  else {
730
0
    XML_Memory_Handling_Suite *mtemp;
731
0
    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
732
0
    if (parser != NULL) {
733
0
      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
734
0
      mtemp->malloc_fcn = malloc;
735
0
      mtemp->realloc_fcn = realloc;
736
0
      mtemp->free_fcn = free;
737
0
    }
738
0
  }
739
0
740
0
  if (!parser)
741
0
    return parser;
742
0
743
0
  buffer = NULL;
744
0
  bufferLim = NULL;
745
0
746
0
  attsSize = INIT_ATTS_SIZE;
747
0
  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
748
0
  if (atts == NULL) {
749
0
    FREE(parser);
750
0
    return NULL;
751
0
  }
752
0
  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
753
0
  if (dataBuf == NULL) {
754
0
    FREE(atts);
755
0
    FREE(parser);
756
0
    return NULL;
757
0
  }
758
0
  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
759
0
760
0
  if (dtd)
761
0
    _dtd = dtd;
762
0
  else {
763
0
    _dtd = dtdCreate(&parser->m_mem);
764
0
    if (_dtd == NULL) {
765
0
      FREE(dataBuf);
766
0
      FREE(atts);
767
0
      FREE(parser);
768
0
      return NULL;
769
0
    }
770
0
  }
771
0
772
0
  freeBindingList = NULL;
773
0
  freeTagList = NULL;
774
0
  freeInternalEntities = NULL;
775
0
776
0
  groupSize = 0;
777
0
  groupConnector = NULL;
778
0
779
0
  unknownEncodingHandler = NULL;
780
0
  unknownEncodingHandlerData = NULL;
781
0
782
0
  namespaceSeparator = '!';
783
0
  ns = XML_FALSE;
784
0
  ns_triplets = XML_FALSE;
785
0
786
0
  nsAtts = NULL;
787
0
  nsAttsVersion = 0;
788
0
  nsAttsPower = 0;
789
0
790
0
  poolInit(&tempPool, &(parser->m_mem));
791
0
  poolInit(&temp2Pool, &(parser->m_mem));
792
0
  parserInit(parser, encodingName);
793
0
794
0
  if (encodingName && !protocolEncodingName) {
795
0
    XML_ParserFree(parser);
796
0
    return NULL;
797
0
  }
798
0
799
0
  if (nameSep) {
800
0
    ns = XML_TRUE;
801
0
    internalEncoding = XmlGetInternalEncodingNS();
802
0
    namespaceSeparator = *nameSep;
803
0
  }
804
0
  else {
805
0
    internalEncoding = XmlGetInternalEncoding();
806
0
  }
807
0
808
0
/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
809
0
  mismatch = NULL;
810
0
/* END MOZILLA CHANGE */
811
0
812
0
  return parser;
813
0
}
814
815
static void
816
parserInit(XML_Parser parser, const XML_Char *encodingName)
817
0
{
818
0
  processor = prologInitProcessor;
819
0
  XmlPrologStateInit(&prologState);
820
0
  protocolEncodingName = (encodingName != NULL
821
0
                          ? poolCopyString(&tempPool, encodingName)
822
0
                          : NULL);
823
0
  curBase = NULL;
824
0
  XmlInitEncoding(&initEncoding, &encoding, 0);
825
0
  userData = NULL;
826
0
  handlerArg = NULL;
827
0
  startElementHandler = NULL;
828
0
  endElementHandler = NULL;
829
0
  characterDataHandler = NULL;
830
0
  processingInstructionHandler = NULL;
831
0
  commentHandler = NULL;
832
0
  startCdataSectionHandler = NULL;
833
0
  endCdataSectionHandler = NULL;
834
0
  defaultHandler = NULL;
835
0
  startDoctypeDeclHandler = NULL;
836
0
  endDoctypeDeclHandler = NULL;
837
0
  unparsedEntityDeclHandler = NULL;
838
0
  notationDeclHandler = NULL;
839
0
  startNamespaceDeclHandler = NULL;
840
0
  endNamespaceDeclHandler = NULL;
841
0
  notStandaloneHandler = NULL;
842
0
  externalEntityRefHandler = NULL;
843
0
  externalEntityRefHandlerArg = parser;
844
0
  skippedEntityHandler = NULL;
845
0
  elementDeclHandler = NULL;
846
0
  attlistDeclHandler = NULL;
847
0
  entityDeclHandler = NULL;
848
0
  xmlDeclHandler = NULL;
849
0
  bufferPtr = buffer;
850
0
  bufferEnd = buffer;
851
0
  parseEndByteIndex = 0;
852
0
  parseEndPtr = NULL;
853
0
  declElementType = NULL;
854
0
  declAttributeId = NULL;
855
0
  declEntity = NULL;
856
0
  doctypeName = NULL;
857
0
  doctypeSysid = NULL;
858
0
  doctypePubid = NULL;
859
0
  declAttributeType = NULL;
860
0
  declNotationName = NULL;
861
0
  declNotationPublicId = NULL;
862
0
  declAttributeIsCdata = XML_FALSE;
863
0
  declAttributeIsId = XML_FALSE;
864
0
  memset(&position, 0, sizeof(POSITION));
865
0
  errorCode = XML_ERROR_NONE;
866
0
  eventPtr = NULL;
867
0
  eventEndPtr = NULL;
868
0
  positionPtr = NULL;
869
0
  openInternalEntities = NULL;
870
0
  defaultExpandInternalEntities = XML_TRUE;
871
0
  tagLevel = 0;
872
0
  tagStack = NULL;
873
0
  inheritedBindings = NULL;
874
0
  nSpecifiedAtts = 0;
875
0
  unknownEncodingMem = NULL;
876
0
  unknownEncodingRelease = NULL;
877
0
  unknownEncodingData = NULL;
878
0
  parentParser = NULL;
879
0
  ps_parsing = XML_INITIALIZED;
880
0
#ifdef XML_DTD
881
0
  isParamEntity = XML_FALSE;
882
0
  useForeignDTD = XML_FALSE;
883
0
  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
884
0
#endif
885
0
}
886
887
/* BEGIN MOZILLA CHANGE (unused API) */
888
#if 0
889
/* moves list of bindings to freeBindingList */
890
static void FASTCALL
891
moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
892
{
893
  while (bindings) {
894
    BINDING *b = bindings;
895
    bindings = bindings->nextTagBinding;
896
    b->nextTagBinding = freeBindingList;
897
    freeBindingList = b;
898
  }
899
}
900
901
XML_Bool XMLCALL
902
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
903
{
904
  TAG *tStk;
905
  OPEN_INTERNAL_ENTITY *openEntityList;
906
  if (parentParser)
907
    return XML_FALSE;
908
  /* move tagStack to freeTagList */
909
  tStk = tagStack;
910
  while (tStk) {
911
    TAG *tag = tStk;
912
    tStk = tStk->parent;
913
    tag->parent = freeTagList;
914
    moveToFreeBindingList(parser, tag->bindings);
915
    tag->bindings = NULL;
916
    freeTagList = tag;
917
  }
918
  /* move openInternalEntities to freeInternalEntities */
919
  openEntityList = openInternalEntities;
920
  while (openEntityList) {
921
    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
922
    openEntityList = openEntity->next;
923
    openEntity->next = freeInternalEntities;
924
    freeInternalEntities = openEntity;
925
  }
926
  moveToFreeBindingList(parser, inheritedBindings);
927
  FREE(unknownEncodingMem);
928
  if (unknownEncodingRelease)
929
    unknownEncodingRelease(unknownEncodingData);
930
  poolClear(&tempPool);
931
  poolClear(&temp2Pool);
932
  parserInit(parser, encodingName);
933
  dtdReset(_dtd, &parser->m_mem);
934
  return setContext(parser, implicitContext);
935
}
936
937
enum XML_Status XMLCALL
938
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
939
{
940
  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
941
     XXX There's no way for the caller to determine which of the
942
     XXX possible error cases caused the XML_STATUS_ERROR return.
943
  */
944
  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
945
    return XML_STATUS_ERROR;
946
  if (encodingName == NULL)
947
    protocolEncodingName = NULL;
948
  else {
949
    protocolEncodingName = poolCopyString(&tempPool, encodingName);
950
    if (!protocolEncodingName)
951
      return XML_STATUS_ERROR;
952
  }
953
  return XML_STATUS_OK;
954
}
955
#endif
956
/* END MOZILLA CHANGE */
957
958
XML_Parser XMLCALL
959
XML_ExternalEntityParserCreate(XML_Parser oldParser,
960
                               const XML_Char *context,
961
                               const XML_Char *encodingName)
962
0
{
963
0
  XML_Parser parser = oldParser;
964
0
  DTD *newDtd = NULL;
965
0
  DTD *oldDtd = _dtd;
966
0
  XML_StartElementHandler oldStartElementHandler = startElementHandler;
967
0
  XML_EndElementHandler oldEndElementHandler = endElementHandler;
968
0
  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
969
0
  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
970
0
      = processingInstructionHandler;
971
0
  XML_CommentHandler oldCommentHandler = commentHandler;
972
0
  XML_StartCdataSectionHandler oldStartCdataSectionHandler
973
0
      = startCdataSectionHandler;
974
0
  XML_EndCdataSectionHandler oldEndCdataSectionHandler
975
0
      = endCdataSectionHandler;
976
0
  XML_DefaultHandler oldDefaultHandler = defaultHandler;
977
0
  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
978
0
      = unparsedEntityDeclHandler;
979
0
  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
980
0
  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
981
0
      = startNamespaceDeclHandler;
982
0
  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
983
0
      = endNamespaceDeclHandler;
984
0
  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
985
0
  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
986
0
      = externalEntityRefHandler;
987
0
  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
988
0
  XML_UnknownEncodingHandler oldUnknownEncodingHandler
989
0
      = unknownEncodingHandler;
990
0
  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
991
0
  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
992
0
  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
993
0
  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
994
0
  ELEMENT_TYPE * oldDeclElementType = declElementType;
995
0
996
0
  void *oldUserData = userData;
997
0
  void *oldHandlerArg = handlerArg;
998
0
  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
999
0
  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
1000
0
#ifdef XML_DTD
1001
0
  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
1002
0
  int oldInEntityValue = prologState.inEntityValue;
1003
0
#endif
1004
0
  XML_Bool oldns_triplets = ns_triplets;
1005
0
1006
0
#ifdef XML_DTD
1007
0
  if (!context)
1008
0
    newDtd = oldDtd;
1009
0
#endif /* XML_DTD */
1010
0
1011
0
  /* Note that the magical uses of the pre-processor to make field
1012
0
     access look more like C++ require that `parser' be overwritten
1013
0
     here.  This makes this function more painful to follow than it
1014
0
     would be otherwise.
1015
0
  */
1016
0
  if (ns) {
1017
0
    XML_Char tmp[2];
1018
0
    *tmp = namespaceSeparator;
1019
0
    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1020
0
  }
1021
0
  else {
1022
0
    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1023
0
  }
1024
0
1025
0
  if (!parser)
1026
0
    return NULL;
1027
0
1028
0
  startElementHandler = oldStartElementHandler;
1029
0
  endElementHandler = oldEndElementHandler;
1030
0
  characterDataHandler = oldCharacterDataHandler;
1031
0
  processingInstructionHandler = oldProcessingInstructionHandler;
1032
0
  commentHandler = oldCommentHandler;
1033
0
  startCdataSectionHandler = oldStartCdataSectionHandler;
1034
0
  endCdataSectionHandler = oldEndCdataSectionHandler;
1035
0
  defaultHandler = oldDefaultHandler;
1036
0
  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1037
0
  notationDeclHandler = oldNotationDeclHandler;
1038
0
  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1039
0
  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1040
0
  notStandaloneHandler = oldNotStandaloneHandler;
1041
0
  externalEntityRefHandler = oldExternalEntityRefHandler;
1042
0
  skippedEntityHandler = oldSkippedEntityHandler;
1043
0
  unknownEncodingHandler = oldUnknownEncodingHandler;
1044
0
  elementDeclHandler = oldElementDeclHandler;
1045
0
  attlistDeclHandler = oldAttlistDeclHandler;
1046
0
  entityDeclHandler = oldEntityDeclHandler;
1047
0
  xmlDeclHandler = oldXmlDeclHandler;
1048
0
  declElementType = oldDeclElementType;
1049
0
  userData = oldUserData;
1050
0
  if (oldUserData == oldHandlerArg)
1051
0
    handlerArg = userData;
1052
0
  else
1053
0
    handlerArg = parser;
1054
0
  if (oldExternalEntityRefHandlerArg != oldParser)
1055
0
    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1056
0
  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1057
0
  ns_triplets = oldns_triplets;
1058
0
  parentParser = oldParser;
1059
0
#ifdef XML_DTD
1060
0
  paramEntityParsing = oldParamEntityParsing;
1061
0
  prologState.inEntityValue = oldInEntityValue;
1062
0
  if (context) {
1063
0
#endif /* XML_DTD */
1064
0
    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
1065
0
      || !setContext(parser, context)) {
1066
0
      XML_ParserFree(parser);
1067
0
      return NULL;
1068
0
    }
1069
0
    processor = externalEntityInitProcessor;
1070
0
#ifdef XML_DTD
1071
0
  }
1072
0
  else {
1073
0
    /* The DTD instance referenced by _dtd is shared between the document's
1074
0
       root parser and external PE parsers, therefore one does not need to
1075
0
       call setContext. In addition, one also *must* not call setContext,
1076
0
       because this would overwrite existing prefix->binding pointers in
1077
0
       _dtd with ones that get destroyed with the external PE parser.
1078
0
       This would leave those prefixes with dangling pointers.
1079
0
    */
1080
0
    isParamEntity = XML_TRUE;
1081
0
    XmlPrologStateInitExternalEntity(&prologState);
1082
0
    processor = externalParEntInitProcessor;
1083
0
  }
1084
0
#endif /* XML_DTD */
1085
0
  return parser;
1086
0
}
1087
1088
static void FASTCALL
1089
destroyBindings(BINDING *bindings, XML_Parser parser)
1090
0
{
1091
0
  for (;;) {
1092
0
    BINDING *b = bindings;
1093
0
    if (!b)
1094
0
      break;
1095
0
    bindings = b->nextTagBinding;
1096
0
    FREE(b->uri);
1097
0
    FREE(b);
1098
0
  }
1099
0
}
1100
1101
void XMLCALL
1102
XML_ParserFree(XML_Parser parser)
1103
0
{
1104
0
  TAG *tagList;
1105
0
  OPEN_INTERNAL_ENTITY *entityList;
1106
0
  if (parser == NULL)
1107
0
    return;
1108
0
  /* free tagStack and freeTagList */
1109
0
  tagList = tagStack;
1110
0
  for (;;) {
1111
0
    TAG *p;
1112
0
    if (tagList == NULL) {
1113
0
      if (freeTagList == NULL)
1114
0
        break;
1115
0
      tagList = freeTagList;
1116
0
      freeTagList = NULL;
1117
0
    }
1118
0
    p = tagList;
1119
0
    tagList = tagList->parent;
1120
0
    FREE(p->buf);
1121
0
    destroyBindings(p->bindings, parser);
1122
0
    FREE(p);
1123
0
  }
1124
0
  /* free openInternalEntities and freeInternalEntities */
1125
0
  entityList = openInternalEntities;
1126
0
  for (;;) {
1127
0
    OPEN_INTERNAL_ENTITY *openEntity;
1128
0
    if (entityList == NULL) {
1129
0
      if (freeInternalEntities == NULL)
1130
0
        break;
1131
0
      entityList = freeInternalEntities;
1132
0
      freeInternalEntities = NULL;
1133
0
    }
1134
0
    openEntity = entityList;
1135
0
    entityList = entityList->next;
1136
0
    FREE(openEntity);
1137
0
  }
1138
0
1139
0
  destroyBindings(freeBindingList, parser);
1140
0
  destroyBindings(inheritedBindings, parser);
1141
0
  poolDestroy(&tempPool);
1142
0
  poolDestroy(&temp2Pool);
1143
0
#ifdef XML_DTD
1144
0
  /* external parameter entity parsers share the DTD structure
1145
0
     parser->m_dtd with the root parser, so we must not destroy it
1146
0
  */
1147
0
  if (!isParamEntity && _dtd)
1148
#else
1149
  if (_dtd)
1150
#endif /* XML_DTD */
1151
0
    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1152
0
  FREE((void *)atts);
1153
0
  FREE(groupConnector);
1154
0
  FREE(buffer);
1155
0
  FREE(dataBuf);
1156
0
  FREE(nsAtts);
1157
0
  FREE(unknownEncodingMem);
1158
0
  if (unknownEncodingRelease)
1159
0
    unknownEncodingRelease(unknownEncodingData);
1160
0
  FREE(parser);
1161
0
}
1162
1163
void XMLCALL
1164
XML_UseParserAsHandlerArg(XML_Parser parser)
1165
0
{
1166
0
  handlerArg = parser;
1167
0
}
1168
1169
/* BEGIN MOZILLA CHANGE (unused API) */
1170
#if 0
1171
enum XML_Error XMLCALL
1172
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1173
{
1174
#ifdef XML_DTD
1175
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1176
  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1177
    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1178
  useForeignDTD = useDTD;
1179
  return XML_ERROR_NONE;
1180
#else
1181
  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1182
#endif
1183
}
1184
#endif
1185
/* END MOZILLA CHANGE */
1186
1187
void XMLCALL
1188
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1189
0
{
1190
0
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1191
0
  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1192
0
    return;
1193
0
  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1194
0
}
1195
1196
void XMLCALL
1197
XML_SetUserData(XML_Parser parser, void *p)
1198
0
{
1199
0
  if (handlerArg == userData)
1200
0
    handlerArg = userData = p;
1201
0
  else
1202
0
    userData = p;
1203
0
}
1204
1205
enum XML_Status XMLCALL
1206
XML_SetBase(XML_Parser parser, const XML_Char *p)
1207
0
{
1208
0
  if (p) {
1209
0
    p = poolCopyString(&_dtd->pool, p);
1210
0
    if (!p)
1211
0
      return XML_STATUS_ERROR;
1212
0
    curBase = p;
1213
0
  }
1214
0
  else
1215
0
    curBase = NULL;
1216
0
  return XML_STATUS_OK;
1217
0
}
1218
1219
const XML_Char * XMLCALL
1220
XML_GetBase(XML_Parser parser)
1221
0
{
1222
0
  return curBase;
1223
0
}
1224
1225
int XMLCALL
1226
XML_GetSpecifiedAttributeCount(XML_Parser parser)
1227
0
{
1228
0
  return nSpecifiedAtts;
1229
0
}
1230
1231
int XMLCALL
1232
XML_GetIdAttributeIndex(XML_Parser parser)
1233
0
{
1234
0
  return idAttIndex;
1235
0
}
1236
1237
void XMLCALL
1238
XML_SetElementHandler(XML_Parser parser,
1239
                      XML_StartElementHandler start,
1240
                      XML_EndElementHandler end)
1241
0
{
1242
0
  startElementHandler = start;
1243
0
  endElementHandler = end;
1244
0
}
1245
1246
/* BEGIN MOZILLA CHANGE (unused API) */
1247
#if 0
1248
void XMLCALL
1249
XML_SetStartElementHandler(XML_Parser parser,
1250
                           XML_StartElementHandler start) {
1251
  startElementHandler = start;
1252
}
1253
1254
void XMLCALL
1255
XML_SetEndElementHandler(XML_Parser parser,
1256
                         XML_EndElementHandler end) {
1257
  endElementHandler = end;
1258
}
1259
#endif
1260
/* END MOZILLA CHANGE */
1261
1262
void XMLCALL
1263
XML_SetCharacterDataHandler(XML_Parser parser,
1264
                            XML_CharacterDataHandler handler)
1265
0
{
1266
0
  characterDataHandler = handler;
1267
0
}
1268
1269
void XMLCALL
1270
XML_SetProcessingInstructionHandler(XML_Parser parser,
1271
                                    XML_ProcessingInstructionHandler handler)
1272
0
{
1273
0
  processingInstructionHandler = handler;
1274
0
}
1275
1276
void XMLCALL
1277
XML_SetCommentHandler(XML_Parser parser,
1278
                      XML_CommentHandler handler)
1279
0
{
1280
0
  commentHandler = handler;
1281
0
}
1282
1283
void XMLCALL
1284
XML_SetCdataSectionHandler(XML_Parser parser,
1285
                           XML_StartCdataSectionHandler start,
1286
                           XML_EndCdataSectionHandler end)
1287
0
{
1288
0
  startCdataSectionHandler = start;
1289
0
  endCdataSectionHandler = end;
1290
0
}
1291
1292
/* BEGIN MOZILLA CHANGE (unused API) */
1293
#if 0
1294
void XMLCALL
1295
XML_SetStartCdataSectionHandler(XML_Parser parser,
1296
                                XML_StartCdataSectionHandler start) {
1297
  startCdataSectionHandler = start;
1298
}
1299
1300
void XMLCALL
1301
XML_SetEndCdataSectionHandler(XML_Parser parser,
1302
                              XML_EndCdataSectionHandler end) {
1303
  endCdataSectionHandler = end;
1304
}
1305
1306
void XMLCALL
1307
XML_SetDefaultHandler(XML_Parser parser,
1308
                      XML_DefaultHandler handler)
1309
{
1310
  defaultHandler = handler;
1311
  defaultExpandInternalEntities = XML_FALSE;
1312
}
1313
#endif
1314
/* END MOZILLA CHANGE */
1315
1316
void XMLCALL
1317
XML_SetDefaultHandlerExpand(XML_Parser parser,
1318
                            XML_DefaultHandler handler)
1319
0
{
1320
0
  defaultHandler = handler;
1321
0
  defaultExpandInternalEntities = XML_TRUE;
1322
0
}
1323
1324
void XMLCALL
1325
XML_SetDoctypeDeclHandler(XML_Parser parser,
1326
                          XML_StartDoctypeDeclHandler start,
1327
                          XML_EndDoctypeDeclHandler end)
1328
0
{
1329
0
  startDoctypeDeclHandler = start;
1330
0
  endDoctypeDeclHandler = end;
1331
0
}
1332
1333
/* BEGIN MOZILLA CHANGE (unused API) */
1334
#if 0
1335
void XMLCALL
1336
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1337
                               XML_StartDoctypeDeclHandler start) {
1338
  startDoctypeDeclHandler = start;
1339
}
1340
1341
void XMLCALL
1342
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1343
                             XML_EndDoctypeDeclHandler end) {
1344
  endDoctypeDeclHandler = end;
1345
}
1346
#endif
1347
/* END MOZILLA CHANGE */
1348
1349
void XMLCALL
1350
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1351
                                 XML_UnparsedEntityDeclHandler handler)
1352
0
{
1353
0
  unparsedEntityDeclHandler = handler;
1354
0
}
1355
1356
void XMLCALL
1357
XML_SetNotationDeclHandler(XML_Parser parser,
1358
                           XML_NotationDeclHandler handler)
1359
0
{
1360
0
  notationDeclHandler = handler;
1361
0
}
1362
1363
void XMLCALL
1364
XML_SetNamespaceDeclHandler(XML_Parser parser,
1365
                            XML_StartNamespaceDeclHandler start,
1366
                            XML_EndNamespaceDeclHandler end)
1367
0
{
1368
0
  startNamespaceDeclHandler = start;
1369
0
  endNamespaceDeclHandler = end;
1370
0
}
1371
1372
1373
/* BEGIN MOZILLA CHANGE (unused API) */
1374
#if 0
1375
void XMLCALL
1376
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1377
                                 XML_StartNamespaceDeclHandler start) {
1378
  startNamespaceDeclHandler = start;
1379
}
1380
1381
void XMLCALL
1382
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1383
                               XML_EndNamespaceDeclHandler end) {
1384
  endNamespaceDeclHandler = end;
1385
}
1386
1387
void XMLCALL
1388
XML_SetNotStandaloneHandler(XML_Parser parser,
1389
                            XML_NotStandaloneHandler handler)
1390
{
1391
  notStandaloneHandler = handler;
1392
}
1393
#endif
1394
/* END MOZILLA CHANGE */
1395
1396
void XMLCALL
1397
XML_SetExternalEntityRefHandler(XML_Parser parser,
1398
                                XML_ExternalEntityRefHandler handler)
1399
0
{
1400
0
  externalEntityRefHandler = handler;
1401
0
}
1402
1403
void XMLCALL
1404
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1405
0
{
1406
0
  if (arg)
1407
0
    externalEntityRefHandlerArg = (XML_Parser)arg;
1408
0
  else
1409
0
    externalEntityRefHandlerArg = parser;
1410
0
}
1411
1412
/* BEGIN MOZILLA CHANGE (unused API) */
1413
#if 0
1414
void XMLCALL
1415
XML_SetSkippedEntityHandler(XML_Parser parser,
1416
                            XML_SkippedEntityHandler handler)
1417
{
1418
  skippedEntityHandler = handler;
1419
}
1420
1421
void XMLCALL
1422
XML_SetUnknownEncodingHandler(XML_Parser parser,
1423
                              XML_UnknownEncodingHandler handler,
1424
                              void *data)
1425
{
1426
  unknownEncodingHandler = handler;
1427
  unknownEncodingHandlerData = data;
1428
}
1429
1430
void XMLCALL
1431
XML_SetElementDeclHandler(XML_Parser parser,
1432
                          XML_ElementDeclHandler eldecl)
1433
{
1434
  elementDeclHandler = eldecl;
1435
}
1436
1437
void XMLCALL
1438
XML_SetAttlistDeclHandler(XML_Parser parser,
1439
                          XML_AttlistDeclHandler attdecl)
1440
{
1441
  attlistDeclHandler = attdecl;
1442
}
1443
1444
void XMLCALL
1445
XML_SetEntityDeclHandler(XML_Parser parser,
1446
                         XML_EntityDeclHandler handler)
1447
{
1448
  entityDeclHandler = handler;
1449
}
1450
#endif
1451
/* END MOZILLA CHANGE */
1452
1453
void XMLCALL
1454
XML_SetXmlDeclHandler(XML_Parser parser,
1455
0
                      XML_XmlDeclHandler handler) {
1456
0
  xmlDeclHandler = handler;
1457
0
}
1458
1459
int XMLCALL
1460
XML_SetParamEntityParsing(XML_Parser parser,
1461
                          enum XML_ParamEntityParsing peParsing)
1462
0
{
1463
0
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1464
0
  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1465
0
    return 0;
1466
0
#ifdef XML_DTD
1467
0
  paramEntityParsing = peParsing;
1468
0
  return 1;
1469
#else
1470
  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1471
#endif
1472
}
1473
1474
enum XML_Status XMLCALL
1475
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1476
0
{
1477
0
  switch (ps_parsing) {
1478
0
  case XML_SUSPENDED:
1479
0
    errorCode = XML_ERROR_SUSPENDED;
1480
0
    return XML_STATUS_ERROR;
1481
0
  case XML_FINISHED:
1482
0
    errorCode = XML_ERROR_FINISHED;
1483
0
    return XML_STATUS_ERROR;
1484
0
  default:
1485
0
    ps_parsing = XML_PARSING;
1486
0
  }
1487
0
1488
0
  if (len == 0) {
1489
0
    ps_finalBuffer = (XML_Bool)isFinal;
1490
0
    if (!isFinal)
1491
0
      return XML_STATUS_OK;
1492
0
    positionPtr = bufferPtr;
1493
0
    parseEndPtr = bufferEnd;
1494
0
1495
0
    /* If data are left over from last buffer, and we now know that these
1496
0
       data are the final chunk of input, then we have to check them again
1497
0
       to detect errors based on that fact.
1498
0
    */
1499
0
    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1500
0
1501
0
    if (errorCode == XML_ERROR_NONE) {
1502
0
      switch (ps_parsing) {
1503
0
      case XML_SUSPENDED:
1504
0
        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1505
0
        positionPtr = bufferPtr;
1506
0
        return XML_STATUS_SUSPENDED;
1507
0
      case XML_INITIALIZED: 
1508
0
      case XML_PARSING:
1509
0
        ps_parsing = XML_FINISHED;
1510
0
        /* fall through */
1511
0
      default:
1512
0
        return XML_STATUS_OK;
1513
0
      }
1514
0
    }
1515
0
    eventEndPtr = eventPtr;
1516
0
    processor = errorProcessor;
1517
0
    return XML_STATUS_ERROR;
1518
0
  }
1519
0
#ifndef XML_CONTEXT_BYTES
1520
0
  else if (bufferPtr == bufferEnd) {
1521
0
    const char *end;
1522
0
    int nLeftOver;
1523
0
/* BEGIN MOZILLA CHANGE (|result| has type XML_Status, not XML_Error) */
1524
0
    enum XML_Status result;
1525
0
/* END MOZILLA CHANGE */
1526
0
    parseEndByteIndex += len;
1527
0
    positionPtr = s;
1528
0
    ps_finalBuffer = (XML_Bool)isFinal;
1529
0
1530
0
    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1531
0
1532
0
    if (errorCode != XML_ERROR_NONE) {
1533
0
      eventEndPtr = eventPtr;
1534
0
      processor = errorProcessor;
1535
0
      return XML_STATUS_ERROR;
1536
0
    }
1537
0
    else {
1538
0
      switch (ps_parsing) {
1539
0
      case XML_SUSPENDED:
1540
0
        result = XML_STATUS_SUSPENDED;
1541
0
        break;
1542
0
      case XML_INITIALIZED:
1543
0
      case XML_PARSING:
1544
0
/* BEGIN MOZILLA CHANGE (always initialize result) */
1545
#if 0
1546
        result = XML_STATUS_OK;
1547
        if (isFinal) {
1548
          ps_parsing = XML_FINISHED;
1549
          return result;
1550
        }
1551
#else
1552
0
        if (isFinal) {
1553
0
          ps_parsing = XML_FINISHED;
1554
0
          return XML_STATUS_OK;
1555
0
        }
1556
0
      /* fall through */
1557
0
      default:
1558
0
        result = XML_STATUS_OK;
1559
0
#endif
1560
0
/* END MOZILLA CHANGE */
1561
0
      }
1562
0
    }
1563
0
1564
0
    XmlUpdatePosition(encoding, positionPtr, end, &position);
1565
0
    nLeftOver = s + len - end;
1566
0
    if (nLeftOver) {
1567
0
      if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1568
0
/* BEGIN MOZILLA CHANGE (check for overflow) */
1569
#if 0
1570
        /* FIXME avoid integer overflow */
1571
        char *temp;
1572
        temp = (buffer == NULL
1573
                ? (char *)MALLOC(len * 2)
1574
                : (char *)REALLOC(buffer, len * 2));
1575
        if (temp == NULL) {
1576
          errorCode = XML_ERROR_NO_MEMORY;
1577
          return XML_STATUS_ERROR;
1578
        }
1579
        buffer = temp;
1580
        if (!buffer) {
1581
          errorCode = XML_ERROR_NO_MEMORY;
1582
          eventPtr = eventEndPtr = NULL;
1583
          processor = errorProcessor;
1584
          return XML_STATUS_ERROR;
1585
        }
1586
        bufferLim = buffer + len * 2;
1587
#else
1588
        char *temp;
1589
0
        int newLen = len * 2;
1590
0
        if (newLen < 0) {
1591
0
          errorCode = XML_ERROR_NO_MEMORY;
1592
0
          return XML_STATUS_ERROR;
1593
0
        }
1594
0
        temp = (buffer == NULL
1595
0
                ? (char *)MALLOC(newLen)
1596
0
                : (char *)REALLOC(buffer, newLen));
1597
0
        if (temp == NULL) {
1598
0
          errorCode = XML_ERROR_NO_MEMORY;
1599
0
          return XML_STATUS_ERROR;
1600
0
        }
1601
0
        buffer = temp;
1602
0
        if (!buffer) {
1603
0
          errorCode = XML_ERROR_NO_MEMORY;
1604
0
          eventPtr = eventEndPtr = NULL;
1605
0
          processor = errorProcessor;
1606
0
          return XML_STATUS_ERROR;
1607
0
        }
1608
0
        bufferLim = buffer + newLen;
1609
0
#endif
1610
0
/* END MOZILLA CHANGE */
1611
0
      }
1612
0
      memcpy(buffer, end, nLeftOver);
1613
0
    }
1614
0
    bufferPtr = buffer;
1615
0
    bufferEnd = buffer + nLeftOver;
1616
0
    positionPtr = bufferPtr;
1617
0
    parseEndPtr = bufferEnd;
1618
0
    eventPtr = bufferPtr;
1619
0
    eventEndPtr = bufferPtr;
1620
0
    return result;
1621
0
  }
1622
0
#endif  /* not defined XML_CONTEXT_BYTES */
1623
0
  else {
1624
0
    void *buff = XML_GetBuffer(parser, len);
1625
0
    if (buff == NULL)
1626
0
      return XML_STATUS_ERROR;
1627
0
    else {
1628
0
      memcpy(buff, s, len);
1629
0
      return XML_ParseBuffer(parser, len, isFinal);
1630
0
    }
1631
0
  }
1632
0
}
1633
1634
enum XML_Status XMLCALL
1635
XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1636
0
{
1637
0
  const char *start;
1638
0
  enum XML_Status result = XML_STATUS_OK;
1639
0
1640
0
  switch (ps_parsing) {
1641
0
  case XML_SUSPENDED:
1642
0
    errorCode = XML_ERROR_SUSPENDED;
1643
0
    return XML_STATUS_ERROR;
1644
0
  case XML_FINISHED:
1645
0
    errorCode = XML_ERROR_FINISHED;
1646
0
    return XML_STATUS_ERROR;
1647
0
  default:
1648
0
    ps_parsing = XML_PARSING;
1649
0
  }
1650
0
1651
0
  start = bufferPtr;
1652
0
  positionPtr = start;
1653
0
  bufferEnd += len;
1654
0
  parseEndPtr = bufferEnd;
1655
0
  parseEndByteIndex += len;
1656
0
  ps_finalBuffer = (XML_Bool)isFinal;
1657
0
1658
0
  errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1659
0
1660
0
  if (errorCode != XML_ERROR_NONE) {
1661
0
    eventEndPtr = eventPtr;
1662
0
    processor = errorProcessor;
1663
0
    return XML_STATUS_ERROR;
1664
0
  }
1665
0
  else {
1666
0
    switch (ps_parsing) {
1667
0
    case XML_SUSPENDED:
1668
0
      result = XML_STATUS_SUSPENDED;
1669
0
      break;
1670
0
    case XML_INITIALIZED: 
1671
0
    case XML_PARSING:
1672
0
      if (isFinal) {
1673
0
        ps_parsing = XML_FINISHED;
1674
0
        return result;
1675
0
      }
1676
0
    default: ;  /* should not happen */
1677
0
    }
1678
0
  }
1679
0
1680
0
  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1681
0
  positionPtr = bufferPtr;
1682
0
  return result;
1683
0
}
1684
1685
void * XMLCALL
1686
XML_GetBuffer(XML_Parser parser, int len)
1687
0
{
1688
0
/* BEGIN MOZILLA CHANGE (sanity check len) */
1689
0
  if (len < 0) {
1690
0
    errorCode = XML_ERROR_NO_MEMORY;
1691
0
    return NULL;
1692
0
  }
1693
0
/* END MOZILLA CHANGE */
1694
0
  switch (ps_parsing) {
1695
0
  case XML_SUSPENDED:
1696
0
    errorCode = XML_ERROR_SUSPENDED;
1697
0
    return NULL;
1698
0
  case XML_FINISHED:
1699
0
    errorCode = XML_ERROR_FINISHED;
1700
0
    return NULL;
1701
0
  default: ;
1702
0
  }
1703
0
1704
0
  if (len > bufferLim - bufferEnd) {
1705
0
    int neededSize = len + (int)(bufferEnd - bufferPtr);
1706
0
/* BEGIN MOZILLA CHANGE (sanity check neededSize) */
1707
0
    if (neededSize < 0) {
1708
0
      errorCode = XML_ERROR_NO_MEMORY;
1709
0
      return NULL;
1710
0
    }
1711
0
/* END MOZILLA CHANGE */
1712
#ifdef XML_CONTEXT_BYTES
1713
    int keep = (int)(bufferPtr - buffer);
1714
1715
    if (keep > XML_CONTEXT_BYTES)
1716
      keep = XML_CONTEXT_BYTES;
1717
    neededSize += keep;
1718
#endif  /* defined XML_CONTEXT_BYTES */
1719
0
    if (neededSize  <= bufferLim - buffer) {
1720
#ifdef XML_CONTEXT_BYTES
1721
      if (keep < bufferPtr - buffer) {
1722
        int offset = (int)(bufferPtr - buffer) - keep;
1723
        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1724
        bufferEnd -= offset;
1725
        bufferPtr -= offset;
1726
      }
1727
#else
1728
0
      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1729
0
      bufferEnd = buffer + (bufferEnd - bufferPtr);
1730
0
      bufferPtr = buffer;
1731
0
#endif  /* not defined XML_CONTEXT_BYTES */
1732
0
    }
1733
0
    else {
1734
0
      char *newBuf;
1735
0
      int bufferSize = (int)(bufferLim - bufferPtr);
1736
0
      if (bufferSize == 0)
1737
0
        bufferSize = INIT_BUFFER_SIZE;
1738
0
      do {
1739
0
        bufferSize *= 2;
1740
0
/* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */
1741
0
      } while (bufferSize < neededSize && bufferSize > 0);
1742
0
/* END MOZILLA CHANGE */
1743
0
/* BEGIN MOZILLA CHANGE (sanity check bufferSize) */
1744
0
      if (bufferSize <= 0) {
1745
0
        errorCode = XML_ERROR_NO_MEMORY;
1746
0
        return NULL;
1747
0
      }
1748
0
/* END MOZILLA CHANGE */
1749
0
      newBuf = (char *)MALLOC(bufferSize);
1750
0
      if (newBuf == 0) {
1751
0
        errorCode = XML_ERROR_NO_MEMORY;
1752
0
        return NULL;
1753
0
      }
1754
0
      bufferLim = newBuf + bufferSize;
1755
#ifdef XML_CONTEXT_BYTES
1756
      if (bufferPtr) {
1757
        int keep = (int)(bufferPtr - buffer);
1758
        if (keep > XML_CONTEXT_BYTES)
1759
          keep = XML_CONTEXT_BYTES;
1760
        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1761
        FREE(buffer);
1762
        buffer = newBuf;
1763
        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1764
        bufferPtr = buffer + keep;
1765
      }
1766
      else {
1767
        bufferEnd = newBuf + (bufferEnd - bufferPtr);
1768
        bufferPtr = buffer = newBuf;
1769
      }
1770
#else
1771
0
      if (bufferPtr) {
1772
0
        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1773
0
        FREE(buffer);
1774
0
      }
1775
0
      bufferEnd = newBuf + (bufferEnd - bufferPtr);
1776
0
      bufferPtr = buffer = newBuf;
1777
0
#endif  /* not defined XML_CONTEXT_BYTES */
1778
0
    }
1779
0
  }
1780
0
  return bufferEnd;
1781
0
}
1782
1783
enum XML_Status XMLCALL
1784
XML_StopParser(XML_Parser parser, XML_Bool resumable)
1785
0
{
1786
0
  switch (ps_parsing) {
1787
0
  case XML_SUSPENDED:
1788
0
    if (resumable) {
1789
0
      errorCode = XML_ERROR_SUSPENDED;
1790
0
      return XML_STATUS_ERROR;
1791
0
    }
1792
0
    ps_parsing = XML_FINISHED;
1793
0
    break;
1794
0
  case XML_FINISHED:
1795
0
    errorCode = XML_ERROR_FINISHED;
1796
0
    return XML_STATUS_ERROR;
1797
0
  default:
1798
0
    if (resumable) {
1799
0
#ifdef XML_DTD
1800
0
      if (isParamEntity) {
1801
0
        errorCode = XML_ERROR_SUSPEND_PE;
1802
0
        return XML_STATUS_ERROR;
1803
0
      }
1804
0
#endif
1805
0
      ps_parsing = XML_SUSPENDED;
1806
0
    }
1807
0
    else
1808
0
      ps_parsing = XML_FINISHED;
1809
0
  }
1810
0
  return XML_STATUS_OK;
1811
0
}
1812
1813
enum XML_Status XMLCALL
1814
XML_ResumeParser(XML_Parser parser)
1815
0
{
1816
0
  enum XML_Status result = XML_STATUS_OK;
1817
0
1818
0
  if (ps_parsing != XML_SUSPENDED) {
1819
0
    errorCode = XML_ERROR_NOT_SUSPENDED;
1820
0
    return XML_STATUS_ERROR;
1821
0
  }
1822
0
  ps_parsing = XML_PARSING;
1823
0
1824
0
  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1825
0
1826
0
  if (errorCode != XML_ERROR_NONE) {
1827
0
    eventEndPtr = eventPtr;
1828
0
    processor = errorProcessor;
1829
0
    return XML_STATUS_ERROR;
1830
0
  }
1831
0
  else {
1832
0
    switch (ps_parsing) {
1833
0
    case XML_SUSPENDED:
1834
0
      result = XML_STATUS_SUSPENDED;
1835
0
      break;
1836
0
    case XML_INITIALIZED: 
1837
0
    case XML_PARSING:
1838
0
      if (ps_finalBuffer) {
1839
0
        ps_parsing = XML_FINISHED;
1840
0
        return result;
1841
0
      }
1842
0
    default: ;
1843
0
    }
1844
0
  }
1845
0
1846
0
  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1847
0
  positionPtr = bufferPtr;
1848
0
/* BEGIN MOZILLA CHANGE (always set eventPtr/eventEndPtr) */
1849
0
  eventPtr = bufferPtr;
1850
0
  eventEndPtr = bufferPtr;
1851
0
/* END MOZILLA CHANGE */
1852
0
  return result;
1853
0
}
1854
1855
void XMLCALL
1856
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1857
0
{
1858
0
  assert(status != NULL);
1859
0
  *status = parser->m_parsingStatus;
1860
0
}
1861
1862
enum XML_Error XMLCALL
1863
XML_GetErrorCode(XML_Parser parser)
1864
0
{
1865
0
  return errorCode;
1866
0
}
1867
1868
XML_Index XMLCALL
1869
XML_GetCurrentByteIndex(XML_Parser parser)
1870
0
{
1871
0
  if (eventPtr)
1872
0
    return parseEndByteIndex - (parseEndPtr - eventPtr);
1873
0
/* BEGIN MOZILLA CHANGE (fix XML_GetCurrentByteIndex) */
1874
#if 0
1875
  return -1;
1876
#else
1877
0
  return parseEndByteIndex;
1878
0
#endif
1879
0
/* END MOZILLA CHANGE */
1880
0
}
1881
1882
/* BEGIN MOZILLA CHANGE (unused API) */
1883
#if 0
1884
int XMLCALL
1885
XML_GetCurrentByteCount(XML_Parser parser)
1886
{
1887
  if (eventEndPtr && eventPtr)
1888
    return (int)(eventEndPtr - eventPtr);
1889
  return 0;
1890
}
1891
1892
const char * XMLCALL
1893
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1894
{
1895
#ifdef XML_CONTEXT_BYTES
1896
  if (eventPtr && buffer) {
1897
    *offset = (int)(eventPtr - buffer);
1898
    *size   = (int)(bufferEnd - buffer);
1899
    return buffer;
1900
  }
1901
#endif /* defined XML_CONTEXT_BYTES */
1902
  return (char *) 0;
1903
}
1904
#endif
1905
/* END MOZILLA CHANGE */
1906
1907
XML_Size XMLCALL
1908
XML_GetCurrentLineNumber(XML_Parser parser)
1909
0
{
1910
0
  if (eventPtr && eventPtr >= positionPtr) {
1911
0
    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1912
0
    positionPtr = eventPtr;
1913
0
  }
1914
0
  return position.lineNumber + 1;
1915
0
}
1916
1917
XML_Size XMLCALL
1918
XML_GetCurrentColumnNumber(XML_Parser parser)
1919
0
{
1920
0
  if (eventPtr && eventPtr >= positionPtr) {
1921
0
    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1922
0
    positionPtr = eventPtr;
1923
0
  }
1924
0
  return position.columnNumber;
1925
0
}
1926
1927
/* BEGIN MOZILLA CHANGE (unused API) */
1928
#if 0
1929
void XMLCALL
1930
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1931
{
1932
  FREE(model);
1933
}
1934
1935
void * XMLCALL
1936
XML_MemMalloc(XML_Parser parser, size_t size)
1937
{
1938
  return MALLOC(size);
1939
}
1940
1941
void * XMLCALL
1942
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1943
{
1944
  return REALLOC(ptr, size);
1945
}
1946
1947
void XMLCALL
1948
XML_MemFree(XML_Parser parser, void *ptr)
1949
{
1950
  FREE(ptr);
1951
}
1952
1953
void XMLCALL
1954
XML_DefaultCurrent(XML_Parser parser)
1955
{
1956
  if (defaultHandler) {
1957
    if (openInternalEntities)
1958
      reportDefault(parser,
1959
                    internalEncoding,
1960
                    openInternalEntities->internalEventPtr,
1961
                    openInternalEntities->internalEventEndPtr);
1962
    else
1963
      reportDefault(parser, encoding, eventPtr, eventEndPtr);
1964
  }
1965
}
1966
1967
const XML_LChar * XMLCALL
1968
XML_ExpatVersion(void) {
1969
1970
  /* V1 is used to string-ize the version number. However, it would
1971
     string-ize the actual version macro *names* unless we get them
1972
     substituted before being passed to V1. CPP is defined to expand
1973
     a macro, then rescan for more expansions. Thus, we use V2 to expand
1974
     the version macros, then CPP will expand the resulting V1() macro
1975
     with the correct numerals. */
1976
  /* ### I'm assuming cpp is portable in this respect... */
1977
1978
#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1979
#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1980
1981
  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1982
1983
#undef V1
1984
#undef V2
1985
}
1986
1987
XML_Expat_Version XMLCALL
1988
XML_ExpatVersionInfo(void)
1989
{
1990
  XML_Expat_Version version;
1991
1992
  version.major = XML_MAJOR_VERSION;
1993
  version.minor = XML_MINOR_VERSION;
1994
  version.micro = XML_MICRO_VERSION;
1995
1996
  return version;
1997
}
1998
1999
const XML_Feature * XMLCALL
2000
XML_GetFeatureList(void)
2001
{
2002
  static const XML_Feature features[] = {
2003
    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
2004
     sizeof(XML_Char)},
2005
    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2006
     sizeof(XML_LChar)},
2007
#ifdef XML_UNICODE
2008
    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
2009
#endif
2010
#ifdef XML_UNICODE_WCHAR_T
2011
    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
2012
#endif
2013
#ifdef XML_DTD
2014
    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
2015
#endif
2016
#ifdef XML_CONTEXT_BYTES
2017
    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
2018
     XML_CONTEXT_BYTES},
2019
#endif
2020
#ifdef XML_MIN_SIZE
2021
    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
2022
#endif
2023
#ifdef XML_NS
2024
    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
2025
#endif
2026
    {XML_FEATURE_END,              NULL, 0}
2027
  };
2028
2029
  return features;
2030
}
2031
#endif
2032
/* END MOZILLA CHANGE */
2033
2034
/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
2035
const XML_Char * XMLCALL
2036
MOZ_XML_GetMismatchedTag(XML_Parser parser)
2037
0
{
2038
0
  return mismatch;
2039
0
}
2040
/* END MOZILLA CHANGE */
2041
2042
/* Initially tag->rawName always points into the parse buffer;
2043
   for those TAG instances opened while the current parse buffer was
2044
   processed, and not yet closed, we need to store tag->rawName in a more
2045
   permanent location, since the parse buffer is about to be discarded.
2046
*/
2047
static XML_Bool
2048
storeRawNames(XML_Parser parser)
2049
0
{
2050
0
  TAG *tag = tagStack;
2051
0
  while (tag) {
2052
0
    int bufSize;
2053
0
    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2054
0
    char *rawNameBuf = tag->buf + nameLen;
2055
0
    /* Stop if already stored.  Since tagStack is a stack, we can stop
2056
0
       at the first entry that has already been copied; everything
2057
0
       below it in the stack is already been accounted for in a
2058
0
       previous call to this function.
2059
0
    */
2060
0
    if (tag->rawName == rawNameBuf)
2061
0
      break;
2062
0
    /* For re-use purposes we need to ensure that the
2063
0
       size of tag->buf is a multiple of sizeof(XML_Char).
2064
0
    */
2065
0
    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2066
0
    if (bufSize > tag->bufEnd - tag->buf) {
2067
0
      char *temp = (char *)REALLOC(tag->buf, bufSize);
2068
0
      if (temp == NULL)
2069
0
        return XML_FALSE;
2070
0
      /* if tag->name.str points to tag->buf (only when namespace
2071
0
         processing is off) then we have to update it
2072
0
      */
2073
0
      if (tag->name.str == (XML_Char *)tag->buf)
2074
0
        tag->name.str = (XML_Char *)temp;
2075
0
      /* if tag->name.localPart is set (when namespace processing is on)
2076
0
         then update it as well, since it will always point into tag->buf
2077
0
      */
2078
0
      if (tag->name.localPart)
2079
0
        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2080
0
                                                  (XML_Char *)tag->buf);
2081
0
      tag->buf = temp;
2082
0
      tag->bufEnd = temp + bufSize;
2083
0
      rawNameBuf = temp + nameLen;
2084
0
    }
2085
0
    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2086
0
    tag->rawName = rawNameBuf;
2087
0
    tag = tag->parent;
2088
0
  }
2089
0
  return XML_TRUE;
2090
0
}
2091
2092
static enum XML_Error PTRCALL
2093
contentProcessor(XML_Parser parser,
2094
                 const char *start,
2095
                 const char *end,
2096
                 const char **endPtr)
2097
0
{
2098
0
  enum XML_Error result = doContent(parser, 0, encoding, start, end, 
2099
0
                                    endPtr, (XML_Bool)!ps_finalBuffer);
2100
0
  if (result == XML_ERROR_NONE) {
2101
0
    if (!storeRawNames(parser))
2102
0
      return XML_ERROR_NO_MEMORY;
2103
0
  }
2104
0
  return result;
2105
0
}
2106
2107
static enum XML_Error PTRCALL
2108
externalEntityInitProcessor(XML_Parser parser,
2109
                            const char *start,
2110
                            const char *end,
2111
                            const char **endPtr)
2112
0
{
2113
0
  enum XML_Error result = initializeEncoding(parser);
2114
0
  if (result != XML_ERROR_NONE)
2115
0
    return result;
2116
0
  processor = externalEntityInitProcessor2;
2117
0
  return externalEntityInitProcessor2(parser, start, end, endPtr);
2118
0
}
2119
2120
static enum XML_Error PTRCALL
2121
externalEntityInitProcessor2(XML_Parser parser,
2122
                             const char *start,
2123
                             const char *end,
2124
                             const char **endPtr)
2125
0
{
2126
0
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
2127
0
  int tok = XmlContentTok(encoding, start, end, &next);
2128
0
  switch (tok) {
2129
0
  case XML_TOK_BOM:
2130
0
    /* If we are at the end of the buffer, this would cause the next stage,
2131
0
       i.e. externalEntityInitProcessor3, to pass control directly to
2132
0
       doContent (by detecting XML_TOK_NONE) without processing any xml text
2133
0
       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2134
0
    */
2135
0
    if (next == end && !ps_finalBuffer) {
2136
0
      *endPtr = next;
2137
0
      return XML_ERROR_NONE;
2138
0
    }
2139
0
    start = next;
2140
0
    break;
2141
0
  case XML_TOK_PARTIAL:
2142
0
    if (!ps_finalBuffer) {
2143
0
      *endPtr = start;
2144
0
      return XML_ERROR_NONE;
2145
0
    }
2146
0
    eventPtr = start;
2147
0
    return XML_ERROR_UNCLOSED_TOKEN;
2148
0
  case XML_TOK_PARTIAL_CHAR:
2149
0
    if (!ps_finalBuffer) {
2150
0
      *endPtr = start;
2151
0
      return XML_ERROR_NONE;
2152
0
    }
2153
0
    eventPtr = start;
2154
0
    return XML_ERROR_PARTIAL_CHAR;
2155
0
  }
2156
0
  processor = externalEntityInitProcessor3;
2157
0
  return externalEntityInitProcessor3(parser, start, end, endPtr);
2158
0
}
2159
2160
static enum XML_Error PTRCALL
2161
externalEntityInitProcessor3(XML_Parser parser,
2162
                             const char *start,
2163
                             const char *end,
2164
                             const char **endPtr)
2165
0
{
2166
0
  int tok;
2167
0
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
2168
0
  eventPtr = start;
2169
0
  tok = XmlContentTok(encoding, start, end, &next);
2170
0
  eventEndPtr = next;
2171
0
2172
0
  switch (tok) {
2173
0
  case XML_TOK_XML_DECL:
2174
0
    {
2175
0
      enum XML_Error result;
2176
0
      result = processXmlDecl(parser, 1, start, next);
2177
0
      if (result != XML_ERROR_NONE)
2178
0
        return result;
2179
0
      switch (ps_parsing) {
2180
0
      case XML_SUSPENDED: 
2181
0
        *endPtr = next;
2182
0
        return XML_ERROR_NONE;
2183
0
      case XML_FINISHED:
2184
0
        return XML_ERROR_ABORTED;
2185
0
      default:
2186
0
        start = next;
2187
0
      }
2188
0
    }
2189
0
    break;
2190
0
  case XML_TOK_PARTIAL:
2191
0
    if (!ps_finalBuffer) {
2192
0
      *endPtr = start;
2193
0
      return XML_ERROR_NONE;
2194
0
    }
2195
0
    return XML_ERROR_UNCLOSED_TOKEN;
2196
0
  case XML_TOK_PARTIAL_CHAR:
2197
0
    if (!ps_finalBuffer) {
2198
0
      *endPtr = start;
2199
0
      return XML_ERROR_NONE;
2200
0
    }
2201
0
    return XML_ERROR_PARTIAL_CHAR;
2202
0
  }
2203
0
  processor = externalEntityContentProcessor;
2204
0
  tagLevel = 1;
2205
0
  return externalEntityContentProcessor(parser, start, end, endPtr);
2206
0
}
2207
2208
static enum XML_Error PTRCALL
2209
externalEntityContentProcessor(XML_Parser parser,
2210
                               const char *start,
2211
                               const char *end,
2212
                               const char **endPtr)
2213
0
{
2214
0
  enum XML_Error result = doContent(parser, 1, encoding, start, end, 
2215
0
                                    endPtr, (XML_Bool)!ps_finalBuffer);
2216
0
  if (result == XML_ERROR_NONE) {
2217
0
    if (!storeRawNames(parser))
2218
0
      return XML_ERROR_NO_MEMORY;
2219
0
  }
2220
0
  return result;
2221
0
}
2222
2223
static enum XML_Error
2224
doContent(XML_Parser parser,
2225
          int startTagLevel,
2226
          const ENCODING *enc,
2227
          const char *s,
2228
          const char *end,
2229
          const char **nextPtr,
2230
          XML_Bool haveMore)
2231
0
{
2232
0
  /* save one level of indirection */
2233
0
  DTD * const dtd = _dtd;  
2234
0
2235
0
  const char **eventPP;
2236
0
  const char **eventEndPP;
2237
0
  if (enc == encoding) {
2238
0
    eventPP = &eventPtr;
2239
0
    eventEndPP = &eventEndPtr;
2240
0
  }
2241
0
  else {
2242
0
    eventPP = &(openInternalEntities->internalEventPtr);
2243
0
    eventEndPP = &(openInternalEntities->internalEventEndPtr);
2244
0
  }
2245
0
  *eventPP = s;
2246
0
2247
0
  for (;;) {
2248
0
    const char *next = s; /* XmlContentTok doesn't always set the last arg */
2249
0
    int tok = XmlContentTok(enc, s, end, &next);
2250
0
    *eventEndPP = next;
2251
0
    switch (tok) {
2252
0
    case XML_TOK_TRAILING_CR:
2253
0
      if (haveMore) {
2254
0
        *nextPtr = s;
2255
0
        return XML_ERROR_NONE;
2256
0
      }
2257
0
      *eventEndPP = end;
2258
0
      if (characterDataHandler) {
2259
0
        XML_Char c = 0xA;
2260
0
        characterDataHandler(handlerArg, &c, 1);
2261
0
      }
2262
0
      else if (defaultHandler)
2263
0
        reportDefault(parser, enc, s, end);
2264
0
      /* We are at the end of the final buffer, should we check for 
2265
0
         XML_SUSPENDED, XML_FINISHED? 
2266
0
      */
2267
0
      if (startTagLevel == 0)
2268
0
        return XML_ERROR_NO_ELEMENTS;
2269
0
      if (tagLevel != startTagLevel)
2270
0
        return XML_ERROR_ASYNC_ENTITY;
2271
0
      *nextPtr = end;
2272
0
      return XML_ERROR_NONE;
2273
0
    case XML_TOK_NONE:
2274
0
      if (haveMore) {
2275
0
        *nextPtr = s;
2276
0
        return XML_ERROR_NONE;
2277
0
      }
2278
0
      if (startTagLevel > 0) {
2279
0
        if (tagLevel != startTagLevel)
2280
0
          return XML_ERROR_ASYNC_ENTITY;
2281
0
        *nextPtr = s;
2282
0
        return XML_ERROR_NONE;
2283
0
      }
2284
0
      return XML_ERROR_NO_ELEMENTS;
2285
0
    case XML_TOK_INVALID:
2286
0
      *eventPP = next;
2287
0
      return XML_ERROR_INVALID_TOKEN;
2288
0
    case XML_TOK_PARTIAL:
2289
0
      if (haveMore) {
2290
0
        *nextPtr = s;
2291
0
        return XML_ERROR_NONE;
2292
0
      }
2293
0
      return XML_ERROR_UNCLOSED_TOKEN;
2294
0
    case XML_TOK_PARTIAL_CHAR:
2295
0
      if (haveMore) {
2296
0
        *nextPtr = s;
2297
0
        return XML_ERROR_NONE;
2298
0
      }
2299
0
      return XML_ERROR_PARTIAL_CHAR;
2300
0
    case XML_TOK_ENTITY_REF:
2301
0
      {
2302
0
        const XML_Char *name;
2303
0
        ENTITY *entity;
2304
0
        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2305
0
                                              s + enc->minBytesPerChar,
2306
0
                                              next - enc->minBytesPerChar);
2307
0
        if (ch) {
2308
0
          if (characterDataHandler)
2309
0
            characterDataHandler(handlerArg, &ch, 1);
2310
0
          else if (defaultHandler)
2311
0
            reportDefault(parser, enc, s, next);
2312
0
          break;
2313
0
        }
2314
0
        name = poolStoreString(&dtd->pool, enc,
2315
0
                                s + enc->minBytesPerChar,
2316
0
                                next - enc->minBytesPerChar);
2317
0
        if (!name)
2318
0
          return XML_ERROR_NO_MEMORY;
2319
0
        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
2320
0
        poolDiscard(&dtd->pool);
2321
0
        /* First, determine if a check for an existing declaration is needed;
2322
0
           if yes, check that the entity exists, and that it is internal,
2323
0
           otherwise call the skipped entity or default handler.
2324
0
        */
2325
0
        if (!dtd->hasParamEntityRefs || dtd->standalone) {
2326
0
          if (!entity)
2327
0
            return XML_ERROR_UNDEFINED_ENTITY;
2328
0
          else if (!entity->is_internal)
2329
0
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
2330
0
        }
2331
0
        else if (!entity) {
2332
0
          if (skippedEntityHandler)
2333
0
            skippedEntityHandler(handlerArg, name, 0);
2334
0
/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=35984) */
2335
#if 0
2336
          else if (defaultHandler)
2337
            reportDefault(parser, enc, s, next);
2338
          break;
2339
#else
2340
          return XML_ERROR_UNDEFINED_ENTITY;
2341
0
#endif
2342
0
/* END MOZILLA CHANGE */
2343
0
        }
2344
0
        if (entity->open)
2345
0
          return XML_ERROR_RECURSIVE_ENTITY_REF;
2346
0
        if (entity->notation)
2347
0
          return XML_ERROR_BINARY_ENTITY_REF;
2348
0
        if (entity->textPtr) {
2349
0
          enum XML_Error result;
2350
0
          if (!defaultExpandInternalEntities) {
2351
0
            if (skippedEntityHandler)
2352
0
              skippedEntityHandler(handlerArg, entity->name, 0);
2353
0
            else if (defaultHandler)
2354
0
              reportDefault(parser, enc, s, next);
2355
0
            break;
2356
0
          }
2357
0
          result = processInternalEntity(parser, entity, XML_FALSE);
2358
0
          if (result != XML_ERROR_NONE)
2359
0
            return result;
2360
0
        }
2361
0
        else if (externalEntityRefHandler) {
2362
0
          const XML_Char *context;
2363
0
          entity->open = XML_TRUE;
2364
0
          context = getContext(parser);
2365
0
          entity->open = XML_FALSE;
2366
0
          if (!context)
2367
0
            return XML_ERROR_NO_MEMORY;
2368
0
          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2369
0
                                        context,
2370
0
                                        entity->base,
2371
0
                                        entity->systemId,
2372
0
                                        entity->publicId))
2373
0
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2374
0
          poolDiscard(&tempPool);
2375
0
        }
2376
0
        else if (defaultHandler)
2377
0
          reportDefault(parser, enc, s, next);
2378
0
        break;
2379
0
      }
2380
0
    case XML_TOK_START_TAG_NO_ATTS:
2381
0
      /* fall through */
2382
0
    case XML_TOK_START_TAG_WITH_ATTS:
2383
0
      {
2384
0
        TAG *tag;
2385
0
        enum XML_Error result;
2386
0
        XML_Char *toPtr;
2387
0
        if (freeTagList) {
2388
0
          tag = freeTagList;
2389
0
          freeTagList = freeTagList->parent;
2390
0
        }
2391
0
        else {
2392
0
          tag = (TAG *)MALLOC(sizeof(TAG));
2393
0
          if (!tag)
2394
0
            return XML_ERROR_NO_MEMORY;
2395
0
          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2396
0
          if (!tag->buf) {
2397
0
            FREE(tag);
2398
0
            return XML_ERROR_NO_MEMORY;
2399
0
          }
2400
0
          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2401
0
        }
2402
0
        tag->bindings = NULL;
2403
0
        tag->parent = tagStack;
2404
0
        tagStack = tag;
2405
0
        tag->name.localPart = NULL;
2406
0
        tag->name.prefix = NULL;
2407
0
        tag->rawName = s + enc->minBytesPerChar;
2408
0
        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2409
0
        ++tagLevel;
2410
0
        {
2411
0
          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2412
0
          const char *fromPtr = tag->rawName;
2413
0
          toPtr = (XML_Char *)tag->buf;
2414
0
          for (;;) {
2415
0
            int bufSize;
2416
0
            int convLen;
2417
0
            XmlConvert(enc,
2418
0
                       &fromPtr, rawNameEnd,
2419
0
                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2420
0
            convLen = (int)(toPtr - (XML_Char *)tag->buf);
2421
0
            if (fromPtr == rawNameEnd) {
2422
0
              tag->name.strLen = convLen;
2423
0
              break;
2424
0
            }
2425
0
            bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2426
0
            {
2427
0
              char *temp = (char *)REALLOC(tag->buf, bufSize);
2428
0
              if (temp == NULL)
2429
0
                return XML_ERROR_NO_MEMORY;
2430
0
              tag->buf = temp;
2431
0
              tag->bufEnd = temp + bufSize;
2432
0
              toPtr = (XML_Char *)temp + convLen;
2433
0
            }
2434
0
          }
2435
0
        }
2436
0
        tag->name.str = (XML_Char *)tag->buf;
2437
0
        *toPtr = XML_T('\0');
2438
0
        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2439
0
        if (result)
2440
0
          return result;
2441
0
        if (startElementHandler)
2442
0
          startElementHandler(handlerArg, tag->name.str,
2443
0
                              (const XML_Char **)atts);
2444
0
        else if (defaultHandler)
2445
0
          reportDefault(parser, enc, s, next);
2446
0
        poolClear(&tempPool);
2447
0
        break;
2448
0
      }
2449
0
    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2450
0
      /* fall through */
2451
0
    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2452
0
      {
2453
0
        const char *rawName = s + enc->minBytesPerChar;
2454
0
        enum XML_Error result;
2455
0
        BINDING *bindings = NULL;
2456
0
        XML_Bool noElmHandlers = XML_TRUE;
2457
0
        TAG_NAME name;
2458
0
        name.str = poolStoreString(&tempPool, enc, rawName,
2459
0
                                   rawName + XmlNameLength(enc, rawName));
2460
0
        if (!name.str)
2461
0
          return XML_ERROR_NO_MEMORY;
2462
0
        poolFinish(&tempPool);
2463
0
        result = storeAtts(parser, enc, s, &name, &bindings);
2464
0
        if (result)
2465
0
          return result;
2466
0
        poolFinish(&tempPool);
2467
0
        if (startElementHandler) {
2468
0
          startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2469
0
          noElmHandlers = XML_FALSE;
2470
0
        }
2471
0
        if (endElementHandler) {
2472
0
          if (startElementHandler)
2473
0
            *eventPP = *eventEndPP;
2474
0
          endElementHandler(handlerArg, name.str);
2475
0
          noElmHandlers = XML_FALSE;
2476
0
        }
2477
0
        if (noElmHandlers && defaultHandler)
2478
0
          reportDefault(parser, enc, s, next);
2479
0
        poolClear(&tempPool);
2480
0
        while (bindings) {
2481
0
          BINDING *b = bindings;
2482
0
          if (endNamespaceDeclHandler)
2483
0
            endNamespaceDeclHandler(handlerArg, b->prefix->name);
2484
0
          bindings = bindings->nextTagBinding;
2485
0
          b->nextTagBinding = freeBindingList;
2486
0
          freeBindingList = b;
2487
0
          b->prefix->binding = b->prevPrefixBinding;
2488
0
        }
2489
0
      }
2490
0
      if (tagLevel == 0)
2491
0
        return epilogProcessor(parser, next, end, nextPtr);
2492
0
      break;
2493
0
    case XML_TOK_END_TAG:
2494
0
      if (tagLevel == startTagLevel)
2495
0
        return XML_ERROR_ASYNC_ENTITY;
2496
0
      else {
2497
0
        int len;
2498
0
        const char *rawName;
2499
0
        TAG *tag = tagStack;
2500
0
        tagStack = tag->parent;
2501
0
        tag->parent = freeTagList;
2502
0
        freeTagList = tag;
2503
0
        rawName = s + enc->minBytesPerChar*2;
2504
0
        len = XmlNameLength(enc, rawName);
2505
0
        if (len != tag->rawNameLength
2506
0
            || memcmp(tag->rawName, rawName, len) != 0) {
2507
0
/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
2508
0
    /* This code is copied from the |if (endElementHandler)| block below */
2509
0
          const XML_Char *localPart;
2510
0
          const XML_Char *prefix;
2511
0
          XML_Char *uri;
2512
0
          localPart = tag->name.localPart;
2513
0
          if (ns && localPart) {
2514
0
            /* localPart and prefix may have been overwritten in
2515
0
               tag->name.str, since this points to the binding->uri
2516
0
               buffer which gets re-used; so we have to add them again
2517
0
            */
2518
0
            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2519
0
            /* don't need to check for space - already done in storeAtts() */
2520
0
            while (*localPart) *uri++ = *localPart++;
2521
0
            prefix = (XML_Char *)tag->name.prefix;
2522
0
            if (ns_triplets && prefix) {
2523
0
              *uri++ = namespaceSeparator;
2524
0
              while (*prefix) *uri++ = *prefix++;
2525
0
             }
2526
0
            *uri = XML_T('\0');
2527
0
          }
2528
0
          mismatch = tag->name.str;
2529
0
/* END MOZILLA CHANGE */
2530
0
          *eventPP = rawName;
2531
0
          return XML_ERROR_TAG_MISMATCH;
2532
0
        }
2533
0
        --tagLevel;
2534
0
        if (endElementHandler) {
2535
0
          const XML_Char *localPart;
2536
0
          const XML_Char *prefix;
2537
0
          XML_Char *uri;
2538
0
          localPart = tag->name.localPart;
2539
0
          if (ns && localPart) {
2540
0
            /* localPart and prefix may have been overwritten in
2541
0
               tag->name.str, since this points to the binding->uri
2542
0
               buffer which gets re-used; so we have to add them again
2543
0
            */
2544
0
            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2545
0
            /* don't need to check for space - already done in storeAtts() */
2546
0
            while (*localPart) *uri++ = *localPart++;
2547
0
            prefix = (XML_Char *)tag->name.prefix;
2548
0
            if (ns_triplets && prefix) {
2549
0
              *uri++ = namespaceSeparator;
2550
0
              while (*prefix) *uri++ = *prefix++;
2551
0
             }
2552
0
            *uri = XML_T('\0');
2553
0
          }
2554
0
          endElementHandler(handlerArg, tag->name.str);
2555
0
        }
2556
0
        else if (defaultHandler)
2557
0
          reportDefault(parser, enc, s, next);
2558
0
        while (tag->bindings) {
2559
0
          BINDING *b = tag->bindings;
2560
0
          if (endNamespaceDeclHandler)
2561
0
            endNamespaceDeclHandler(handlerArg, b->prefix->name);
2562
0
          tag->bindings = tag->bindings->nextTagBinding;
2563
0
          b->nextTagBinding = freeBindingList;
2564
0
          freeBindingList = b;
2565
0
          b->prefix->binding = b->prevPrefixBinding;
2566
0
        }
2567
0
        if (tagLevel == 0)
2568
0
          return epilogProcessor(parser, next, end, nextPtr);
2569
0
      }
2570
0
      break;
2571
0
    case XML_TOK_CHAR_REF:
2572
0
      {
2573
0
        int n = XmlCharRefNumber(enc, s);
2574
0
        if (n < 0)
2575
0
          return XML_ERROR_BAD_CHAR_REF;
2576
0
        if (characterDataHandler) {
2577
0
          XML_Char buf[XML_ENCODE_MAX];
2578
0
          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2579
0
        }
2580
0
        else if (defaultHandler)
2581
0
          reportDefault(parser, enc, s, next);
2582
0
      }
2583
0
      break;
2584
0
    case XML_TOK_XML_DECL:
2585
0
      return XML_ERROR_MISPLACED_XML_PI;
2586
0
    case XML_TOK_DATA_NEWLINE:
2587
0
      if (characterDataHandler) {
2588
0
        XML_Char c = 0xA;
2589
0
        characterDataHandler(handlerArg, &c, 1);
2590
0
      }
2591
0
      else if (defaultHandler)
2592
0
        reportDefault(parser, enc, s, next);
2593
0
      break;
2594
0
    case XML_TOK_CDATA_SECT_OPEN:
2595
0
      {
2596
0
        enum XML_Error result;
2597
0
        if (startCdataSectionHandler)
2598
0
          startCdataSectionHandler(handlerArg);
2599
#if 0
2600
        /* Suppose you doing a transformation on a document that involves
2601
           changing only the character data.  You set up a defaultHandler
2602
           and a characterDataHandler.  The defaultHandler simply copies
2603
           characters through.  The characterDataHandler does the
2604
           transformation and writes the characters out escaping them as
2605
           necessary.  This case will fail to work if we leave out the
2606
           following two lines (because & and < inside CDATA sections will
2607
           be incorrectly escaped).
2608
2609
           However, now we have a start/endCdataSectionHandler, so it seems
2610
           easier to let the user deal with this.
2611
        */
2612
        else if (characterDataHandler)
2613
          characterDataHandler(handlerArg, dataBuf, 0);
2614
#endif
2615
0
        else if (defaultHandler)
2616
0
          reportDefault(parser, enc, s, next);
2617
0
        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2618
0
        if (result != XML_ERROR_NONE)
2619
0
          return result;
2620
0
        else if (!next) {
2621
0
          processor = cdataSectionProcessor;
2622
0
          return result;
2623
0
        }
2624
0
      }
2625
0
      break;
2626
0
    case XML_TOK_TRAILING_RSQB:
2627
0
      if (haveMore) {
2628
0
        *nextPtr = s;
2629
0
        return XML_ERROR_NONE;
2630
0
      }
2631
0
      if (characterDataHandler) {
2632
0
        if (MUST_CONVERT(enc, s)) {
2633
0
          ICHAR *dataPtr = (ICHAR *)dataBuf;
2634
0
          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2635
0
          characterDataHandler(handlerArg, dataBuf,
2636
0
                               (int)(dataPtr - (ICHAR *)dataBuf));
2637
0
        }
2638
0
        else
2639
0
          characterDataHandler(handlerArg,
2640
0
                               (XML_Char *)s,
2641
0
                               (int)((XML_Char *)end - (XML_Char *)s));
2642
0
      }
2643
0
      else if (defaultHandler)
2644
0
        reportDefault(parser, enc, s, end);
2645
0
      /* We are at the end of the final buffer, should we check for 
2646
0
         XML_SUSPENDED, XML_FINISHED? 
2647
0
      */
2648
0
      if (startTagLevel == 0) {
2649
0
        *eventPP = end;
2650
0
        return XML_ERROR_NO_ELEMENTS;
2651
0
      }
2652
0
      if (tagLevel != startTagLevel) {
2653
0
        *eventPP = end;
2654
0
        return XML_ERROR_ASYNC_ENTITY;
2655
0
      }
2656
0
      *nextPtr = end;
2657
0
      return XML_ERROR_NONE;
2658
0
    case XML_TOK_DATA_CHARS:
2659
0
      if (characterDataHandler) {
2660
0
        if (MUST_CONVERT(enc, s)) {
2661
0
          for (;;) {
2662
0
            ICHAR *dataPtr = (ICHAR *)dataBuf;
2663
0
            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2664
0
            *eventEndPP = s;
2665
0
            characterDataHandler(handlerArg, dataBuf,
2666
0
                                 (int)(dataPtr - (ICHAR *)dataBuf));
2667
0
            if (s == next)
2668
0
              break;
2669
0
            *eventPP = s;
2670
0
          }
2671
0
        }
2672
0
        else
2673
0
          characterDataHandler(handlerArg,
2674
0
                               (XML_Char *)s,
2675
0
                               (int)((XML_Char *)next - (XML_Char *)s));
2676
0
      }
2677
0
      else if (defaultHandler)
2678
0
        reportDefault(parser, enc, s, next);
2679
0
      break;
2680
0
    case XML_TOK_PI:
2681
0
      if (!reportProcessingInstruction(parser, enc, s, next))
2682
0
        return XML_ERROR_NO_MEMORY;
2683
0
      break;
2684
0
    case XML_TOK_COMMENT:
2685
0
      if (!reportComment(parser, enc, s, next))
2686
0
        return XML_ERROR_NO_MEMORY;
2687
0
      break;
2688
0
    default:
2689
0
      if (defaultHandler)
2690
0
        reportDefault(parser, enc, s, next);
2691
0
      break;
2692
0
    }
2693
0
    *eventPP = s = next;
2694
0
    switch (ps_parsing) {
2695
0
    case XML_SUSPENDED: 
2696
0
      *nextPtr = next;
2697
0
      return XML_ERROR_NONE;
2698
0
    case XML_FINISHED:
2699
0
      return XML_ERROR_ABORTED;
2700
0
    default: ;
2701
0
    }
2702
0
  }
2703
0
  /* not reached */
2704
0
}
2705
2706
/* Precondition: all arguments must be non-NULL;
2707
   Purpose:
2708
   - normalize attributes
2709
   - check attributes for well-formedness
2710
   - generate namespace aware attribute names (URI, prefix)
2711
   - build list of attributes for startElementHandler
2712
   - default attributes
2713
   - process namespace declarations (check and report them)
2714
   - generate namespace aware element name (URI, prefix)
2715
*/
2716
static enum XML_Error
2717
storeAtts(XML_Parser parser, const ENCODING *enc,
2718
          const char *attStr, TAG_NAME *tagNamePtr,
2719
          BINDING **bindingsPtr)
2720
0
{
2721
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
2722
0
  ELEMENT_TYPE *elementType;
2723
0
  int nDefaultAtts;
2724
0
  const XML_Char **appAtts;   /* the attribute list for the application */
2725
0
  int attIndex = 0;
2726
0
  int prefixLen;
2727
0
  int i;
2728
0
  int n;
2729
0
  XML_Char *uri;
2730
0
  int nPrefixes = 0;
2731
0
/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
2732
0
  int nXMLNSDeclarations = 0;
2733
0
/* END MOZILLA CHANGE */
2734
0
  BINDING *binding;
2735
0
  const XML_Char *localPart;
2736
0
2737
0
  /* lookup the element type name */
2738
0
  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2739
0
  if (!elementType) {
2740
0
    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2741
0
    if (!name)
2742
0
      return XML_ERROR_NO_MEMORY;
2743
0
    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2744
0
                                         sizeof(ELEMENT_TYPE));
2745
0
    if (!elementType)
2746
0
      return XML_ERROR_NO_MEMORY;
2747
0
    if (ns && !setElementTypePrefix(parser, elementType))
2748
0
      return XML_ERROR_NO_MEMORY;
2749
0
  }
2750
0
  nDefaultAtts = elementType->nDefaultAtts;
2751
0
2752
0
  /* get the attributes from the tokenizer */
2753
0
  n = XmlGetAttributes(enc, attStr, attsSize, atts);
2754
0
  if (n + nDefaultAtts > attsSize) {
2755
0
    int oldAttsSize = attsSize;
2756
0
    ATTRIBUTE *temp;
2757
0
    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2758
0
    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2759
0
    if (temp == NULL)
2760
0
      return XML_ERROR_NO_MEMORY;
2761
0
    atts = temp;
2762
0
    if (n > oldAttsSize)
2763
0
      XmlGetAttributes(enc, attStr, n, atts);
2764
0
  }
2765
0
2766
0
  appAtts = (const XML_Char **)atts;
2767
0
  for (i = 0; i < n; i++) {
2768
0
    /* add the name and value to the attribute list */
2769
0
    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
2770
0
                                         atts[i].name
2771
0
                                         + XmlNameLength(enc, atts[i].name));
2772
0
    if (!attId)
2773
0
      return XML_ERROR_NO_MEMORY;
2774
0
    /* Detect duplicate attributes by their QNames. This does not work when
2775
0
       namespace processing is turned on and different prefixes for the same
2776
0
       namespace are used. For this case we have a check further down.
2777
0
    */
2778
0
    if ((attId->name)[-1]) {
2779
0
      if (enc == encoding)
2780
0
        eventPtr = atts[i].name;
2781
0
      return XML_ERROR_DUPLICATE_ATTRIBUTE;
2782
0
    }
2783
0
    (attId->name)[-1] = 1;
2784
0
    appAtts[attIndex++] = attId->name;
2785
0
    if (!atts[i].normalized) {
2786
0
      enum XML_Error result;
2787
0
      XML_Bool isCdata = XML_TRUE;
2788
0
2789
0
      /* figure out whether declared as other than CDATA */
2790
0
      if (attId->maybeTokenized) {
2791
0
        int j;
2792
0
        for (j = 0; j < nDefaultAtts; j++) {
2793
0
          if (attId == elementType->defaultAtts[j].id) {
2794
0
            isCdata = elementType->defaultAtts[j].isCdata;
2795
0
            break;
2796
0
          }
2797
0
        }
2798
0
      }
2799
0
2800
0
      /* normalize the attribute value */
2801
0
      result = storeAttributeValue(parser, enc, isCdata,
2802
0
                                   atts[i].valuePtr, atts[i].valueEnd,
2803
0
                                   &tempPool);
2804
0
      if (result)
2805
0
        return result;
2806
0
      appAtts[attIndex] = poolStart(&tempPool);
2807
0
      poolFinish(&tempPool);
2808
0
    }
2809
0
    else {
2810
0
      /* the value did not need normalizing */
2811
0
      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2812
0
                                          atts[i].valueEnd);
2813
0
      if (appAtts[attIndex] == 0)
2814
0
        return XML_ERROR_NO_MEMORY;
2815
0
      poolFinish(&tempPool);
2816
0
    }
2817
0
    /* handle prefixed attribute names */
2818
0
    if (attId->prefix) {
2819
0
      if (attId->xmlns) {
2820
0
        /* deal with namespace declarations here */
2821
0
        enum XML_Error result = addBinding(parser, attId->prefix, attId,
2822
0
                                           appAtts[attIndex], bindingsPtr);
2823
0
        if (result)
2824
0
          return result;
2825
0
/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
2826
#if 0
2827
        --attIndex;
2828
#else
2829
0
        attIndex++;
2830
0
        nXMLNSDeclarations++;
2831
0
        (attId->name)[-1] = 3;
2832
0
#endif
2833
0
/* END MOZILLA CHANGE */
2834
0
      }
2835
0
      else {
2836
0
        /* deal with other prefixed names later */
2837
0
        attIndex++;
2838
0
        nPrefixes++;
2839
0
        (attId->name)[-1] = 2;
2840
0
      }
2841
0
    }
2842
0
    else
2843
0
      attIndex++;
2844
0
  }
2845
0
2846
0
  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2847
0
  nSpecifiedAtts = attIndex;
2848
0
  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2849
0
    for (i = 0; i < attIndex; i += 2)
2850
0
      if (appAtts[i] == elementType->idAtt->name) {
2851
0
        idAttIndex = i;
2852
0
        break;
2853
0
      }
2854
0
  }
2855
0
  else
2856
0
    idAttIndex = -1;
2857
0
2858
0
  /* do attribute defaulting */
2859
0
  for (i = 0; i < nDefaultAtts; i++) {
2860
0
    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2861
0
    if (!(da->id->name)[-1] && da->value) {
2862
0
      if (da->id->prefix) {
2863
0
        if (da->id->xmlns) {
2864
0
          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2865
0
                                             da->value, bindingsPtr);
2866
0
          if (result)
2867
0
            return result;
2868
0
/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
2869
0
          (da->id->name)[-1] = 3;
2870
0
          nXMLNSDeclarations++;
2871
0
          appAtts[attIndex++] = da->id->name;
2872
0
          appAtts[attIndex++] = da->value;
2873
0
/* END MOZILLA CHANGE */
2874
0
        }
2875
0
        else {
2876
0
          (da->id->name)[-1] = 2;
2877
0
          nPrefixes++;
2878
0
          appAtts[attIndex++] = da->id->name;
2879
0
          appAtts[attIndex++] = da->value;
2880
0
        }
2881
0
      }
2882
0
      else {
2883
0
        (da->id->name)[-1] = 1;
2884
0
        appAtts[attIndex++] = da->id->name;
2885
0
        appAtts[attIndex++] = da->value;
2886
0
      }
2887
0
    }
2888
0
  }
2889
0
  appAtts[attIndex] = 0;
2890
0
2891
0
  /* expand prefixed attribute names, check for duplicates,
2892
0
     and clear flags that say whether attributes were specified */
2893
0
  i = 0;
2894
0
/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
2895
#if 0
2896
  if (nPrefixes) {
2897
#else
2898
0
  if (nPrefixes || nXMLNSDeclarations) {
2899
0
#endif
2900
0
/* END MOZILLA CHANGE */
2901
0
    int j;  /* hash table index */
2902
0
    unsigned long version = nsAttsVersion;
2903
0
    int nsAttsSize = (int)1 << nsAttsPower;
2904
0
/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
2905
0
    if (nPrefixes) {
2906
0
/* END MOZILLA CHANGE */
2907
0
    /* size of hash table must be at least 2 * (# of prefixed attributes) */
2908
0
    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
2909
0
      NS_ATT *temp;
2910
0
      /* hash table size must also be a power of 2 and >= 8 */
2911
0
      while (nPrefixes >> nsAttsPower++);
2912
0
      if (nsAttsPower < 3)
2913
0
        nsAttsPower = 3;
2914
0
      nsAttsSize = (int)1 << nsAttsPower;
2915
0
      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2916
0
      if (!temp)
2917
0
        return XML_ERROR_NO_MEMORY;
2918
0
      nsAtts = temp;
2919
0
      version = 0;  /* force re-initialization of nsAtts hash table */
2920
0
    }
2921
0
    /* using a version flag saves us from initializing nsAtts every time */
2922
0
    if (!version) {  /* initialize version flags when version wraps around */
2923
0
      version = INIT_ATTS_VERSION;
2924
0
      for (j = nsAttsSize; j != 0; )
2925
0
        nsAtts[--j].version = version;
2926
0
    }
2927
0
    nsAttsVersion = --version;
2928
0
/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
2929
0
    }
2930
0
/* END MOZILLA CHANGE */
2931
0
2932
0
    /* expand prefixed names and check for duplicates */
2933
0
    for (; i < attIndex; i += 2) {
2934
0
      const XML_Char *s = appAtts[i];
2935
0
      if (s[-1] == 2) {  /* prefixed */
2936
0
        ATTRIBUTE_ID *id;
2937
0
        const BINDING *b;
2938
0
        unsigned long uriHash = 0;
2939
0
        ((XML_Char *)s)[-1] = 0;  /* clear flag */
2940
0
        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
2941
0
        b = id->prefix->binding;
2942
0
        if (!b)
2943
0
          return XML_ERROR_UNBOUND_PREFIX;
2944
0
2945
0
        /* as we expand the name we also calculate its hash value */
2946
0
        for (j = 0; j < b->uriLen; j++) {
2947
0
          const XML_Char c = b->uri[j];
2948
0
          if (!poolAppendChar(&tempPool, c))
2949
0
            return XML_ERROR_NO_MEMORY;
2950
0
          uriHash = CHAR_HASH(uriHash, c);
2951
0
        }
2952
0
        while (*s++ != XML_T(':'))
2953
0
          ;
2954
0
        do {  /* copies null terminator */
2955
0
          const XML_Char c = *s;
2956
0
          if (!poolAppendChar(&tempPool, *s))
2957
0
            return XML_ERROR_NO_MEMORY;
2958
0
          uriHash = CHAR_HASH(uriHash, c);
2959
0
        } while (*s++);
2960
0
2961
0
        { /* Check hash table for duplicate of expanded name (uriName).
2962
0
             Derived from code in lookup(HASH_TABLE *table, ...).
2963
0
          */
2964
0
          unsigned char step = 0;
2965
0
          unsigned long mask = nsAttsSize - 1;
2966
0
          j = uriHash & mask;  /* index into hash table */
2967
0
          while (nsAtts[j].version == version) {
2968
0
            /* for speed we compare stored hash values first */
2969
0
            if (uriHash == nsAtts[j].hash) {
2970
0
              const XML_Char *s1 = poolStart(&tempPool);
2971
0
              const XML_Char *s2 = nsAtts[j].uriName;
2972
0
              /* s1 is null terminated, but not s2 */
2973
0
              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2974
0
              if (*s1 == 0)
2975
0
                return XML_ERROR_DUPLICATE_ATTRIBUTE;
2976
0
            }
2977
0
            if (!step)
2978
0
              step = PROBE_STEP(uriHash, mask, nsAttsPower);
2979
0
            j < step ? (j += nsAttsSize - step) : (j -= step);
2980
0
          }
2981
0
        }
2982
0
2983
0
        if (ns_triplets) {  /* append namespace separator and prefix */
2984
0
          tempPool.ptr[-1] = namespaceSeparator;
2985
0
          s = b->prefix->name;
2986
0
          do {
2987
0
            if (!poolAppendChar(&tempPool, *s))
2988
0
              return XML_ERROR_NO_MEMORY;
2989
0
          } while (*s++);
2990
0
        }
2991
0
2992
0
        /* store expanded name in attribute list */
2993
0
        s = poolStart(&tempPool);
2994
0
        poolFinish(&tempPool);
2995
0
        appAtts[i] = s;
2996
0
2997
0
        /* fill empty slot with new version, uriName and hash value */
2998
0
        nsAtts[j].version = version;
2999
0
        nsAtts[j].hash = uriHash;
3000
0
        nsAtts[j].uriName = s;
3001
0
3002
0
/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
3003
#if 0
3004
        if (!--nPrefixes)
3005
#else
3006
0
        if (!--nPrefixes && !nXMLNSDeclarations) {
3007
0
#endif
3008
0
/* END MOZILLA CHANGE */
3009
0
          i += 2;
3010
0
          break;
3011
0
        }
3012
0
      }
3013
0
/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
3014
0
      else if (s[-1] == 3) { /* xmlns attribute */
3015
0
        static const XML_Char xmlnsNamespace[] = {
3016
0
          'h', 't', 't', 'p', ':', '/', '/',
3017
0
          'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
3018
0
          '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
3019
0
        };
3020
0
        static const XML_Char xmlnsPrefix[] = {
3021
0
          'x', 'm', 'l', 'n', 's', '\0'
3022
0
        };
3023
0
3024
0
        ((XML_Char *)s)[-1] = 0;  /* clear flag */
3025
0
        if (!poolAppendString(&tempPool, xmlnsNamespace)
3026
0
            || !poolAppendChar(&tempPool, namespaceSeparator))
3027
0
          return XML_ERROR_NO_MEMORY;
3028
0
        s += sizeof(xmlnsPrefix) / sizeof(xmlnsPrefix[0]) - 1;
3029
0
        if (*s == XML_T(':')) {
3030
0
          ++s;
3031
0
          do {  /* copies null terminator */
3032
0
            if (!poolAppendChar(&tempPool, *s))
3033
0
              return XML_ERROR_NO_MEMORY;
3034
0
          } while (*s++);
3035
0
          if (ns_triplets) { /* append namespace separator and prefix */
3036
0
            tempPool.ptr[-1] = namespaceSeparator;
3037
0
            if (!poolAppendString(&tempPool, xmlnsPrefix)
3038
0
                || !poolAppendChar(&tempPool, '\0'))
3039
0
              return XML_ERROR_NO_MEMORY;
3040
0
          }
3041
0
        }
3042
0
        else {
3043
0
          /* xlmns attribute without a prefix. */
3044
0
          if (!poolAppendString(&tempPool, xmlnsPrefix)
3045
0
              || !poolAppendChar(&tempPool, '\0'))
3046
0
            return XML_ERROR_NO_MEMORY;
3047
0
        }
3048
0
3049
0
        /* store expanded name in attribute list */
3050
0
        s = poolStart(&tempPool);
3051
0
        poolFinish(&tempPool);
3052
0
        appAtts[i] = s;
3053
0
3054
0
        if (!--nXMLNSDeclarations && !nPrefixes) {
3055
0
          i += 2;
3056
0
          break;
3057
0
        }
3058
0
      }
3059
0
/* END MOZILLA CHANGE */
3060
0
      else  /* not prefixed */
3061
0
        ((XML_Char *)s)[-1] = 0;  /* clear flag */
3062
0
    }
3063
0
  }
3064
0
  /* clear flags for the remaining attributes */
3065
0
  for (; i < attIndex; i += 2)
3066
0
    ((XML_Char *)(appAtts[i]))[-1] = 0;
3067
0
  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3068
0
    binding->attId->name[-1] = 0;
3069
0
3070
0
  if (!ns)
3071
0
    return XML_ERROR_NONE;
3072
0
3073
0
  /* expand the element type name */
3074
0
  if (elementType->prefix) {
3075
0
    binding = elementType->prefix->binding;
3076
0
    if (!binding)
3077
0
      return XML_ERROR_UNBOUND_PREFIX;
3078
0
    localPart = tagNamePtr->str;
3079
0
    while (*localPart++ != XML_T(':'))
3080
0
      ;
3081
0
  }
3082
0
  else if (dtd->defaultPrefix.binding) {
3083
0
    binding = dtd->defaultPrefix.binding;
3084
0
    localPart = tagNamePtr->str;
3085
0
  }
3086
0
  else
3087
0
    return XML_ERROR_NONE;
3088
0
  prefixLen = 0;
3089
0
  if (ns_triplets && binding->prefix->name) {
3090
0
    for (; binding->prefix->name[prefixLen++];)
3091
0
      ;  /* prefixLen includes null terminator */
3092
0
  }
3093
0
  tagNamePtr->localPart = localPart;
3094
0
  tagNamePtr->uriLen = binding->uriLen;
3095
0
  tagNamePtr->prefix = binding->prefix->name;
3096
0
  tagNamePtr->prefixLen = prefixLen;
3097
0
  for (i = 0; localPart[i++];)
3098
0
    ;  /* i includes null terminator */
3099
0
  n = i + binding->uriLen + prefixLen;
3100
0
  if (n > binding->uriAlloc) {
3101
0
    TAG *p;
3102
0
    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
3103
0
    if (!uri)
3104
0
      return XML_ERROR_NO_MEMORY;
3105
0
    binding->uriAlloc = n + EXPAND_SPARE;
3106
0
    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3107
0
    for (p = tagStack; p; p = p->parent)
3108
0
      if (p->name.str == binding->uri)
3109
0
        p->name.str = uri;
3110
0
    FREE(binding->uri);
3111
0
    binding->uri = uri;
3112
0
  }
3113
0
  /* if namespaceSeparator != '\0' then uri includes it already */
3114
0
  uri = binding->uri + binding->uriLen;
3115
0
  memcpy(uri, localPart, i * sizeof(XML_Char));
3116
0
  /* we always have a namespace separator between localPart and prefix */
3117
0
  if (prefixLen) {
3118
0
    uri += i - 1;
3119
0
    *uri = namespaceSeparator;  /* replace null terminator */
3120
0
    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3121
0
  }
3122
0
  tagNamePtr->str = binding->uri;
3123
0
  return XML_ERROR_NONE;
3124
0
}
3125
3126
/* addBinding() overwrites the value of prefix->binding without checking.
3127
   Therefore one must keep track of the old value outside of addBinding().
3128
*/
3129
static enum XML_Error
3130
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3131
           const XML_Char *uri, BINDING **bindingsPtr)
3132
0
{
3133
0
  static const XML_Char xmlNamespace[] = {
3134
0
    'h', 't', 't', 'p', ':', '/', '/',
3135
0
    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
3136
0
    'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
3137
0
    'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
3138
0
  };
3139
0
  static const int xmlLen = 
3140
0
    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3141
0
  static const XML_Char xmlnsNamespace[] = {
3142
0
    'h', 't', 't', 'p', ':', '/', '/',
3143
0
    'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
3144
0
    '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
3145
0
  };
3146
0
  static const int xmlnsLen = 
3147
0
    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3148
0
3149
0
  XML_Bool mustBeXML = XML_FALSE;
3150
0
  XML_Bool isXML = XML_TRUE;
3151
0
  XML_Bool isXMLNS = XML_TRUE;
3152
0
  
3153
0
  BINDING *b;
3154
0
  int len;
3155
0
3156
0
  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3157
0
  if (*uri == XML_T('\0') && prefix->name)
3158
0
    return XML_ERROR_UNDECLARING_PREFIX;
3159
0
3160
0
  if (prefix->name
3161
0
      && prefix->name[0] == XML_T('x')
3162
0
      && prefix->name[1] == XML_T('m')
3163
0
      && prefix->name[2] == XML_T('l')) {
3164
0
3165
0
    /* Not allowed to bind xmlns */
3166
0
    if (prefix->name[3] == XML_T('n')
3167
0
        && prefix->name[4] == XML_T('s')
3168
0
        && prefix->name[5] == XML_T('\0'))
3169
0
      return XML_ERROR_RESERVED_PREFIX_XMLNS;
3170
0
3171
0
    if (prefix->name[3] == XML_T('\0'))
3172
0
      mustBeXML = XML_TRUE;
3173
0
  }
3174
0
3175
0
  for (len = 0; uri[len]; len++) {
3176
0
    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3177
0
      isXML = XML_FALSE;
3178
0
3179
0
    if (!mustBeXML && isXMLNS 
3180
0
        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3181
0
      isXMLNS = XML_FALSE;
3182
0
  }
3183
0
  isXML = isXML && len == xmlLen;
3184
0
  isXMLNS = isXMLNS && len == xmlnsLen;
3185
0
3186
0
  if (mustBeXML != isXML)
3187
0
    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3188
0
                     : XML_ERROR_RESERVED_NAMESPACE_URI;
3189
0
3190
0
  if (isXMLNS)
3191
0
    return XML_ERROR_RESERVED_NAMESPACE_URI;
3192
0
3193
0
  if (namespaceSeparator)
3194
0
    len++;
3195
0
  if (freeBindingList) {
3196
0
    b = freeBindingList;
3197
0
    if (len > b->uriAlloc) {
3198
0
      XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3199
0
                          sizeof(XML_Char) * (len + EXPAND_SPARE));
3200
0
      if (temp == NULL)
3201
0
        return XML_ERROR_NO_MEMORY;
3202
0
      b->uri = temp;
3203
0
      b->uriAlloc = len + EXPAND_SPARE;
3204
0
    }
3205
0
    freeBindingList = b->nextTagBinding;
3206
0
  }
3207
0
  else {
3208
0
    b = (BINDING *)MALLOC(sizeof(BINDING));
3209
0
    if (!b)
3210
0
      return XML_ERROR_NO_MEMORY;
3211
0
    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3212
0
    if (!b->uri) {
3213
0
      FREE(b);
3214
0
      return XML_ERROR_NO_MEMORY;
3215
0
    }
3216
0
    b->uriAlloc = len + EXPAND_SPARE;
3217
0
  }
3218
0
  b->uriLen = len;
3219
0
  memcpy(b->uri, uri, len * sizeof(XML_Char));
3220
0
  if (namespaceSeparator)
3221
0
    b->uri[len - 1] = namespaceSeparator;
3222
0
  b->prefix = prefix;
3223
0
  b->attId = attId;
3224
0
  b->prevPrefixBinding = prefix->binding;
3225
0
  /* NULL binding when default namespace undeclared */
3226
0
  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3227
0
    prefix->binding = NULL;
3228
0
  else
3229
0
    prefix->binding = b;
3230
0
  b->nextTagBinding = *bindingsPtr;
3231
0
  *bindingsPtr = b;
3232
0
  /* if attId == NULL then we are not starting a namespace scope */
3233
0
  if (attId && startNamespaceDeclHandler)
3234
0
    startNamespaceDeclHandler(handlerArg, prefix->name,
3235
0
                              prefix->binding ? uri : 0);
3236
0
  return XML_ERROR_NONE;
3237
0
}
3238
3239
/* The idea here is to avoid using stack for each CDATA section when
3240
   the whole file is parsed with one call.
3241
*/
3242
static enum XML_Error PTRCALL
3243
cdataSectionProcessor(XML_Parser parser,
3244
                      const char *start,
3245
                      const char *end,
3246
                      const char **endPtr)
3247
0
{
3248
0
  enum XML_Error result = doCdataSection(parser, encoding, &start, end,
3249
0
                                         endPtr, (XML_Bool)!ps_finalBuffer);
3250
0
  if (result != XML_ERROR_NONE)
3251
0
    return result;
3252
0
  if (start) {
3253
0
    if (parentParser) {  /* we are parsing an external entity */
3254
0
      processor = externalEntityContentProcessor;
3255
0
      return externalEntityContentProcessor(parser, start, end, endPtr);
3256
0
    }
3257
0
    else {
3258
0
      processor = contentProcessor;
3259
0
      return contentProcessor(parser, start, end, endPtr);
3260
0
    }
3261
0
  }
3262
0
  return result;
3263
0
}
3264
3265
/* startPtr gets set to non-null if the section is closed, and to null if
3266
   the section is not yet closed.
3267
*/
3268
static enum XML_Error
3269
doCdataSection(XML_Parser parser,
3270
               const ENCODING *enc,
3271
               const char **startPtr,
3272
               const char *end,
3273
               const char **nextPtr,
3274
               XML_Bool haveMore)
3275
0
{
3276
0
  const char *s = *startPtr;
3277
0
  const char **eventPP;
3278
0
  const char **eventEndPP;
3279
0
  if (enc == encoding) {
3280
0
    eventPP = &eventPtr;
3281
0
    *eventPP = s;
3282
0
    eventEndPP = &eventEndPtr;
3283
0
  }
3284
0
  else {
3285
0
    eventPP = &(openInternalEntities->internalEventPtr);
3286
0
    eventEndPP = &(openInternalEntities->internalEventEndPtr);
3287
0
  }
3288
0
  *eventPP = s;
3289
0
  *startPtr = NULL;
3290
0
3291
0
  for (;;) {
3292
0
    const char *next;
3293
0
    int tok = XmlCdataSectionTok(enc, s, end, &next);
3294
0
    *eventEndPP = next;
3295
0
    switch (tok) {
3296
0
    case XML_TOK_CDATA_SECT_CLOSE:
3297
0
      if (endCdataSectionHandler)
3298
0
        endCdataSectionHandler(handlerArg);
3299
#if 0
3300
      /* see comment under XML_TOK_CDATA_SECT_OPEN */
3301
      else if (characterDataHandler)
3302
        characterDataHandler(handlerArg, dataBuf, 0);
3303
#endif
3304
0
      else if (defaultHandler)
3305
0
        reportDefault(parser, enc, s, next);
3306
0
      *startPtr = next;
3307
0
      *nextPtr = next;
3308
0
      if (ps_parsing == XML_FINISHED)
3309
0
        return XML_ERROR_ABORTED;
3310
0
      else
3311
0
        return XML_ERROR_NONE;
3312
0
    case XML_TOK_DATA_NEWLINE:
3313
0
      if (characterDataHandler) {
3314
0
        XML_Char c = 0xA;
3315
0
        characterDataHandler(handlerArg, &c, 1);
3316
0
      }
3317
0
      else if (defaultHandler)
3318
0
        reportDefault(parser, enc, s, next);
3319
0
      break;
3320
0
    case XML_TOK_DATA_CHARS:
3321
0
      if (characterDataHandler) {
3322
0
        if (MUST_CONVERT(enc, s)) {
3323
0
          for (;;) {
3324
0
            ICHAR *dataPtr = (ICHAR *)dataBuf;
3325
0
            XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3326
0
            *eventEndPP = next;
3327
0
            characterDataHandler(handlerArg, dataBuf,
3328
0
                                 (int)(dataPtr - (ICHAR *)dataBuf));
3329
0
            if (s == next)
3330
0
              break;
3331
0
            *eventPP = s;
3332
0
          }
3333
0
        }
3334
0
        else
3335
0
          characterDataHandler(handlerArg,
3336
0
                               (XML_Char *)s,
3337
0
                               (int)((XML_Char *)next - (XML_Char *)s));
3338
0
      }
3339
0
      else if (defaultHandler)
3340
0
        reportDefault(parser, enc, s, next);
3341
0
      break;
3342
0
    case XML_TOK_INVALID:
3343
0
      *eventPP = next;
3344
0
      return XML_ERROR_INVALID_TOKEN;
3345
0
    case XML_TOK_PARTIAL_CHAR:
3346
0
      if (haveMore) {
3347
0
        *nextPtr = s;
3348
0
        return XML_ERROR_NONE;
3349
0
      }
3350
0
      return XML_ERROR_PARTIAL_CHAR;
3351
0
    case XML_TOK_PARTIAL:
3352
0
    case XML_TOK_NONE:
3353
0
      if (haveMore) {
3354
0
        *nextPtr = s;
3355
0
        return XML_ERROR_NONE;
3356
0
      }
3357
0
      return XML_ERROR_UNCLOSED_CDATA_SECTION;
3358
0
    default:
3359
0
      *eventPP = next;
3360
0
      return XML_ERROR_UNEXPECTED_STATE;
3361
0
    }
3362
0
3363
0
    *eventPP = s = next;
3364
0
    switch (ps_parsing) {
3365
0
    case XML_SUSPENDED:
3366
0
      *nextPtr = next;
3367
0
      return XML_ERROR_NONE;
3368
0
    case XML_FINISHED:
3369
0
      return XML_ERROR_ABORTED;
3370
0
    default: ;
3371
0
    }
3372
0
  }
3373
0
  /* not reached */
3374
0
}
3375
3376
#ifdef XML_DTD
3377
3378
/* The idea here is to avoid using stack for each IGNORE section when
3379
   the whole file is parsed with one call.
3380
*/
3381
static enum XML_Error PTRCALL
3382
ignoreSectionProcessor(XML_Parser parser,
3383
                       const char *start,
3384
                       const char *end,
3385
                       const char **endPtr)
3386
0
{
3387
0
  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
3388
0
                                          endPtr, (XML_Bool)!ps_finalBuffer);
3389
0
  if (result != XML_ERROR_NONE)
3390
0
    return result;
3391
0
  if (start) {
3392
0
    processor = prologProcessor;
3393
0
    return prologProcessor(parser, start, end, endPtr);
3394
0
  }
3395
0
  return result;
3396
0
}
3397
3398
/* startPtr gets set to non-null is the section is closed, and to null
3399
   if the section is not yet closed.
3400
*/
3401
static enum XML_Error
3402
doIgnoreSection(XML_Parser parser,
3403
                const ENCODING *enc,
3404
                const char **startPtr,
3405
                const char *end,
3406
                const char **nextPtr,
3407
                XML_Bool haveMore)
3408
0
{
3409
0
  const char *next;
3410
0
  int tok;
3411
0
  const char *s = *startPtr;
3412
0
  const char **eventPP;
3413
0
  const char **eventEndPP;
3414
0
  if (enc == encoding) {
3415
0
    eventPP = &eventPtr;
3416
0
    *eventPP = s;
3417
0
    eventEndPP = &eventEndPtr;
3418
0
  }
3419
0
  else {
3420
0
    eventPP = &(openInternalEntities->internalEventPtr);
3421
0
    eventEndPP = &(openInternalEntities->internalEventEndPtr);
3422
0
  }
3423
0
  *eventPP = s;
3424
0
  *startPtr = NULL;
3425
0
  tok = XmlIgnoreSectionTok(enc, s, end, &next);
3426
0
  *eventEndPP = next;
3427
0
  switch (tok) {
3428
0
  case XML_TOK_IGNORE_SECT:
3429
0
    if (defaultHandler)
3430
0
      reportDefault(parser, enc, s, next);
3431
0
    *startPtr = next;
3432
0
    *nextPtr = next;
3433
0
    if (ps_parsing == XML_FINISHED)
3434
0
      return XML_ERROR_ABORTED;
3435
0
    else
3436
0
      return XML_ERROR_NONE;
3437
0
  case XML_TOK_INVALID:
3438
0
    *eventPP = next;
3439
0
    return XML_ERROR_INVALID_TOKEN;
3440
0
  case XML_TOK_PARTIAL_CHAR:
3441
0
    if (haveMore) {
3442
0
      *nextPtr = s;
3443
0
      return XML_ERROR_NONE;
3444
0
    }
3445
0
    return XML_ERROR_PARTIAL_CHAR;
3446
0
  case XML_TOK_PARTIAL:
3447
0
  case XML_TOK_NONE:
3448
0
    if (haveMore) {
3449
0
      *nextPtr = s;
3450
0
      return XML_ERROR_NONE;
3451
0
    }
3452
0
    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3453
0
  default:
3454
0
    *eventPP = next;
3455
0
    return XML_ERROR_UNEXPECTED_STATE;
3456
0
  }
3457
0
  /* not reached */
3458
0
}
3459
3460
#endif /* XML_DTD */
3461
3462
static enum XML_Error
3463
initializeEncoding(XML_Parser parser)
3464
0
{
3465
0
  const char *s;
3466
0
#ifdef XML_UNICODE
3467
0
  char encodingBuf[128];
3468
0
  if (!protocolEncodingName)
3469
0
    s = NULL;
3470
0
  else {
3471
0
    int i;
3472
0
    for (i = 0; protocolEncodingName[i]; i++) {
3473
0
      if (i == sizeof(encodingBuf) - 1
3474
0
          || (protocolEncodingName[i] & ~0x7f) != 0) {
3475
0
        encodingBuf[0] = '\0';
3476
0
        break;
3477
0
      }
3478
0
      encodingBuf[i] = (char)protocolEncodingName[i];
3479
0
    }
3480
0
    encodingBuf[i] = '\0';
3481
0
    s = encodingBuf;
3482
0
  }
3483
#else
3484
  s = protocolEncodingName;
3485
#endif
3486
0
  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3487
0
    return XML_ERROR_NONE;
3488
0
  return handleUnknownEncoding(parser, protocolEncodingName);
3489
0
}
3490
3491
static enum XML_Error
3492
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3493
               const char *s, const char *next)
3494
0
{
3495
0
  const char *encodingName = NULL;
3496
0
  const XML_Char *storedEncName = NULL;
3497
0
  const ENCODING *newEncoding = NULL;
3498
0
  const char *version = NULL;
3499
0
  const char *versionend;
3500
0
  const XML_Char *storedversion = NULL;
3501
0
  int standalone = -1;
3502
0
  if (!(ns
3503
0
        ? XmlParseXmlDeclNS
3504
0
        : XmlParseXmlDecl)(isGeneralTextEntity,
3505
0
                           encoding,
3506
0
                           s,
3507
0
                           next,
3508
0
                           &eventPtr,
3509
0
                           &version,
3510
0
                           &versionend,
3511
0
                           &encodingName,
3512
0
                           &newEncoding,
3513
0
                           &standalone)) {
3514
0
    if (isGeneralTextEntity)
3515
0
      return XML_ERROR_TEXT_DECL;
3516
0
    else
3517
0
      return XML_ERROR_XML_DECL;
3518
0
  }
3519
0
  if (!isGeneralTextEntity && standalone == 1) {
3520
0
    _dtd->standalone = XML_TRUE;
3521
0
#ifdef XML_DTD
3522
0
    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3523
0
      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3524
0
#endif /* XML_DTD */
3525
0
  }
3526
0
  if (xmlDeclHandler) {
3527
0
    if (encodingName != NULL) {
3528
0
      storedEncName = poolStoreString(&temp2Pool,
3529
0
                                      encoding,
3530
0
                                      encodingName,
3531
0
                                      encodingName
3532
0
                                      + XmlNameLength(encoding, encodingName));
3533
0
      if (!storedEncName)
3534
0
              return XML_ERROR_NO_MEMORY;
3535
0
      poolFinish(&temp2Pool);
3536
0
    }
3537
0
    if (version) {
3538
0
      storedversion = poolStoreString(&temp2Pool,
3539
0
                                      encoding,
3540
0
                                      version,
3541
0
                                      versionend - encoding->minBytesPerChar);
3542
0
      if (!storedversion)
3543
0
        return XML_ERROR_NO_MEMORY;
3544
0
    }
3545
0
    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3546
0
  }
3547
0
  else if (defaultHandler)
3548
0
    reportDefault(parser, encoding, s, next);
3549
0
  if (protocolEncodingName == NULL) {
3550
0
    if (newEncoding) {
3551
0
      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3552
0
        eventPtr = encodingName;
3553
0
        return XML_ERROR_INCORRECT_ENCODING;
3554
0
      }
3555
0
      encoding = newEncoding;
3556
0
    }
3557
0
    else if (encodingName) {
3558
0
      enum XML_Error result;
3559
0
      if (!storedEncName) {
3560
0
        storedEncName = poolStoreString(
3561
0
          &temp2Pool, encoding, encodingName,
3562
0
          encodingName + XmlNameLength(encoding, encodingName));
3563
0
        if (!storedEncName)
3564
0
          return XML_ERROR_NO_MEMORY;
3565
0
      }
3566
0
      result = handleUnknownEncoding(parser, storedEncName);
3567
0
      poolClear(&temp2Pool);
3568
0
      if (result == XML_ERROR_UNKNOWN_ENCODING)
3569
0
        eventPtr = encodingName;
3570
0
      return result;
3571
0
    }
3572
0
  }
3573
0
3574
0
  if (storedEncName || storedversion)
3575
0
    poolClear(&temp2Pool);
3576
0
3577
0
  return XML_ERROR_NONE;
3578
0
}
3579
3580
static enum XML_Error
3581
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3582
0
{
3583
0
  if (unknownEncodingHandler) {
3584
0
    XML_Encoding info;
3585
0
    int i;
3586
0
    for (i = 0; i < 256; i++)
3587
0
      info.map[i] = -1;
3588
0
    info.convert = NULL;
3589
0
    info.data = NULL;
3590
0
    info.release = NULL;
3591
0
    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3592
0
                               &info)) {
3593
0
      ENCODING *enc;
3594
0
      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3595
0
      if (!unknownEncodingMem) {
3596
0
        if (info.release)
3597
0
          info.release(info.data);
3598
0
        return XML_ERROR_NO_MEMORY;
3599
0
      }
3600
0
      enc = (ns
3601
0
             ? XmlInitUnknownEncodingNS
3602
0
             : XmlInitUnknownEncoding)(unknownEncodingMem,
3603
0
                                       info.map,
3604
0
                                       info.convert,
3605
0
                                       info.data);
3606
0
      if (enc) {
3607
0
        unknownEncodingData = info.data;
3608
0
        unknownEncodingRelease = info.release;
3609
0
        encoding = enc;
3610
0
        return XML_ERROR_NONE;
3611
0
      }
3612
0
    }
3613
0
    if (info.release != NULL)
3614
0
      info.release(info.data);
3615
0
  }
3616
0
  return XML_ERROR_UNKNOWN_ENCODING;
3617
0
}
3618
3619
static enum XML_Error PTRCALL
3620
prologInitProcessor(XML_Parser parser,
3621
                    const char *s,
3622
                    const char *end,
3623
                    const char **nextPtr)
3624
0
{
3625
0
  enum XML_Error result = initializeEncoding(parser);
3626
0
  if (result != XML_ERROR_NONE)
3627
0
    return result;
3628
0
  processor = prologProcessor;
3629
0
  return prologProcessor(parser, s, end, nextPtr);
3630
0
}
3631
3632
#ifdef XML_DTD
3633
3634
static enum XML_Error PTRCALL
3635
externalParEntInitProcessor(XML_Parser parser,
3636
                            const char *s,
3637
                            const char *end,
3638
                            const char **nextPtr)
3639
0
{
3640
0
  enum XML_Error result = initializeEncoding(parser);
3641
0
  if (result != XML_ERROR_NONE)
3642
0
    return result;
3643
0
3644
0
  /* we know now that XML_Parse(Buffer) has been called,
3645
0
     so we consider the external parameter entity read */
3646
0
  _dtd->paramEntityRead = XML_TRUE;
3647
0
3648
0
  if (prologState.inEntityValue) {
3649
0
    processor = entityValueInitProcessor;
3650
0
    return entityValueInitProcessor(parser, s, end, nextPtr);
3651
0
  }
3652
0
  else {
3653
0
    processor = externalParEntProcessor;
3654
0
    return externalParEntProcessor(parser, s, end, nextPtr);
3655
0
  }
3656
0
}
3657
3658
static enum XML_Error PTRCALL
3659
entityValueInitProcessor(XML_Parser parser,
3660
                         const char *s,
3661
                         const char *end,
3662
                         const char **nextPtr)
3663
0
{
3664
0
  int tok;
3665
0
  const char *start = s;
3666
0
  const char *next = start;
3667
0
  eventPtr = start;
3668
0
3669
0
  for (;;) {  
3670
0
    tok = XmlPrologTok(encoding, start, end, &next);
3671
0
    eventEndPtr = next;
3672
0
    if (tok <= 0) {
3673
0
      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3674
0
        *nextPtr = s;
3675
0
        return XML_ERROR_NONE;
3676
0
      }
3677
0
      switch (tok) {
3678
0
      case XML_TOK_INVALID:
3679
0
        return XML_ERROR_INVALID_TOKEN;
3680
0
      case XML_TOK_PARTIAL:
3681
0
        return XML_ERROR_UNCLOSED_TOKEN;
3682
0
      case XML_TOK_PARTIAL_CHAR:
3683
0
        return XML_ERROR_PARTIAL_CHAR;
3684
0
      case XML_TOK_NONE:   /* start == end */
3685
0
      default:
3686
0
        break;
3687
0
      }
3688
0
      /* found end of entity value - can store it now */
3689
0
      return storeEntityValue(parser, encoding, s, end);
3690
0
    }
3691
0
    else if (tok == XML_TOK_XML_DECL) {
3692
0
      enum XML_Error result;
3693
0
      result = processXmlDecl(parser, 0, start, next);
3694
0
      if (result != XML_ERROR_NONE)
3695
0
        return result;
3696
0
      switch (ps_parsing) {
3697
0
      case XML_SUSPENDED: 
3698
0
        *nextPtr = next;
3699
0
        return XML_ERROR_NONE;
3700
0
      case XML_FINISHED:
3701
0
        return XML_ERROR_ABORTED;
3702
0
      default:
3703
0
        *nextPtr = next;
3704
0
      }
3705
0
      /* stop scanning for text declaration - we found one */
3706
0
      processor = entityValueProcessor;
3707
0
      return entityValueProcessor(parser, next, end, nextPtr);
3708
0
    }
3709
0
    /* If we are at the end of the buffer, this would cause XmlPrologTok to
3710
0
       return XML_TOK_NONE on the next call, which would then cause the
3711
0
       function to exit with *nextPtr set to s - that is what we want for other
3712
0
       tokens, but not for the BOM - we would rather like to skip it;
3713
0
       then, when this routine is entered the next time, XmlPrologTok will
3714
0
       return XML_TOK_INVALID, since the BOM is still in the buffer
3715
0
    */
3716
0
    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
3717
0
      *nextPtr = next;
3718
0
      return XML_ERROR_NONE;
3719
0
    }
3720
0
    start = next;
3721
0
    eventPtr = start;
3722
0
  }
3723
0
}
3724
3725
static enum XML_Error PTRCALL
3726
externalParEntProcessor(XML_Parser parser,
3727
                        const char *s,
3728
                        const char *end,
3729
                        const char **nextPtr)
3730
0
{
3731
0
  const char *next = s;
3732
0
  int tok;
3733
0
3734
0
  tok = XmlPrologTok(encoding, s, end, &next);
3735
0
  if (tok <= 0) {
3736
0
    if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3737
0
      *nextPtr = s;
3738
0
      return XML_ERROR_NONE;
3739
0
    }
3740
0
    switch (tok) {
3741
0
    case XML_TOK_INVALID:
3742
0
      return XML_ERROR_INVALID_TOKEN;
3743
0
    case XML_TOK_PARTIAL:
3744
0
      return XML_ERROR_UNCLOSED_TOKEN;
3745
0
    case XML_TOK_PARTIAL_CHAR:
3746
0
      return XML_ERROR_PARTIAL_CHAR;
3747
0
    case XML_TOK_NONE:   /* start == end */
3748
0
    default:
3749
0
      break;
3750
0
    }
3751
0
  }
3752
0
  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3753
0
     However, when parsing an external subset, doProlog will not accept a BOM
3754
0
     as valid, and report a syntax error, so we have to skip the BOM
3755
0
  */
3756
0
  else if (tok == XML_TOK_BOM) {
3757
0
    s = next;
3758
0
    tok = XmlPrologTok(encoding, s, end, &next);
3759
0
  }
3760
0
3761
0
  processor = prologProcessor;
3762
0
  return doProlog(parser, encoding, s, end, tok, next, 
3763
0
                  nextPtr, (XML_Bool)!ps_finalBuffer);
3764
0
}
3765
3766
static enum XML_Error PTRCALL
3767
entityValueProcessor(XML_Parser parser,
3768
                     const char *s,
3769
                     const char *end,
3770
                     const char **nextPtr)
3771
0
{
3772
0
  const char *start = s;
3773
0
  const char *next = s;
3774
0
  const ENCODING *enc = encoding;
3775
0
  int tok;
3776
0
3777
0
  for (;;) {
3778
0
    tok = XmlPrologTok(enc, start, end, &next);
3779
0
    if (tok <= 0) {
3780
0
      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3781
0
        *nextPtr = s;
3782
0
        return XML_ERROR_NONE;
3783
0
      }
3784
0
      switch (tok) {
3785
0
      case XML_TOK_INVALID:
3786
0
        return XML_ERROR_INVALID_TOKEN;
3787
0
      case XML_TOK_PARTIAL:
3788
0
        return XML_ERROR_UNCLOSED_TOKEN;
3789
0
      case XML_TOK_PARTIAL_CHAR:
3790
0
        return XML_ERROR_PARTIAL_CHAR;
3791
0
      case XML_TOK_NONE:   /* start == end */
3792
0
      default:
3793
0
        break;
3794
0
      }
3795
0
      /* found end of entity value - can store it now */
3796
0
      return storeEntityValue(parser, enc, s, end);
3797
0
    }
3798
0
    start = next;
3799
0
  }
3800
0
}
3801
3802
#endif /* XML_DTD */
3803
3804
static enum XML_Error PTRCALL
3805
prologProcessor(XML_Parser parser,
3806
                const char *s,
3807
                const char *end,
3808
                const char **nextPtr)
3809
0
{
3810
0
  const char *next = s;
3811
0
  int tok = XmlPrologTok(encoding, s, end, &next);
3812
0
  return doProlog(parser, encoding, s, end, tok, next, 
3813
0
                  nextPtr, (XML_Bool)!ps_finalBuffer);
3814
0
}
3815
3816
static enum XML_Error
3817
doProlog(XML_Parser parser,
3818
         const ENCODING *enc,
3819
         const char *s,
3820
         const char *end,
3821
         int tok,
3822
         const char *next,
3823
         const char **nextPtr,
3824
         XML_Bool haveMore)
3825
0
{
3826
0
#ifdef XML_DTD
3827
0
  static const XML_Char externalSubsetName[] = { '#' , '\0' };
3828
0
#endif /* XML_DTD */
3829
0
  static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3830
0
  static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3831
0
  static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3832
0
  static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3833
0
  static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3834
0
  static const XML_Char atypeENTITIES[] =
3835
0
      { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3836
0
  static const XML_Char atypeNMTOKEN[] = {
3837
0
      'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3838
0
  static const XML_Char atypeNMTOKENS[] = {
3839
0
      'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3840
0
  static const XML_Char notationPrefix[] = {
3841
0
      'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3842
0
  static const XML_Char enumValueSep[] = { '|', '\0' };
3843
0
  static const XML_Char enumValueStart[] = { '(', '\0' };
3844
0
3845
0
  /* save one level of indirection */
3846
0
  DTD * const dtd = _dtd; 
3847
0
3848
0
  const char **eventPP;
3849
0
  const char **eventEndPP;
3850
0
  enum XML_Content_Quant quant;
3851
0
3852
0
  if (enc == encoding) {
3853
0
    eventPP = &eventPtr;
3854
0
    eventEndPP = &eventEndPtr;
3855
0
  }
3856
0
  else {
3857
0
    eventPP = &(openInternalEntities->internalEventPtr);
3858
0
    eventEndPP = &(openInternalEntities->internalEventEndPtr);
3859
0
  }
3860
0
3861
0
  for (;;) {
3862
0
    int role;
3863
0
    XML_Bool handleDefault = XML_TRUE;
3864
0
    *eventPP = s;
3865
0
    *eventEndPP = next;
3866
0
    if (tok <= 0) {
3867
0
      if (haveMore && tok != XML_TOK_INVALID) {
3868
0
        *nextPtr = s;
3869
0
        return XML_ERROR_NONE;
3870
0
      }
3871
0
      switch (tok) {
3872
0
      case XML_TOK_INVALID:
3873
0
        *eventPP = next;
3874
0
        return XML_ERROR_INVALID_TOKEN;
3875
0
      case XML_TOK_PARTIAL:
3876
0
        return XML_ERROR_UNCLOSED_TOKEN;
3877
0
      case XML_TOK_PARTIAL_CHAR:
3878
0
        return XML_ERROR_PARTIAL_CHAR;
3879
0
      case XML_TOK_NONE:
3880
0
#ifdef XML_DTD
3881
0
        /* for internal PE NOT referenced between declarations */
3882
0
        if (enc != encoding && !openInternalEntities->betweenDecl) {
3883
0
          *nextPtr = s;
3884
0
          return XML_ERROR_NONE;
3885
0
        }
3886
0
        /* WFC: PE Between Declarations - must check that PE contains
3887
0
           complete markup, not only for external PEs, but also for
3888
0
           internal PEs if the reference occurs between declarations.
3889
0
        */
3890
0
        if (isParamEntity || enc != encoding) {
3891
0
          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3892
0
              == XML_ROLE_ERROR)
3893
0
            return XML_ERROR_INCOMPLETE_PE;
3894
0
          *nextPtr = s;
3895
0
          return XML_ERROR_NONE;
3896
0
        }
3897
0
#endif /* XML_DTD */
3898
0
        return XML_ERROR_NO_ELEMENTS;
3899
0
      default:
3900
0
        tok = -tok;
3901
0
        next = end;
3902
0
        break;
3903
0
      }
3904
0
    }
3905
0
    role = XmlTokenRole(&prologState, tok, s, next, enc);
3906
0
    switch (role) {
3907
0
    case XML_ROLE_XML_DECL:
3908
0
      {
3909
0
        enum XML_Error result = processXmlDecl(parser, 0, s, next);
3910
0
        if (result != XML_ERROR_NONE)
3911
0
          return result;
3912
0
        enc = encoding;
3913
0
        handleDefault = XML_FALSE;
3914
0
      }
3915
0
      break;
3916
0
    case XML_ROLE_DOCTYPE_NAME:
3917
0
      if (startDoctypeDeclHandler) {
3918
0
        doctypeName = poolStoreString(&tempPool, enc, s, next);
3919
0
        if (!doctypeName)
3920
0
          return XML_ERROR_NO_MEMORY;
3921
0
        poolFinish(&tempPool);
3922
0
        doctypePubid = NULL;
3923
0
        handleDefault = XML_FALSE;
3924
0
      }
3925
0
      doctypeSysid = NULL; /* always initialize to NULL */
3926
0
      break;
3927
0
    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3928
0
      if (startDoctypeDeclHandler) {
3929
0
        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3930
0
                                doctypePubid, 1);
3931
0
        doctypeName = NULL;
3932
0
        poolClear(&tempPool);
3933
0
        handleDefault = XML_FALSE;
3934
0
      }
3935
0
      break;
3936
0
#ifdef XML_DTD
3937
0
    case XML_ROLE_TEXT_DECL:
3938
0
      {
3939
0
        enum XML_Error result = processXmlDecl(parser, 1, s, next);
3940
0
        if (result != XML_ERROR_NONE)
3941
0
          return result;
3942
0
        enc = encoding;
3943
0
        handleDefault = XML_FALSE;
3944
0
      }
3945
0
      break;
3946
0
#endif /* XML_DTD */
3947
0
    case XML_ROLE_DOCTYPE_PUBLIC_ID:
3948
0
#ifdef XML_DTD
3949
0
      useForeignDTD = XML_FALSE;
3950
0
      declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3951
0
                                    externalSubsetName,
3952
0
                                    sizeof(ENTITY));
3953
0
      if (!declEntity)
3954
0
        return XML_ERROR_NO_MEMORY;
3955
0
#endif /* XML_DTD */
3956
0
      dtd->hasParamEntityRefs = XML_TRUE;
3957
0
      if (startDoctypeDeclHandler) {
3958
0
        if (!XmlIsPublicId(enc, s, next, eventPP))
3959
0
          return XML_ERROR_PUBLICID;
3960
0
        doctypePubid = poolStoreString(&tempPool, enc,
3961
0
                                       s + enc->minBytesPerChar,
3962
0
                                       next - enc->minBytesPerChar);
3963
0
        if (!doctypePubid)
3964
0
          return XML_ERROR_NO_MEMORY;
3965
0
        normalizePublicId((XML_Char *)doctypePubid);
3966
0
        poolFinish(&tempPool);
3967
0
        handleDefault = XML_FALSE;
3968
0
        goto alreadyChecked;
3969
0
      }
3970
0
      /* fall through */
3971
0
    case XML_ROLE_ENTITY_PUBLIC_ID:
3972
0
      if (!XmlIsPublicId(enc, s, next, eventPP))
3973
0
        return XML_ERROR_PUBLICID;
3974
0
    alreadyChecked:
3975
0
      if (dtd->keepProcessing && declEntity) {
3976
0
        XML_Char *tem = poolStoreString(&dtd->pool,
3977
0
                                        enc,
3978
0
                                        s + enc->minBytesPerChar,
3979
0
                                        next - enc->minBytesPerChar);
3980
0
        if (!tem)
3981
0
          return XML_ERROR_NO_MEMORY;
3982
0
        normalizePublicId(tem);
3983
0
        declEntity->publicId = tem;
3984
0
        poolFinish(&dtd->pool);
3985
0
        if (entityDeclHandler)
3986
0
          handleDefault = XML_FALSE;
3987
0
      }
3988
0
      break;
3989
0
    case XML_ROLE_DOCTYPE_CLOSE:
3990
0
      if (doctypeName) {
3991
0
        startDoctypeDeclHandler(handlerArg, doctypeName,
3992
0
                                doctypeSysid, doctypePubid, 0);
3993
0
        poolClear(&tempPool);
3994
0
        handleDefault = XML_FALSE;
3995
0
      }
3996
0
      /* doctypeSysid will be non-NULL in the case of a previous
3997
0
         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3998
0
         was not set, indicating an external subset
3999
0
      */
4000
0
#ifdef XML_DTD
4001
0
      if (doctypeSysid || useForeignDTD) {
4002
0
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4003
0
        dtd->hasParamEntityRefs = XML_TRUE;
4004
0
        if (paramEntityParsing && externalEntityRefHandler) {
4005
0
          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
4006
0
                                            externalSubsetName,
4007
0
                                            sizeof(ENTITY));
4008
0
          if (!entity)
4009
0
            return XML_ERROR_NO_MEMORY;
4010
0
          if (useForeignDTD)
4011
0
            entity->base = curBase;
4012
0
          dtd->paramEntityRead = XML_FALSE;
4013
0
          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4014
0
                                        0,
4015
0
                                        entity->base,
4016
0
                                        entity->systemId,
4017
0
                                        entity->publicId))
4018
0
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4019
0
          if (dtd->paramEntityRead) {
4020
0
            if (!dtd->standalone && 
4021
0
                notStandaloneHandler && 
4022
0
                !notStandaloneHandler(handlerArg))
4023
0
              return XML_ERROR_NOT_STANDALONE;
4024
0
          }
4025
0
          /* if we didn't read the foreign DTD then this means that there
4026
0
             is no external subset and we must reset dtd->hasParamEntityRefs
4027
0
          */
4028
0
          else if (!doctypeSysid)
4029
0
            dtd->hasParamEntityRefs = hadParamEntityRefs;
4030
0
          /* end of DTD - no need to update dtd->keepProcessing */
4031
0
        }
4032
0
        useForeignDTD = XML_FALSE;
4033
0
      }
4034
0
#endif /* XML_DTD */
4035
0
      if (endDoctypeDeclHandler) {
4036
0
        endDoctypeDeclHandler(handlerArg);
4037
0
        handleDefault = XML_FALSE;
4038
0
      }
4039
0
      break;
4040
0
    case XML_ROLE_INSTANCE_START:
4041
0
#ifdef XML_DTD
4042
0
      /* if there is no DOCTYPE declaration then now is the
4043
0
         last chance to read the foreign DTD
4044
0
      */
4045
0
      if (useForeignDTD) {
4046
0
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4047
0
        dtd->hasParamEntityRefs = XML_TRUE;
4048
0
        if (paramEntityParsing && externalEntityRefHandler) {
4049
0
          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
4050
0
                                            externalSubsetName,
4051
0
                                            sizeof(ENTITY));
4052
0
          if (!entity)
4053
0
            return XML_ERROR_NO_MEMORY;
4054
0
          entity->base = curBase;
4055
0
          dtd->paramEntityRead = XML_FALSE;
4056
0
          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4057
0
                                        0,
4058
0
                                        entity->base,
4059
0
                                        entity->systemId,
4060
0
                                        entity->publicId))
4061
0
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4062
0
          if (dtd->paramEntityRead) {
4063
0
            if (!dtd->standalone &&
4064
0
                notStandaloneHandler &&
4065
0
                !notStandaloneHandler(handlerArg))
4066
0
              return XML_ERROR_NOT_STANDALONE;
4067
0
          }
4068
0
          /* if we didn't read the foreign DTD then this means that there
4069
0
             is no external subset and we must reset dtd->hasParamEntityRefs
4070
0
          */
4071
0
          else
4072
0
            dtd->hasParamEntityRefs = hadParamEntityRefs;
4073
0
          /* end of DTD - no need to update dtd->keepProcessing */
4074
0
        }
4075
0
      }
4076
0
#endif /* XML_DTD */
4077
0
      processor = contentProcessor;
4078
0
      return contentProcessor(parser, s, end, nextPtr);
4079
0
    case XML_ROLE_ATTLIST_ELEMENT_NAME:
4080
0
      declElementType = getElementType(parser, enc, s, next);
4081
0
      if (!declElementType)
4082
0
        return XML_ERROR_NO_MEMORY;
4083
0
      goto checkAttListDeclHandler;
4084
0
    case XML_ROLE_ATTRIBUTE_NAME:
4085
0
      declAttributeId = getAttributeId(parser, enc, s, next);
4086
0
      if (!declAttributeId)
4087
0
        return XML_ERROR_NO_MEMORY;
4088
0
      declAttributeIsCdata = XML_FALSE;
4089
0
      declAttributeType = NULL;
4090
0
      declAttributeIsId = XML_FALSE;
4091
0
      goto checkAttListDeclHandler;
4092
0
    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4093
0
      declAttributeIsCdata = XML_TRUE;
4094
0
      declAttributeType = atypeCDATA;
4095
0
      goto checkAttListDeclHandler;
4096
0
    case XML_ROLE_ATTRIBUTE_TYPE_ID:
4097
0
      declAttributeIsId = XML_TRUE;
4098
0
      declAttributeType = atypeID;
4099
0
      goto checkAttListDeclHandler;
4100
0
    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4101
0
      declAttributeType = atypeIDREF;
4102
0
      goto checkAttListDeclHandler;
4103
0
    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4104
0
      declAttributeType = atypeIDREFS;
4105
0
      goto checkAttListDeclHandler;
4106
0
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4107
0
      declAttributeType = atypeENTITY;
4108
0
      goto checkAttListDeclHandler;
4109
0
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4110
0
      declAttributeType = atypeENTITIES;
4111
0
      goto checkAttListDeclHandler;
4112
0
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4113
0
      declAttributeType = atypeNMTOKEN;
4114
0
      goto checkAttListDeclHandler;
4115
0
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4116
0
      declAttributeType = atypeNMTOKENS;
4117
0
    checkAttListDeclHandler:
4118
0
      if (dtd->keepProcessing && attlistDeclHandler)
4119
0
        handleDefault = XML_FALSE;
4120
0
      break;
4121
0
    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4122
0
    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4123
0
      if (dtd->keepProcessing && attlistDeclHandler) {
4124
0
        const XML_Char *prefix;
4125
0
        if (declAttributeType) {
4126
0
          prefix = enumValueSep;
4127
0
        }
4128
0
        else {
4129
0
          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4130
0
                    ? notationPrefix
4131
0
                    : enumValueStart);
4132
0
        }
4133
0
        if (!poolAppendString(&tempPool, prefix))
4134
0
          return XML_ERROR_NO_MEMORY;
4135
0
        if (!poolAppend(&tempPool, enc, s, next))
4136
0
          return XML_ERROR_NO_MEMORY;
4137
0
        declAttributeType = tempPool.start;
4138
0
        handleDefault = XML_FALSE;
4139
0
      }
4140
0
      break;
4141
0
    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4142
0
    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4143
0
      if (dtd->keepProcessing) {
4144
0
        if (!defineAttribute(declElementType, declAttributeId,
4145
0
                             declAttributeIsCdata, declAttributeIsId,
4146
0
                             0, parser))
4147
0
          return XML_ERROR_NO_MEMORY;
4148
0
        if (attlistDeclHandler && declAttributeType) {
4149
0
          if (*declAttributeType == XML_T('(')
4150
0
              || (*declAttributeType == XML_T('N')
4151
0
                  && declAttributeType[1] == XML_T('O'))) {
4152
0
            /* Enumerated or Notation type */
4153
0
            if (!poolAppendChar(&tempPool, XML_T(')'))
4154
0
                || !poolAppendChar(&tempPool, XML_T('\0')))
4155
0
              return XML_ERROR_NO_MEMORY;
4156
0
            declAttributeType = tempPool.start;
4157
0
            poolFinish(&tempPool);
4158
0
          }
4159
0
          *eventEndPP = s;
4160
0
          attlistDeclHandler(handlerArg, declElementType->name,
4161
0
                             declAttributeId->name, declAttributeType,
4162
0
                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4163
0
          poolClear(&tempPool);
4164
0
          handleDefault = XML_FALSE;
4165
0
        }
4166
0
      }
4167
0
      break;
4168
0
    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4169
0
    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4170
0
      if (dtd->keepProcessing) {
4171
0
        const XML_Char *attVal;
4172
0
        enum XML_Error result =
4173
0
          storeAttributeValue(parser, enc, declAttributeIsCdata,
4174
0
                              s + enc->minBytesPerChar,
4175
0
                              next - enc->minBytesPerChar,
4176
0
                              &dtd->pool);
4177
0
        if (result)
4178
0
          return result;
4179
0
        attVal = poolStart(&dtd->pool);
4180
0
        poolFinish(&dtd->pool);
4181
0
        /* ID attributes aren't allowed to have a default */
4182
0
        if (!defineAttribute(declElementType, declAttributeId,
4183
0
                             declAttributeIsCdata, XML_FALSE, attVal, parser))
4184
0
          return XML_ERROR_NO_MEMORY;
4185
0
        if (attlistDeclHandler && declAttributeType) {
4186
0
          if (*declAttributeType == XML_T('(')
4187
0
              || (*declAttributeType == XML_T('N')
4188
0
                  && declAttributeType[1] == XML_T('O'))) {
4189
0
            /* Enumerated or Notation type */
4190
0
            if (!poolAppendChar(&tempPool, XML_T(')'))
4191
0
                || !poolAppendChar(&tempPool, XML_T('\0')))
4192
0
              return XML_ERROR_NO_MEMORY;
4193
0
            declAttributeType = tempPool.start;
4194
0
            poolFinish(&tempPool);
4195
0
          }
4196
0
          *eventEndPP = s;
4197
0
          attlistDeclHandler(handlerArg, declElementType->name,
4198
0
                             declAttributeId->name, declAttributeType,
4199
0
                             attVal,
4200
0
                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4201
0
          poolClear(&tempPool);
4202
0
          handleDefault = XML_FALSE;
4203
0
        }
4204
0
      }
4205
0
      break;
4206
0
    case XML_ROLE_ENTITY_VALUE:
4207
0
      if (dtd->keepProcessing) {
4208
0
        enum XML_Error result = storeEntityValue(parser, enc,
4209
0
                                            s + enc->minBytesPerChar,
4210
0
                                            next - enc->minBytesPerChar);
4211
0
        if (declEntity) {
4212
0
          declEntity->textPtr = poolStart(&dtd->entityValuePool);
4213
0
          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4214
0
          poolFinish(&dtd->entityValuePool);
4215
0
          if (entityDeclHandler) {
4216
0
            *eventEndPP = s;
4217
0
            entityDeclHandler(handlerArg,
4218
0
                              declEntity->name,
4219
0
                              declEntity->is_param,
4220
0
                              declEntity->textPtr,
4221
0
                              declEntity->textLen,
4222
0
                              curBase, 0, 0, 0);
4223
0
            handleDefault = XML_FALSE;
4224
0
          }
4225
0
        }
4226
0
        else
4227
0
          poolDiscard(&dtd->entityValuePool);
4228
0
        if (result != XML_ERROR_NONE)
4229
0
          return result;
4230
0
      }
4231
0
      break;
4232
0
    case XML_ROLE_DOCTYPE_SYSTEM_ID:
4233
0
#ifdef XML_DTD
4234
0
      useForeignDTD = XML_FALSE;
4235
0
#endif /* XML_DTD */
4236
0
      dtd->hasParamEntityRefs = XML_TRUE;
4237
0
      if (startDoctypeDeclHandler) {
4238
0
        doctypeSysid = poolStoreString(&tempPool, enc,
4239
0
                                       s + enc->minBytesPerChar,
4240
0
                                       next - enc->minBytesPerChar);
4241
0
        if (doctypeSysid == NULL)
4242
0
          return XML_ERROR_NO_MEMORY;
4243
0
        poolFinish(&tempPool);
4244
0
        handleDefault = XML_FALSE;
4245
0
      }
4246
0
#ifdef XML_DTD
4247
0
      else
4248
0
        /* use externalSubsetName to make doctypeSysid non-NULL
4249
0
           for the case where no startDoctypeDeclHandler is set */
4250
0
        doctypeSysid = externalSubsetName;
4251
0
#endif /* XML_DTD */
4252
0
      if (!dtd->standalone
4253
0
#ifdef XML_DTD
4254
0
          && !paramEntityParsing
4255
0
#endif /* XML_DTD */
4256
0
          && notStandaloneHandler
4257
0
          && !notStandaloneHandler(handlerArg))
4258
0
        return XML_ERROR_NOT_STANDALONE;
4259
#ifndef XML_DTD
4260
      break;
4261
#else /* XML_DTD */
4262
0
      if (!declEntity) {
4263
0
        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4264
0
                                      externalSubsetName,
4265
0
                                      sizeof(ENTITY));
4266
0
        if (!declEntity)
4267
0
          return XML_ERROR_NO_MEMORY;
4268
0
        declEntity->publicId = NULL;
4269
0
      }
4270
0
      /* fall through */
4271
0
#endif /* XML_DTD */
4272
0
    case XML_ROLE_ENTITY_SYSTEM_ID:
4273
0
      if (dtd->keepProcessing && declEntity) {
4274
0
        declEntity->systemId = poolStoreString(&dtd->pool, enc,
4275
0
                                               s + enc->minBytesPerChar,
4276
0
                                               next - enc->minBytesPerChar);
4277
0
        if (!declEntity->systemId)
4278
0
          return XML_ERROR_NO_MEMORY;
4279
0
        declEntity->base = curBase;
4280
0
        poolFinish(&dtd->pool);
4281
0
        if (entityDeclHandler)
4282
0
          handleDefault = XML_FALSE;
4283
0
      }
4284
0
      break;
4285
0
    case XML_ROLE_ENTITY_COMPLETE:
4286
0
      if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4287
0
        *eventEndPP = s;
4288
0
        entityDeclHandler(handlerArg,
4289
0
                          declEntity->name,
4290
0
                          declEntity->is_param,
4291
0
                          0,0,
4292
0
                          declEntity->base,
4293
0
                          declEntity->systemId,
4294
0
                          declEntity->publicId,
4295
0
                          0);
4296
0
        handleDefault = XML_FALSE;
4297
0
      }
4298
0
      break;
4299
0
    case XML_ROLE_ENTITY_NOTATION_NAME:
4300
0
      if (dtd->keepProcessing && declEntity) {
4301
0
        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4302
0
        if (!declEntity->notation)
4303
0
          return XML_ERROR_NO_MEMORY;
4304
0
        poolFinish(&dtd->pool);
4305
0
        if (unparsedEntityDeclHandler) {
4306
0
          *eventEndPP = s;
4307
0
          unparsedEntityDeclHandler(handlerArg,
4308
0
                                    declEntity->name,
4309
0
                                    declEntity->base,
4310
0
                                    declEntity->systemId,
4311
0
                                    declEntity->publicId,
4312
0
                                    declEntity->notation);
4313
0
          handleDefault = XML_FALSE;
4314
0
        }
4315
0
        else if (entityDeclHandler) {
4316
0
          *eventEndPP = s;
4317
0
          entityDeclHandler(handlerArg,
4318
0
                            declEntity->name,
4319
0
                            0,0,0,
4320
0
                            declEntity->base,
4321
0
                            declEntity->systemId,
4322
0
                            declEntity->publicId,
4323
0
                            declEntity->notation);
4324
0
          handleDefault = XML_FALSE;
4325
0
        }
4326
0
      }
4327
0
      break;
4328
0
    case XML_ROLE_GENERAL_ENTITY_NAME:
4329
0
      {
4330
0
        if (XmlPredefinedEntityName(enc, s, next)) {
4331
0
          declEntity = NULL;
4332
0
          break;
4333
0
        }
4334
0
        if (dtd->keepProcessing) {
4335
0
          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4336
0
          if (!name)
4337
0
            return XML_ERROR_NO_MEMORY;
4338
0
          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
4339
0
                                        sizeof(ENTITY));
4340
0
          if (!declEntity)
4341
0
            return XML_ERROR_NO_MEMORY;
4342
0
          if (declEntity->name != name) {
4343
0
            poolDiscard(&dtd->pool);
4344
0
            declEntity = NULL;
4345
0
          }
4346
0
          else {
4347
0
            poolFinish(&dtd->pool);
4348
0
            declEntity->publicId = NULL;
4349
0
            declEntity->is_param = XML_FALSE;
4350
0
            /* if we have a parent parser or are reading an internal parameter
4351
0
               entity, then the entity declaration is not considered "internal"
4352
0
            */
4353
0
            declEntity->is_internal = !(parentParser || openInternalEntities);
4354
0
            if (entityDeclHandler)
4355
0
              handleDefault = XML_FALSE;
4356
0
          }
4357
0
        }
4358
0
        else {
4359
0
          poolDiscard(&dtd->pool);
4360
0
          declEntity = NULL;
4361
0
        }
4362
0
      }
4363
0
      break;
4364
0
    case XML_ROLE_PARAM_ENTITY_NAME:
4365
0
#ifdef XML_DTD
4366
0
      if (dtd->keepProcessing) {
4367
0
        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4368
0
        if (!name)
4369
0
          return XML_ERROR_NO_MEMORY;
4370
0
        declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4371
0
                                           name, sizeof(ENTITY));
4372
0
        if (!declEntity)
4373
0
          return XML_ERROR_NO_MEMORY;
4374
0
        if (declEntity->name != name) {
4375
0
          poolDiscard(&dtd->pool);
4376
0
          declEntity = NULL;
4377
0
        }
4378
0
        else {
4379
0
          poolFinish(&dtd->pool);
4380
0
          declEntity->publicId = NULL;
4381
0
          declEntity->is_param = XML_TRUE;
4382
0
          /* if we have a parent parser or are reading an internal parameter
4383
0
             entity, then the entity declaration is not considered "internal"
4384
0
          */
4385
0
          declEntity->is_internal = !(parentParser || openInternalEntities);
4386
0
          if (entityDeclHandler)
4387
0
            handleDefault = XML_FALSE;
4388
0
        }
4389
0
      }
4390
0
      else {
4391
0
        poolDiscard(&dtd->pool);
4392
0
        declEntity = NULL;
4393
0
      }
4394
#else /* not XML_DTD */
4395
      declEntity = NULL;
4396
#endif /* XML_DTD */
4397
0
      break;
4398
0
    case XML_ROLE_NOTATION_NAME:
4399
0
      declNotationPublicId = NULL;
4400
0
      declNotationName = NULL;
4401
0
      if (notationDeclHandler) {
4402
0
        declNotationName = poolStoreString(&tempPool, enc, s, next);
4403
0
        if (!declNotationName)
4404
0
          return XML_ERROR_NO_MEMORY;
4405
0
        poolFinish(&tempPool);
4406
0
        handleDefault = XML_FALSE;
4407
0
      }
4408
0
      break;
4409
0
    case XML_ROLE_NOTATION_PUBLIC_ID:
4410
0
      if (!XmlIsPublicId(enc, s, next, eventPP))
4411
0
        return XML_ERROR_PUBLICID;
4412
0
      if (declNotationName) {  /* means notationDeclHandler != NULL */
4413
0
        XML_Char *tem = poolStoreString(&tempPool,
4414
0
                                        enc,
4415
0
                                        s + enc->minBytesPerChar,
4416
0
                                        next - enc->minBytesPerChar);
4417
0
        if (!tem)
4418
0
          return XML_ERROR_NO_MEMORY;
4419
0
        normalizePublicId(tem);
4420
0
        declNotationPublicId = tem;
4421
0
        poolFinish(&tempPool);
4422
0
        handleDefault = XML_FALSE;
4423
0
      }
4424
0
      break;
4425
0
    case XML_ROLE_NOTATION_SYSTEM_ID:
4426
0
      if (declNotationName && notationDeclHandler) {
4427
0
        const XML_Char *systemId
4428
0
          = poolStoreString(&tempPool, enc,
4429
0
                            s + enc->minBytesPerChar,
4430
0
                            next - enc->minBytesPerChar);
4431
0
        if (!systemId)
4432
0
          return XML_ERROR_NO_MEMORY;
4433
0
        *eventEndPP = s;
4434
0
        notationDeclHandler(handlerArg,
4435
0
                            declNotationName,
4436
0
                            curBase,
4437
0
                            systemId,
4438
0
                            declNotationPublicId);
4439
0
        handleDefault = XML_FALSE;
4440
0
      }
4441
0
      poolClear(&tempPool);
4442
0
      break;
4443
0
    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4444
0
      if (declNotationPublicId && notationDeclHandler) {
4445
0
        *eventEndPP = s;
4446
0
        notationDeclHandler(handlerArg,
4447
0
                            declNotationName,
4448
0
                            curBase,
4449
0
                            0,
4450
0
                            declNotationPublicId);
4451
0
        handleDefault = XML_FALSE;
4452
0
      }
4453
0
      poolClear(&tempPool);
4454
0
      break;
4455
0
    case XML_ROLE_ERROR:
4456
0
      switch (tok) {
4457
0
      case XML_TOK_PARAM_ENTITY_REF:
4458
0
        /* PE references in internal subset are
4459
0
           not allowed within declarations. */  
4460
0
        return XML_ERROR_PARAM_ENTITY_REF;
4461
0
      case XML_TOK_XML_DECL:
4462
0
        return XML_ERROR_MISPLACED_XML_PI;
4463
0
      default:
4464
0
        return XML_ERROR_SYNTAX;
4465
0
      }
4466
0
#ifdef XML_DTD
4467
0
    case XML_ROLE_IGNORE_SECT:
4468
0
      {
4469
0
        enum XML_Error result;
4470
0
        if (defaultHandler)
4471
0
          reportDefault(parser, enc, s, next);
4472
0
        handleDefault = XML_FALSE;
4473
0
        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4474
0
        if (result != XML_ERROR_NONE)
4475
0
          return result;
4476
0
        else if (!next) {
4477
0
          processor = ignoreSectionProcessor;
4478
0
          return result;
4479
0
        }
4480
0
      }
4481
0
      break;
4482
0
#endif /* XML_DTD */
4483
0
    case XML_ROLE_GROUP_OPEN:
4484
0
      if (prologState.level >= groupSize) {
4485
0
        if (groupSize) {
4486
0
          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4487
0
          if (temp == NULL)
4488
0
            return XML_ERROR_NO_MEMORY;
4489
0
          groupConnector = temp;
4490
0
          if (dtd->scaffIndex) {
4491
0
            int *temp = (int *)REALLOC(dtd->scaffIndex,
4492
0
                          groupSize * sizeof(int));
4493
0
            if (temp == NULL)
4494
0
              return XML_ERROR_NO_MEMORY;
4495
0
            dtd->scaffIndex = temp;
4496
0
          }
4497
0
        }
4498
0
        else {
4499
0
          groupConnector = (char *)MALLOC(groupSize = 32);
4500
0
          if (!groupConnector)
4501
0
            return XML_ERROR_NO_MEMORY;
4502
0
        }
4503
0
      }
4504
0
      groupConnector[prologState.level] = 0;
4505
0
      if (dtd->in_eldecl) {
4506
0
        int myindex = nextScaffoldPart(parser);
4507
0
        if (myindex < 0)
4508
0
          return XML_ERROR_NO_MEMORY;
4509
0
        dtd->scaffIndex[dtd->scaffLevel] = myindex;
4510
0
        dtd->scaffLevel++;
4511
0
        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4512
0
        if (elementDeclHandler)
4513
0
          handleDefault = XML_FALSE;
4514
0
      }
4515
0
      break;
4516
0
    case XML_ROLE_GROUP_SEQUENCE:
4517
0
      if (groupConnector[prologState.level] == '|')
4518
0
        return XML_ERROR_SYNTAX;
4519
0
      groupConnector[prologState.level] = ',';
4520
0
      if (dtd->in_eldecl && elementDeclHandler)
4521
0
        handleDefault = XML_FALSE;
4522
0
      break;
4523
0
    case XML_ROLE_GROUP_CHOICE:
4524
0
      if (groupConnector[prologState.level] == ',')
4525
0
        return XML_ERROR_SYNTAX;
4526
0
      if (dtd->in_eldecl
4527
0
          && !groupConnector[prologState.level]
4528
0
          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4529
0
              != XML_CTYPE_MIXED)
4530
0
          ) {
4531
0
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4532
0
            = XML_CTYPE_CHOICE;
4533
0
        if (elementDeclHandler)
4534
0
          handleDefault = XML_FALSE;
4535
0
      }
4536
0
      groupConnector[prologState.level] = '|';
4537
0
      break;
4538
0
    case XML_ROLE_PARAM_ENTITY_REF:
4539
0
#ifdef XML_DTD
4540
0
    case XML_ROLE_INNER_PARAM_ENTITY_REF:
4541
0
      dtd->hasParamEntityRefs = XML_TRUE;
4542
0
      if (!paramEntityParsing)
4543
0
        dtd->keepProcessing = dtd->standalone;
4544
0
      else {
4545
0
        const XML_Char *name;
4546
0
        ENTITY *entity;
4547
0
        name = poolStoreString(&dtd->pool, enc,
4548
0
                                s + enc->minBytesPerChar,
4549
0
                                next - enc->minBytesPerChar);
4550
0
        if (!name)
4551
0
          return XML_ERROR_NO_MEMORY;
4552
0
        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4553
0
        poolDiscard(&dtd->pool);
4554
0
        /* first, determine if a check for an existing declaration is needed;
4555
0
           if yes, check that the entity exists, and that it is internal,
4556
0
           otherwise call the skipped entity handler
4557
0
        */
4558
0
        if (prologState.documentEntity &&
4559
0
            (dtd->standalone
4560
0
             ? !openInternalEntities
4561
0
             : !dtd->hasParamEntityRefs)) {
4562
0
          if (!entity)
4563
0
            return XML_ERROR_UNDEFINED_ENTITY;
4564
0
          else if (!entity->is_internal)
4565
0
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
4566
0
        }
4567
0
        else if (!entity) {
4568
0
          dtd->keepProcessing = dtd->standalone;
4569
0
          /* cannot report skipped entities in declarations */
4570
0
          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4571
0
            skippedEntityHandler(handlerArg, name, 1);
4572
0
            handleDefault = XML_FALSE;
4573
0
          }
4574
0
          break;
4575
0
        }
4576
0
        if (entity->open)
4577
0
          return XML_ERROR_RECURSIVE_ENTITY_REF;
4578
0
        if (entity->textPtr) {
4579
0
          enum XML_Error result;
4580
0
          XML_Bool betweenDecl = 
4581
0
            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4582
0
          result = processInternalEntity(parser, entity, betweenDecl);
4583
0
          if (result != XML_ERROR_NONE)
4584
0
            return result;
4585
0
          handleDefault = XML_FALSE;
4586
0
          break;
4587
0
        }
4588
0
        if (externalEntityRefHandler) {
4589
0
          dtd->paramEntityRead = XML_FALSE;
4590
0
          entity->open = XML_TRUE;
4591
0
          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4592
0
/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=191482) */
4593
#if 0
4594
                                        0,
4595
#else
4596
                                        entity->name,
4597
0
#endif
4598
0
/* END MOZILLA CHANGE */
4599
0
                                        entity->base,
4600
0
                                        entity->systemId,
4601
0
                                        entity->publicId)) {
4602
0
            entity->open = XML_FALSE;
4603
0
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4604
0
          }
4605
0
          entity->open = XML_FALSE;
4606
0
          handleDefault = XML_FALSE;
4607
0
          if (!dtd->paramEntityRead) {
4608
0
            dtd->keepProcessing = dtd->standalone;
4609
0
            break;
4610
0
          }
4611
0
        }
4612
0
        else {
4613
0
          dtd->keepProcessing = dtd->standalone;
4614
0
          break;
4615
0
        }
4616
0
      }
4617
0
#endif /* XML_DTD */
4618
0
      if (!dtd->standalone &&
4619
0
          notStandaloneHandler &&
4620
0
          !notStandaloneHandler(handlerArg))
4621
0
        return XML_ERROR_NOT_STANDALONE;
4622
0
      break;
4623
0
4624
0
    /* Element declaration stuff */
4625
0
4626
0
    case XML_ROLE_ELEMENT_NAME:
4627
0
      if (elementDeclHandler) {
4628
0
        declElementType = getElementType(parser, enc, s, next);
4629
0
        if (!declElementType)
4630
0
          return XML_ERROR_NO_MEMORY;
4631
0
        dtd->scaffLevel = 0;
4632
0
        dtd->scaffCount = 0;
4633
0
        dtd->in_eldecl = XML_TRUE;
4634
0
        handleDefault = XML_FALSE;
4635
0
      }
4636
0
      break;
4637
0
4638
0
    case XML_ROLE_CONTENT_ANY:
4639
0
    case XML_ROLE_CONTENT_EMPTY:
4640
0
      if (dtd->in_eldecl) {
4641
0
        if (elementDeclHandler) {
4642
0
          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4643
0
          if (!content)
4644
0
            return XML_ERROR_NO_MEMORY;
4645
0
          content->quant = XML_CQUANT_NONE;
4646
0
          content->name = NULL;
4647
0
          content->numchildren = 0;
4648
0
          content->children = NULL;
4649
0
          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4650
0
                           XML_CTYPE_ANY :
4651
0
                           XML_CTYPE_EMPTY);
4652
0
          *eventEndPP = s;
4653
0
          elementDeclHandler(handlerArg, declElementType->name, content);
4654
0
          handleDefault = XML_FALSE;
4655
0
        }
4656
0
        dtd->in_eldecl = XML_FALSE;
4657
0
      }
4658
0
      break;
4659
0
4660
0
    case XML_ROLE_CONTENT_PCDATA:
4661
0
      if (dtd->in_eldecl) {
4662
0
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4663
0
            = XML_CTYPE_MIXED;
4664
0
        if (elementDeclHandler)
4665
0
          handleDefault = XML_FALSE;
4666
0
      }
4667
0
      break;
4668
0
4669
0
    case XML_ROLE_CONTENT_ELEMENT:
4670
0
      quant = XML_CQUANT_NONE;
4671
0
      goto elementContent;
4672
0
    case XML_ROLE_CONTENT_ELEMENT_OPT:
4673
0
      quant = XML_CQUANT_OPT;
4674
0
      goto elementContent;
4675
0
    case XML_ROLE_CONTENT_ELEMENT_REP:
4676
0
      quant = XML_CQUANT_REP;
4677
0
      goto elementContent;
4678
0
    case XML_ROLE_CONTENT_ELEMENT_PLUS:
4679
0
      quant = XML_CQUANT_PLUS;
4680
0
    elementContent:
4681
0
      if (dtd->in_eldecl) {
4682
0
        ELEMENT_TYPE *el;
4683
0
        const XML_Char *name;
4684
0
        int nameLen;
4685
0
        const char *nxt = (quant == XML_CQUANT_NONE
4686
0
                           ? next
4687
0
                           : next - enc->minBytesPerChar);
4688
0
        int myindex = nextScaffoldPart(parser);
4689
0
        if (myindex < 0)
4690
0
          return XML_ERROR_NO_MEMORY;
4691
0
        dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4692
0
        dtd->scaffold[myindex].quant = quant;
4693
0
        el = getElementType(parser, enc, s, nxt);
4694
0
        if (!el)
4695
0
          return XML_ERROR_NO_MEMORY;
4696
0
        name = el->name;
4697
0
        dtd->scaffold[myindex].name = name;
4698
0
        nameLen = 0;
4699
0
        for (; name[nameLen++]; );
4700
0
        dtd->contentStringLen +=  nameLen;
4701
0
        if (elementDeclHandler)
4702
0
          handleDefault = XML_FALSE;
4703
0
      }
4704
0
      break;
4705
0
4706
0
    case XML_ROLE_GROUP_CLOSE:
4707
0
      quant = XML_CQUANT_NONE;
4708
0
      goto closeGroup;
4709
0
    case XML_ROLE_GROUP_CLOSE_OPT:
4710
0
      quant = XML_CQUANT_OPT;
4711
0
      goto closeGroup;
4712
0
    case XML_ROLE_GROUP_CLOSE_REP:
4713
0
      quant = XML_CQUANT_REP;
4714
0
      goto closeGroup;
4715
0
    case XML_ROLE_GROUP_CLOSE_PLUS:
4716
0
      quant = XML_CQUANT_PLUS;
4717
0
    closeGroup:
4718
0
      if (dtd->in_eldecl) {
4719
0
        if (elementDeclHandler)
4720
0
          handleDefault = XML_FALSE;
4721
0
        dtd->scaffLevel--;
4722
0
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4723
0
        if (dtd->scaffLevel == 0) {
4724
0
          if (!handleDefault) {
4725
0
            XML_Content *model = build_model(parser);
4726
0
            if (!model)
4727
0
              return XML_ERROR_NO_MEMORY;
4728
0
            *eventEndPP = s;
4729
0
            elementDeclHandler(handlerArg, declElementType->name, model);
4730
0
          }
4731
0
          dtd->in_eldecl = XML_FALSE;
4732
0
          dtd->contentStringLen = 0;
4733
0
        }
4734
0
      }
4735
0
      break;
4736
0
      /* End element declaration stuff */
4737
0
4738
0
    case XML_ROLE_PI:
4739
0
      if (!reportProcessingInstruction(parser, enc, s, next))
4740
0
        return XML_ERROR_NO_MEMORY;
4741
0
      handleDefault = XML_FALSE;
4742
0
      break;
4743
0
    case XML_ROLE_COMMENT:
4744
0
      if (!reportComment(parser, enc, s, next))
4745
0
        return XML_ERROR_NO_MEMORY;
4746
0
      handleDefault = XML_FALSE;
4747
0
      break;
4748
0
    case XML_ROLE_NONE:
4749
0
      switch (tok) {
4750
0
      case XML_TOK_BOM:
4751
0
        handleDefault = XML_FALSE;
4752
0
        break;
4753
0
      }
4754
0
      break;
4755
0
    case XML_ROLE_DOCTYPE_NONE:
4756
0
      if (startDoctypeDeclHandler)
4757
0
        handleDefault = XML_FALSE;
4758
0
      break;
4759
0
    case XML_ROLE_ENTITY_NONE:
4760
0
      if (dtd->keepProcessing && entityDeclHandler)
4761
0
        handleDefault = XML_FALSE;
4762
0
      break;
4763
0
    case XML_ROLE_NOTATION_NONE:
4764
0
      if (notationDeclHandler)
4765
0
        handleDefault = XML_FALSE;
4766
0
      break;
4767
0
    case XML_ROLE_ATTLIST_NONE:
4768
0
      if (dtd->keepProcessing && attlistDeclHandler)
4769
0
        handleDefault = XML_FALSE;
4770
0
      break;
4771
0
    case XML_ROLE_ELEMENT_NONE:
4772
0
      if (elementDeclHandler)
4773
0
        handleDefault = XML_FALSE;
4774
0
      break;
4775
0
    } /* end of big switch */
4776
0
4777
0
    if (handleDefault && defaultHandler)
4778
0
      reportDefault(parser, enc, s, next);
4779
0
4780
0
    switch (ps_parsing) {
4781
0
    case XML_SUSPENDED: 
4782
0
      *nextPtr = next;
4783
0
      return XML_ERROR_NONE;
4784
0
    case XML_FINISHED:
4785
0
      return XML_ERROR_ABORTED;
4786
0
    default:
4787
0
      s = next;
4788
0
      tok = XmlPrologTok(enc, s, end, &next);
4789
0
    }
4790
0
  }
4791
0
  /* not reached */
4792
0
}
4793
4794
static enum XML_Error PTRCALL
4795
epilogProcessor(XML_Parser parser,
4796
                const char *s,
4797
                const char *end,
4798
                const char **nextPtr)
4799
0
{
4800
0
  processor = epilogProcessor;
4801
0
  eventPtr = s;
4802
0
  for (;;) {
4803
0
    const char *next = NULL;
4804
0
    int tok = XmlPrologTok(encoding, s, end, &next);
4805
0
    eventEndPtr = next;
4806
0
    switch (tok) {
4807
0
    /* report partial linebreak - it might be the last token */
4808
0
    case -XML_TOK_PROLOG_S:
4809
0
      if (defaultHandler) {
4810
0
        reportDefault(parser, encoding, s, next);
4811
0
        if (ps_parsing == XML_FINISHED)
4812
0
          return XML_ERROR_ABORTED;
4813
0
      }
4814
0
      *nextPtr = next;
4815
0
      return XML_ERROR_NONE;
4816
0
    case XML_TOK_NONE:
4817
0
      *nextPtr = s;
4818
0
      return XML_ERROR_NONE;
4819
0
    case XML_TOK_PROLOG_S:
4820
0
      if (defaultHandler)
4821
0
        reportDefault(parser, encoding, s, next);
4822
0
      break;
4823
0
    case XML_TOK_PI:
4824
0
      if (!reportProcessingInstruction(parser, encoding, s, next))
4825
0
        return XML_ERROR_NO_MEMORY;
4826
0
      break;
4827
0
    case XML_TOK_COMMENT:
4828
0
      if (!reportComment(parser, encoding, s, next))
4829
0
        return XML_ERROR_NO_MEMORY;
4830
0
      break;
4831
0
    case XML_TOK_INVALID:
4832
0
      eventPtr = next;
4833
0
      return XML_ERROR_INVALID_TOKEN;
4834
0
    case XML_TOK_PARTIAL:
4835
0
      if (!ps_finalBuffer) {
4836
0
        *nextPtr = s;
4837
0
        return XML_ERROR_NONE;
4838
0
      }
4839
0
      return XML_ERROR_UNCLOSED_TOKEN;
4840
0
    case XML_TOK_PARTIAL_CHAR:
4841
0
      if (!ps_finalBuffer) {
4842
0
        *nextPtr = s;
4843
0
        return XML_ERROR_NONE;
4844
0
      }
4845
0
      return XML_ERROR_PARTIAL_CHAR;
4846
0
    default:
4847
0
      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4848
0
    }
4849
0
    eventPtr = s = next;
4850
0
    switch (ps_parsing) {
4851
0
    case XML_SUSPENDED: 
4852
0
      *nextPtr = next;
4853
0
      return XML_ERROR_NONE;
4854
0
    case XML_FINISHED:
4855
0
      return XML_ERROR_ABORTED;
4856
0
    default: ;
4857
0
    }
4858
0
  }
4859
0
}
4860
4861
static enum XML_Error
4862
processInternalEntity(XML_Parser parser, ENTITY *entity,
4863
                      XML_Bool betweenDecl)
4864
0
{
4865
0
  const char *textStart, *textEnd;
4866
0
  const char *next;
4867
0
  enum XML_Error result;
4868
0
  OPEN_INTERNAL_ENTITY *openEntity;
4869
0
4870
0
  if (freeInternalEntities) {
4871
0
    openEntity = freeInternalEntities;
4872
0
    freeInternalEntities = openEntity->next;
4873
0
  }
4874
0
  else {
4875
0
    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4876
0
    if (!openEntity)
4877
0
      return XML_ERROR_NO_MEMORY;
4878
0
  }
4879
0
  entity->open = XML_TRUE;
4880
0
  entity->processed = 0;
4881
0
  openEntity->next = openInternalEntities;
4882
0
  openInternalEntities = openEntity;
4883
0
  openEntity->entity = entity;
4884
0
  openEntity->startTagLevel = tagLevel;
4885
0
  openEntity->betweenDecl = betweenDecl;
4886
0
  openEntity->internalEventPtr = NULL;
4887
0
  openEntity->internalEventEndPtr = NULL;
4888
0
  textStart = (char *)entity->textPtr;
4889
0
  textEnd = (char *)(entity->textPtr + entity->textLen);
4890
0
4891
0
#ifdef XML_DTD
4892
0
  if (entity->is_param) {
4893
0
    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4894
0
    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
4895
0
                      next, &next, XML_FALSE);
4896
0
  }
4897
0
  else 
4898
0
#endif /* XML_DTD */
4899
0
    result = doContent(parser, tagLevel, internalEncoding, textStart, 
4900
0
                       textEnd, &next, XML_FALSE);
4901
0
4902
0
  if (result == XML_ERROR_NONE) {
4903
0
    if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4904
0
      entity->processed = (int)(next - textStart);
4905
0
      processor = internalEntityProcessor;
4906
0
    }
4907
0
    else {
4908
0
      entity->open = XML_FALSE;
4909
0
/* BEGIN MOZILLA CHANGE (Deal with parser interruption from nested entities) */
4910
#if 0
4911
      openInternalEntities = openEntity->next;
4912
#else
4913
0
      if (openInternalEntities == openEntity) {
4914
0
        openInternalEntities = openEntity->next;
4915
0
      }
4916
0
      else {
4917
0
        /* openEntity should be closed, but it contains an inner entity that is
4918
0
           still open. Remove openEntity from the openInternalEntities linked
4919
0
           list by looking for the inner entity in the list that links to
4920
0
           openEntity and fixing up its 'next' member
4921
0
        */
4922
0
        OPEN_INTERNAL_ENTITY *innerOpenEntity = openInternalEntities;
4923
0
        do {
4924
0
          if (innerOpenEntity->next == openEntity) {
4925
0
            innerOpenEntity->next = openEntity->next;
4926
0
            break;
4927
0
          }
4928
0
        } while ((innerOpenEntity = innerOpenEntity->next));
4929
0
      }
4930
0
#endif
4931
0
/* END MOZILLA CHANGE */
4932
0
      /* put openEntity back in list of free instances */
4933
0
      openEntity->next = freeInternalEntities;
4934
0
      freeInternalEntities = openEntity;
4935
0
    }
4936
0
  }
4937
0
  return result;
4938
0
}
4939
4940
static enum XML_Error PTRCALL
4941
internalEntityProcessor(XML_Parser parser,
4942
                        const char *s,
4943
                        const char *end,
4944
                        const char **nextPtr)
4945
0
{
4946
0
  ENTITY *entity;
4947
0
  const char *textStart, *textEnd;
4948
0
  const char *next;
4949
0
  enum XML_Error result;
4950
0
  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4951
0
  if (!openEntity)
4952
0
    return XML_ERROR_UNEXPECTED_STATE;
4953
0
4954
0
  entity = openEntity->entity;
4955
0
  textStart = ((char *)entity->textPtr) + entity->processed;
4956
0
  textEnd = (char *)(entity->textPtr + entity->textLen);
4957
0
4958
0
#ifdef XML_DTD
4959
0
  if (entity->is_param) {
4960
0
    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4961
0
    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
4962
0
                      next, &next, XML_FALSE);
4963
0
  }
4964
0
  else
4965
0
#endif /* XML_DTD */
4966
0
    result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
4967
0
                       textStart, textEnd, &next, XML_FALSE);  
4968
0
4969
0
  if (result != XML_ERROR_NONE)
4970
0
    return result;
4971
0
  else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4972
0
    entity->processed = (int)(next - (char *)entity->textPtr);
4973
0
    return result;
4974
0
  }
4975
0
  else {
4976
0
    entity->open = XML_FALSE;
4977
0
    openInternalEntities = openEntity->next;
4978
0
    /* put openEntity back in list of free instances */
4979
0
    openEntity->next = freeInternalEntities;
4980
0
    freeInternalEntities = openEntity;
4981
0
  }
4982
0
4983
0
#ifdef XML_DTD
4984
0
  if (entity->is_param) {
4985
0
    int tok;
4986
0
    processor = prologProcessor;
4987
0
    tok = XmlPrologTok(encoding, s, end, &next);
4988
0
    return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
4989
0
                    (XML_Bool)!ps_finalBuffer);
4990
0
  }
4991
0
  else
4992
0
#endif /* XML_DTD */
4993
0
  {
4994
0
    processor = contentProcessor;
4995
0
    /* see externalEntityContentProcessor vs contentProcessor */
4996
0
    return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
4997
0
                     nextPtr, (XML_Bool)!ps_finalBuffer); 
4998
0
  }  
4999
0
}
5000
5001
static enum XML_Error PTRCALL
5002
errorProcessor(XML_Parser parser,
5003
               const char *s,
5004
               const char *end,
5005
               const char **nextPtr)
5006
0
{
5007
0
  return errorCode;
5008
0
}
5009
5010
static enum XML_Error
5011
storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5012
                    const char *ptr, const char *end,
5013
                    STRING_POOL *pool)
5014
0
{
5015
0
  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
5016
0
                                               end, pool);
5017
0
  if (result)
5018
0
    return result;
5019
0
  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
5020
0
    poolChop(pool);
5021
0
  if (!poolAppendChar(pool, XML_T('\0')))
5022
0
    return XML_ERROR_NO_MEMORY;
5023
0
  return XML_ERROR_NONE;
5024
0
}
5025
5026
static enum XML_Error
5027
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5028
                     const char *ptr, const char *end,
5029
                     STRING_POOL *pool)
5030
0
{
5031
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
5032
0
  for (;;) {
5033
0
    const char *next;
5034
0
    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5035
0
    switch (tok) {
5036
0
    case XML_TOK_NONE:
5037
0
      return XML_ERROR_NONE;
5038
0
    case XML_TOK_INVALID:
5039
0
      if (enc == encoding)
5040
0
        eventPtr = next;
5041
0
      return XML_ERROR_INVALID_TOKEN;
5042
0
    case XML_TOK_PARTIAL:
5043
0
      if (enc == encoding)
5044
0
        eventPtr = ptr;
5045
0
      return XML_ERROR_INVALID_TOKEN;
5046
0
    case XML_TOK_CHAR_REF:
5047
0
      {
5048
0
        XML_Char buf[XML_ENCODE_MAX];
5049
0
        int i;
5050
0
        int n = XmlCharRefNumber(enc, ptr);
5051
0
        if (n < 0) {
5052
0
          if (enc == encoding)
5053
0
            eventPtr = ptr;
5054
0
          return XML_ERROR_BAD_CHAR_REF;
5055
0
        }
5056
0
        if (!isCdata
5057
0
            && n == 0x20 /* space */
5058
0
            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5059
0
          break;
5060
0
        n = XmlEncode(n, (ICHAR *)buf);
5061
0
        if (!n) {
5062
0
          if (enc == encoding)
5063
0
            eventPtr = ptr;
5064
0
          return XML_ERROR_BAD_CHAR_REF;
5065
0
        }
5066
0
        for (i = 0; i < n; i++) {
5067
0
          if (!poolAppendChar(pool, buf[i]))
5068
0
            return XML_ERROR_NO_MEMORY;
5069
0
        }
5070
0
      }
5071
0
      break;
5072
0
    case XML_TOK_DATA_CHARS:
5073
0
      if (!poolAppend(pool, enc, ptr, next))
5074
0
        return XML_ERROR_NO_MEMORY;
5075
0
      break;
5076
0
    case XML_TOK_TRAILING_CR:
5077
0
      next = ptr + enc->minBytesPerChar;
5078
0
      /* fall through */
5079
0
    case XML_TOK_ATTRIBUTE_VALUE_S:
5080
0
    case XML_TOK_DATA_NEWLINE:
5081
0
      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5082
0
        break;
5083
0
      if (!poolAppendChar(pool, 0x20))
5084
0
        return XML_ERROR_NO_MEMORY;
5085
0
      break;
5086
0
    case XML_TOK_ENTITY_REF:
5087
0
      {
5088
0
        const XML_Char *name;
5089
0
        ENTITY *entity;
5090
0
        char checkEntityDecl;
5091
0
        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
5092
0
                                              ptr + enc->minBytesPerChar,
5093
0
                                              next - enc->minBytesPerChar);
5094
0
        if (ch) {
5095
0
          if (!poolAppendChar(pool, ch))
5096
0
                return XML_ERROR_NO_MEMORY;
5097
0
          break;
5098
0
        }
5099
0
        name = poolStoreString(&temp2Pool, enc,
5100
0
                               ptr + enc->minBytesPerChar,
5101
0
                               next - enc->minBytesPerChar);
5102
0
        if (!name)
5103
0
          return XML_ERROR_NO_MEMORY;
5104
0
        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
5105
0
        poolDiscard(&temp2Pool);
5106
0
        /* First, determine if a check for an existing declaration is needed;
5107
0
           if yes, check that the entity exists, and that it is internal.
5108
0
        */
5109
0
        if (pool == &dtd->pool)  /* are we called from prolog? */
5110
0
          checkEntityDecl =
5111
0
#ifdef XML_DTD
5112
0
              prologState.documentEntity &&
5113
0
#endif /* XML_DTD */
5114
0
              (dtd->standalone
5115
0
               ? !openInternalEntities
5116
0
               : !dtd->hasParamEntityRefs);
5117
0
        else /* if (pool == &tempPool): we are called from content */
5118
0
          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
5119
0
        if (checkEntityDecl) {
5120
0
          if (!entity)
5121
0
            return XML_ERROR_UNDEFINED_ENTITY;
5122
0
          else if (!entity->is_internal)
5123
0
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
5124
0
        }
5125
0
        else if (!entity) {
5126
0
          /* Cannot report skipped entity here - see comments on
5127
0
             skippedEntityHandler.
5128
0
          if (skippedEntityHandler)
5129
0
            skippedEntityHandler(handlerArg, name, 0);
5130
0
          */
5131
0
          /* Cannot call the default handler because this would be
5132
0
             out of sync with the call to the startElementHandler.
5133
0
          if ((pool == &tempPool) && defaultHandler)
5134
0
            reportDefault(parser, enc, ptr, next);
5135
0
          */
5136
0
/* BEGIN MOZILLA CHANGE (http://bugzilla.mozilla.org/show_bug.cgi?id=35984) */
5137
#if 0
5138
          break;
5139
#else
5140
          return XML_ERROR_UNDEFINED_ENTITY;
5141
0
#endif
5142
0
/* END MOZILLA CHANGE */
5143
0
        }
5144
0
        if (entity->open) {
5145
0
          if (enc == encoding)
5146
0
            eventPtr = ptr;
5147
0
          return XML_ERROR_RECURSIVE_ENTITY_REF;
5148
0
        }
5149
0
        if (entity->notation) {
5150
0
          if (enc == encoding)
5151
0
            eventPtr = ptr;
5152
0
          return XML_ERROR_BINARY_ENTITY_REF;
5153
0
        }
5154
0
        if (!entity->textPtr) {
5155
0
          if (enc == encoding)
5156
0
            eventPtr = ptr;
5157
0
              return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5158
0
        }
5159
0
        else {
5160
0
          enum XML_Error result;
5161
0
          const XML_Char *textEnd = entity->textPtr + entity->textLen;
5162
0
          entity->open = XML_TRUE;
5163
0
          result = appendAttributeValue(parser, internalEncoding, isCdata,
5164
0
                                        (char *)entity->textPtr,
5165
0
                                        (char *)textEnd, pool);
5166
0
          entity->open = XML_FALSE;
5167
0
          if (result)
5168
0
            return result;
5169
0
        }
5170
0
      }
5171
0
      break;
5172
0
    default:
5173
0
      if (enc == encoding)
5174
0
        eventPtr = ptr;
5175
0
      return XML_ERROR_UNEXPECTED_STATE;
5176
0
    }
5177
0
    ptr = next;
5178
0
  }
5179
0
  /* not reached */
5180
0
}
5181
5182
static enum XML_Error
5183
storeEntityValue(XML_Parser parser,
5184
                 const ENCODING *enc,
5185
                 const char *entityTextPtr,
5186
                 const char *entityTextEnd)
5187
0
{
5188
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
5189
0
  STRING_POOL *pool = &(dtd->entityValuePool);
5190
0
  enum XML_Error result = XML_ERROR_NONE;
5191
0
#ifdef XML_DTD
5192
0
  int oldInEntityValue = prologState.inEntityValue;
5193
0
  prologState.inEntityValue = 1;
5194
0
#endif /* XML_DTD */
5195
0
  /* never return Null for the value argument in EntityDeclHandler,
5196
0
     since this would indicate an external entity; therefore we
5197
0
     have to make sure that entityValuePool.start is not null */
5198
0
  if (!pool->blocks) {
5199
0
    if (!poolGrow(pool))
5200
0
      return XML_ERROR_NO_MEMORY;
5201
0
  }
5202
0
5203
0
  for (;;) {
5204
0
    const char *next;
5205
0
    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5206
0
    switch (tok) {
5207
0
    case XML_TOK_PARAM_ENTITY_REF:
5208
0
#ifdef XML_DTD
5209
0
      if (isParamEntity || enc != encoding) {
5210
0
        const XML_Char *name;
5211
0
        ENTITY *entity;
5212
0
        name = poolStoreString(&tempPool, enc,
5213
0
                               entityTextPtr + enc->minBytesPerChar,
5214
0
                               next - enc->minBytesPerChar);
5215
0
        if (!name) {
5216
0
          result = XML_ERROR_NO_MEMORY;
5217
0
          goto endEntityValue;
5218
0
        }
5219
0
        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
5220
0
        poolDiscard(&tempPool);
5221
0
        if (!entity) {
5222
0
          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5223
0
          /* cannot report skipped entity here - see comments on
5224
0
             skippedEntityHandler
5225
0
          if (skippedEntityHandler)
5226
0
            skippedEntityHandler(handlerArg, name, 0);
5227
0
          */
5228
0
          dtd->keepProcessing = dtd->standalone;
5229
0
          goto endEntityValue;
5230
0
        }
5231
0
        if (entity->open) {
5232
0
          if (enc == encoding)
5233
0
            eventPtr = entityTextPtr;
5234
0
          result = XML_ERROR_RECURSIVE_ENTITY_REF;
5235
0
          goto endEntityValue;
5236
0
        }
5237
0
        if (entity->systemId) {
5238
0
          if (externalEntityRefHandler) {
5239
0
            dtd->paramEntityRead = XML_FALSE;
5240
0
            entity->open = XML_TRUE;
5241
0
            if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5242
0
                                          0,
5243
0
                                          entity->base,
5244
0
                                          entity->systemId,
5245
0
                                          entity->publicId)) {
5246
0
              entity->open = XML_FALSE;
5247
0
              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5248
0
              goto endEntityValue;
5249
0
            }
5250
0
            entity->open = XML_FALSE;
5251
0
            if (!dtd->paramEntityRead)
5252
0
              dtd->keepProcessing = dtd->standalone;
5253
0
          }
5254
0
          else
5255
0
            dtd->keepProcessing = dtd->standalone;
5256
0
        }
5257
0
        else {
5258
0
          entity->open = XML_TRUE;
5259
0
          result = storeEntityValue(parser,
5260
0
                                    internalEncoding,
5261
0
                                    (char *)entity->textPtr,
5262
0
                                    (char *)(entity->textPtr
5263
0
                                             + entity->textLen));
5264
0
          entity->open = XML_FALSE;
5265
0
          if (result)
5266
0
            goto endEntityValue;
5267
0
        }
5268
0
        break;
5269
0
      }
5270
0
#endif /* XML_DTD */
5271
0
      /* In the internal subset, PE references are not legal
5272
0
         within markup declarations, e.g entity values in this case. */
5273
0
      eventPtr = entityTextPtr;
5274
0
      result = XML_ERROR_PARAM_ENTITY_REF;
5275
0
      goto endEntityValue;
5276
0
    case XML_TOK_NONE:
5277
0
      result = XML_ERROR_NONE;
5278
0
      goto endEntityValue;
5279
0
    case XML_TOK_ENTITY_REF:
5280
0
    case XML_TOK_DATA_CHARS:
5281
0
      if (!poolAppend(pool, enc, entityTextPtr, next)) {
5282
0
        result = XML_ERROR_NO_MEMORY;
5283
0
        goto endEntityValue;
5284
0
      }
5285
0
      break;
5286
0
    case XML_TOK_TRAILING_CR:
5287
0
      next = entityTextPtr + enc->minBytesPerChar;
5288
0
      /* fall through */
5289
0
    case XML_TOK_DATA_NEWLINE:
5290
0
      if (pool->end == pool->ptr && !poolGrow(pool)) {
5291
0
              result = XML_ERROR_NO_MEMORY;
5292
0
        goto endEntityValue;
5293
0
      }
5294
0
      *(pool->ptr)++ = 0xA;
5295
0
      break;
5296
0
    case XML_TOK_CHAR_REF:
5297
0
      {
5298
0
        XML_Char buf[XML_ENCODE_MAX];
5299
0
        int i;
5300
0
        int n = XmlCharRefNumber(enc, entityTextPtr);
5301
0
        if (n < 0) {
5302
0
          if (enc == encoding)
5303
0
            eventPtr = entityTextPtr;
5304
0
          result = XML_ERROR_BAD_CHAR_REF;
5305
0
          goto endEntityValue;
5306
0
        }
5307
0
        n = XmlEncode(n, (ICHAR *)buf);
5308
0
        if (!n) {
5309
0
          if (enc == encoding)
5310
0
            eventPtr = entityTextPtr;
5311
0
          result = XML_ERROR_BAD_CHAR_REF;
5312
0
          goto endEntityValue;
5313
0
        }
5314
0
        for (i = 0; i < n; i++) {
5315
0
          if (pool->end == pool->ptr && !poolGrow(pool)) {
5316
0
            result = XML_ERROR_NO_MEMORY;
5317
0
            goto endEntityValue;
5318
0
          }
5319
0
          *(pool->ptr)++ = buf[i];
5320
0
        }
5321
0
      }
5322
0
      break;
5323
0
    case XML_TOK_PARTIAL:
5324
0
      if (enc == encoding)
5325
0
        eventPtr = entityTextPtr;
5326
0
      result = XML_ERROR_INVALID_TOKEN;
5327
0
      goto endEntityValue;
5328
0
    case XML_TOK_INVALID:
5329
0
      if (enc == encoding)
5330
0
        eventPtr = next;
5331
0
      result = XML_ERROR_INVALID_TOKEN;
5332
0
      goto endEntityValue;
5333
0
    default:
5334
0
      if (enc == encoding)
5335
0
        eventPtr = entityTextPtr;
5336
0
      result = XML_ERROR_UNEXPECTED_STATE;
5337
0
      goto endEntityValue;
5338
0
    }
5339
0
    entityTextPtr = next;
5340
0
  }
5341
0
endEntityValue:
5342
0
#ifdef XML_DTD
5343
0
  prologState.inEntityValue = oldInEntityValue;
5344
0
#endif /* XML_DTD */
5345
0
  return result;
5346
0
}
5347
5348
static void FASTCALL
5349
normalizeLines(XML_Char *s)
5350
0
{
5351
0
  XML_Char *p;
5352
0
  for (;; s++) {
5353
0
    if (*s == XML_T('\0'))
5354
0
      return;
5355
0
    if (*s == 0xD)
5356
0
      break;
5357
0
  }
5358
0
  p = s;
5359
0
  do {
5360
0
    if (*s == 0xD) {
5361
0
      *p++ = 0xA;
5362
0
      if (*++s == 0xA)
5363
0
        s++;
5364
0
    }
5365
0
    else
5366
0
      *p++ = *s++;
5367
0
  } while (*s);
5368
0
  *p = XML_T('\0');
5369
0
}
5370
5371
static int
5372
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5373
                            const char *start, const char *end)
5374
0
{
5375
0
  const XML_Char *target;
5376
0
  XML_Char *data;
5377
0
  const char *tem;
5378
0
  if (!processingInstructionHandler) {
5379
0
    if (defaultHandler)
5380
0
      reportDefault(parser, enc, start, end);
5381
0
    return 1;
5382
0
  }
5383
0
  start += enc->minBytesPerChar * 2;
5384
0
  tem = start + XmlNameLength(enc, start);
5385
0
  target = poolStoreString(&tempPool, enc, start, tem);
5386
0
  if (!target)
5387
0
    return 0;
5388
0
  poolFinish(&tempPool);
5389
0
  data = poolStoreString(&tempPool, enc,
5390
0
                        XmlSkipS(enc, tem),
5391
0
                        end - enc->minBytesPerChar*2);
5392
0
  if (!data)
5393
0
    return 0;
5394
0
  normalizeLines(data);
5395
0
  processingInstructionHandler(handlerArg, target, data);
5396
0
  poolClear(&tempPool);
5397
0
  return 1;
5398
0
}
5399
5400
static int
5401
reportComment(XML_Parser parser, const ENCODING *enc,
5402
              const char *start, const char *end)
5403
0
{
5404
0
  XML_Char *data;
5405
0
  if (!commentHandler) {
5406
0
    if (defaultHandler)
5407
0
      reportDefault(parser, enc, start, end);
5408
0
    return 1;
5409
0
  }
5410
0
  data = poolStoreString(&tempPool,
5411
0
                         enc,
5412
0
                         start + enc->minBytesPerChar * 4,
5413
0
                         end - enc->minBytesPerChar * 3);
5414
0
  if (!data)
5415
0
    return 0;
5416
0
  normalizeLines(data);
5417
0
  commentHandler(handlerArg, data);
5418
0
  poolClear(&tempPool);
5419
0
  return 1;
5420
0
}
5421
5422
static void
5423
reportDefault(XML_Parser parser, const ENCODING *enc,
5424
              const char *s, const char *end)
5425
0
{
5426
0
  if (MUST_CONVERT(enc, s)) {
5427
0
    const char **eventPP;
5428
0
    const char **eventEndPP;
5429
0
    if (enc == encoding) {
5430
0
      eventPP = &eventPtr;
5431
0
      eventEndPP = &eventEndPtr;
5432
0
    }
5433
0
    else {
5434
0
      eventPP = &(openInternalEntities->internalEventPtr);
5435
0
      eventEndPP = &(openInternalEntities->internalEventEndPtr);
5436
0
    }
5437
0
    do {
5438
0
      ICHAR *dataPtr = (ICHAR *)dataBuf;
5439
0
      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5440
0
      *eventEndPP = s;
5441
0
      defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
5442
0
      *eventPP = s;
5443
0
    } while (s != end);
5444
0
  }
5445
0
  else
5446
0
    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5447
0
}
5448
5449
5450
static int
5451
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5452
                XML_Bool isId, const XML_Char *value, XML_Parser parser)
5453
0
{
5454
0
  DEFAULT_ATTRIBUTE *att;
5455
0
  if (value || isId) {
5456
0
    /* The handling of default attributes gets messed up if we have
5457
0
       a default which duplicates a non-default. */
5458
0
    int i;
5459
0
    for (i = 0; i < type->nDefaultAtts; i++)
5460
0
      if (attId == type->defaultAtts[i].id)
5461
0
        return 1;
5462
0
    if (isId && !type->idAtt && !attId->xmlns)
5463
0
      type->idAtt = attId;
5464
0
  }
5465
0
  if (type->nDefaultAtts == type->allocDefaultAtts) {
5466
0
    if (type->allocDefaultAtts == 0) {
5467
0
      type->allocDefaultAtts = 8;
5468
0
      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
5469
0
                            * sizeof(DEFAULT_ATTRIBUTE));
5470
0
      if (!type->defaultAtts)
5471
0
        return 0;
5472
0
    }
5473
0
    else {
5474
0
      DEFAULT_ATTRIBUTE *temp;
5475
0
      int count = type->allocDefaultAtts * 2;
5476
0
      temp = (DEFAULT_ATTRIBUTE *)
5477
0
        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5478
0
      if (temp == NULL)
5479
0
        return 0;
5480
0
      type->allocDefaultAtts = count;
5481
0
      type->defaultAtts = temp;
5482
0
    }
5483
0
  }
5484
0
  att = type->defaultAtts + type->nDefaultAtts;
5485
0
  att->id = attId;
5486
0
  att->value = value;
5487
0
  att->isCdata = isCdata;
5488
0
  if (!isCdata)
5489
0
    attId->maybeTokenized = XML_TRUE;
5490
0
  type->nDefaultAtts += 1;
5491
0
  return 1;
5492
0
}
5493
5494
static int
5495
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
5496
0
{
5497
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
5498
0
  const XML_Char *name;
5499
0
  for (name = elementType->name; *name; name++) {
5500
0
    if (*name == XML_T(':')) {
5501
0
      PREFIX *prefix;
5502
0
      const XML_Char *s;
5503
0
      for (s = elementType->name; s != name; s++) {
5504
0
        if (!poolAppendChar(&dtd->pool, *s))
5505
0
          return 0;
5506
0
      }
5507
0
      if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5508
0
        return 0;
5509
0
      prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5510
0
                                sizeof(PREFIX));
5511
0
      if (!prefix)
5512
0
        return 0;
5513
0
      if (prefix->name == poolStart(&dtd->pool))
5514
0
        poolFinish(&dtd->pool);
5515
0
      else
5516
0
        poolDiscard(&dtd->pool);
5517
0
      elementType->prefix = prefix;
5518
0
5519
0
    }
5520
0
  }
5521
0
  return 1;
5522
0
}
5523
5524
static ATTRIBUTE_ID *
5525
getAttributeId(XML_Parser parser, const ENCODING *enc,
5526
               const char *start, const char *end)
5527
0
{
5528
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
5529
0
  ATTRIBUTE_ID *id;
5530
0
  const XML_Char *name;
5531
0
  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5532
0
    return NULL;
5533
0
  name = poolStoreString(&dtd->pool, enc, start, end);
5534
0
  if (!name)
5535
0
    return NULL;
5536
0
  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5537
0
  ++name;
5538
0
  id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
5539
0
  if (!id)
5540
0
    return NULL;
5541
0
  if (id->name != name)
5542
0
    poolDiscard(&dtd->pool);
5543
0
  else {
5544
0
    poolFinish(&dtd->pool);
5545
0
    if (!ns)
5546
0
      ;
5547
0
    else if (name[0] == XML_T('x')
5548
0
        && name[1] == XML_T('m')
5549
0
        && name[2] == XML_T('l')
5550
0
        && name[3] == XML_T('n')
5551
0
        && name[4] == XML_T('s')
5552
0
        && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
5553
0
      if (name[5] == XML_T('\0'))
5554
0
        id->prefix = &dtd->defaultPrefix;
5555
0
      else
5556
0
        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
5557
0
      id->xmlns = XML_TRUE;
5558
0
    }
5559
0
    else {
5560
0
      int i;
5561
0
      for (i = 0; name[i]; i++) {
5562
0
        /* attributes without prefix are *not* in the default namespace */
5563
0
        if (name[i] == XML_T(':')) {
5564
0
          int j;
5565
0
          for (j = 0; j < i; j++) {
5566
0
            if (!poolAppendChar(&dtd->pool, name[j]))
5567
0
              return NULL;
5568
0
          }
5569
0
          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5570
0
            return NULL;
5571
0
          id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5572
0
                                        sizeof(PREFIX));
5573
0
          if (id->prefix->name == poolStart(&dtd->pool))
5574
0
            poolFinish(&dtd->pool);
5575
0
          else
5576
0
            poolDiscard(&dtd->pool);
5577
0
          break;
5578
0
        }
5579
0
      }
5580
0
    }
5581
0
  }
5582
0
  return id;
5583
0
}
5584
5585
0
#define CONTEXT_SEP XML_T('\f')
5586
5587
static const XML_Char *
5588
getContext(XML_Parser parser)
5589
0
{
5590
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
5591
0
  HASH_TABLE_ITER iter;
5592
0
  XML_Bool needSep = XML_FALSE;
5593
0
5594
0
  if (dtd->defaultPrefix.binding) {
5595
0
    int i;
5596
0
    int len;
5597
0
    if (!poolAppendChar(&tempPool, XML_T('=')))
5598
0
      return NULL;
5599
0
    len = dtd->defaultPrefix.binding->uriLen;
5600
0
    if (namespaceSeparator)
5601
0
      len--;
5602
0
    for (i = 0; i < len; i++)
5603
0
      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5604
0
        return NULL;
5605
0
    needSep = XML_TRUE;
5606
0
  }
5607
0
5608
0
  hashTableIterInit(&iter, &(dtd->prefixes));
5609
0
  for (;;) {
5610
0
    int i;
5611
0
    int len;
5612
0
    const XML_Char *s;
5613
0
    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5614
0
    if (!prefix)
5615
0
      break;
5616
0
    if (!prefix->binding)
5617
0
      continue;
5618
0
    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5619
0
      return NULL;
5620
0
    for (s = prefix->name; *s; s++)
5621
0
      if (!poolAppendChar(&tempPool, *s))
5622
0
        return NULL;
5623
0
    if (!poolAppendChar(&tempPool, XML_T('=')))
5624
0
      return NULL;
5625
0
    len = prefix->binding->uriLen;
5626
0
    if (namespaceSeparator)
5627
0
      len--;
5628
0
    for (i = 0; i < len; i++)
5629
0
      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
5630
0
        return NULL;
5631
0
    needSep = XML_TRUE;
5632
0
  }
5633
0
5634
0
5635
0
  hashTableIterInit(&iter, &(dtd->generalEntities));
5636
0
  for (;;) {
5637
0
    const XML_Char *s;
5638
0
    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5639
0
    if (!e)
5640
0
      break;
5641
0
    if (!e->open)
5642
0
      continue;
5643
0
    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5644
0
      return NULL;
5645
0
    for (s = e->name; *s; s++)
5646
0
      if (!poolAppendChar(&tempPool, *s))
5647
0
        return 0;
5648
0
    needSep = XML_TRUE;
5649
0
  }
5650
0
5651
0
  if (!poolAppendChar(&tempPool, XML_T('\0')))
5652
0
    return NULL;
5653
0
  return tempPool.start;
5654
0
}
5655
5656
static XML_Bool
5657
setContext(XML_Parser parser, const XML_Char *context)
5658
0
{
5659
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
5660
0
  const XML_Char *s = context;
5661
0
5662
0
  while (*context != XML_T('\0')) {
5663
0
    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5664
0
      ENTITY *e;
5665
0
      if (!poolAppendChar(&tempPool, XML_T('\0')))
5666
0
        return XML_FALSE;
5667
0
      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
5668
0
      if (e)
5669
0
        e->open = XML_TRUE;
5670
0
      if (*s != XML_T('\0'))
5671
0
        s++;
5672
0
      context = s;
5673
0
      poolDiscard(&tempPool);
5674
0
    }
5675
0
    else if (*s == XML_T('=')) {
5676
0
      PREFIX *prefix;
5677
0
      if (poolLength(&tempPool) == 0)
5678
0
        prefix = &dtd->defaultPrefix;
5679
0
      else {
5680
0
        if (!poolAppendChar(&tempPool, XML_T('\0')))
5681
0
          return XML_FALSE;
5682
0
        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
5683
0
                                  sizeof(PREFIX));
5684
0
        if (!prefix)
5685
0
          return XML_FALSE;
5686
0
        if (prefix->name == poolStart(&tempPool)) {
5687
0
          prefix->name = poolCopyString(&dtd->pool, prefix->name);
5688
0
          if (!prefix->name)
5689
0
            return XML_FALSE;
5690
0
        }
5691
0
        poolDiscard(&tempPool);
5692
0
      }
5693
0
      for (context = s + 1;
5694
0
           *context != CONTEXT_SEP && *context != XML_T('\0');
5695
0
           context++)
5696
0
        if (!poolAppendChar(&tempPool, *context))
5697
0
          return XML_FALSE;
5698
0
      if (!poolAppendChar(&tempPool, XML_T('\0')))
5699
0
        return XML_FALSE;
5700
0
      if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
5701
0
                     &inheritedBindings) != XML_ERROR_NONE)
5702
0
        return XML_FALSE;
5703
0
      poolDiscard(&tempPool);
5704
0
      if (*context != XML_T('\0'))
5705
0
        ++context;
5706
0
      s = context;
5707
0
    }
5708
0
    else {
5709
0
      if (!poolAppendChar(&tempPool, *s))
5710
0
        return XML_FALSE;
5711
0
      s++;
5712
0
    }
5713
0
  }
5714
0
  return XML_TRUE;
5715
0
}
5716
5717
static void FASTCALL
5718
normalizePublicId(XML_Char *publicId)
5719
0
{
5720
0
  XML_Char *p = publicId;
5721
0
  XML_Char *s;
5722
0
  for (s = publicId; *s; s++) {
5723
0
    switch (*s) {
5724
0
    case 0x20:
5725
0
    case 0xD:
5726
0
    case 0xA:
5727
0
      if (p != publicId && p[-1] != 0x20)
5728
0
        *p++ = 0x20;
5729
0
      break;
5730
0
    default:
5731
0
      *p++ = *s;
5732
0
    }
5733
0
  }
5734
0
  if (p != publicId && p[-1] == 0x20)
5735
0
    --p;
5736
0
  *p = XML_T('\0');
5737
0
}
5738
5739
static DTD *
5740
dtdCreate(const XML_Memory_Handling_Suite *ms)
5741
0
{
5742
0
  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5743
0
  if (p == NULL)
5744
0
    return p;
5745
0
  poolInit(&(p->pool), ms);
5746
0
  poolInit(&(p->entityValuePool), ms);
5747
0
  hashTableInit(&(p->generalEntities), ms);
5748
0
  hashTableInit(&(p->elementTypes), ms);
5749
0
  hashTableInit(&(p->attributeIds), ms);
5750
0
  hashTableInit(&(p->prefixes), ms);
5751
0
#ifdef XML_DTD
5752
0
  p->paramEntityRead = XML_FALSE;
5753
0
  hashTableInit(&(p->paramEntities), ms);
5754
0
#endif /* XML_DTD */
5755
0
  p->defaultPrefix.name = NULL;
5756
0
  p->defaultPrefix.binding = NULL;
5757
0
5758
0
  p->in_eldecl = XML_FALSE;
5759
0
  p->scaffIndex = NULL;
5760
0
  p->scaffold = NULL;
5761
0
  p->scaffLevel = 0;
5762
0
  p->scaffSize = 0;
5763
0
  p->scaffCount = 0;
5764
0
  p->contentStringLen = 0;
5765
0
5766
0
  p->keepProcessing = XML_TRUE;
5767
0
  p->hasParamEntityRefs = XML_FALSE;
5768
0
  p->standalone = XML_FALSE;
5769
0
  return p;
5770
0
}
5771
5772
/* BEGIN MOZILLA CHANGE (unused API) */
5773
#if 0
5774
static void
5775
dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
5776
{
5777
  HASH_TABLE_ITER iter;
5778
  hashTableIterInit(&iter, &(p->elementTypes));
5779
  for (;;) {
5780
    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5781
    if (!e)
5782
      break;
5783
    if (e->allocDefaultAtts != 0)
5784
      ms->free_fcn(e->defaultAtts);
5785
  }
5786
  hashTableClear(&(p->generalEntities));
5787
#ifdef XML_DTD
5788
  p->paramEntityRead = XML_FALSE;
5789
  hashTableClear(&(p->paramEntities));
5790
#endif /* XML_DTD */
5791
  hashTableClear(&(p->elementTypes));
5792
  hashTableClear(&(p->attributeIds));
5793
  hashTableClear(&(p->prefixes));
5794
  poolClear(&(p->pool));
5795
  poolClear(&(p->entityValuePool));
5796
  p->defaultPrefix.name = NULL;
5797
  p->defaultPrefix.binding = NULL;
5798
5799
  p->in_eldecl = XML_FALSE;
5800
5801
  ms->free_fcn(p->scaffIndex);
5802
  p->scaffIndex = NULL;
5803
  ms->free_fcn(p->scaffold);
5804
  p->scaffold = NULL;
5805
5806
  p->scaffLevel = 0;
5807
  p->scaffSize = 0;
5808
  p->scaffCount = 0;
5809
  p->contentStringLen = 0;
5810
5811
  p->keepProcessing = XML_TRUE;
5812
  p->hasParamEntityRefs = XML_FALSE;
5813
  p->standalone = XML_FALSE;
5814
}
5815
#endif
5816
/* END MOZILLA CHANGE */
5817
5818
static void
5819
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5820
0
{
5821
0
  HASH_TABLE_ITER iter;
5822
0
  hashTableIterInit(&iter, &(p->elementTypes));
5823
0
  for (;;) {
5824
0
    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5825
0
    if (!e)
5826
0
      break;
5827
0
    if (e->allocDefaultAtts != 0)
5828
0
      ms->free_fcn(e->defaultAtts);
5829
0
  }
5830
0
  hashTableDestroy(&(p->generalEntities));
5831
0
#ifdef XML_DTD
5832
0
  hashTableDestroy(&(p->paramEntities));
5833
0
#endif /* XML_DTD */
5834
0
  hashTableDestroy(&(p->elementTypes));
5835
0
  hashTableDestroy(&(p->attributeIds));
5836
0
  hashTableDestroy(&(p->prefixes));
5837
0
  poolDestroy(&(p->pool));
5838
0
  poolDestroy(&(p->entityValuePool));
5839
0
  if (isDocEntity) {
5840
0
    ms->free_fcn(p->scaffIndex);
5841
0
    ms->free_fcn(p->scaffold);
5842
0
  }
5843
0
  ms->free_fcn(p);
5844
0
}
5845
5846
/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5847
   The new DTD has already been initialized.
5848
*/
5849
static int
5850
dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5851
0
{
5852
0
  HASH_TABLE_ITER iter;
5853
0
5854
0
  /* Copy the prefix table. */
5855
0
5856
0
  hashTableIterInit(&iter, &(oldDtd->prefixes));
5857
0
  for (;;) {
5858
0
    const XML_Char *name;
5859
0
    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5860
0
    if (!oldP)
5861
0
      break;
5862
0
    name = poolCopyString(&(newDtd->pool), oldP->name);
5863
0
    if (!name)
5864
0
      return 0;
5865
0
    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5866
0
      return 0;
5867
0
  }
5868
0
5869
0
  hashTableIterInit(&iter, &(oldDtd->attributeIds));
5870
0
5871
0
  /* Copy the attribute id table. */
5872
0
5873
0
  for (;;) {
5874
0
    ATTRIBUTE_ID *newA;
5875
0
    const XML_Char *name;
5876
0
    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5877
0
5878
0
    if (!oldA)
5879
0
      break;
5880
0
    /* Remember to allocate the scratch byte before the name. */
5881
0
    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5882
0
      return 0;
5883
0
    name = poolCopyString(&(newDtd->pool), oldA->name);
5884
0
    if (!name)
5885
0
      return 0;
5886
0
    ++name;
5887
0
    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5888
0
                                  sizeof(ATTRIBUTE_ID));
5889
0
    if (!newA)
5890
0
      return 0;
5891
0
    newA->maybeTokenized = oldA->maybeTokenized;
5892
0
    if (oldA->prefix) {
5893
0
      newA->xmlns = oldA->xmlns;
5894
0
      if (oldA->prefix == &oldDtd->defaultPrefix)
5895
0
        newA->prefix = &newDtd->defaultPrefix;
5896
0
      else
5897
0
        newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5898
0
                                        oldA->prefix->name, 0);
5899
0
    }
5900
0
  }
5901
0
5902
0
  /* Copy the element type table. */
5903
0
5904
0
  hashTableIterInit(&iter, &(oldDtd->elementTypes));
5905
0
5906
0
  for (;;) {
5907
0
    int i;
5908
0
    ELEMENT_TYPE *newE;
5909
0
    const XML_Char *name;
5910
0
    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5911
0
    if (!oldE)
5912
0
      break;
5913
0
    name = poolCopyString(&(newDtd->pool), oldE->name);
5914
0
    if (!name)
5915
0
      return 0;
5916
0
    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5917
0
                                  sizeof(ELEMENT_TYPE));
5918
0
    if (!newE)
5919
0
      return 0;
5920
0
    if (oldE->nDefaultAtts) {
5921
0
      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5922
0
          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5923
0
      if (!newE->defaultAtts) {
5924
0
        ms->free_fcn(newE);
5925
0
        return 0;
5926
0
      }
5927
0
    }
5928
0
    if (oldE->idAtt)
5929
0
      newE->idAtt = (ATTRIBUTE_ID *)
5930
0
          lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
5931
0
    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5932
0
    if (oldE->prefix)
5933
0
      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5934
0
                                      oldE->prefix->name, 0);
5935
0
    for (i = 0; i < newE->nDefaultAtts; i++) {
5936
0
      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5937
0
          lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5938
0
      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5939
0
      if (oldE->defaultAtts[i].value) {
5940
0
        newE->defaultAtts[i].value
5941
0
            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5942
0
        if (!newE->defaultAtts[i].value)
5943
0
          return 0;
5944
0
      }
5945
0
      else
5946
0
        newE->defaultAtts[i].value = NULL;
5947
0
    }
5948
0
  }
5949
0
5950
0
  /* Copy the entity tables. */
5951
0
  if (!copyEntityTable(&(newDtd->generalEntities),
5952
0
                       &(newDtd->pool),
5953
0
                       &(oldDtd->generalEntities)))
5954
0
      return 0;
5955
0
5956
0
#ifdef XML_DTD
5957
0
  if (!copyEntityTable(&(newDtd->paramEntities),
5958
0
                       &(newDtd->pool),
5959
0
                       &(oldDtd->paramEntities)))
5960
0
      return 0;
5961
0
  newDtd->paramEntityRead = oldDtd->paramEntityRead;
5962
0
#endif /* XML_DTD */
5963
0
5964
0
  newDtd->keepProcessing = oldDtd->keepProcessing;
5965
0
  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5966
0
  newDtd->standalone = oldDtd->standalone;
5967
0
5968
0
  /* Don't want deep copying for scaffolding */
5969
0
  newDtd->in_eldecl = oldDtd->in_eldecl;
5970
0
  newDtd->scaffold = oldDtd->scaffold;
5971
0
  newDtd->contentStringLen = oldDtd->contentStringLen;
5972
0
  newDtd->scaffSize = oldDtd->scaffSize;
5973
0
  newDtd->scaffLevel = oldDtd->scaffLevel;
5974
0
  newDtd->scaffIndex = oldDtd->scaffIndex;
5975
0
5976
0
  return 1;
5977
0
}  /* End dtdCopy */
5978
5979
static int
5980
copyEntityTable(HASH_TABLE *newTable,
5981
                STRING_POOL *newPool,
5982
                const HASH_TABLE *oldTable)
5983
0
{
5984
0
  HASH_TABLE_ITER iter;
5985
0
  const XML_Char *cachedOldBase = NULL;
5986
0
  const XML_Char *cachedNewBase = NULL;
5987
0
5988
0
  hashTableIterInit(&iter, oldTable);
5989
0
5990
0
  for (;;) {
5991
0
    ENTITY *newE;
5992
0
    const XML_Char *name;
5993
0
    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5994
0
    if (!oldE)
5995
0
      break;
5996
0
    name = poolCopyString(newPool, oldE->name);
5997
0
    if (!name)
5998
0
      return 0;
5999
0
    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
6000
0
    if (!newE)
6001
0
      return 0;
6002
0
    if (oldE->systemId) {
6003
0
      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
6004
0
      if (!tem)
6005
0
        return 0;
6006
0
      newE->systemId = tem;
6007
0
      if (oldE->base) {
6008
0
        if (oldE->base == cachedOldBase)
6009
0
          newE->base = cachedNewBase;
6010
0
        else {
6011
0
          cachedOldBase = oldE->base;
6012
0
          tem = poolCopyString(newPool, cachedOldBase);
6013
0
          if (!tem)
6014
0
            return 0;
6015
0
          cachedNewBase = newE->base = tem;
6016
0
        }
6017
0
      }
6018
0
      if (oldE->publicId) {
6019
0
        tem = poolCopyString(newPool, oldE->publicId);
6020
0
        if (!tem)
6021
0
          return 0;
6022
0
        newE->publicId = tem;
6023
0
      }
6024
0
    }
6025
0
    else {
6026
0
      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
6027
0
                                            oldE->textLen);
6028
0
      if (!tem)
6029
0
        return 0;
6030
0
      newE->textPtr = tem;
6031
0
      newE->textLen = oldE->textLen;
6032
0
    }
6033
0
    if (oldE->notation) {
6034
0
      const XML_Char *tem = poolCopyString(newPool, oldE->notation);
6035
0
      if (!tem)
6036
0
        return 0;
6037
0
      newE->notation = tem;
6038
0
    }
6039
0
    newE->is_param = oldE->is_param;
6040
0
    newE->is_internal = oldE->is_internal;
6041
0
  }
6042
0
  return 1;
6043
0
}
6044
6045
0
#define INIT_POWER 6
6046
6047
static XML_Bool FASTCALL
6048
keyeq(KEY s1, KEY s2)
6049
0
{
6050
0
  for (; *s1 == *s2; s1++, s2++)
6051
0
    if (*s1 == 0)
6052
0
      return XML_TRUE;
6053
0
  return XML_FALSE;
6054
0
}
6055
6056
static unsigned long FASTCALL
6057
hash(KEY s)
6058
0
{
6059
0
  unsigned long h = 0;
6060
0
  while (*s)
6061
0
    h = CHAR_HASH(h, *s++);
6062
0
  return h;
6063
0
}
6064
6065
static NAMED *
6066
lookup(HASH_TABLE *table, KEY name, size_t createSize)
6067
0
{
6068
0
  size_t i;
6069
0
  if (table->size == 0) {
6070
0
    size_t tsize;
6071
0
    if (!createSize)
6072
0
      return NULL;
6073
0
    table->power = INIT_POWER;
6074
0
    /* table->size is a power of 2 */
6075
0
    table->size = (size_t)1 << INIT_POWER;
6076
0
    tsize = table->size * sizeof(NAMED *);
6077
0
    table->v = (NAMED **)table->mem->malloc_fcn(tsize);
6078
0
    if (!table->v) {
6079
0
      table->size = 0;
6080
0
      return NULL;
6081
0
    }
6082
0
    memset(table->v, 0, tsize);
6083
0
    i = hash(name) & ((unsigned long)table->size - 1);
6084
0
  }
6085
0
  else {
6086
0
    unsigned long h = hash(name);
6087
0
    unsigned long mask = (unsigned long)table->size - 1;
6088
0
    unsigned char step = 0;
6089
0
    i = h & mask;
6090
0
    while (table->v[i]) {
6091
0
      if (keyeq(name, table->v[i]->name))
6092
0
        return table->v[i];
6093
0
      if (!step)
6094
0
        step = PROBE_STEP(h, mask, table->power);
6095
0
      i < step ? (i += table->size - step) : (i -= step);
6096
0
    }
6097
0
    if (!createSize)
6098
0
      return NULL;
6099
0
6100
0
    /* check for overflow (table is half full) */
6101
0
    if (table->used >> (table->power - 1)) {
6102
0
      unsigned char newPower = table->power + 1;
6103
0
      size_t newSize = (size_t)1 << newPower;
6104
0
      unsigned long newMask = (unsigned long)newSize - 1;
6105
0
      size_t tsize = newSize * sizeof(NAMED *);
6106
0
      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
6107
0
      if (!newV)
6108
0
        return NULL;
6109
0
      memset(newV, 0, tsize);
6110
0
      for (i = 0; i < table->size; i++)
6111
0
        if (table->v[i]) {
6112
0
          unsigned long newHash = hash(table->v[i]->name);
6113
0
          size_t j = newHash & newMask;
6114
0
          step = 0;
6115
0
          while (newV[j]) {
6116
0
            if (!step)
6117
0
              step = PROBE_STEP(newHash, newMask, newPower);
6118
0
            j < step ? (j += newSize - step) : (j -= step);
6119
0
          }
6120
0
          newV[j] = table->v[i];
6121
0
        }
6122
0
      table->mem->free_fcn(table->v);
6123
0
      table->v = newV;
6124
0
      table->power = newPower;
6125
0
      table->size = newSize;
6126
0
      i = h & newMask;
6127
0
      step = 0;
6128
0
      while (table->v[i]) {
6129
0
        if (!step)
6130
0
          step = PROBE_STEP(h, newMask, newPower);
6131
0
        i < step ? (i += newSize - step) : (i -= step);
6132
0
      }
6133
0
    }
6134
0
  }
6135
0
  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
6136
0
  if (!table->v[i])
6137
0
    return NULL;
6138
0
  memset(table->v[i], 0, createSize);
6139
0
  table->v[i]->name = name;
6140
0
  (table->used)++;
6141
0
  return table->v[i];
6142
0
}
6143
6144
/* BEGIN MOZILLA CHANGE (unused API) */
6145
#if 0
6146
static void FASTCALL
6147
hashTableClear(HASH_TABLE *table)
6148
{
6149
  size_t i;
6150
  for (i = 0; i < table->size; i++) {
6151
    table->mem->free_fcn(table->v[i]);
6152
    table->v[i] = NULL;
6153
  }
6154
  table->used = 0;
6155
}
6156
#endif
6157
/* END MOZILLA CHANGE */
6158
6159
static void FASTCALL
6160
hashTableDestroy(HASH_TABLE *table)
6161
0
{
6162
0
  size_t i;
6163
0
  for (i = 0; i < table->size; i++)
6164
0
    table->mem->free_fcn(table->v[i]);
6165
0
  table->mem->free_fcn(table->v);
6166
0
}
6167
6168
static void FASTCALL
6169
hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
6170
0
{
6171
0
  p->power = 0;
6172
0
  p->size = 0;
6173
0
  p->used = 0;
6174
0
  p->v = NULL;
6175
0
  p->mem = ms;
6176
0
}
6177
6178
static void FASTCALL
6179
hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
6180
0
{
6181
0
  iter->p = table->v;
6182
0
  iter->end = iter->p + table->size;
6183
0
}
6184
6185
static NAMED * FASTCALL
6186
hashTableIterNext(HASH_TABLE_ITER *iter)
6187
0
{
6188
0
  while (iter->p != iter->end) {
6189
0
    NAMED *tem = *(iter->p)++;
6190
0
    if (tem)
6191
0
      return tem;
6192
0
  }
6193
0
  return NULL;
6194
0
}
6195
6196
static void FASTCALL
6197
poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
6198
0
{
6199
0
  pool->blocks = NULL;
6200
0
  pool->freeBlocks = NULL;
6201
0
  pool->start = NULL;
6202
0
  pool->ptr = NULL;
6203
0
  pool->end = NULL;
6204
0
  pool->mem = ms;
6205
0
}
6206
6207
static void FASTCALL
6208
poolClear(STRING_POOL *pool)
6209
0
{
6210
0
  if (!pool->freeBlocks)
6211
0
    pool->freeBlocks = pool->blocks;
6212
0
  else {
6213
0
    BLOCK *p = pool->blocks;
6214
0
    while (p) {
6215
0
      BLOCK *tem = p->next;
6216
0
      p->next = pool->freeBlocks;
6217
0
      pool->freeBlocks = p;
6218
0
      p = tem;
6219
0
    }
6220
0
  }
6221
0
  pool->blocks = NULL;
6222
0
  pool->start = NULL;
6223
0
  pool->ptr = NULL;
6224
0
  pool->end = NULL;
6225
0
}
6226
6227
static void FASTCALL
6228
poolDestroy(STRING_POOL *pool)
6229
0
{
6230
0
  BLOCK *p = pool->blocks;
6231
0
  while (p) {
6232
0
    BLOCK *tem = p->next;
6233
0
    pool->mem->free_fcn(p);
6234
0
    p = tem;
6235
0
  }
6236
0
  p = pool->freeBlocks;
6237
0
  while (p) {
6238
0
    BLOCK *tem = p->next;
6239
0
    pool->mem->free_fcn(p);
6240
0
    p = tem;
6241
0
  }
6242
0
}
6243
6244
static XML_Char *
6245
poolAppend(STRING_POOL *pool, const ENCODING *enc,
6246
           const char *ptr, const char *end)
6247
0
{
6248
0
  if (!pool->ptr && !poolGrow(pool))
6249
0
    return NULL;
6250
0
  for (;;) {
6251
0
    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6252
0
    if (ptr == end)
6253
0
      break;
6254
0
    if (!poolGrow(pool))
6255
0
      return NULL;
6256
0
  }
6257
0
  return pool->start;
6258
0
}
6259
6260
static const XML_Char * FASTCALL
6261
poolCopyString(STRING_POOL *pool, const XML_Char *s)
6262
0
{
6263
0
  do {
6264
0
    if (!poolAppendChar(pool, *s))
6265
0
      return NULL;
6266
0
  } while (*s++);
6267
0
  s = pool->start;
6268
0
  poolFinish(pool);
6269
0
  return s;
6270
0
}
6271
6272
static const XML_Char *
6273
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
6274
0
{
6275
0
  if (!pool->ptr && !poolGrow(pool))
6276
0
    return NULL;
6277
0
  for (; n > 0; --n, s++) {
6278
0
    if (!poolAppendChar(pool, *s))
6279
0
      return NULL;
6280
0
  }
6281
0
  s = pool->start;
6282
0
  poolFinish(pool);
6283
0
  return s;
6284
0
}
6285
6286
static const XML_Char * FASTCALL
6287
poolAppendString(STRING_POOL *pool, const XML_Char *s)
6288
0
{
6289
0
  while (*s) {
6290
0
    if (!poolAppendChar(pool, *s))
6291
0
      return NULL;
6292
0
    s++;
6293
0
  }
6294
0
  return pool->start;
6295
0
}
6296
6297
static XML_Char *
6298
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6299
                const char *ptr, const char *end)
6300
0
{
6301
0
  if (!poolAppend(pool, enc, ptr, end))
6302
0
    return NULL;
6303
0
  if (pool->ptr == pool->end && !poolGrow(pool))
6304
0
    return NULL;
6305
0
  *(pool->ptr)++ = 0;
6306
0
  return pool->start;
6307
0
}
6308
6309
static XML_Bool FASTCALL
6310
poolGrow(STRING_POOL *pool)
6311
0
{
6312
0
  if (pool->freeBlocks) {
6313
0
    if (pool->start == 0) {
6314
0
      pool->blocks = pool->freeBlocks;
6315
0
      pool->freeBlocks = pool->freeBlocks->next;
6316
0
      pool->blocks->next = NULL;
6317
0
      pool->start = pool->blocks->s;
6318
0
      pool->end = pool->start + pool->blocks->size;
6319
0
      pool->ptr = pool->start;
6320
0
      return XML_TRUE;
6321
0
    }
6322
0
    if (pool->end - pool->start < pool->freeBlocks->size) {
6323
0
      BLOCK *tem = pool->freeBlocks->next;
6324
0
      pool->freeBlocks->next = pool->blocks;
6325
0
      pool->blocks = pool->freeBlocks;
6326
0
      pool->freeBlocks = tem;
6327
0
      memcpy(pool->blocks->s, pool->start,
6328
0
             (pool->end - pool->start) * sizeof(XML_Char));
6329
0
      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6330
0
      pool->start = pool->blocks->s;
6331
0
      pool->end = pool->start + pool->blocks->size;
6332
0
      return XML_TRUE;
6333
0
    }
6334
0
  }
6335
0
  if (pool->blocks && pool->start == pool->blocks->s) {
6336
0
    int blockSize = (int)(pool->end - pool->start)*2;
6337
0
    if (blockSize < 0)
6338
0
      return XML_FALSE;
6339
0
6340
0
    pool->blocks = (BLOCK *)
6341
0
      pool->mem->realloc_fcn(pool->blocks,
6342
0
                             (offsetof(BLOCK, s)
6343
0
                              + blockSize * sizeof(XML_Char)));
6344
0
    if (pool->blocks == NULL)
6345
0
      return XML_FALSE;
6346
0
    pool->blocks->size = blockSize;
6347
0
    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6348
0
    pool->start = pool->blocks->s;
6349
0
    pool->end = pool->start + blockSize;
6350
0
  }
6351
0
  else {
6352
0
    BLOCK *tem;
6353
0
    int blockSize = (int)(pool->end - pool->start);
6354
0
    if (blockSize < 0)
6355
0
      return XML_FALSE;
6356
0
6357
0
    if (blockSize < INIT_BLOCK_SIZE)
6358
0
      blockSize = INIT_BLOCK_SIZE;
6359
0
    else
6360
0
      blockSize *= 2;
6361
0
6362
0
    if (blockSize < 0)
6363
0
      return XML_FALSE;
6364
0
6365
0
    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
6366
0
                                        + blockSize * sizeof(XML_Char));
6367
0
    if (!tem)
6368
0
      return XML_FALSE;
6369
0
    tem->size = blockSize;
6370
0
    tem->next = pool->blocks;
6371
0
    pool->blocks = tem;
6372
0
    if (pool->ptr != pool->start)
6373
0
      memcpy(tem->s, pool->start,
6374
0
             (pool->ptr - pool->start) * sizeof(XML_Char));
6375
0
    pool->ptr = tem->s + (pool->ptr - pool->start);
6376
0
    pool->start = tem->s;
6377
0
    pool->end = tem->s + blockSize;
6378
0
  }
6379
0
  return XML_TRUE;
6380
0
}
6381
6382
static int FASTCALL
6383
nextScaffoldPart(XML_Parser parser)
6384
0
{
6385
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
6386
0
  CONTENT_SCAFFOLD * me;
6387
0
  int next;
6388
0
6389
0
  if (!dtd->scaffIndex) {
6390
0
    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6391
0
    if (!dtd->scaffIndex)
6392
0
      return -1;
6393
0
    dtd->scaffIndex[0] = 0;
6394
0
  }
6395
0
6396
0
  if (dtd->scaffCount >= dtd->scaffSize) {
6397
0
    CONTENT_SCAFFOLD *temp;
6398
0
    if (dtd->scaffold) {
6399
0
      temp = (CONTENT_SCAFFOLD *)
6400
0
        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6401
0
      if (temp == NULL)
6402
0
        return -1;
6403
0
      dtd->scaffSize *= 2;
6404
0
    }
6405
0
    else {
6406
0
      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6407
0
                                        * sizeof(CONTENT_SCAFFOLD));
6408
0
      if (temp == NULL)
6409
0
        return -1;
6410
0
      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6411
0
    }
6412
0
    dtd->scaffold = temp;
6413
0
  }
6414
0
  next = dtd->scaffCount++;
6415
0
  me = &dtd->scaffold[next];
6416
0
  if (dtd->scaffLevel) {
6417
0
    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
6418
0
    if (parent->lastchild) {
6419
0
      dtd->scaffold[parent->lastchild].nextsib = next;
6420
0
    }
6421
0
    if (!parent->childcnt)
6422
0
      parent->firstchild = next;
6423
0
    parent->lastchild = next;
6424
0
    parent->childcnt++;
6425
0
  }
6426
0
  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6427
0
  return next;
6428
0
}
6429
6430
static void
6431
build_node(XML_Parser parser,
6432
           int src_node,
6433
           XML_Content *dest,
6434
           XML_Content **contpos,
6435
           XML_Char **strpos)
6436
0
{
6437
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
6438
0
  dest->type = dtd->scaffold[src_node].type;
6439
0
  dest->quant = dtd->scaffold[src_node].quant;
6440
0
  if (dest->type == XML_CTYPE_NAME) {
6441
0
    const XML_Char *src;
6442
0
    dest->name = *strpos;
6443
0
    src = dtd->scaffold[src_node].name;
6444
0
    for (;;) {
6445
0
      *(*strpos)++ = *src;
6446
0
      if (!*src)
6447
0
        break;
6448
0
      src++;
6449
0
    }
6450
0
    dest->numchildren = 0;
6451
0
    dest->children = NULL;
6452
0
  }
6453
0
  else {
6454
0
    unsigned int i;
6455
0
    int cn;
6456
0
    dest->numchildren = dtd->scaffold[src_node].childcnt;
6457
0
    dest->children = *contpos;
6458
0
    *contpos += dest->numchildren;
6459
0
    for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6460
0
         i < dest->numchildren;
6461
0
         i++, cn = dtd->scaffold[cn].nextsib) {
6462
0
      build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6463
0
    }
6464
0
    dest->name = NULL;
6465
0
  }
6466
0
}
6467
6468
static XML_Content *
6469
build_model (XML_Parser parser)
6470
0
{
6471
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
6472
0
  XML_Content *ret;
6473
0
  XML_Content *cpos;
6474
0
  XML_Char * str;
6475
0
  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6476
0
                   + (dtd->contentStringLen * sizeof(XML_Char)));
6477
0
6478
0
  ret = (XML_Content *)MALLOC(allocsize);
6479
0
  if (!ret)
6480
0
    return NULL;
6481
0
6482
0
  str =  (XML_Char *) (&ret[dtd->scaffCount]);
6483
0
  cpos = &ret[1];
6484
0
6485
0
  build_node(parser, 0, ret, &cpos, &str);
6486
0
  return ret;
6487
0
}
6488
6489
static ELEMENT_TYPE *
6490
getElementType(XML_Parser parser,
6491
               const ENCODING *enc,
6492
               const char *ptr,
6493
               const char *end)
6494
0
{
6495
0
  DTD * const dtd = _dtd;  /* save one level of indirection */
6496
0
  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6497
0
  ELEMENT_TYPE *ret;
6498
0
6499
0
  if (!name)
6500
0
    return NULL;
6501
0
  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6502
0
  if (!ret)
6503
0
    return NULL;
6504
0
  if (ret->name != name)
6505
0
    poolDiscard(&dtd->pool);
6506
0
  else {
6507
0
    poolFinish(&dtd->pool);
6508
0
    if (!setElementTypePrefix(parser, ret))
6509
0
      return NULL;
6510
0
  }
6511
0
  return ret;
6512
0
}