Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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