~ubuntu-branches/ubuntu/oneiric/jabberd2/oneiric-security

« back to all changes in this revision

Viewing changes to expat/xmlparse.c

  • Committer: Bazaar Package Importer
  • Author(s): Nicolai Spohrer
  • Date: 2008-08-12 16:13:43 UTC
  • mfrom: (1.1.3 upstream) (0.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20080812161343-6trz3r97dtevxd17
Tags: 2.2.1-1ubuntu1
* Merge with Debian unstable (LP: #257130), remaining changes:
  - debian/control:
    + Modify Maintainer field as per spec
    + Depend on libdb4.6-dev instead of libdb4.4-dev
    + Added Conflicts and Replaces: ..., jabber for jabberd2
  - debian/rules: Added libtoolize call (jabberd2 ships with
     an older ltmain.sh version that conflicts with the
     current libtool version)
  - debian/init: create /var/run/jabber directory with correct
     permissions
* Dropped changes:
  - Debian already depends on libpq-dev

Show diffs side-by-side

added added

removed removed

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