1
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2
See the file COPYING for copying permission.
6
#include <string.h> /* memset(), memcpy() */
8
#include <limits.h> /* UINT_MAX */
9
#include <time.h> /* time() */
11
#define XML_BUILDING_EXPAT 1
13
#ifdef COMPILED_FROM_DSP
14
#include "winconfig.h"
15
#elif defined(MACOS_CLASSIC)
16
#include "macconfig.h"
17
#elif defined(__amigaos__)
18
#include "amigaconfig.h"
19
#elif defined(__WATCOMC__)
20
#include "watcomconfig.h"
21
#elif defined(HAVE_EXPAT_CONFIG_H)
22
#include <expat_config.h>
23
#endif /* ndef COMPILED_FROM_DSP */
29
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
30
#define XmlConvert XmlUtf16Convert
31
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
32
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
33
#define XmlEncode XmlUtf16Encode
34
/* Using pointer subtraction to convert to integer type. */
35
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
36
typedef unsigned short ICHAR;
38
#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
39
#define XmlConvert XmlUtf8Convert
40
#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
41
#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
42
#define XmlEncode XmlUtf8Encode
43
#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
50
#define XmlInitEncodingNS XmlInitEncoding
51
#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
52
#undef XmlGetInternalEncodingNS
53
#define XmlGetInternalEncodingNS XmlGetInternalEncoding
54
#define XmlParseXmlDeclNS XmlParseXmlDecl
60
#ifdef XML_UNICODE_WCHAR_T
61
#define XML_T(x) (const wchar_t)x
62
#define XML_L(x) L ## x
64
#define XML_T(x) (const unsigned short)x
75
/* Round up n to be a multiple of sz, where sz is a power of 2. */
76
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
78
/* Handle the case where memmove() doesn't exist. */
81
#define memmove(d,s,l) bcopy((s),(d),(l))
83
#error memmove does not exist on this platform, nor is a substitute available
84
#endif /* HAVE_BCOPY */
85
#endif /* HAVE_MEMMOVE */
91
typedef const XML_Char *KEY;
102
const XML_Memory_Handling_Suite *mem;
105
/* Basic character hash algorithm, taken from Python's string hash:
106
h = h * 1000003 ^ character, the constant being a prime number.
110
#define CHAR_HASH(h, c) \
111
(((h) * 0xF4243) ^ (unsigned short)(c))
113
#define CHAR_HASH(h, c) \
114
(((h) * 0xF4243) ^ (unsigned char)(c))
117
/* For probing (after a collision) we need a step size relative prime
118
to the hash table size, which is a power of 2. We use double-hashing,
119
since we can calculate a second hash value cheaply by taking those bits
120
of the first hash value that were discarded (masked out) when the table
121
index was calculated: index = hash & mask, where mask = table->size - 1.
122
We limit the maximum step size to table->size / 4 (mask >> 2) and make
123
it odd, since odd numbers are always relative prime to a power of 2.
125
#define SECOND_HASH(hash, mask, power) \
126
((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
127
#define PROBE_STEP(hash, mask, power) \
128
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
135
#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
136
#define INIT_DATA_BUF_SIZE 1024
137
#define INIT_ATTS_SIZE 16
138
#define INIT_ATTS_VERSION 0xFFFFFFFF
139
#define INIT_BLOCK_SIZE 1024
140
#define INIT_BUFFER_SIZE 1024
142
#define EXPAND_SPARE 24
144
typedef struct binding {
145
struct prefix *prefix;
146
struct binding *nextTagBinding;
147
struct binding *prevPrefixBinding;
148
const struct attribute_id *attId;
154
typedef struct prefix {
155
const XML_Char *name;
161
const XML_Char *localPart;
162
const XML_Char *prefix;
168
/* TAG represents an open element.
169
The name of the element is stored in both the document and API
170
encodings. The memory buffer 'buf' is a separately-allocated
171
memory area which stores the name. During the XML_Parse()/
172
XMLParseBuffer() when the element is open, the memory for the 'raw'
173
version of the name (in the document encoding) is shared with the
174
document buffer. If the element is open across calls to
175
XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
176
contain the 'raw' name as well.
178
A parser re-uses these structures, maintaining a list of allocated
179
TAG objects in a free list.
182
struct tag *parent; /* parent of this element */
183
const char *rawName; /* tagName in the original encoding */
185
TAG_NAME name; /* tagName in the API encoding */
186
char *buf; /* buffer for name components */
187
char *bufEnd; /* end of the buffer */
192
const XML_Char *name;
193
const XML_Char *textPtr;
194
int textLen; /* length in XML_Chars */
195
int processed; /* # of processed bytes - when suspended */
196
const XML_Char *systemId;
197
const XML_Char *base;
198
const XML_Char *publicId;
199
const XML_Char *notation;
202
XML_Bool is_internal; /* true if declared in internal subset outside PE */
206
enum XML_Content_Type type;
207
enum XML_Content_Quant quant;
208
const XML_Char * name;
215
#define INIT_SCAFFOLD_ELEMENTS 32
217
typedef struct block {
229
const XML_Memory_Handling_Suite *mem;
232
/* The XML_Char before the name is used to determine whether
233
an attribute has been specified. */
234
typedef struct attribute_id {
237
XML_Bool maybeTokenized;
242
const ATTRIBUTE_ID *id;
244
const XML_Char *value;
248
unsigned long version;
250
const XML_Char *uriName;
254
const XML_Char *name;
256
const ATTRIBUTE_ID *idAtt;
258
int allocDefaultAtts;
259
DEFAULT_ATTRIBUTE *defaultAtts;
263
HASH_TABLE generalEntities;
264
HASH_TABLE elementTypes;
265
HASH_TABLE attributeIds;
268
STRING_POOL entityValuePool;
269
/* false once a parameter entity reference has been skipped */
270
XML_Bool keepProcessing;
271
/* true once an internal or external PE reference has been encountered;
272
this includes the reference to an external subset */
273
XML_Bool hasParamEntityRefs;
276
/* indicates if external PE has been read */
277
XML_Bool paramEntityRead;
278
HASH_TABLE paramEntities;
280
PREFIX defaultPrefix;
281
/* === scaffolding for building content model === */
283
CONTENT_SCAFFOLD *scaffold;
284
unsigned contentStringLen;
291
typedef struct open_internal_entity {
292
const char *internalEventPtr;
293
const char *internalEventEndPtr;
294
struct open_internal_entity *next;
297
XML_Bool betweenDecl; /* WFC: PE Between Declarations */
298
} OPEN_INTERNAL_ENTITY;
300
typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
303
const char **endPtr);
305
static Processor prologProcessor;
306
static Processor prologInitProcessor;
307
static Processor contentProcessor;
308
static Processor cdataSectionProcessor;
310
static Processor ignoreSectionProcessor;
311
static Processor externalParEntProcessor;
312
static Processor externalParEntInitProcessor;
313
static Processor entityValueProcessor;
314
static Processor entityValueInitProcessor;
316
static Processor epilogProcessor;
317
static Processor errorProcessor;
318
static Processor externalEntityInitProcessor;
319
static Processor externalEntityInitProcessor2;
320
static Processor externalEntityInitProcessor3;
321
static Processor externalEntityContentProcessor;
322
static Processor internalEntityProcessor;
324
static enum XML_Error
325
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
326
static enum XML_Error
327
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
328
const char *s, const char *next);
329
static enum XML_Error
330
initializeEncoding(XML_Parser parser);
331
static enum XML_Error
332
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
333
const char *end, int tok, const char *next, const char **nextPtr,
335
static enum XML_Error
336
processInternalEntity(XML_Parser parser, ENTITY *entity,
337
XML_Bool betweenDecl);
338
static enum XML_Error
339
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
340
const char *start, const char *end, const char **endPtr,
342
static enum XML_Error
343
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
344
const char *end, const char **nextPtr, XML_Bool haveMore);
346
static enum XML_Error
347
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
348
const char *end, const char **nextPtr, XML_Bool haveMore);
351
static enum XML_Error
352
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
353
TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
354
static enum XML_Error
355
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
356
const XML_Char *uri, BINDING **bindingsPtr);
358
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
359
XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
360
static enum XML_Error
361
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
362
const char *, const char *, STRING_POOL *);
363
static enum XML_Error
364
appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
365
const char *, const char *, STRING_POOL *);
366
static ATTRIBUTE_ID *
367
getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
370
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
371
static enum XML_Error
372
storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
375
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
376
const char *start, const char *end);
378
reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
381
reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
384
static const XML_Char * getContext(XML_Parser parser);
386
setContext(XML_Parser parser, const XML_Char *context);
388
static void FASTCALL normalizePublicId(XML_Char *s);
390
static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
391
/* do not call if parentParser != NULL */
392
static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
394
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
396
dtdCopy(XML_Parser oldParser,
397
DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
399
copyEntityTable(XML_Parser oldParser,
400
HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
402
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
404
hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
405
static void FASTCALL hashTableClear(HASH_TABLE *);
406
static void FASTCALL hashTableDestroy(HASH_TABLE *);
408
hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
409
static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
412
poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
413
static void FASTCALL poolClear(STRING_POOL *);
414
static void FASTCALL poolDestroy(STRING_POOL *);
416
poolAppend(STRING_POOL *pool, const ENCODING *enc,
417
const char *ptr, const char *end);
419
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
420
const char *ptr, const char *end);
421
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
422
static const XML_Char * FASTCALL
423
poolCopyString(STRING_POOL *pool, const XML_Char *s);
424
static const XML_Char *
425
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
426
static const XML_Char * FASTCALL
427
poolAppendString(STRING_POOL *pool, const XML_Char *s);
429
static int FASTCALL nextScaffoldPart(XML_Parser parser);
430
static XML_Content * build_model(XML_Parser parser);
431
static ELEMENT_TYPE *
432
getElementType(XML_Parser parser, const ENCODING *enc,
433
const char *ptr, const char *end);
435
static unsigned long generate_hash_secret_salt(void);
436
static XML_Bool startParsing(XML_Parser parser);
439
parserCreate(const XML_Char *encodingName,
440
const XML_Memory_Handling_Suite *memsuite,
441
const XML_Char *nameSep,
445
parserInit(XML_Parser parser, const XML_Char *encodingName);
447
#define poolStart(pool) ((pool)->start)
448
#define poolEnd(pool) ((pool)->ptr)
449
#define poolLength(pool) ((pool)->ptr - (pool)->start)
450
#define poolChop(pool) ((void)--(pool->ptr))
451
#define poolLastChar(pool) (((pool)->ptr)[-1])
452
#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
453
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
454
#define poolAppendChar(pool, c) \
455
(((pool)->ptr == (pool)->end && !poolGrow(pool)) \
457
: ((*((pool)->ptr)++ = c), 1))
459
struct XML_ParserStruct {
460
/* The first member must be userData so that the XML_GetUserData
465
const XML_Memory_Handling_Suite m_mem;
466
/* first character to be parsed */
467
const char *m_bufferPtr;
468
/* past last character to be parsed */
470
/* allocated end of buffer */
471
const char *m_bufferLim;
472
XML_Index m_parseEndByteIndex;
473
const char *m_parseEndPtr;
475
XML_Char *m_dataBufEnd;
476
XML_StartElementHandler m_startElementHandler;
477
XML_EndElementHandler m_endElementHandler;
478
XML_CharacterDataHandler m_characterDataHandler;
479
XML_ProcessingInstructionHandler m_processingInstructionHandler;
480
XML_CommentHandler m_commentHandler;
481
XML_StartCdataSectionHandler m_startCdataSectionHandler;
482
XML_EndCdataSectionHandler m_endCdataSectionHandler;
483
XML_DefaultHandler m_defaultHandler;
484
XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
485
XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
486
XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
487
XML_NotationDeclHandler m_notationDeclHandler;
488
XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
489
XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
490
XML_NotStandaloneHandler m_notStandaloneHandler;
491
XML_ExternalEntityRefHandler m_externalEntityRefHandler;
492
XML_Parser m_externalEntityRefHandlerArg;
493
XML_SkippedEntityHandler m_skippedEntityHandler;
494
XML_UnknownEncodingHandler m_unknownEncodingHandler;
495
XML_ElementDeclHandler m_elementDeclHandler;
496
XML_AttlistDeclHandler m_attlistDeclHandler;
497
XML_EntityDeclHandler m_entityDeclHandler;
498
XML_XmlDeclHandler m_xmlDeclHandler;
499
const ENCODING *m_encoding;
500
INIT_ENCODING m_initEncoding;
501
const ENCODING *m_internalEncoding;
502
const XML_Char *m_protocolEncodingName;
504
XML_Bool m_ns_triplets;
505
void *m_unknownEncodingMem;
506
void *m_unknownEncodingData;
507
void *m_unknownEncodingHandlerData;
508
void (XMLCALL *m_unknownEncodingRelease)(void *);
509
PROLOG_STATE m_prologState;
510
Processor *m_processor;
511
enum XML_Error m_errorCode;
512
const char *m_eventPtr;
513
const char *m_eventEndPtr;
514
const char *m_positionPtr;
515
OPEN_INTERNAL_ENTITY *m_openInternalEntities;
516
OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
517
XML_Bool m_defaultExpandInternalEntities;
519
ENTITY *m_declEntity;
520
const XML_Char *m_doctypeName;
521
const XML_Char *m_doctypeSysid;
522
const XML_Char *m_doctypePubid;
523
const XML_Char *m_declAttributeType;
524
const XML_Char *m_declNotationName;
525
const XML_Char *m_declNotationPublicId;
526
ELEMENT_TYPE *m_declElementType;
527
ATTRIBUTE_ID *m_declAttributeId;
528
XML_Bool m_declAttributeIsCdata;
529
XML_Bool m_declAttributeIsId;
531
const XML_Char *m_curBase;
534
BINDING *m_inheritedBindings;
535
BINDING *m_freeBindingList;
537
int m_nSpecifiedAtts;
541
unsigned long m_nsAttsVersion;
542
unsigned char m_nsAttsPower;
544
XML_AttrInfo *m_attInfo;
547
STRING_POOL m_tempPool;
548
STRING_POOL m_temp2Pool;
549
char *m_groupConnector;
550
unsigned int m_groupSize;
551
XML_Char m_namespaceSeparator;
552
XML_Parser m_parentParser;
553
XML_ParsingStatus m_parsingStatus;
555
XML_Bool m_isParamEntity;
556
XML_Bool m_useForeignDTD;
557
enum XML_ParamEntityParsing m_paramEntityParsing;
559
unsigned long m_hash_secret_salt;
562
#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
563
#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
564
#define FREE(p) (parser->m_mem.free_fcn((p)))
566
#define userData (parser->m_userData)
567
#define handlerArg (parser->m_handlerArg)
568
#define startElementHandler (parser->m_startElementHandler)
569
#define endElementHandler (parser->m_endElementHandler)
570
#define characterDataHandler (parser->m_characterDataHandler)
571
#define processingInstructionHandler \
572
(parser->m_processingInstructionHandler)
573
#define commentHandler (parser->m_commentHandler)
574
#define startCdataSectionHandler \
575
(parser->m_startCdataSectionHandler)
576
#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
577
#define defaultHandler (parser->m_defaultHandler)
578
#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
579
#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
580
#define unparsedEntityDeclHandler \
581
(parser->m_unparsedEntityDeclHandler)
582
#define notationDeclHandler (parser->m_notationDeclHandler)
583
#define startNamespaceDeclHandler \
584
(parser->m_startNamespaceDeclHandler)
585
#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
586
#define notStandaloneHandler (parser->m_notStandaloneHandler)
587
#define externalEntityRefHandler \
588
(parser->m_externalEntityRefHandler)
589
#define externalEntityRefHandlerArg \
590
(parser->m_externalEntityRefHandlerArg)
591
#define internalEntityRefHandler \
592
(parser->m_internalEntityRefHandler)
593
#define skippedEntityHandler (parser->m_skippedEntityHandler)
594
#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
595
#define elementDeclHandler (parser->m_elementDeclHandler)
596
#define attlistDeclHandler (parser->m_attlistDeclHandler)
597
#define entityDeclHandler (parser->m_entityDeclHandler)
598
#define xmlDeclHandler (parser->m_xmlDeclHandler)
599
#define encoding (parser->m_encoding)
600
#define initEncoding (parser->m_initEncoding)
601
#define internalEncoding (parser->m_internalEncoding)
602
#define unknownEncodingMem (parser->m_unknownEncodingMem)
603
#define unknownEncodingData (parser->m_unknownEncodingData)
604
#define unknownEncodingHandlerData \
605
(parser->m_unknownEncodingHandlerData)
606
#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
607
#define protocolEncodingName (parser->m_protocolEncodingName)
608
#define ns (parser->m_ns)
609
#define ns_triplets (parser->m_ns_triplets)
610
#define prologState (parser->m_prologState)
611
#define processor (parser->m_processor)
612
#define errorCode (parser->m_errorCode)
613
#define eventPtr (parser->m_eventPtr)
614
#define eventEndPtr (parser->m_eventEndPtr)
615
#define positionPtr (parser->m_positionPtr)
616
#define position (parser->m_position)
617
#define openInternalEntities (parser->m_openInternalEntities)
618
#define freeInternalEntities (parser->m_freeInternalEntities)
619
#define defaultExpandInternalEntities \
620
(parser->m_defaultExpandInternalEntities)
621
#define tagLevel (parser->m_tagLevel)
622
#define buffer (parser->m_buffer)
623
#define bufferPtr (parser->m_bufferPtr)
624
#define bufferEnd (parser->m_bufferEnd)
625
#define parseEndByteIndex (parser->m_parseEndByteIndex)
626
#define parseEndPtr (parser->m_parseEndPtr)
627
#define bufferLim (parser->m_bufferLim)
628
#define dataBuf (parser->m_dataBuf)
629
#define dataBufEnd (parser->m_dataBufEnd)
630
#define _dtd (parser->m_dtd)
631
#define curBase (parser->m_curBase)
632
#define declEntity (parser->m_declEntity)
633
#define doctypeName (parser->m_doctypeName)
634
#define doctypeSysid (parser->m_doctypeSysid)
635
#define doctypePubid (parser->m_doctypePubid)
636
#define declAttributeType (parser->m_declAttributeType)
637
#define declNotationName (parser->m_declNotationName)
638
#define declNotationPublicId (parser->m_declNotationPublicId)
639
#define declElementType (parser->m_declElementType)
640
#define declAttributeId (parser->m_declAttributeId)
641
#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
642
#define declAttributeIsId (parser->m_declAttributeIsId)
643
#define freeTagList (parser->m_freeTagList)
644
#define freeBindingList (parser->m_freeBindingList)
645
#define inheritedBindings (parser->m_inheritedBindings)
646
#define tagStack (parser->m_tagStack)
647
#define atts (parser->m_atts)
648
#define attsSize (parser->m_attsSize)
649
#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
650
#define idAttIndex (parser->m_idAttIndex)
651
#define nsAtts (parser->m_nsAtts)
652
#define nsAttsVersion (parser->m_nsAttsVersion)
653
#define nsAttsPower (parser->m_nsAttsPower)
654
#define attInfo (parser->m_attInfo)
655
#define tempPool (parser->m_tempPool)
656
#define temp2Pool (parser->m_temp2Pool)
657
#define groupConnector (parser->m_groupConnector)
658
#define groupSize (parser->m_groupSize)
659
#define namespaceSeparator (parser->m_namespaceSeparator)
660
#define parentParser (parser->m_parentParser)
661
#define ps_parsing (parser->m_parsingStatus.parsing)
662
#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
664
#define isParamEntity (parser->m_isParamEntity)
665
#define useForeignDTD (parser->m_useForeignDTD)
666
#define paramEntityParsing (parser->m_paramEntityParsing)
668
#define hash_secret_salt (parser->m_hash_secret_salt)
671
XML_ParserCreate(const XML_Char *encodingName)
673
return XML_ParserCreate_MM(encodingName, NULL, NULL);
677
XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
681
return XML_ParserCreate_MM(encodingName, NULL, tmp);
684
static const XML_Char implicitContext[] = {
685
ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
686
ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
687
ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
688
ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
689
ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
690
ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
694
generate_hash_secret_salt(void)
696
unsigned int seed = time(NULL) % UINT_MAX;
701
static XML_Bool /* only valid for root parser */
702
startParsing(XML_Parser parser)
704
/* hash functions must be initialized before setContext() is called */
705
if (hash_secret_salt == 0)
706
hash_secret_salt = generate_hash_secret_salt();
708
/* implicit context only set for root parser, since child
709
parsers (i.e. external entity parsers) will inherit it
711
return setContext(parser, implicitContext);
717
XML_ParserCreate_MM(const XML_Char *encodingName,
718
const XML_Memory_Handling_Suite *memsuite,
719
const XML_Char *nameSep)
721
return parserCreate(encodingName, memsuite, nameSep, NULL);
725
parserCreate(const XML_Char *encodingName,
726
const XML_Memory_Handling_Suite *memsuite,
727
const XML_Char *nameSep,
733
XML_Memory_Handling_Suite *mtemp;
734
parser = (XML_Parser)
735
memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
736
if (parser != NULL) {
737
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
738
mtemp->malloc_fcn = memsuite->malloc_fcn;
739
mtemp->realloc_fcn = memsuite->realloc_fcn;
740
mtemp->free_fcn = memsuite->free_fcn;
744
XML_Memory_Handling_Suite *mtemp;
745
parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
746
if (parser != NULL) {
747
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
748
mtemp->malloc_fcn = malloc;
749
mtemp->realloc_fcn = realloc;
750
mtemp->free_fcn = free;
760
attsSize = INIT_ATTS_SIZE;
761
atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
767
attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
768
if (attInfo == NULL) {
774
dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
775
if (dataBuf == NULL) {
783
dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
788
_dtd = dtdCreate(&parser->m_mem);
800
freeBindingList = NULL;
802
freeInternalEntities = NULL;
805
groupConnector = NULL;
807
unknownEncodingHandler = NULL;
808
unknownEncodingHandlerData = NULL;
810
namespaceSeparator = ASCII_EXCL;
812
ns_triplets = XML_FALSE;
818
poolInit(&tempPool, &(parser->m_mem));
819
poolInit(&temp2Pool, &(parser->m_mem));
820
parserInit(parser, encodingName);
822
if (encodingName && !protocolEncodingName) {
823
XML_ParserFree(parser);
829
internalEncoding = XmlGetInternalEncodingNS();
830
namespaceSeparator = *nameSep;
833
internalEncoding = XmlGetInternalEncoding();
840
parserInit(XML_Parser parser, const XML_Char *encodingName)
842
processor = prologInitProcessor;
843
XmlPrologStateInit(&prologState);
844
protocolEncodingName = (encodingName != NULL
845
? poolCopyString(&tempPool, encodingName)
848
XmlInitEncoding(&initEncoding, &encoding, 0);
851
startElementHandler = NULL;
852
endElementHandler = NULL;
853
characterDataHandler = NULL;
854
processingInstructionHandler = NULL;
855
commentHandler = NULL;
856
startCdataSectionHandler = NULL;
857
endCdataSectionHandler = NULL;
858
defaultHandler = NULL;
859
startDoctypeDeclHandler = NULL;
860
endDoctypeDeclHandler = NULL;
861
unparsedEntityDeclHandler = NULL;
862
notationDeclHandler = NULL;
863
startNamespaceDeclHandler = NULL;
864
endNamespaceDeclHandler = NULL;
865
notStandaloneHandler = NULL;
866
externalEntityRefHandler = NULL;
867
externalEntityRefHandlerArg = parser;
868
skippedEntityHandler = NULL;
869
elementDeclHandler = NULL;
870
attlistDeclHandler = NULL;
871
entityDeclHandler = NULL;
872
xmlDeclHandler = NULL;
875
parseEndByteIndex = 0;
877
declElementType = NULL;
878
declAttributeId = NULL;
883
declAttributeType = NULL;
884
declNotationName = NULL;
885
declNotationPublicId = NULL;
886
declAttributeIsCdata = XML_FALSE;
887
declAttributeIsId = XML_FALSE;
888
memset(&position, 0, sizeof(POSITION));
889
errorCode = XML_ERROR_NONE;
893
openInternalEntities = NULL;
894
defaultExpandInternalEntities = XML_TRUE;
897
inheritedBindings = NULL;
899
unknownEncodingMem = NULL;
900
unknownEncodingRelease = NULL;
901
unknownEncodingData = NULL;
903
ps_parsing = XML_INITIALIZED;
905
isParamEntity = XML_FALSE;
906
useForeignDTD = XML_FALSE;
907
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
909
hash_secret_salt = 0;
912
/* moves list of bindings to freeBindingList */
914
moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
917
BINDING *b = bindings;
918
bindings = bindings->nextTagBinding;
919
b->nextTagBinding = freeBindingList;
925
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
928
OPEN_INTERNAL_ENTITY *openEntityList;
931
/* move tagStack to freeTagList */
936
tag->parent = freeTagList;
937
moveToFreeBindingList(parser, tag->bindings);
938
tag->bindings = NULL;
941
/* move openInternalEntities to freeInternalEntities */
942
openEntityList = openInternalEntities;
943
while (openEntityList) {
944
OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
945
openEntityList = openEntity->next;
946
openEntity->next = freeInternalEntities;
947
freeInternalEntities = openEntity;
949
moveToFreeBindingList(parser, inheritedBindings);
950
FREE(unknownEncodingMem);
951
if (unknownEncodingRelease)
952
unknownEncodingRelease(unknownEncodingData);
953
poolClear(&tempPool);
954
poolClear(&temp2Pool);
955
parserInit(parser, encodingName);
956
dtdReset(_dtd, &parser->m_mem);
960
enum XML_Status XMLCALL
961
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
963
/* Block after XML_Parse()/XML_ParseBuffer() has been called.
964
XXX There's no way for the caller to determine which of the
965
XXX possible error cases caused the XML_STATUS_ERROR return.
967
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
968
return XML_STATUS_ERROR;
969
if (encodingName == NULL)
970
protocolEncodingName = NULL;
972
protocolEncodingName = poolCopyString(&tempPool, encodingName);
973
if (!protocolEncodingName)
974
return XML_STATUS_ERROR;
976
return XML_STATUS_OK;
980
XML_ExternalEntityParserCreate(XML_Parser oldParser,
981
const XML_Char *context,
982
const XML_Char *encodingName)
984
XML_Parser parser = oldParser;
987
XML_StartElementHandler oldStartElementHandler = startElementHandler;
988
XML_EndElementHandler oldEndElementHandler = endElementHandler;
989
XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
990
XML_ProcessingInstructionHandler oldProcessingInstructionHandler
991
= processingInstructionHandler;
992
XML_CommentHandler oldCommentHandler = commentHandler;
993
XML_StartCdataSectionHandler oldStartCdataSectionHandler
994
= startCdataSectionHandler;
995
XML_EndCdataSectionHandler oldEndCdataSectionHandler
996
= endCdataSectionHandler;
997
XML_DefaultHandler oldDefaultHandler = defaultHandler;
998
XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
999
= unparsedEntityDeclHandler;
1000
XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
1001
XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
1002
= startNamespaceDeclHandler;
1003
XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
1004
= endNamespaceDeclHandler;
1005
XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
1006
XML_ExternalEntityRefHandler oldExternalEntityRefHandler
1007
= externalEntityRefHandler;
1008
XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
1009
XML_UnknownEncodingHandler oldUnknownEncodingHandler
1010
= unknownEncodingHandler;
1011
XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
1012
XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
1013
XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
1014
XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
1015
ELEMENT_TYPE * oldDeclElementType = declElementType;
1017
void *oldUserData = userData;
1018
void *oldHandlerArg = handlerArg;
1019
XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
1020
XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
1022
enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
1023
int oldInEntityValue = prologState.inEntityValue;
1025
XML_Bool oldns_triplets = ns_triplets;
1026
/* Note that the new parser shares the same hash secret as the old
1027
parser, so that dtdCopy and copyEntityTable can lookup values
1028
from hash tables associated with either parser without us having
1029
to worry which hash secrets each table has.
1031
unsigned long oldhash_secret_salt = hash_secret_salt;
1036
#endif /* XML_DTD */
1038
/* Note that the magical uses of the pre-processor to make field
1039
access look more like C++ require that `parser' be overwritten
1040
here. This makes this function more painful to follow than it
1045
*tmp = namespaceSeparator;
1046
parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1049
parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1055
startElementHandler = oldStartElementHandler;
1056
endElementHandler = oldEndElementHandler;
1057
characterDataHandler = oldCharacterDataHandler;
1058
processingInstructionHandler = oldProcessingInstructionHandler;
1059
commentHandler = oldCommentHandler;
1060
startCdataSectionHandler = oldStartCdataSectionHandler;
1061
endCdataSectionHandler = oldEndCdataSectionHandler;
1062
defaultHandler = oldDefaultHandler;
1063
unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1064
notationDeclHandler = oldNotationDeclHandler;
1065
startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1066
endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1067
notStandaloneHandler = oldNotStandaloneHandler;
1068
externalEntityRefHandler = oldExternalEntityRefHandler;
1069
skippedEntityHandler = oldSkippedEntityHandler;
1070
unknownEncodingHandler = oldUnknownEncodingHandler;
1071
elementDeclHandler = oldElementDeclHandler;
1072
attlistDeclHandler = oldAttlistDeclHandler;
1073
entityDeclHandler = oldEntityDeclHandler;
1074
xmlDeclHandler = oldXmlDeclHandler;
1075
declElementType = oldDeclElementType;
1076
userData = oldUserData;
1077
if (oldUserData == oldHandlerArg)
1078
handlerArg = userData;
1080
handlerArg = parser;
1081
if (oldExternalEntityRefHandlerArg != oldParser)
1082
externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1083
defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1084
ns_triplets = oldns_triplets;
1085
hash_secret_salt = oldhash_secret_salt;
1086
parentParser = oldParser;
1088
paramEntityParsing = oldParamEntityParsing;
1089
prologState.inEntityValue = oldInEntityValue;
1091
#endif /* XML_DTD */
1092
if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
1093
|| !setContext(parser, context)) {
1094
XML_ParserFree(parser);
1097
processor = externalEntityInitProcessor;
1101
/* The DTD instance referenced by _dtd is shared between the document's
1102
root parser and external PE parsers, therefore one does not need to
1103
call setContext. In addition, one also *must* not call setContext,
1104
because this would overwrite existing prefix->binding pointers in
1105
_dtd with ones that get destroyed with the external PE parser.
1106
This would leave those prefixes with dangling pointers.
1108
isParamEntity = XML_TRUE;
1109
XmlPrologStateInitExternalEntity(&prologState);
1110
processor = externalParEntInitProcessor;
1112
#endif /* XML_DTD */
1116
static void FASTCALL
1117
destroyBindings(BINDING *bindings, XML_Parser parser)
1120
BINDING *b = bindings;
1123
bindings = b->nextTagBinding;
1130
XML_ParserFree(XML_Parser parser)
1133
OPEN_INTERNAL_ENTITY *entityList;
1136
/* free tagStack and freeTagList */
1140
if (tagList == NULL) {
1141
if (freeTagList == NULL)
1143
tagList = freeTagList;
1147
tagList = tagList->parent;
1149
destroyBindings(p->bindings, parser);
1152
/* free openInternalEntities and freeInternalEntities */
1153
entityList = openInternalEntities;
1155
OPEN_INTERNAL_ENTITY *openEntity;
1156
if (entityList == NULL) {
1157
if (freeInternalEntities == NULL)
1159
entityList = freeInternalEntities;
1160
freeInternalEntities = NULL;
1162
openEntity = entityList;
1163
entityList = entityList->next;
1167
destroyBindings(freeBindingList, parser);
1168
destroyBindings(inheritedBindings, parser);
1169
poolDestroy(&tempPool);
1170
poolDestroy(&temp2Pool);
1172
/* external parameter entity parsers share the DTD structure
1173
parser->m_dtd with the root parser, so we must not destroy it
1175
if (!isParamEntity && _dtd)
1178
#endif /* XML_DTD */
1179
dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1181
#ifdef XML_ATTR_INFO
1182
FREE((void *)attInfo);
1184
FREE(groupConnector);
1188
FREE(unknownEncodingMem);
1189
if (unknownEncodingRelease)
1190
unknownEncodingRelease(unknownEncodingData);
1195
XML_UseParserAsHandlerArg(XML_Parser parser)
1197
handlerArg = parser;
1200
enum XML_Error XMLCALL
1201
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1204
/* block after XML_Parse()/XML_ParseBuffer() has been called */
1205
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1206
return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1207
useForeignDTD = useDTD;
1208
return XML_ERROR_NONE;
1210
return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1215
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1217
/* block after XML_Parse()/XML_ParseBuffer() has been called */
1218
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1220
ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1224
XML_SetUserData(XML_Parser parser, void *p)
1226
if (handlerArg == userData)
1227
handlerArg = userData = p;
1232
enum XML_Status XMLCALL
1233
XML_SetBase(XML_Parser parser, const XML_Char *p)
1236
p = poolCopyString(&_dtd->pool, p);
1238
return XML_STATUS_ERROR;
1243
return XML_STATUS_OK;
1246
const XML_Char * XMLCALL
1247
XML_GetBase(XML_Parser parser)
1253
XML_GetSpecifiedAttributeCount(XML_Parser parser)
1255
return nSpecifiedAtts;
1259
XML_GetIdAttributeIndex(XML_Parser parser)
1264
#ifdef XML_ATTR_INFO
1265
const XML_AttrInfo * XMLCALL
1266
XML_GetAttributeInfo(XML_Parser parser)
1273
XML_SetElementHandler(XML_Parser parser,
1274
XML_StartElementHandler start,
1275
XML_EndElementHandler end)
1277
startElementHandler = start;
1278
endElementHandler = end;
1282
XML_SetStartElementHandler(XML_Parser parser,
1283
XML_StartElementHandler start) {
1284
startElementHandler = start;
1288
XML_SetEndElementHandler(XML_Parser parser,
1289
XML_EndElementHandler end) {
1290
endElementHandler = end;
1294
XML_SetCharacterDataHandler(XML_Parser parser,
1295
XML_CharacterDataHandler handler)
1297
characterDataHandler = handler;
1301
XML_SetProcessingInstructionHandler(XML_Parser parser,
1302
XML_ProcessingInstructionHandler handler)
1304
processingInstructionHandler = handler;
1308
XML_SetCommentHandler(XML_Parser parser,
1309
XML_CommentHandler handler)
1311
commentHandler = handler;
1315
XML_SetCdataSectionHandler(XML_Parser parser,
1316
XML_StartCdataSectionHandler start,
1317
XML_EndCdataSectionHandler end)
1319
startCdataSectionHandler = start;
1320
endCdataSectionHandler = end;
1324
XML_SetStartCdataSectionHandler(XML_Parser parser,
1325
XML_StartCdataSectionHandler start) {
1326
startCdataSectionHandler = start;
1330
XML_SetEndCdataSectionHandler(XML_Parser parser,
1331
XML_EndCdataSectionHandler end) {
1332
endCdataSectionHandler = end;
1336
XML_SetDefaultHandler(XML_Parser parser,
1337
XML_DefaultHandler handler)
1339
defaultHandler = handler;
1340
defaultExpandInternalEntities = XML_FALSE;
1344
XML_SetDefaultHandlerExpand(XML_Parser parser,
1345
XML_DefaultHandler handler)
1347
defaultHandler = handler;
1348
defaultExpandInternalEntities = XML_TRUE;
1352
XML_SetDoctypeDeclHandler(XML_Parser parser,
1353
XML_StartDoctypeDeclHandler start,
1354
XML_EndDoctypeDeclHandler end)
1356
startDoctypeDeclHandler = start;
1357
endDoctypeDeclHandler = end;
1361
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1362
XML_StartDoctypeDeclHandler start) {
1363
startDoctypeDeclHandler = start;
1367
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1368
XML_EndDoctypeDeclHandler end) {
1369
endDoctypeDeclHandler = end;
1373
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1374
XML_UnparsedEntityDeclHandler handler)
1376
unparsedEntityDeclHandler = handler;
1380
XML_SetNotationDeclHandler(XML_Parser parser,
1381
XML_NotationDeclHandler handler)
1383
notationDeclHandler = handler;
1387
XML_SetNamespaceDeclHandler(XML_Parser parser,
1388
XML_StartNamespaceDeclHandler start,
1389
XML_EndNamespaceDeclHandler end)
1391
startNamespaceDeclHandler = start;
1392
endNamespaceDeclHandler = end;
1396
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1397
XML_StartNamespaceDeclHandler start) {
1398
startNamespaceDeclHandler = start;
1402
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1403
XML_EndNamespaceDeclHandler end) {
1404
endNamespaceDeclHandler = end;
1408
XML_SetNotStandaloneHandler(XML_Parser parser,
1409
XML_NotStandaloneHandler handler)
1411
notStandaloneHandler = handler;
1415
XML_SetExternalEntityRefHandler(XML_Parser parser,
1416
XML_ExternalEntityRefHandler handler)
1418
externalEntityRefHandler = handler;
1422
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1425
externalEntityRefHandlerArg = (XML_Parser)arg;
1427
externalEntityRefHandlerArg = parser;
1431
XML_SetSkippedEntityHandler(XML_Parser parser,
1432
XML_SkippedEntityHandler handler)
1434
skippedEntityHandler = handler;
1438
XML_SetUnknownEncodingHandler(XML_Parser parser,
1439
XML_UnknownEncodingHandler handler,
1442
unknownEncodingHandler = handler;
1443
unknownEncodingHandlerData = data;
1447
XML_SetElementDeclHandler(XML_Parser parser,
1448
XML_ElementDeclHandler eldecl)
1450
elementDeclHandler = eldecl;
1454
XML_SetAttlistDeclHandler(XML_Parser parser,
1455
XML_AttlistDeclHandler attdecl)
1457
attlistDeclHandler = attdecl;
1461
XML_SetEntityDeclHandler(XML_Parser parser,
1462
XML_EntityDeclHandler handler)
1464
entityDeclHandler = handler;
1468
XML_SetXmlDeclHandler(XML_Parser parser,
1469
XML_XmlDeclHandler handler) {
1470
xmlDeclHandler = handler;
1474
XML_SetParamEntityParsing(XML_Parser parser,
1475
enum XML_ParamEntityParsing peParsing)
1477
/* block after XML_Parse()/XML_ParseBuffer() has been called */
1478
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1481
paramEntityParsing = peParsing;
1484
return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1489
XML_SetHashSalt(XML_Parser parser,
1490
unsigned long hash_salt)
1492
/* block after XML_Parse()/XML_ParseBuffer() has been called */
1493
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1495
hash_secret_salt = hash_salt;
1499
enum XML_Status XMLCALL
1500
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1502
switch (ps_parsing) {
1504
errorCode = XML_ERROR_SUSPENDED;
1505
return XML_STATUS_ERROR;
1507
errorCode = XML_ERROR_FINISHED;
1508
return XML_STATUS_ERROR;
1509
case XML_INITIALIZED:
1510
if (parentParser == NULL && !startParsing(parser)) {
1511
errorCode = XML_ERROR_NO_MEMORY;
1512
return XML_STATUS_ERROR;
1515
ps_parsing = XML_PARSING;
1519
ps_finalBuffer = (XML_Bool)isFinal;
1521
return XML_STATUS_OK;
1522
positionPtr = bufferPtr;
1523
parseEndPtr = bufferEnd;
1525
/* If data are left over from last buffer, and we now know that these
1526
data are the final chunk of input, then we have to check them again
1527
to detect errors based on that fact.
1529
errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1531
if (errorCode == XML_ERROR_NONE) {
1532
switch (ps_parsing) {
1534
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1535
positionPtr = bufferPtr;
1536
return XML_STATUS_SUSPENDED;
1537
case XML_INITIALIZED:
1539
ps_parsing = XML_FINISHED;
1542
return XML_STATUS_OK;
1545
eventEndPtr = eventPtr;
1546
processor = errorProcessor;
1547
return XML_STATUS_ERROR;
1549
#ifndef XML_CONTEXT_BYTES
1550
else if (bufferPtr == bufferEnd) {
1553
enum XML_Error result;
1554
parseEndByteIndex += len;
1556
ps_finalBuffer = (XML_Bool)isFinal;
1558
errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1560
if (errorCode != XML_ERROR_NONE) {
1561
eventEndPtr = eventPtr;
1562
processor = errorProcessor;
1563
return XML_STATUS_ERROR;
1566
switch (ps_parsing) {
1568
result = XML_STATUS_SUSPENDED;
1570
case XML_INITIALIZED:
1573
ps_parsing = XML_FINISHED;
1574
return XML_STATUS_OK;
1578
result = XML_STATUS_OK;
1582
XmlUpdatePosition(encoding, positionPtr, end, &position);
1583
nLeftOver = s + len - end;
1585
if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1586
/* FIXME avoid integer overflow */
1588
temp = (buffer == NULL
1589
? (char *)MALLOC(len * 2)
1590
: (char *)REALLOC(buffer, len * 2));
1592
errorCode = XML_ERROR_NO_MEMORY;
1593
eventPtr = eventEndPtr = NULL;
1594
processor = errorProcessor;
1595
return XML_STATUS_ERROR;
1598
bufferLim = buffer + len * 2;
1600
memcpy(buffer, end, nLeftOver);
1603
bufferEnd = buffer + nLeftOver;
1604
positionPtr = bufferPtr;
1605
parseEndPtr = bufferEnd;
1606
eventPtr = bufferPtr;
1607
eventEndPtr = bufferPtr;
1610
#endif /* not defined XML_CONTEXT_BYTES */
1612
void *buff = XML_GetBuffer(parser, len);
1614
return XML_STATUS_ERROR;
1616
memcpy(buff, s, len);
1617
return XML_ParseBuffer(parser, len, isFinal);
1622
enum XML_Status XMLCALL
1623
XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1626
enum XML_Status result = XML_STATUS_OK;
1628
switch (ps_parsing) {
1630
errorCode = XML_ERROR_SUSPENDED;
1631
return XML_STATUS_ERROR;
1633
errorCode = XML_ERROR_FINISHED;
1634
return XML_STATUS_ERROR;
1635
case XML_INITIALIZED:
1636
if (parentParser == NULL && !startParsing(parser)) {
1637
errorCode = XML_ERROR_NO_MEMORY;
1638
return XML_STATUS_ERROR;
1641
ps_parsing = XML_PARSING;
1645
positionPtr = start;
1647
parseEndPtr = bufferEnd;
1648
parseEndByteIndex += len;
1649
ps_finalBuffer = (XML_Bool)isFinal;
1651
errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1653
if (errorCode != XML_ERROR_NONE) {
1654
eventEndPtr = eventPtr;
1655
processor = errorProcessor;
1656
return XML_STATUS_ERROR;
1659
switch (ps_parsing) {
1661
result = XML_STATUS_SUSPENDED;
1663
case XML_INITIALIZED:
1666
ps_parsing = XML_FINISHED;
1669
default: ; /* should not happen */
1673
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1674
positionPtr = bufferPtr;
1679
XML_GetBuffer(XML_Parser parser, int len)
1681
switch (ps_parsing) {
1683
errorCode = XML_ERROR_SUSPENDED;
1686
errorCode = XML_ERROR_FINISHED;
1691
if (len > bufferLim - bufferEnd) {
1692
/* FIXME avoid integer overflow */
1693
int neededSize = len + (int)(bufferEnd - bufferPtr);
1694
#ifdef XML_CONTEXT_BYTES
1695
int keep = (int)(bufferPtr - buffer);
1697
if (keep > XML_CONTEXT_BYTES)
1698
keep = XML_CONTEXT_BYTES;
1700
#endif /* defined XML_CONTEXT_BYTES */
1701
if (neededSize <= bufferLim - buffer) {
1702
#ifdef XML_CONTEXT_BYTES
1703
if (keep < bufferPtr - buffer) {
1704
int offset = (int)(bufferPtr - buffer) - keep;
1705
memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1706
bufferEnd -= offset;
1707
bufferPtr -= offset;
1710
memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1711
bufferEnd = buffer + (bufferEnd - bufferPtr);
1713
#endif /* not defined XML_CONTEXT_BYTES */
1717
int bufferSize = (int)(bufferLim - bufferPtr);
1718
if (bufferSize == 0)
1719
bufferSize = INIT_BUFFER_SIZE;
1722
} while (bufferSize < neededSize);
1723
newBuf = (char *)MALLOC(bufferSize);
1725
errorCode = XML_ERROR_NO_MEMORY;
1728
bufferLim = newBuf + bufferSize;
1729
#ifdef XML_CONTEXT_BYTES
1731
int keep = (int)(bufferPtr - buffer);
1732
if (keep > XML_CONTEXT_BYTES)
1733
keep = XML_CONTEXT_BYTES;
1734
memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1737
bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1738
bufferPtr = buffer + keep;
1741
bufferEnd = newBuf + (bufferEnd - bufferPtr);
1742
bufferPtr = buffer = newBuf;
1746
memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1749
bufferEnd = newBuf + (bufferEnd - bufferPtr);
1750
bufferPtr = buffer = newBuf;
1751
#endif /* not defined XML_CONTEXT_BYTES */
1753
eventPtr = eventEndPtr = NULL;
1759
enum XML_Status XMLCALL
1760
XML_StopParser(XML_Parser parser, XML_Bool resumable)
1762
switch (ps_parsing) {
1765
errorCode = XML_ERROR_SUSPENDED;
1766
return XML_STATUS_ERROR;
1768
ps_parsing = XML_FINISHED;
1771
errorCode = XML_ERROR_FINISHED;
1772
return XML_STATUS_ERROR;
1776
if (isParamEntity) {
1777
errorCode = XML_ERROR_SUSPEND_PE;
1778
return XML_STATUS_ERROR;
1781
ps_parsing = XML_SUSPENDED;
1784
ps_parsing = XML_FINISHED;
1786
return XML_STATUS_OK;
1789
enum XML_Status XMLCALL
1790
XML_ResumeParser(XML_Parser parser)
1792
enum XML_Status result = XML_STATUS_OK;
1794
if (ps_parsing != XML_SUSPENDED) {
1795
errorCode = XML_ERROR_NOT_SUSPENDED;
1796
return XML_STATUS_ERROR;
1798
ps_parsing = XML_PARSING;
1800
errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1802
if (errorCode != XML_ERROR_NONE) {
1803
eventEndPtr = eventPtr;
1804
processor = errorProcessor;
1805
return XML_STATUS_ERROR;
1808
switch (ps_parsing) {
1810
result = XML_STATUS_SUSPENDED;
1812
case XML_INITIALIZED:
1814
if (ps_finalBuffer) {
1815
ps_parsing = XML_FINISHED;
1822
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1823
positionPtr = bufferPtr;
1828
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1830
assert(status != NULL);
1831
*status = parser->m_parsingStatus;
1834
enum XML_Error XMLCALL
1835
XML_GetErrorCode(XML_Parser parser)
1841
XML_GetCurrentByteIndex(XML_Parser parser)
1844
return parseEndByteIndex - (parseEndPtr - eventPtr);
1849
XML_GetCurrentByteCount(XML_Parser parser)
1851
if (eventEndPtr && eventPtr)
1852
return (int)(eventEndPtr - eventPtr);
1856
const char * XMLCALL
1857
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1859
#ifdef XML_CONTEXT_BYTES
1860
if (eventPtr && buffer) {
1861
*offset = (int)(eventPtr - buffer);
1862
*size = (int)(bufferEnd - buffer);
1865
#endif /* defined XML_CONTEXT_BYTES */
1870
XML_GetCurrentLineNumber(XML_Parser parser)
1872
if (eventPtr && eventPtr >= positionPtr) {
1873
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1874
positionPtr = eventPtr;
1876
return position.lineNumber + 1;
1880
XML_GetCurrentColumnNumber(XML_Parser parser)
1882
if (eventPtr && eventPtr >= positionPtr) {
1883
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1884
positionPtr = eventPtr;
1886
return position.columnNumber;
1890
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1896
XML_MemMalloc(XML_Parser parser, size_t size)
1898
return MALLOC(size);
1902
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1904
return REALLOC(ptr, size);
1908
XML_MemFree(XML_Parser parser, void *ptr)
1914
XML_DefaultCurrent(XML_Parser parser)
1916
if (defaultHandler) {
1917
if (openInternalEntities)
1918
reportDefault(parser,
1920
openInternalEntities->internalEventPtr,
1921
openInternalEntities->internalEventEndPtr);
1923
reportDefault(parser, encoding, eventPtr, eventEndPtr);
1927
const XML_LChar * XMLCALL
1928
XML_ErrorString(enum XML_Error code)
1930
static const XML_LChar* const message[] = {
1932
XML_L("out of memory"),
1933
XML_L("syntax error"),
1934
XML_L("no element found"),
1935
XML_L("not well-formed (invalid token)"),
1936
XML_L("unclosed token"),
1937
XML_L("partial character"),
1938
XML_L("mismatched tag"),
1939
XML_L("duplicate attribute"),
1940
XML_L("junk after document element"),
1941
XML_L("illegal parameter entity reference"),
1942
XML_L("undefined entity"),
1943
XML_L("recursive entity reference"),
1944
XML_L("asynchronous entity"),
1945
XML_L("reference to invalid character number"),
1946
XML_L("reference to binary entity"),
1947
XML_L("reference to external entity in attribute"),
1948
XML_L("XML or text declaration not at start of entity"),
1949
XML_L("unknown encoding"),
1950
XML_L("encoding specified in XML declaration is incorrect"),
1951
XML_L("unclosed CDATA section"),
1952
XML_L("error in processing external entity reference"),
1953
XML_L("document is not standalone"),
1954
XML_L("unexpected parser state - please send a bug report"),
1955
XML_L("entity declared in parameter entity"),
1956
XML_L("requested feature requires XML_DTD support in Expat"),
1957
XML_L("cannot change setting once parsing has begun"),
1958
XML_L("unbound prefix"),
1959
XML_L("must not undeclare prefix"),
1960
XML_L("incomplete markup in parameter entity"),
1961
XML_L("XML declaration not well-formed"),
1962
XML_L("text declaration not well-formed"),
1963
XML_L("illegal character(s) in public id"),
1964
XML_L("parser suspended"),
1965
XML_L("parser not suspended"),
1966
XML_L("parsing aborted"),
1967
XML_L("parsing finished"),
1968
XML_L("cannot suspend in external parameter entity"),
1969
XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1970
XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1971
XML_L("prefix must not be bound to one of the reserved namespace names")
1973
if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1974
return message[code];
1978
const XML_LChar * XMLCALL
1979
XML_ExpatVersion(void) {
1981
/* V1 is used to string-ize the version number. However, it would
1982
string-ize the actual version macro *names* unless we get them
1983
substituted before being passed to V1. CPP is defined to expand
1984
a macro, then rescan for more expansions. Thus, we use V2 to expand
1985
the version macros, then CPP will expand the resulting V1() macro
1986
with the correct numerals. */
1987
/* ### I'm assuming cpp is portable in this respect... */
1989
#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1990
#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1992
return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1998
XML_Expat_Version XMLCALL
1999
XML_ExpatVersionInfo(void)
2001
XML_Expat_Version version;
2003
version.major = XML_MAJOR_VERSION;
2004
version.minor = XML_MINOR_VERSION;
2005
version.micro = XML_MICRO_VERSION;
2010
const XML_Feature * XMLCALL
2011
XML_GetFeatureList(void)
2013
static const XML_Feature features[] = {
2014
{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2016
{XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2019
{XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
2021
#ifdef XML_UNICODE_WCHAR_T
2022
{XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
2025
{XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
2027
#ifdef XML_CONTEXT_BYTES
2028
{XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2032
{XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
2035
{XML_FEATURE_NS, XML_L("XML_NS"), 0},
2037
#ifdef XML_LARGE_SIZE
2038
{XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
2040
#ifdef XML_ATTR_INFO
2041
{XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
2043
{XML_FEATURE_END, NULL, 0}
2049
/* Initially tag->rawName always points into the parse buffer;
2050
for those TAG instances opened while the current parse buffer was
2051
processed, and not yet closed, we need to store tag->rawName in a more
2052
permanent location, since the parse buffer is about to be discarded.
2055
storeRawNames(XML_Parser parser)
2057
TAG *tag = tagStack;
2060
int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2061
char *rawNameBuf = tag->buf + nameLen;
2062
/* Stop if already stored. Since tagStack is a stack, we can stop
2063
at the first entry that has already been copied; everything
2064
below it in the stack is already been accounted for in a
2065
previous call to this function.
2067
if (tag->rawName == rawNameBuf)
2069
/* For re-use purposes we need to ensure that the
2070
size of tag->buf is a multiple of sizeof(XML_Char).
2072
bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2073
if (bufSize > tag->bufEnd - tag->buf) {
2074
char *temp = (char *)REALLOC(tag->buf, bufSize);
2077
/* if tag->name.str points to tag->buf (only when namespace
2078
processing is off) then we have to update it
2080
if (tag->name.str == (XML_Char *)tag->buf)
2081
tag->name.str = (XML_Char *)temp;
2082
/* if tag->name.localPart is set (when namespace processing is on)
2083
then update it as well, since it will always point into tag->buf
2085
if (tag->name.localPart)
2086
tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2087
(XML_Char *)tag->buf);
2089
tag->bufEnd = temp + bufSize;
2090
rawNameBuf = temp + nameLen;
2092
memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2093
tag->rawName = rawNameBuf;
2099
static enum XML_Error PTRCALL
2100
contentProcessor(XML_Parser parser,
2103
const char **endPtr)
2105
enum XML_Error result = doContent(parser, 0, encoding, start, end,
2106
endPtr, (XML_Bool)!ps_finalBuffer);
2107
if (result == XML_ERROR_NONE) {
2108
if (!storeRawNames(parser))
2109
return XML_ERROR_NO_MEMORY;
2114
static enum XML_Error PTRCALL
2115
externalEntityInitProcessor(XML_Parser parser,
2118
const char **endPtr)
2120
enum XML_Error result = initializeEncoding(parser);
2121
if (result != XML_ERROR_NONE)
2123
processor = externalEntityInitProcessor2;
2124
return externalEntityInitProcessor2(parser, start, end, endPtr);
2127
static enum XML_Error PTRCALL
2128
externalEntityInitProcessor2(XML_Parser parser,
2131
const char **endPtr)
2133
const char *next = start; /* XmlContentTok doesn't always set the last arg */
2134
int tok = XmlContentTok(encoding, start, end, &next);
2137
/* If we are at the end of the buffer, this would cause the next stage,
2138
i.e. externalEntityInitProcessor3, to pass control directly to
2139
doContent (by detecting XML_TOK_NONE) without processing any xml text
2140
declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2142
if (next == end && !ps_finalBuffer) {
2144
return XML_ERROR_NONE;
2148
case XML_TOK_PARTIAL:
2149
if (!ps_finalBuffer) {
2151
return XML_ERROR_NONE;
2154
return XML_ERROR_UNCLOSED_TOKEN;
2155
case XML_TOK_PARTIAL_CHAR:
2156
if (!ps_finalBuffer) {
2158
return XML_ERROR_NONE;
2161
return XML_ERROR_PARTIAL_CHAR;
2163
processor = externalEntityInitProcessor3;
2164
return externalEntityInitProcessor3(parser, start, end, endPtr);
2167
static enum XML_Error PTRCALL
2168
externalEntityInitProcessor3(XML_Parser parser,
2171
const char **endPtr)
2174
const char *next = start; /* XmlContentTok doesn't always set the last arg */
2176
tok = XmlContentTok(encoding, start, end, &next);
2180
case XML_TOK_XML_DECL:
2182
enum XML_Error result;
2183
result = processXmlDecl(parser, 1, start, next);
2184
if (result != XML_ERROR_NONE)
2186
switch (ps_parsing) {
2189
return XML_ERROR_NONE;
2191
return XML_ERROR_ABORTED;
2197
case XML_TOK_PARTIAL:
2198
if (!ps_finalBuffer) {
2200
return XML_ERROR_NONE;
2202
return XML_ERROR_UNCLOSED_TOKEN;
2203
case XML_TOK_PARTIAL_CHAR:
2204
if (!ps_finalBuffer) {
2206
return XML_ERROR_NONE;
2208
return XML_ERROR_PARTIAL_CHAR;
2210
processor = externalEntityContentProcessor;
2212
return externalEntityContentProcessor(parser, start, end, endPtr);
2215
static enum XML_Error PTRCALL
2216
externalEntityContentProcessor(XML_Parser parser,
2219
const char **endPtr)
2221
enum XML_Error result = doContent(parser, 1, encoding, start, end,
2222
endPtr, (XML_Bool)!ps_finalBuffer);
2223
if (result == XML_ERROR_NONE) {
2224
if (!storeRawNames(parser))
2225
return XML_ERROR_NO_MEMORY;
2230
static enum XML_Error
2231
doContent(XML_Parser parser,
2233
const ENCODING *enc,
2236
const char **nextPtr,
2239
/* save one level of indirection */
2240
DTD * const dtd = _dtd;
2242
const char **eventPP;
2243
const char **eventEndPP;
2244
if (enc == encoding) {
2245
eventPP = &eventPtr;
2246
eventEndPP = &eventEndPtr;
2249
eventPP = &(openInternalEntities->internalEventPtr);
2250
eventEndPP = &(openInternalEntities->internalEventEndPtr);
2255
const char *next = s; /* XmlContentTok doesn't always set the last arg */
2256
int tok = XmlContentTok(enc, s, end, &next);
2259
case XML_TOK_TRAILING_CR:
2262
return XML_ERROR_NONE;
2265
if (characterDataHandler) {
2267
characterDataHandler(handlerArg, &c, 1);
2269
else if (defaultHandler)
2270
reportDefault(parser, enc, s, end);
2271
/* We are at the end of the final buffer, should we check for
2272
XML_SUSPENDED, XML_FINISHED?
2274
if (startTagLevel == 0)
2275
return XML_ERROR_NO_ELEMENTS;
2276
if (tagLevel != startTagLevel)
2277
return XML_ERROR_ASYNC_ENTITY;
2279
return XML_ERROR_NONE;
2283
return XML_ERROR_NONE;
2285
if (startTagLevel > 0) {
2286
if (tagLevel != startTagLevel)
2287
return XML_ERROR_ASYNC_ENTITY;
2289
return XML_ERROR_NONE;
2291
return XML_ERROR_NO_ELEMENTS;
2292
case XML_TOK_INVALID:
2294
return XML_ERROR_INVALID_TOKEN;
2295
case XML_TOK_PARTIAL:
2298
return XML_ERROR_NONE;
2300
return XML_ERROR_UNCLOSED_TOKEN;
2301
case XML_TOK_PARTIAL_CHAR:
2304
return XML_ERROR_NONE;
2306
return XML_ERROR_PARTIAL_CHAR;
2307
case XML_TOK_ENTITY_REF:
2309
const XML_Char *name;
2311
XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2312
s + enc->minBytesPerChar,
2313
next - enc->minBytesPerChar);
2315
if (characterDataHandler)
2316
characterDataHandler(handlerArg, &ch, 1);
2317
else if (defaultHandler)
2318
reportDefault(parser, enc, s, next);
2321
name = poolStoreString(&dtd->pool, enc,
2322
s + enc->minBytesPerChar,
2323
next - enc->minBytesPerChar);
2325
return XML_ERROR_NO_MEMORY;
2326
entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2327
poolDiscard(&dtd->pool);
2328
/* First, determine if a check for an existing declaration is needed;
2329
if yes, check that the entity exists, and that it is internal,
2330
otherwise call the skipped entity or default handler.
2332
if (!dtd->hasParamEntityRefs || dtd->standalone) {
2334
return XML_ERROR_UNDEFINED_ENTITY;
2335
else if (!entity->is_internal)
2336
return XML_ERROR_ENTITY_DECLARED_IN_PE;
2339
if (skippedEntityHandler)
2340
skippedEntityHandler(handlerArg, name, 0);
2341
else if (defaultHandler)
2342
reportDefault(parser, enc, s, next);
2346
return XML_ERROR_RECURSIVE_ENTITY_REF;
2347
if (entity->notation)
2348
return XML_ERROR_BINARY_ENTITY_REF;
2349
if (entity->textPtr) {
2350
enum XML_Error result;
2351
if (!defaultExpandInternalEntities) {
2352
if (skippedEntityHandler)
2353
skippedEntityHandler(handlerArg, entity->name, 0);
2354
else if (defaultHandler)
2355
reportDefault(parser, enc, s, next);
2358
result = processInternalEntity(parser, entity, XML_FALSE);
2359
if (result != XML_ERROR_NONE)
2362
else if (externalEntityRefHandler) {
2363
const XML_Char *context;
2364
entity->open = XML_TRUE;
2365
context = getContext(parser);
2366
entity->open = XML_FALSE;
2368
return XML_ERROR_NO_MEMORY;
2369
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2374
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2375
poolDiscard(&tempPool);
2377
else if (defaultHandler)
2378
reportDefault(parser, enc, s, next);
2381
case XML_TOK_START_TAG_NO_ATTS:
2383
case XML_TOK_START_TAG_WITH_ATTS:
2386
enum XML_Error result;
2390
freeTagList = freeTagList->parent;
2393
tag = (TAG *)MALLOC(sizeof(TAG));
2395
return XML_ERROR_NO_MEMORY;
2396
tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2399
return XML_ERROR_NO_MEMORY;
2401
tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2403
tag->bindings = NULL;
2404
tag->parent = tagStack;
2406
tag->name.localPart = NULL;
2407
tag->name.prefix = NULL;
2408
tag->rawName = s + enc->minBytesPerChar;
2409
tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2412
const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2413
const char *fromPtr = tag->rawName;
2414
toPtr = (XML_Char *)tag->buf;
2419
&fromPtr, rawNameEnd,
2420
(ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2421
convLen = (int)(toPtr - (XML_Char *)tag->buf);
2422
if (fromPtr == rawNameEnd) {
2423
tag->name.strLen = convLen;
2426
bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2428
char *temp = (char *)REALLOC(tag->buf, bufSize);
2430
return XML_ERROR_NO_MEMORY;
2432
tag->bufEnd = temp + bufSize;
2433
toPtr = (XML_Char *)temp + convLen;
2437
tag->name.str = (XML_Char *)tag->buf;
2438
*toPtr = XML_T('\0');
2439
result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2442
if (startElementHandler)
2443
startElementHandler(handlerArg, tag->name.str,
2444
(const XML_Char **)atts);
2445
else if (defaultHandler)
2446
reportDefault(parser, enc, s, next);
2447
poolClear(&tempPool);
2450
case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2452
case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2454
const char *rawName = s + enc->minBytesPerChar;
2455
enum XML_Error result;
2456
BINDING *bindings = NULL;
2457
XML_Bool noElmHandlers = XML_TRUE;
2459
name.str = poolStoreString(&tempPool, enc, rawName,
2460
rawName + XmlNameLength(enc, rawName));
2462
return XML_ERROR_NO_MEMORY;
2463
poolFinish(&tempPool);
2464
result = storeAtts(parser, enc, s, &name, &bindings);
2467
poolFinish(&tempPool);
2468
if (startElementHandler) {
2469
startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2470
noElmHandlers = XML_FALSE;
2472
if (endElementHandler) {
2473
if (startElementHandler)
2474
*eventPP = *eventEndPP;
2475
endElementHandler(handlerArg, name.str);
2476
noElmHandlers = XML_FALSE;
2478
if (noElmHandlers && defaultHandler)
2479
reportDefault(parser, enc, s, next);
2480
poolClear(&tempPool);
2482
BINDING *b = bindings;
2483
if (endNamespaceDeclHandler)
2484
endNamespaceDeclHandler(handlerArg, b->prefix->name);
2485
bindings = bindings->nextTagBinding;
2486
b->nextTagBinding = freeBindingList;
2487
freeBindingList = b;
2488
b->prefix->binding = b->prevPrefixBinding;
2492
return epilogProcessor(parser, next, end, nextPtr);
2494
case XML_TOK_END_TAG:
2495
if (tagLevel == startTagLevel)
2496
return XML_ERROR_ASYNC_ENTITY;
2499
const char *rawName;
2500
TAG *tag = tagStack;
2501
tagStack = tag->parent;
2502
tag->parent = freeTagList;
2504
rawName = s + enc->minBytesPerChar*2;
2505
len = XmlNameLength(enc, rawName);
2506
if (len != tag->rawNameLength
2507
|| memcmp(tag->rawName, rawName, len) != 0) {
2509
return XML_ERROR_TAG_MISMATCH;
2512
if (endElementHandler) {
2513
const XML_Char *localPart;
2514
const XML_Char *prefix;
2516
localPart = tag->name.localPart;
2517
if (ns && localPart) {
2518
/* localPart and prefix may have been overwritten in
2519
tag->name.str, since this points to the binding->uri
2520
buffer which gets re-used; so we have to add them again
2522
uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2523
/* don't need to check for space - already done in storeAtts() */
2524
while (*localPart) *uri++ = *localPart++;
2525
prefix = (XML_Char *)tag->name.prefix;
2526
if (ns_triplets && prefix) {
2527
*uri++ = namespaceSeparator;
2528
while (*prefix) *uri++ = *prefix++;
2532
endElementHandler(handlerArg, tag->name.str);
2534
else if (defaultHandler)
2535
reportDefault(parser, enc, s, next);
2536
while (tag->bindings) {
2537
BINDING *b = tag->bindings;
2538
if (endNamespaceDeclHandler)
2539
endNamespaceDeclHandler(handlerArg, b->prefix->name);
2540
tag->bindings = tag->bindings->nextTagBinding;
2541
b->nextTagBinding = freeBindingList;
2542
freeBindingList = b;
2543
b->prefix->binding = b->prevPrefixBinding;
2546
return epilogProcessor(parser, next, end, nextPtr);
2549
case XML_TOK_CHAR_REF:
2551
int n = XmlCharRefNumber(enc, s);
2553
return XML_ERROR_BAD_CHAR_REF;
2554
if (characterDataHandler) {
2555
XML_Char buf[XML_ENCODE_MAX];
2556
characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2558
else if (defaultHandler)
2559
reportDefault(parser, enc, s, next);
2562
case XML_TOK_XML_DECL:
2563
return XML_ERROR_MISPLACED_XML_PI;
2564
case XML_TOK_DATA_NEWLINE:
2565
if (characterDataHandler) {
2567
characterDataHandler(handlerArg, &c, 1);
2569
else if (defaultHandler)
2570
reportDefault(parser, enc, s, next);
2572
case XML_TOK_CDATA_SECT_OPEN:
2574
enum XML_Error result;
2575
if (startCdataSectionHandler)
2576
startCdataSectionHandler(handlerArg);
2578
/* Suppose you doing a transformation on a document that involves
2579
changing only the character data. You set up a defaultHandler
2580
and a characterDataHandler. The defaultHandler simply copies
2581
characters through. The characterDataHandler does the
2582
transformation and writes the characters out escaping them as
2583
necessary. This case will fail to work if we leave out the
2584
following two lines (because & and < inside CDATA sections will
2585
be incorrectly escaped).
2587
However, now we have a start/endCdataSectionHandler, so it seems
2588
easier to let the user deal with this.
2590
else if (characterDataHandler)
2591
characterDataHandler(handlerArg, dataBuf, 0);
2593
else if (defaultHandler)
2594
reportDefault(parser, enc, s, next);
2595
result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2596
if (result != XML_ERROR_NONE)
2599
processor = cdataSectionProcessor;
2604
case XML_TOK_TRAILING_RSQB:
2607
return XML_ERROR_NONE;
2609
if (characterDataHandler) {
2610
if (MUST_CONVERT(enc, s)) {
2611
ICHAR *dataPtr = (ICHAR *)dataBuf;
2612
XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2613
characterDataHandler(handlerArg, dataBuf,
2614
(int)(dataPtr - (ICHAR *)dataBuf));
2617
characterDataHandler(handlerArg,
2619
(int)((XML_Char *)end - (XML_Char *)s));
2621
else if (defaultHandler)
2622
reportDefault(parser, enc, s, end);
2623
/* We are at the end of the final buffer, should we check for
2624
XML_SUSPENDED, XML_FINISHED?
2626
if (startTagLevel == 0) {
2628
return XML_ERROR_NO_ELEMENTS;
2630
if (tagLevel != startTagLevel) {
2632
return XML_ERROR_ASYNC_ENTITY;
2635
return XML_ERROR_NONE;
2636
case XML_TOK_DATA_CHARS:
2638
XML_CharacterDataHandler charDataHandler = characterDataHandler;
2639
if (charDataHandler) {
2640
if (MUST_CONVERT(enc, s)) {
2642
ICHAR *dataPtr = (ICHAR *)dataBuf;
2643
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2645
charDataHandler(handlerArg, dataBuf,
2646
(int)(dataPtr - (ICHAR *)dataBuf));
2653
charDataHandler(handlerArg,
2655
(int)((XML_Char *)next - (XML_Char *)s));
2657
else if (defaultHandler)
2658
reportDefault(parser, enc, s, next);
2662
if (!reportProcessingInstruction(parser, enc, s, next))
2663
return XML_ERROR_NO_MEMORY;
2665
case XML_TOK_COMMENT:
2666
if (!reportComment(parser, enc, s, next))
2667
return XML_ERROR_NO_MEMORY;
2671
reportDefault(parser, enc, s, next);
2674
*eventPP = s = next;
2675
switch (ps_parsing) {
2678
return XML_ERROR_NONE;
2680
return XML_ERROR_ABORTED;
2687
/* Precondition: all arguments must be non-NULL;
2689
- normalize attributes
2690
- check attributes for well-formedness
2691
- generate namespace aware attribute names (URI, prefix)
2692
- build list of attributes for startElementHandler
2693
- default attributes
2694
- process namespace declarations (check and report them)
2695
- generate namespace aware element name (URI, prefix)
2697
static enum XML_Error
2698
storeAtts(XML_Parser parser, const ENCODING *enc,
2699
const char *attStr, TAG_NAME *tagNamePtr,
2700
BINDING **bindingsPtr)
2702
DTD * const dtd = _dtd; /* save one level of indirection */
2703
ELEMENT_TYPE *elementType;
2705
const XML_Char **appAtts; /* the attribute list for the application */
2713
const XML_Char *localPart;
2715
/* lookup the element type name */
2716
elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
2718
const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2720
return XML_ERROR_NO_MEMORY;
2721
elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
2722
sizeof(ELEMENT_TYPE));
2724
return XML_ERROR_NO_MEMORY;
2725
if (ns && !setElementTypePrefix(parser, elementType))
2726
return XML_ERROR_NO_MEMORY;
2728
nDefaultAtts = elementType->nDefaultAtts;
2730
/* get the attributes from the tokenizer */
2731
n = XmlGetAttributes(enc, attStr, attsSize, atts);
2732
if (n + nDefaultAtts > attsSize) {
2733
int oldAttsSize = attsSize;
2735
#ifdef XML_ATTR_INFO
2736
XML_AttrInfo *temp2;
2738
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2739
temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2741
return XML_ERROR_NO_MEMORY;
2743
#ifdef XML_ATTR_INFO
2744
temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
2746
return XML_ERROR_NO_MEMORY;
2749
if (n > oldAttsSize)
2750
XmlGetAttributes(enc, attStr, n, atts);
2753
appAtts = (const XML_Char **)atts;
2754
for (i = 0; i < n; i++) {
2755
ATTRIBUTE *currAtt = &atts[i];
2756
#ifdef XML_ATTR_INFO
2757
XML_AttrInfo *currAttInfo = &attInfo[i];
2759
/* add the name and value to the attribute list */
2760
ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
2762
+ XmlNameLength(enc, currAtt->name));
2764
return XML_ERROR_NO_MEMORY;
2765
#ifdef XML_ATTR_INFO
2766
currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
2767
currAttInfo->nameEnd = currAttInfo->nameStart +
2768
XmlNameLength(enc, currAtt->name);
2769
currAttInfo->valueStart = parseEndByteIndex -
2770
(parseEndPtr - currAtt->valuePtr);
2771
currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
2773
/* Detect duplicate attributes by their QNames. This does not work when
2774
namespace processing is turned on and different prefixes for the same
2775
namespace are used. For this case we have a check further down.
2777
if ((attId->name)[-1]) {
2778
if (enc == encoding)
2779
eventPtr = atts[i].name;
2780
return XML_ERROR_DUPLICATE_ATTRIBUTE;
2782
(attId->name)[-1] = 1;
2783
appAtts[attIndex++] = attId->name;
2784
if (!atts[i].normalized) {
2785
enum XML_Error result;
2786
XML_Bool isCdata = XML_TRUE;
2788
/* figure out whether declared as other than CDATA */
2789
if (attId->maybeTokenized) {
2791
for (j = 0; j < nDefaultAtts; j++) {
2792
if (attId == elementType->defaultAtts[j].id) {
2793
isCdata = elementType->defaultAtts[j].isCdata;
2799
/* normalize the attribute value */
2800
result = storeAttributeValue(parser, enc, isCdata,
2801
atts[i].valuePtr, atts[i].valueEnd,
2805
appAtts[attIndex] = poolStart(&tempPool);
2806
poolFinish(&tempPool);
2809
/* the value did not need normalizing */
2810
appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2812
if (appAtts[attIndex] == 0)
2813
return XML_ERROR_NO_MEMORY;
2814
poolFinish(&tempPool);
2816
/* handle prefixed attribute names */
2817
if (attId->prefix) {
2819
/* deal with namespace declarations here */
2820
enum XML_Error result = addBinding(parser, attId->prefix, attId,
2821
appAtts[attIndex], bindingsPtr);
2827
/* deal with other prefixed names later */
2830
(attId->name)[-1] = 2;
2837
/* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2838
nSpecifiedAtts = attIndex;
2839
if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2840
for (i = 0; i < attIndex; i += 2)
2841
if (appAtts[i] == elementType->idAtt->name) {
2849
/* do attribute defaulting */
2850
for (i = 0; i < nDefaultAtts; i++) {
2851
const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2852
if (!(da->id->name)[-1] && da->value) {
2853
if (da->id->prefix) {
2854
if (da->id->xmlns) {
2855
enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2856
da->value, bindingsPtr);
2861
(da->id->name)[-1] = 2;
2863
appAtts[attIndex++] = da->id->name;
2864
appAtts[attIndex++] = da->value;
2868
(da->id->name)[-1] = 1;
2869
appAtts[attIndex++] = da->id->name;
2870
appAtts[attIndex++] = da->value;
2874
appAtts[attIndex] = 0;
2876
/* expand prefixed attribute names, check for duplicates,
2877
and clear flags that say whether attributes were specified */
2880
int j; /* hash table index */
2881
unsigned long version = nsAttsVersion;
2882
int nsAttsSize = (int)1 << nsAttsPower;
2883
/* size of hash table must be at least 2 * (# of prefixed attributes) */
2884
if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2886
/* hash table size must also be a power of 2 and >= 8 */
2887
while (nPrefixes >> nsAttsPower++);
2888
if (nsAttsPower < 3)
2890
nsAttsSize = (int)1 << nsAttsPower;
2891
temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2893
return XML_ERROR_NO_MEMORY;
2895
version = 0; /* force re-initialization of nsAtts hash table */
2897
/* using a version flag saves us from initializing nsAtts every time */
2898
if (!version) { /* initialize version flags when version wraps around */
2899
version = INIT_ATTS_VERSION;
2900
for (j = nsAttsSize; j != 0; )
2901
nsAtts[--j].version = version;
2903
nsAttsVersion = --version;
2905
/* expand prefixed names and check for duplicates */
2906
for (; i < attIndex; i += 2) {
2907
const XML_Char *s = appAtts[i];
2908
if (s[-1] == 2) { /* prefixed */
2911
unsigned long uriHash = hash_secret_salt;
2912
((XML_Char *)s)[-1] = 0; /* clear flag */
2913
id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
2914
b = id->prefix->binding;
2916
return XML_ERROR_UNBOUND_PREFIX;
2918
/* as we expand the name we also calculate its hash value */
2919
for (j = 0; j < b->uriLen; j++) {
2920
const XML_Char c = b->uri[j];
2921
if (!poolAppendChar(&tempPool, c))
2922
return XML_ERROR_NO_MEMORY;
2923
uriHash = CHAR_HASH(uriHash, c);
2925
while (*s++ != XML_T(ASCII_COLON))
2927
do { /* copies null terminator */
2928
const XML_Char c = *s;
2929
if (!poolAppendChar(&tempPool, *s))
2930
return XML_ERROR_NO_MEMORY;
2931
uriHash = CHAR_HASH(uriHash, c);
2934
{ /* Check hash table for duplicate of expanded name (uriName).
2935
Derived from code in lookup(parser, HASH_TABLE *table, ...).
2937
unsigned char step = 0;
2938
unsigned long mask = nsAttsSize - 1;
2939
j = uriHash & mask; /* index into hash table */
2940
while (nsAtts[j].version == version) {
2941
/* for speed we compare stored hash values first */
2942
if (uriHash == nsAtts[j].hash) {
2943
const XML_Char *s1 = poolStart(&tempPool);
2944
const XML_Char *s2 = nsAtts[j].uriName;
2945
/* s1 is null terminated, but not s2 */
2946
for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2948
return XML_ERROR_DUPLICATE_ATTRIBUTE;
2951
step = PROBE_STEP(uriHash, mask, nsAttsPower);
2952
j < step ? (j += nsAttsSize - step) : (j -= step);
2956
if (ns_triplets) { /* append namespace separator and prefix */
2957
tempPool.ptr[-1] = namespaceSeparator;
2958
s = b->prefix->name;
2960
if (!poolAppendChar(&tempPool, *s))
2961
return XML_ERROR_NO_MEMORY;
2965
/* store expanded name in attribute list */
2966
s = poolStart(&tempPool);
2967
poolFinish(&tempPool);
2970
/* fill empty slot with new version, uriName and hash value */
2971
nsAtts[j].version = version;
2972
nsAtts[j].hash = uriHash;
2973
nsAtts[j].uriName = s;
2980
else /* not prefixed */
2981
((XML_Char *)s)[-1] = 0; /* clear flag */
2984
/* clear flags for the remaining attributes */
2985
for (; i < attIndex; i += 2)
2986
((XML_Char *)(appAtts[i]))[-1] = 0;
2987
for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2988
binding->attId->name[-1] = 0;
2991
return XML_ERROR_NONE;
2993
/* expand the element type name */
2994
if (elementType->prefix) {
2995
binding = elementType->prefix->binding;
2997
return XML_ERROR_UNBOUND_PREFIX;
2998
localPart = tagNamePtr->str;
2999
while (*localPart++ != XML_T(ASCII_COLON))
3002
else if (dtd->defaultPrefix.binding) {
3003
binding = dtd->defaultPrefix.binding;
3004
localPart = tagNamePtr->str;
3007
return XML_ERROR_NONE;
3009
if (ns_triplets && binding->prefix->name) {
3010
for (; binding->prefix->name[prefixLen++];)
3011
; /* prefixLen includes null terminator */
3013
tagNamePtr->localPart = localPart;
3014
tagNamePtr->uriLen = binding->uriLen;
3015
tagNamePtr->prefix = binding->prefix->name;
3016
tagNamePtr->prefixLen = prefixLen;
3017
for (i = 0; localPart[i++];)
3018
; /* i includes null terminator */
3019
n = i + binding->uriLen + prefixLen;
3020
if (n > binding->uriAlloc) {
3022
uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
3024
return XML_ERROR_NO_MEMORY;
3025
binding->uriAlloc = n + EXPAND_SPARE;
3026
memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3027
for (p = tagStack; p; p = p->parent)
3028
if (p->name.str == binding->uri)
3033
/* if namespaceSeparator != '\0' then uri includes it already */
3034
uri = binding->uri + binding->uriLen;
3035
memcpy(uri, localPart, i * sizeof(XML_Char));
3036
/* we always have a namespace separator between localPart and prefix */
3039
*uri = namespaceSeparator; /* replace null terminator */
3040
memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3042
tagNamePtr->str = binding->uri;
3043
return XML_ERROR_NONE;
3046
/* addBinding() overwrites the value of prefix->binding without checking.
3047
Therefore one must keep track of the old value outside of addBinding().
3049
static enum XML_Error
3050
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3051
const XML_Char *uri, BINDING **bindingsPtr)
3053
static const XML_Char xmlNamespace[] = {
3054
ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3055
ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3056
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
3057
ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
3058
ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3061
static const int xmlLen =
3062
(int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3063
static const XML_Char xmlnsNamespace[] = {
3064
ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3065
ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3066
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
3067
ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
3070
static const int xmlnsLen =
3071
(int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3073
XML_Bool mustBeXML = XML_FALSE;
3074
XML_Bool isXML = XML_TRUE;
3075
XML_Bool isXMLNS = XML_TRUE;
3080
/* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3081
if (*uri == XML_T('\0') && prefix->name)
3082
return XML_ERROR_UNDECLARING_PREFIX;
3085
&& prefix->name[0] == XML_T(ASCII_x)
3086
&& prefix->name[1] == XML_T(ASCII_m)
3087
&& prefix->name[2] == XML_T(ASCII_l)) {
3089
/* Not allowed to bind xmlns */
3090
if (prefix->name[3] == XML_T(ASCII_n)
3091
&& prefix->name[4] == XML_T(ASCII_s)
3092
&& prefix->name[5] == XML_T('\0'))
3093
return XML_ERROR_RESERVED_PREFIX_XMLNS;
3095
if (prefix->name[3] == XML_T('\0'))
3096
mustBeXML = XML_TRUE;
3099
for (len = 0; uri[len]; len++) {
3100
if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3103
if (!mustBeXML && isXMLNS
3104
&& (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3105
isXMLNS = XML_FALSE;
3107
isXML = isXML && len == xmlLen;
3108
isXMLNS = isXMLNS && len == xmlnsLen;
3110
if (mustBeXML != isXML)
3111
return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3112
: XML_ERROR_RESERVED_NAMESPACE_URI;
3115
return XML_ERROR_RESERVED_NAMESPACE_URI;
3117
if (namespaceSeparator)
3119
if (freeBindingList) {
3120
b = freeBindingList;
3121
if (len > b->uriAlloc) {
3122
XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3123
sizeof(XML_Char) * (len + EXPAND_SPARE));
3125
return XML_ERROR_NO_MEMORY;
3127
b->uriAlloc = len + EXPAND_SPARE;
3129
freeBindingList = b->nextTagBinding;
3132
b = (BINDING *)MALLOC(sizeof(BINDING));
3134
return XML_ERROR_NO_MEMORY;
3135
b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3138
return XML_ERROR_NO_MEMORY;
3140
b->uriAlloc = len + EXPAND_SPARE;
3143
memcpy(b->uri, uri, len * sizeof(XML_Char));
3144
if (namespaceSeparator)
3145
b->uri[len - 1] = namespaceSeparator;
3148
b->prevPrefixBinding = prefix->binding;
3149
/* NULL binding when default namespace undeclared */
3150
if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3151
prefix->binding = NULL;
3153
prefix->binding = b;
3154
b->nextTagBinding = *bindingsPtr;
3156
/* if attId == NULL then we are not starting a namespace scope */
3157
if (attId && startNamespaceDeclHandler)
3158
startNamespaceDeclHandler(handlerArg, prefix->name,
3159
prefix->binding ? uri : 0);
3160
return XML_ERROR_NONE;
3163
/* The idea here is to avoid using stack for each CDATA section when
3164
the whole file is parsed with one call.
3166
static enum XML_Error PTRCALL
3167
cdataSectionProcessor(XML_Parser parser,
3170
const char **endPtr)
3172
enum XML_Error result = doCdataSection(parser, encoding, &start, end,
3173
endPtr, (XML_Bool)!ps_finalBuffer);
3174
if (result != XML_ERROR_NONE)
3177
if (parentParser) { /* we are parsing an external entity */
3178
processor = externalEntityContentProcessor;
3179
return externalEntityContentProcessor(parser, start, end, endPtr);
3182
processor = contentProcessor;
3183
return contentProcessor(parser, start, end, endPtr);
3189
/* startPtr gets set to non-null if the section is closed, and to null if
3190
the section is not yet closed.
3192
static enum XML_Error
3193
doCdataSection(XML_Parser parser,
3194
const ENCODING *enc,
3195
const char **startPtr,
3197
const char **nextPtr,
3200
const char *s = *startPtr;
3201
const char **eventPP;
3202
const char **eventEndPP;
3203
if (enc == encoding) {
3204
eventPP = &eventPtr;
3206
eventEndPP = &eventEndPtr;
3209
eventPP = &(openInternalEntities->internalEventPtr);
3210
eventEndPP = &(openInternalEntities->internalEventEndPtr);
3217
int tok = XmlCdataSectionTok(enc, s, end, &next);
3220
case XML_TOK_CDATA_SECT_CLOSE:
3221
if (endCdataSectionHandler)
3222
endCdataSectionHandler(handlerArg);
3224
/* see comment under XML_TOK_CDATA_SECT_OPEN */
3225
else if (characterDataHandler)
3226
characterDataHandler(handlerArg, dataBuf, 0);
3228
else if (defaultHandler)
3229
reportDefault(parser, enc, s, next);
3232
if (ps_parsing == XML_FINISHED)
3233
return XML_ERROR_ABORTED;
3235
return XML_ERROR_NONE;
3236
case XML_TOK_DATA_NEWLINE:
3237
if (characterDataHandler) {
3239
characterDataHandler(handlerArg, &c, 1);
3241
else if (defaultHandler)
3242
reportDefault(parser, enc, s, next);
3244
case XML_TOK_DATA_CHARS:
3246
XML_CharacterDataHandler charDataHandler = characterDataHandler;
3247
if (charDataHandler) {
3248
if (MUST_CONVERT(enc, s)) {
3250
ICHAR *dataPtr = (ICHAR *)dataBuf;
3251
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3253
charDataHandler(handlerArg, dataBuf,
3254
(int)(dataPtr - (ICHAR *)dataBuf));
3261
charDataHandler(handlerArg,
3263
(int)((XML_Char *)next - (XML_Char *)s));
3265
else if (defaultHandler)
3266
reportDefault(parser, enc, s, next);
3269
case XML_TOK_INVALID:
3271
return XML_ERROR_INVALID_TOKEN;
3272
case XML_TOK_PARTIAL_CHAR:
3275
return XML_ERROR_NONE;
3277
return XML_ERROR_PARTIAL_CHAR;
3278
case XML_TOK_PARTIAL:
3282
return XML_ERROR_NONE;
3284
return XML_ERROR_UNCLOSED_CDATA_SECTION;
3287
return XML_ERROR_UNEXPECTED_STATE;
3290
*eventPP = s = next;
3291
switch (ps_parsing) {
3294
return XML_ERROR_NONE;
3296
return XML_ERROR_ABORTED;
3305
/* The idea here is to avoid using stack for each IGNORE section when
3306
the whole file is parsed with one call.
3308
static enum XML_Error PTRCALL
3309
ignoreSectionProcessor(XML_Parser parser,
3312
const char **endPtr)
3314
enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
3315
endPtr, (XML_Bool)!ps_finalBuffer);
3316
if (result != XML_ERROR_NONE)
3319
processor = prologProcessor;
3320
return prologProcessor(parser, start, end, endPtr);
3325
/* startPtr gets set to non-null is the section is closed, and to null
3326
if the section is not yet closed.
3328
static enum XML_Error
3329
doIgnoreSection(XML_Parser parser,
3330
const ENCODING *enc,
3331
const char **startPtr,
3333
const char **nextPtr,
3338
const char *s = *startPtr;
3339
const char **eventPP;
3340
const char **eventEndPP;
3341
if (enc == encoding) {
3342
eventPP = &eventPtr;
3344
eventEndPP = &eventEndPtr;
3347
eventPP = &(openInternalEntities->internalEventPtr);
3348
eventEndPP = &(openInternalEntities->internalEventEndPtr);
3352
tok = XmlIgnoreSectionTok(enc, s, end, &next);
3355
case XML_TOK_IGNORE_SECT:
3357
reportDefault(parser, enc, s, next);
3360
if (ps_parsing == XML_FINISHED)
3361
return XML_ERROR_ABORTED;
3363
return XML_ERROR_NONE;
3364
case XML_TOK_INVALID:
3366
return XML_ERROR_INVALID_TOKEN;
3367
case XML_TOK_PARTIAL_CHAR:
3370
return XML_ERROR_NONE;
3372
return XML_ERROR_PARTIAL_CHAR;
3373
case XML_TOK_PARTIAL:
3377
return XML_ERROR_NONE;
3379
return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3382
return XML_ERROR_UNEXPECTED_STATE;
3387
#endif /* XML_DTD */
3389
static enum XML_Error
3390
initializeEncoding(XML_Parser parser)
3394
char encodingBuf[128];
3395
if (!protocolEncodingName)
3399
for (i = 0; protocolEncodingName[i]; i++) {
3400
if (i == sizeof(encodingBuf) - 1
3401
|| (protocolEncodingName[i] & ~0x7f) != 0) {
3402
encodingBuf[0] = '\0';
3405
encodingBuf[i] = (char)protocolEncodingName[i];
3407
encodingBuf[i] = '\0';
3411
s = protocolEncodingName;
3413
if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3414
return XML_ERROR_NONE;
3415
return handleUnknownEncoding(parser, protocolEncodingName);
3418
static enum XML_Error
3419
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3420
const char *s, const char *next)
3422
const char *encodingName = NULL;
3423
const XML_Char *storedEncName = NULL;
3424
const ENCODING *newEncoding = NULL;
3425
const char *version = NULL;
3426
const char *versionend;
3427
const XML_Char *storedversion = NULL;
3428
int standalone = -1;
3431
: XmlParseXmlDecl)(isGeneralTextEntity,
3441
if (isGeneralTextEntity)
3442
return XML_ERROR_TEXT_DECL;
3444
return XML_ERROR_XML_DECL;
3446
if (!isGeneralTextEntity && standalone == 1) {
3447
_dtd->standalone = XML_TRUE;
3449
if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3450
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3451
#endif /* XML_DTD */
3453
if (xmlDeclHandler) {
3454
if (encodingName != NULL) {
3455
storedEncName = poolStoreString(&temp2Pool,
3459
+ XmlNameLength(encoding, encodingName));
3461
return XML_ERROR_NO_MEMORY;
3462
poolFinish(&temp2Pool);
3465
storedversion = poolStoreString(&temp2Pool,
3468
versionend - encoding->minBytesPerChar);
3470
return XML_ERROR_NO_MEMORY;
3472
xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3474
else if (defaultHandler)
3475
reportDefault(parser, encoding, s, next);
3476
if (protocolEncodingName == NULL) {
3478
if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3479
eventPtr = encodingName;
3480
return XML_ERROR_INCORRECT_ENCODING;
3482
encoding = newEncoding;
3484
else if (encodingName) {
3485
enum XML_Error result;
3486
if (!storedEncName) {
3487
storedEncName = poolStoreString(
3488
&temp2Pool, encoding, encodingName,
3489
encodingName + XmlNameLength(encoding, encodingName));
3491
return XML_ERROR_NO_MEMORY;
3493
result = handleUnknownEncoding(parser, storedEncName);
3494
poolClear(&temp2Pool);
3495
if (result == XML_ERROR_UNKNOWN_ENCODING)
3496
eventPtr = encodingName;
3501
if (storedEncName || storedversion)
3502
poolClear(&temp2Pool);
3504
return XML_ERROR_NONE;
3507
static enum XML_Error
3508
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3510
if (unknownEncodingHandler) {
3513
for (i = 0; i < 256; i++)
3515
info.convert = NULL;
3517
info.release = NULL;
3518
if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3521
unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3522
if (!unknownEncodingMem) {
3524
info.release(info.data);
3525
return XML_ERROR_NO_MEMORY;
3528
? XmlInitUnknownEncodingNS
3529
: XmlInitUnknownEncoding)(unknownEncodingMem,
3534
unknownEncodingData = info.data;
3535
unknownEncodingRelease = info.release;
3537
return XML_ERROR_NONE;
3540
if (info.release != NULL)
3541
info.release(info.data);
3543
return XML_ERROR_UNKNOWN_ENCODING;
3546
static enum XML_Error PTRCALL
3547
prologInitProcessor(XML_Parser parser,
3550
const char **nextPtr)
3552
enum XML_Error result = initializeEncoding(parser);
3553
if (result != XML_ERROR_NONE)
3555
processor = prologProcessor;
3556
return prologProcessor(parser, s, end, nextPtr);
3561
static enum XML_Error PTRCALL
3562
externalParEntInitProcessor(XML_Parser parser,
3565
const char **nextPtr)
3567
enum XML_Error result = initializeEncoding(parser);
3568
if (result != XML_ERROR_NONE)
3571
/* we know now that XML_Parse(Buffer) has been called,
3572
so we consider the external parameter entity read */
3573
_dtd->paramEntityRead = XML_TRUE;
3575
if (prologState.inEntityValue) {
3576
processor = entityValueInitProcessor;
3577
return entityValueInitProcessor(parser, s, end, nextPtr);
3580
processor = externalParEntProcessor;
3581
return externalParEntProcessor(parser, s, end, nextPtr);
3585
static enum XML_Error PTRCALL
3586
entityValueInitProcessor(XML_Parser parser,
3589
const char **nextPtr)
3592
const char *start = s;
3593
const char *next = start;
3597
tok = XmlPrologTok(encoding, start, end, &next);
3600
if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3602
return XML_ERROR_NONE;
3605
case XML_TOK_INVALID:
3606
return XML_ERROR_INVALID_TOKEN;
3607
case XML_TOK_PARTIAL:
3608
return XML_ERROR_UNCLOSED_TOKEN;
3609
case XML_TOK_PARTIAL_CHAR:
3610
return XML_ERROR_PARTIAL_CHAR;
3611
case XML_TOK_NONE: /* start == end */
3615
/* found end of entity value - can store it now */
3616
return storeEntityValue(parser, encoding, s, end);
3618
else if (tok == XML_TOK_XML_DECL) {
3619
enum XML_Error result;
3620
result = processXmlDecl(parser, 0, start, next);
3621
if (result != XML_ERROR_NONE)
3623
switch (ps_parsing) {
3626
return XML_ERROR_NONE;
3628
return XML_ERROR_ABORTED;
3632
/* stop scanning for text declaration - we found one */
3633
processor = entityValueProcessor;
3634
return entityValueProcessor(parser, next, end, nextPtr);
3636
/* If we are at the end of the buffer, this would cause XmlPrologTok to
3637
return XML_TOK_NONE on the next call, which would then cause the
3638
function to exit with *nextPtr set to s - that is what we want for other
3639
tokens, but not for the BOM - we would rather like to skip it;
3640
then, when this routine is entered the next time, XmlPrologTok will
3641
return XML_TOK_INVALID, since the BOM is still in the buffer
3643
else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
3645
return XML_ERROR_NONE;
3652
static enum XML_Error PTRCALL
3653
externalParEntProcessor(XML_Parser parser,
3656
const char **nextPtr)
3658
const char *next = s;
3661
tok = XmlPrologTok(encoding, s, end, &next);
3663
if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3665
return XML_ERROR_NONE;
3668
case XML_TOK_INVALID:
3669
return XML_ERROR_INVALID_TOKEN;
3670
case XML_TOK_PARTIAL:
3671
return XML_ERROR_UNCLOSED_TOKEN;
3672
case XML_TOK_PARTIAL_CHAR:
3673
return XML_ERROR_PARTIAL_CHAR;
3674
case XML_TOK_NONE: /* start == end */
3679
/* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3680
However, when parsing an external subset, doProlog will not accept a BOM
3681
as valid, and report a syntax error, so we have to skip the BOM
3683
else if (tok == XML_TOK_BOM) {
3685
tok = XmlPrologTok(encoding, s, end, &next);
3688
processor = prologProcessor;
3689
return doProlog(parser, encoding, s, end, tok, next,
3690
nextPtr, (XML_Bool)!ps_finalBuffer);
3693
static enum XML_Error PTRCALL
3694
entityValueProcessor(XML_Parser parser,
3697
const char **nextPtr)
3699
const char *start = s;
3700
const char *next = s;
3701
const ENCODING *enc = encoding;
3705
tok = XmlPrologTok(enc, start, end, &next);
3707
if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3709
return XML_ERROR_NONE;
3712
case XML_TOK_INVALID:
3713
return XML_ERROR_INVALID_TOKEN;
3714
case XML_TOK_PARTIAL:
3715
return XML_ERROR_UNCLOSED_TOKEN;
3716
case XML_TOK_PARTIAL_CHAR:
3717
return XML_ERROR_PARTIAL_CHAR;
3718
case XML_TOK_NONE: /* start == end */
3722
/* found end of entity value - can store it now */
3723
return storeEntityValue(parser, enc, s, end);
3729
#endif /* XML_DTD */
3731
static enum XML_Error PTRCALL
3732
prologProcessor(XML_Parser parser,
3735
const char **nextPtr)
3737
const char *next = s;
3738
int tok = XmlPrologTok(encoding, s, end, &next);
3739
return doProlog(parser, encoding, s, end, tok, next,
3740
nextPtr, (XML_Bool)!ps_finalBuffer);
3743
static enum XML_Error
3744
doProlog(XML_Parser parser,
3745
const ENCODING *enc,
3750
const char **nextPtr,
3754
static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
3755
#endif /* XML_DTD */
3756
static const XML_Char atypeCDATA[] =
3757
{ ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
3758
static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
3759
static const XML_Char atypeIDREF[] =
3760
{ ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
3761
static const XML_Char atypeIDREFS[] =
3762
{ ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
3763
static const XML_Char atypeENTITY[] =
3764
{ ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
3765
static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
3766
ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
3767
static const XML_Char atypeNMTOKEN[] = {
3768
ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
3769
static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
3770
ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
3771
static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
3772
ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
3773
static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
3774
static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
3776
/* save one level of indirection */
3777
DTD * const dtd = _dtd;
3779
const char **eventPP;
3780
const char **eventEndPP;
3781
enum XML_Content_Quant quant;
3783
if (enc == encoding) {
3784
eventPP = &eventPtr;
3785
eventEndPP = &eventEndPtr;
3788
eventPP = &(openInternalEntities->internalEventPtr);
3789
eventEndPP = &(openInternalEntities->internalEventEndPtr);
3794
XML_Bool handleDefault = XML_TRUE;
3798
if (haveMore && tok != XML_TOK_INVALID) {
3800
return XML_ERROR_NONE;
3803
case XML_TOK_INVALID:
3805
return XML_ERROR_INVALID_TOKEN;
3806
case XML_TOK_PARTIAL:
3807
return XML_ERROR_UNCLOSED_TOKEN;
3808
case XML_TOK_PARTIAL_CHAR:
3809
return XML_ERROR_PARTIAL_CHAR;
3810
case -XML_TOK_PROLOG_S:
3815
/* for internal PE NOT referenced between declarations */
3816
if (enc != encoding && !openInternalEntities->betweenDecl) {
3818
return XML_ERROR_NONE;
3820
/* WFC: PE Between Declarations - must check that PE contains
3821
complete markup, not only for external PEs, but also for
3822
internal PEs if the reference occurs between declarations.
3824
if (isParamEntity || enc != encoding) {
3825
if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3827
return XML_ERROR_INCOMPLETE_PE;
3829
return XML_ERROR_NONE;
3831
#endif /* XML_DTD */
3832
return XML_ERROR_NO_ELEMENTS;
3839
role = XmlTokenRole(&prologState, tok, s, next, enc);
3841
case XML_ROLE_XML_DECL:
3843
enum XML_Error result = processXmlDecl(parser, 0, s, next);
3844
if (result != XML_ERROR_NONE)
3847
handleDefault = XML_FALSE;
3850
case XML_ROLE_DOCTYPE_NAME:
3851
if (startDoctypeDeclHandler) {
3852
doctypeName = poolStoreString(&tempPool, enc, s, next);
3854
return XML_ERROR_NO_MEMORY;
3855
poolFinish(&tempPool);
3856
doctypePubid = NULL;
3857
handleDefault = XML_FALSE;
3859
doctypeSysid = NULL; /* always initialize to NULL */
3861
case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3862
if (startDoctypeDeclHandler) {
3863
startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3866
poolClear(&tempPool);
3867
handleDefault = XML_FALSE;
3871
case XML_ROLE_TEXT_DECL:
3873
enum XML_Error result = processXmlDecl(parser, 1, s, next);
3874
if (result != XML_ERROR_NONE)
3877
handleDefault = XML_FALSE;
3880
#endif /* XML_DTD */
3881
case XML_ROLE_DOCTYPE_PUBLIC_ID:
3883
useForeignDTD = XML_FALSE;
3884
declEntity = (ENTITY *)lookup(parser,
3885
&dtd->paramEntities,
3889
return XML_ERROR_NO_MEMORY;
3890
#endif /* XML_DTD */
3891
dtd->hasParamEntityRefs = XML_TRUE;
3892
if (startDoctypeDeclHandler) {
3894
if (!XmlIsPublicId(enc, s, next, eventPP))
3895
return XML_ERROR_PUBLICID;
3896
pubId = poolStoreString(&tempPool, enc,
3897
s + enc->minBytesPerChar,
3898
next - enc->minBytesPerChar);
3900
return XML_ERROR_NO_MEMORY;
3901
normalizePublicId(pubId);
3902
poolFinish(&tempPool);
3903
doctypePubid = pubId;
3904
handleDefault = XML_FALSE;
3905
goto alreadyChecked;
3908
case XML_ROLE_ENTITY_PUBLIC_ID:
3909
if (!XmlIsPublicId(enc, s, next, eventPP))
3910
return XML_ERROR_PUBLICID;
3912
if (dtd->keepProcessing && declEntity) {
3913
XML_Char *tem = poolStoreString(&dtd->pool,
3915
s + enc->minBytesPerChar,
3916
next - enc->minBytesPerChar);
3918
return XML_ERROR_NO_MEMORY;
3919
normalizePublicId(tem);
3920
declEntity->publicId = tem;
3921
poolFinish(&dtd->pool);
3922
if (entityDeclHandler)
3923
handleDefault = XML_FALSE;
3926
case XML_ROLE_DOCTYPE_CLOSE:
3928
startDoctypeDeclHandler(handlerArg, doctypeName,
3929
doctypeSysid, doctypePubid, 0);
3930
poolClear(&tempPool);
3931
handleDefault = XML_FALSE;
3933
/* doctypeSysid will be non-NULL in the case of a previous
3934
XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3935
was not set, indicating an external subset
3938
if (doctypeSysid || useForeignDTD) {
3939
XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3940
dtd->hasParamEntityRefs = XML_TRUE;
3941
if (paramEntityParsing && externalEntityRefHandler) {
3942
ENTITY *entity = (ENTITY *)lookup(parser,
3943
&dtd->paramEntities,
3947
return XML_ERROR_NO_MEMORY;
3949
entity->base = curBase;
3950
dtd->paramEntityRead = XML_FALSE;
3951
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3956
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3957
if (dtd->paramEntityRead) {
3958
if (!dtd->standalone &&
3959
notStandaloneHandler &&
3960
!notStandaloneHandler(handlerArg))
3961
return XML_ERROR_NOT_STANDALONE;
3963
/* if we didn't read the foreign DTD then this means that there
3964
is no external subset and we must reset dtd->hasParamEntityRefs
3966
else if (!doctypeSysid)
3967
dtd->hasParamEntityRefs = hadParamEntityRefs;
3968
/* end of DTD - no need to update dtd->keepProcessing */
3970
useForeignDTD = XML_FALSE;
3972
#endif /* XML_DTD */
3973
if (endDoctypeDeclHandler) {
3974
endDoctypeDeclHandler(handlerArg);
3975
handleDefault = XML_FALSE;
3978
case XML_ROLE_INSTANCE_START:
3980
/* if there is no DOCTYPE declaration then now is the
3981
last chance to read the foreign DTD
3983
if (useForeignDTD) {
3984
XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3985
dtd->hasParamEntityRefs = XML_TRUE;
3986
if (paramEntityParsing && externalEntityRefHandler) {
3987
ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
3991
return XML_ERROR_NO_MEMORY;
3992
entity->base = curBase;
3993
dtd->paramEntityRead = XML_FALSE;
3994
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3999
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4000
if (dtd->paramEntityRead) {
4001
if (!dtd->standalone &&
4002
notStandaloneHandler &&
4003
!notStandaloneHandler(handlerArg))
4004
return XML_ERROR_NOT_STANDALONE;
4006
/* if we didn't read the foreign DTD then this means that there
4007
is no external subset and we must reset dtd->hasParamEntityRefs
4010
dtd->hasParamEntityRefs = hadParamEntityRefs;
4011
/* end of DTD - no need to update dtd->keepProcessing */
4014
#endif /* XML_DTD */
4015
processor = contentProcessor;
4016
return contentProcessor(parser, s, end, nextPtr);
4017
case XML_ROLE_ATTLIST_ELEMENT_NAME:
4018
declElementType = getElementType(parser, enc, s, next);
4019
if (!declElementType)
4020
return XML_ERROR_NO_MEMORY;
4021
goto checkAttListDeclHandler;
4022
case XML_ROLE_ATTRIBUTE_NAME:
4023
declAttributeId = getAttributeId(parser, enc, s, next);
4024
if (!declAttributeId)
4025
return XML_ERROR_NO_MEMORY;
4026
declAttributeIsCdata = XML_FALSE;
4027
declAttributeType = NULL;
4028
declAttributeIsId = XML_FALSE;
4029
goto checkAttListDeclHandler;
4030
case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4031
declAttributeIsCdata = XML_TRUE;
4032
declAttributeType = atypeCDATA;
4033
goto checkAttListDeclHandler;
4034
case XML_ROLE_ATTRIBUTE_TYPE_ID:
4035
declAttributeIsId = XML_TRUE;
4036
declAttributeType = atypeID;
4037
goto checkAttListDeclHandler;
4038
case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4039
declAttributeType = atypeIDREF;
4040
goto checkAttListDeclHandler;
4041
case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4042
declAttributeType = atypeIDREFS;
4043
goto checkAttListDeclHandler;
4044
case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4045
declAttributeType = atypeENTITY;
4046
goto checkAttListDeclHandler;
4047
case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4048
declAttributeType = atypeENTITIES;
4049
goto checkAttListDeclHandler;
4050
case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4051
declAttributeType = atypeNMTOKEN;
4052
goto checkAttListDeclHandler;
4053
case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4054
declAttributeType = atypeNMTOKENS;
4055
checkAttListDeclHandler:
4056
if (dtd->keepProcessing && attlistDeclHandler)
4057
handleDefault = XML_FALSE;
4059
case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4060
case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4061
if (dtd->keepProcessing && attlistDeclHandler) {
4062
const XML_Char *prefix;
4063
if (declAttributeType) {
4064
prefix = enumValueSep;
4067
prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4071
if (!poolAppendString(&tempPool, prefix))
4072
return XML_ERROR_NO_MEMORY;
4073
if (!poolAppend(&tempPool, enc, s, next))
4074
return XML_ERROR_NO_MEMORY;
4075
declAttributeType = tempPool.start;
4076
handleDefault = XML_FALSE;
4079
case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4080
case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4081
if (dtd->keepProcessing) {
4082
if (!defineAttribute(declElementType, declAttributeId,
4083
declAttributeIsCdata, declAttributeIsId,
4085
return XML_ERROR_NO_MEMORY;
4086
if (attlistDeclHandler && declAttributeType) {
4087
if (*declAttributeType == XML_T(ASCII_LPAREN)
4088
|| (*declAttributeType == XML_T(ASCII_N)
4089
&& declAttributeType[1] == XML_T(ASCII_O))) {
4090
/* Enumerated or Notation type */
4091
if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4092
|| !poolAppendChar(&tempPool, XML_T('\0')))
4093
return XML_ERROR_NO_MEMORY;
4094
declAttributeType = tempPool.start;
4095
poolFinish(&tempPool);
4098
attlistDeclHandler(handlerArg, declElementType->name,
4099
declAttributeId->name, declAttributeType,
4100
0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4101
poolClear(&tempPool);
4102
handleDefault = XML_FALSE;
4106
case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4107
case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4108
if (dtd->keepProcessing) {
4109
const XML_Char *attVal;
4110
enum XML_Error result =
4111
storeAttributeValue(parser, enc, declAttributeIsCdata,
4112
s + enc->minBytesPerChar,
4113
next - enc->minBytesPerChar,
4117
attVal = poolStart(&dtd->pool);
4118
poolFinish(&dtd->pool);
4119
/* ID attributes aren't allowed to have a default */
4120
if (!defineAttribute(declElementType, declAttributeId,
4121
declAttributeIsCdata, XML_FALSE, attVal, parser))
4122
return XML_ERROR_NO_MEMORY;
4123
if (attlistDeclHandler && declAttributeType) {
4124
if (*declAttributeType == XML_T(ASCII_LPAREN)
4125
|| (*declAttributeType == XML_T(ASCII_N)
4126
&& declAttributeType[1] == XML_T(ASCII_O))) {
4127
/* Enumerated or Notation type */
4128
if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4129
|| !poolAppendChar(&tempPool, XML_T('\0')))
4130
return XML_ERROR_NO_MEMORY;
4131
declAttributeType = tempPool.start;
4132
poolFinish(&tempPool);
4135
attlistDeclHandler(handlerArg, declElementType->name,
4136
declAttributeId->name, declAttributeType,
4138
role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4139
poolClear(&tempPool);
4140
handleDefault = XML_FALSE;
4144
case XML_ROLE_ENTITY_VALUE:
4145
if (dtd->keepProcessing) {
4146
enum XML_Error result = storeEntityValue(parser, enc,
4147
s + enc->minBytesPerChar,
4148
next - enc->minBytesPerChar);
4150
declEntity->textPtr = poolStart(&dtd->entityValuePool);
4151
declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4152
poolFinish(&dtd->entityValuePool);
4153
if (entityDeclHandler) {
4155
entityDeclHandler(handlerArg,
4157
declEntity->is_param,
4158
declEntity->textPtr,
4159
declEntity->textLen,
4161
handleDefault = XML_FALSE;
4165
poolDiscard(&dtd->entityValuePool);
4166
if (result != XML_ERROR_NONE)
4170
case XML_ROLE_DOCTYPE_SYSTEM_ID:
4172
useForeignDTD = XML_FALSE;
4173
#endif /* XML_DTD */
4174
dtd->hasParamEntityRefs = XML_TRUE;
4175
if (startDoctypeDeclHandler) {
4176
doctypeSysid = poolStoreString(&tempPool, enc,
4177
s + enc->minBytesPerChar,
4178
next - enc->minBytesPerChar);
4179
if (doctypeSysid == NULL)
4180
return XML_ERROR_NO_MEMORY;
4181
poolFinish(&tempPool);
4182
handleDefault = XML_FALSE;
4186
/* use externalSubsetName to make doctypeSysid non-NULL
4187
for the case where no startDoctypeDeclHandler is set */
4188
doctypeSysid = externalSubsetName;
4189
#endif /* XML_DTD */
4190
if (!dtd->standalone
4192
&& !paramEntityParsing
4193
#endif /* XML_DTD */
4194
&& notStandaloneHandler
4195
&& !notStandaloneHandler(handlerArg))
4196
return XML_ERROR_NOT_STANDALONE;
4201
declEntity = (ENTITY *)lookup(parser,
4202
&dtd->paramEntities,
4206
return XML_ERROR_NO_MEMORY;
4207
declEntity->publicId = NULL;
4210
#endif /* XML_DTD */
4211
case XML_ROLE_ENTITY_SYSTEM_ID:
4212
if (dtd->keepProcessing && declEntity) {
4213
declEntity->systemId = poolStoreString(&dtd->pool, enc,
4214
s + enc->minBytesPerChar,
4215
next - enc->minBytesPerChar);
4216
if (!declEntity->systemId)
4217
return XML_ERROR_NO_MEMORY;
4218
declEntity->base = curBase;
4219
poolFinish(&dtd->pool);
4220
if (entityDeclHandler)
4221
handleDefault = XML_FALSE;
4224
case XML_ROLE_ENTITY_COMPLETE:
4225
if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4227
entityDeclHandler(handlerArg,
4229
declEntity->is_param,
4232
declEntity->systemId,
4233
declEntity->publicId,
4235
handleDefault = XML_FALSE;
4238
case XML_ROLE_ENTITY_NOTATION_NAME:
4239
if (dtd->keepProcessing && declEntity) {
4240
declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4241
if (!declEntity->notation)
4242
return XML_ERROR_NO_MEMORY;
4243
poolFinish(&dtd->pool);
4244
if (unparsedEntityDeclHandler) {
4246
unparsedEntityDeclHandler(handlerArg,
4249
declEntity->systemId,
4250
declEntity->publicId,
4251
declEntity->notation);
4252
handleDefault = XML_FALSE;
4254
else if (entityDeclHandler) {
4256
entityDeclHandler(handlerArg,
4260
declEntity->systemId,
4261
declEntity->publicId,
4262
declEntity->notation);
4263
handleDefault = XML_FALSE;
4267
case XML_ROLE_GENERAL_ENTITY_NAME:
4269
if (XmlPredefinedEntityName(enc, s, next)) {
4273
if (dtd->keepProcessing) {
4274
const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4276
return XML_ERROR_NO_MEMORY;
4277
declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
4280
return XML_ERROR_NO_MEMORY;
4281
if (declEntity->name != name) {
4282
poolDiscard(&dtd->pool);
4286
poolFinish(&dtd->pool);
4287
declEntity->publicId = NULL;
4288
declEntity->is_param = XML_FALSE;
4289
/* if we have a parent parser or are reading an internal parameter
4290
entity, then the entity declaration is not considered "internal"
4292
declEntity->is_internal = !(parentParser || openInternalEntities);
4293
if (entityDeclHandler)
4294
handleDefault = XML_FALSE;
4298
poolDiscard(&dtd->pool);
4303
case XML_ROLE_PARAM_ENTITY_NAME:
4305
if (dtd->keepProcessing) {
4306
const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4308
return XML_ERROR_NO_MEMORY;
4309
declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4310
name, sizeof(ENTITY));
4312
return XML_ERROR_NO_MEMORY;
4313
if (declEntity->name != name) {
4314
poolDiscard(&dtd->pool);
4318
poolFinish(&dtd->pool);
4319
declEntity->publicId = NULL;
4320
declEntity->is_param = XML_TRUE;
4321
/* if we have a parent parser or are reading an internal parameter
4322
entity, then the entity declaration is not considered "internal"
4324
declEntity->is_internal = !(parentParser || openInternalEntities);
4325
if (entityDeclHandler)
4326
handleDefault = XML_FALSE;
4330
poolDiscard(&dtd->pool);
4333
#else /* not XML_DTD */
4335
#endif /* XML_DTD */
4337
case XML_ROLE_NOTATION_NAME:
4338
declNotationPublicId = NULL;
4339
declNotationName = NULL;
4340
if (notationDeclHandler) {
4341
declNotationName = poolStoreString(&tempPool, enc, s, next);
4342
if (!declNotationName)
4343
return XML_ERROR_NO_MEMORY;
4344
poolFinish(&tempPool);
4345
handleDefault = XML_FALSE;
4348
case XML_ROLE_NOTATION_PUBLIC_ID:
4349
if (!XmlIsPublicId(enc, s, next, eventPP))
4350
return XML_ERROR_PUBLICID;
4351
if (declNotationName) { /* means notationDeclHandler != NULL */
4352
XML_Char *tem = poolStoreString(&tempPool,
4354
s + enc->minBytesPerChar,
4355
next - enc->minBytesPerChar);
4357
return XML_ERROR_NO_MEMORY;
4358
normalizePublicId(tem);
4359
declNotationPublicId = tem;
4360
poolFinish(&tempPool);
4361
handleDefault = XML_FALSE;
4364
case XML_ROLE_NOTATION_SYSTEM_ID:
4365
if (declNotationName && notationDeclHandler) {
4366
const XML_Char *systemId
4367
= poolStoreString(&tempPool, enc,
4368
s + enc->minBytesPerChar,
4369
next - enc->minBytesPerChar);
4371
return XML_ERROR_NO_MEMORY;
4373
notationDeclHandler(handlerArg,
4377
declNotationPublicId);
4378
handleDefault = XML_FALSE;
4380
poolClear(&tempPool);
4382
case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4383
if (declNotationPublicId && notationDeclHandler) {
4385
notationDeclHandler(handlerArg,
4389
declNotationPublicId);
4390
handleDefault = XML_FALSE;
4392
poolClear(&tempPool);
4394
case XML_ROLE_ERROR:
4396
case XML_TOK_PARAM_ENTITY_REF:
4397
/* PE references in internal subset are
4398
not allowed within declarations. */
4399
return XML_ERROR_PARAM_ENTITY_REF;
4400
case XML_TOK_XML_DECL:
4401
return XML_ERROR_MISPLACED_XML_PI;
4403
return XML_ERROR_SYNTAX;
4406
case XML_ROLE_IGNORE_SECT:
4408
enum XML_Error result;
4410
reportDefault(parser, enc, s, next);
4411
handleDefault = XML_FALSE;
4412
result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4413
if (result != XML_ERROR_NONE)
4416
processor = ignoreSectionProcessor;
4421
#endif /* XML_DTD */
4422
case XML_ROLE_GROUP_OPEN:
4423
if (prologState.level >= groupSize) {
4425
char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4427
return XML_ERROR_NO_MEMORY;
4428
groupConnector = temp;
4429
if (dtd->scaffIndex) {
4430
int *temp = (int *)REALLOC(dtd->scaffIndex,
4431
groupSize * sizeof(int));
4433
return XML_ERROR_NO_MEMORY;
4434
dtd->scaffIndex = temp;
4438
groupConnector = (char *)MALLOC(groupSize = 32);
4439
if (!groupConnector)
4440
return XML_ERROR_NO_MEMORY;
4443
groupConnector[prologState.level] = 0;
4444
if (dtd->in_eldecl) {
4445
int myindex = nextScaffoldPart(parser);
4447
return XML_ERROR_NO_MEMORY;
4448
dtd->scaffIndex[dtd->scaffLevel] = myindex;
4450
dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4451
if (elementDeclHandler)
4452
handleDefault = XML_FALSE;
4455
case XML_ROLE_GROUP_SEQUENCE:
4456
if (groupConnector[prologState.level] == ASCII_PIPE)
4457
return XML_ERROR_SYNTAX;
4458
groupConnector[prologState.level] = ASCII_COMMA;
4459
if (dtd->in_eldecl && elementDeclHandler)
4460
handleDefault = XML_FALSE;
4462
case XML_ROLE_GROUP_CHOICE:
4463
if (groupConnector[prologState.level] == ASCII_COMMA)
4464
return XML_ERROR_SYNTAX;
4466
&& !groupConnector[prologState.level]
4467
&& (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4470
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4472
if (elementDeclHandler)
4473
handleDefault = XML_FALSE;
4475
groupConnector[prologState.level] = ASCII_PIPE;
4477
case XML_ROLE_PARAM_ENTITY_REF:
4479
case XML_ROLE_INNER_PARAM_ENTITY_REF:
4480
dtd->hasParamEntityRefs = XML_TRUE;
4481
if (!paramEntityParsing)
4482
dtd->keepProcessing = dtd->standalone;
4484
const XML_Char *name;
4486
name = poolStoreString(&dtd->pool, enc,
4487
s + enc->minBytesPerChar,
4488
next - enc->minBytesPerChar);
4490
return XML_ERROR_NO_MEMORY;
4491
entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
4492
poolDiscard(&dtd->pool);
4493
/* first, determine if a check for an existing declaration is needed;
4494
if yes, check that the entity exists, and that it is internal,
4495
otherwise call the skipped entity handler
4497
if (prologState.documentEntity &&
4499
? !openInternalEntities
4500
: !dtd->hasParamEntityRefs)) {
4502
return XML_ERROR_UNDEFINED_ENTITY;
4503
else if (!entity->is_internal)
4504
return XML_ERROR_ENTITY_DECLARED_IN_PE;
4507
dtd->keepProcessing = dtd->standalone;
4508
/* cannot report skipped entities in declarations */
4509
if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4510
skippedEntityHandler(handlerArg, name, 1);
4511
handleDefault = XML_FALSE;
4516
return XML_ERROR_RECURSIVE_ENTITY_REF;
4517
if (entity->textPtr) {
4518
enum XML_Error result;
4519
XML_Bool betweenDecl =
4520
(role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4521
result = processInternalEntity(parser, entity, betweenDecl);
4522
if (result != XML_ERROR_NONE)
4524
handleDefault = XML_FALSE;
4527
if (externalEntityRefHandler) {
4528
dtd->paramEntityRead = XML_FALSE;
4529
entity->open = XML_TRUE;
4530
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4534
entity->publicId)) {
4535
entity->open = XML_FALSE;
4536
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4538
entity->open = XML_FALSE;
4539
handleDefault = XML_FALSE;
4540
if (!dtd->paramEntityRead) {
4541
dtd->keepProcessing = dtd->standalone;
4546
dtd->keepProcessing = dtd->standalone;
4550
#endif /* XML_DTD */
4551
if (!dtd->standalone &&
4552
notStandaloneHandler &&
4553
!notStandaloneHandler(handlerArg))
4554
return XML_ERROR_NOT_STANDALONE;
4557
/* Element declaration stuff */
4559
case XML_ROLE_ELEMENT_NAME:
4560
if (elementDeclHandler) {
4561
declElementType = getElementType(parser, enc, s, next);
4562
if (!declElementType)
4563
return XML_ERROR_NO_MEMORY;
4564
dtd->scaffLevel = 0;
4565
dtd->scaffCount = 0;
4566
dtd->in_eldecl = XML_TRUE;
4567
handleDefault = XML_FALSE;
4571
case XML_ROLE_CONTENT_ANY:
4572
case XML_ROLE_CONTENT_EMPTY:
4573
if (dtd->in_eldecl) {
4574
if (elementDeclHandler) {
4575
XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4577
return XML_ERROR_NO_MEMORY;
4578
content->quant = XML_CQUANT_NONE;
4579
content->name = NULL;
4580
content->numchildren = 0;
4581
content->children = NULL;
4582
content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4586
elementDeclHandler(handlerArg, declElementType->name, content);
4587
handleDefault = XML_FALSE;
4589
dtd->in_eldecl = XML_FALSE;
4593
case XML_ROLE_CONTENT_PCDATA:
4594
if (dtd->in_eldecl) {
4595
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4597
if (elementDeclHandler)
4598
handleDefault = XML_FALSE;
4602
case XML_ROLE_CONTENT_ELEMENT:
4603
quant = XML_CQUANT_NONE;
4604
goto elementContent;
4605
case XML_ROLE_CONTENT_ELEMENT_OPT:
4606
quant = XML_CQUANT_OPT;
4607
goto elementContent;
4608
case XML_ROLE_CONTENT_ELEMENT_REP:
4609
quant = XML_CQUANT_REP;
4610
goto elementContent;
4611
case XML_ROLE_CONTENT_ELEMENT_PLUS:
4612
quant = XML_CQUANT_PLUS;
4614
if (dtd->in_eldecl) {
4616
const XML_Char *name;
4618
const char *nxt = (quant == XML_CQUANT_NONE
4620
: next - enc->minBytesPerChar);
4621
int myindex = nextScaffoldPart(parser);
4623
return XML_ERROR_NO_MEMORY;
4624
dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4625
dtd->scaffold[myindex].quant = quant;
4626
el = getElementType(parser, enc, s, nxt);
4628
return XML_ERROR_NO_MEMORY;
4630
dtd->scaffold[myindex].name = name;
4632
for (; name[nameLen++]; );
4633
dtd->contentStringLen += nameLen;
4634
if (elementDeclHandler)
4635
handleDefault = XML_FALSE;
4639
case XML_ROLE_GROUP_CLOSE:
4640
quant = XML_CQUANT_NONE;
4642
case XML_ROLE_GROUP_CLOSE_OPT:
4643
quant = XML_CQUANT_OPT;
4645
case XML_ROLE_GROUP_CLOSE_REP:
4646
quant = XML_CQUANT_REP;
4648
case XML_ROLE_GROUP_CLOSE_PLUS:
4649
quant = XML_CQUANT_PLUS;
4651
if (dtd->in_eldecl) {
4652
if (elementDeclHandler)
4653
handleDefault = XML_FALSE;
4655
dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4656
if (dtd->scaffLevel == 0) {
4657
if (!handleDefault) {
4658
XML_Content *model = build_model(parser);
4660
return XML_ERROR_NO_MEMORY;
4662
elementDeclHandler(handlerArg, declElementType->name, model);
4664
dtd->in_eldecl = XML_FALSE;
4665
dtd->contentStringLen = 0;
4669
/* End element declaration stuff */
4672
if (!reportProcessingInstruction(parser, enc, s, next))
4673
return XML_ERROR_NO_MEMORY;
4674
handleDefault = XML_FALSE;
4676
case XML_ROLE_COMMENT:
4677
if (!reportComment(parser, enc, s, next))
4678
return XML_ERROR_NO_MEMORY;
4679
handleDefault = XML_FALSE;
4684
handleDefault = XML_FALSE;
4688
case XML_ROLE_DOCTYPE_NONE:
4689
if (startDoctypeDeclHandler)
4690
handleDefault = XML_FALSE;
4692
case XML_ROLE_ENTITY_NONE:
4693
if (dtd->keepProcessing && entityDeclHandler)
4694
handleDefault = XML_FALSE;
4696
case XML_ROLE_NOTATION_NONE:
4697
if (notationDeclHandler)
4698
handleDefault = XML_FALSE;
4700
case XML_ROLE_ATTLIST_NONE:
4701
if (dtd->keepProcessing && attlistDeclHandler)
4702
handleDefault = XML_FALSE;
4704
case XML_ROLE_ELEMENT_NONE:
4705
if (elementDeclHandler)
4706
handleDefault = XML_FALSE;
4708
} /* end of big switch */
4710
if (handleDefault && defaultHandler)
4711
reportDefault(parser, enc, s, next);
4713
switch (ps_parsing) {
4716
return XML_ERROR_NONE;
4718
return XML_ERROR_ABORTED;
4721
tok = XmlPrologTok(enc, s, end, &next);
4727
static enum XML_Error PTRCALL
4728
epilogProcessor(XML_Parser parser,
4731
const char **nextPtr)
4733
processor = epilogProcessor;
4736
const char *next = NULL;
4737
int tok = XmlPrologTok(encoding, s, end, &next);
4740
/* report partial linebreak - it might be the last token */
4741
case -XML_TOK_PROLOG_S:
4742
if (defaultHandler) {
4743
reportDefault(parser, encoding, s, next);
4744
if (ps_parsing == XML_FINISHED)
4745
return XML_ERROR_ABORTED;
4748
return XML_ERROR_NONE;
4751
return XML_ERROR_NONE;
4752
case XML_TOK_PROLOG_S:
4754
reportDefault(parser, encoding, s, next);
4757
if (!reportProcessingInstruction(parser, encoding, s, next))
4758
return XML_ERROR_NO_MEMORY;
4760
case XML_TOK_COMMENT:
4761
if (!reportComment(parser, encoding, s, next))
4762
return XML_ERROR_NO_MEMORY;
4764
case XML_TOK_INVALID:
4766
return XML_ERROR_INVALID_TOKEN;
4767
case XML_TOK_PARTIAL:
4768
if (!ps_finalBuffer) {
4770
return XML_ERROR_NONE;
4772
return XML_ERROR_UNCLOSED_TOKEN;
4773
case XML_TOK_PARTIAL_CHAR:
4774
if (!ps_finalBuffer) {
4776
return XML_ERROR_NONE;
4778
return XML_ERROR_PARTIAL_CHAR;
4780
return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4782
eventPtr = s = next;
4783
switch (ps_parsing) {
4786
return XML_ERROR_NONE;
4788
return XML_ERROR_ABORTED;
4794
static enum XML_Error
4795
processInternalEntity(XML_Parser parser, ENTITY *entity,
4796
XML_Bool betweenDecl)
4798
const char *textStart, *textEnd;
4800
enum XML_Error result;
4801
OPEN_INTERNAL_ENTITY *openEntity;
4803
if (freeInternalEntities) {
4804
openEntity = freeInternalEntities;
4805
freeInternalEntities = openEntity->next;
4808
openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4810
return XML_ERROR_NO_MEMORY;
4812
entity->open = XML_TRUE;
4813
entity->processed = 0;
4814
openEntity->next = openInternalEntities;
4815
openInternalEntities = openEntity;
4816
openEntity->entity = entity;
4817
openEntity->startTagLevel = tagLevel;
4818
openEntity->betweenDecl = betweenDecl;
4819
openEntity->internalEventPtr = NULL;
4820
openEntity->internalEventEndPtr = NULL;
4821
textStart = (char *)entity->textPtr;
4822
textEnd = (char *)(entity->textPtr + entity->textLen);
4825
if (entity->is_param) {
4826
int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4827
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4828
next, &next, XML_FALSE);
4831
#endif /* XML_DTD */
4832
result = doContent(parser, tagLevel, internalEncoding, textStart,
4833
textEnd, &next, XML_FALSE);
4835
if (result == XML_ERROR_NONE) {
4836
if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4837
entity->processed = (int)(next - textStart);
4838
processor = internalEntityProcessor;
4841
entity->open = XML_FALSE;
4842
openInternalEntities = openEntity->next;
4843
/* put openEntity back in list of free instances */
4844
openEntity->next = freeInternalEntities;
4845
freeInternalEntities = openEntity;
4851
static enum XML_Error PTRCALL
4852
internalEntityProcessor(XML_Parser parser,
4855
const char **nextPtr)
4858
const char *textStart, *textEnd;
4860
enum XML_Error result;
4861
OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4863
return XML_ERROR_UNEXPECTED_STATE;
4865
entity = openEntity->entity;
4866
textStart = ((char *)entity->textPtr) + entity->processed;
4867
textEnd = (char *)(entity->textPtr + entity->textLen);
4870
if (entity->is_param) {
4871
int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4872
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4873
next, &next, XML_FALSE);
4876
#endif /* XML_DTD */
4877
result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4878
textStart, textEnd, &next, XML_FALSE);
4880
if (result != XML_ERROR_NONE)
4882
else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4883
entity->processed = (int)(next - (char *)entity->textPtr);
4887
entity->open = XML_FALSE;
4888
openInternalEntities = openEntity->next;
4889
/* put openEntity back in list of free instances */
4890
openEntity->next = freeInternalEntities;
4891
freeInternalEntities = openEntity;
4895
if (entity->is_param) {
4897
processor = prologProcessor;
4898
tok = XmlPrologTok(encoding, s, end, &next);
4899
return doProlog(parser, encoding, s, end, tok, next, nextPtr,
4900
(XML_Bool)!ps_finalBuffer);
4903
#endif /* XML_DTD */
4905
processor = contentProcessor;
4906
/* see externalEntityContentProcessor vs contentProcessor */
4907
return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
4908
nextPtr, (XML_Bool)!ps_finalBuffer);
4912
static enum XML_Error PTRCALL
4913
errorProcessor(XML_Parser parser,
4916
const char **nextPtr)
4921
static enum XML_Error
4922
storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4923
const char *ptr, const char *end,
4926
enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4930
if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4932
if (!poolAppendChar(pool, XML_T('\0')))
4933
return XML_ERROR_NO_MEMORY;
4934
return XML_ERROR_NONE;
4937
static enum XML_Error
4938
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4939
const char *ptr, const char *end,
4942
DTD * const dtd = _dtd; /* save one level of indirection */
4945
int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4948
return XML_ERROR_NONE;
4949
case XML_TOK_INVALID:
4950
if (enc == encoding)
4952
return XML_ERROR_INVALID_TOKEN;
4953
case XML_TOK_PARTIAL:
4954
if (enc == encoding)
4956
return XML_ERROR_INVALID_TOKEN;
4957
case XML_TOK_CHAR_REF:
4959
XML_Char buf[XML_ENCODE_MAX];
4961
int n = XmlCharRefNumber(enc, ptr);
4963
if (enc == encoding)
4965
return XML_ERROR_BAD_CHAR_REF;
4968
&& n == 0x20 /* space */
4969
&& (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4971
n = XmlEncode(n, (ICHAR *)buf);
4973
if (enc == encoding)
4975
return XML_ERROR_BAD_CHAR_REF;
4977
for (i = 0; i < n; i++) {
4978
if (!poolAppendChar(pool, buf[i]))
4979
return XML_ERROR_NO_MEMORY;
4983
case XML_TOK_DATA_CHARS:
4984
if (!poolAppend(pool, enc, ptr, next))
4985
return XML_ERROR_NO_MEMORY;
4987
case XML_TOK_TRAILING_CR:
4988
next = ptr + enc->minBytesPerChar;
4990
case XML_TOK_ATTRIBUTE_VALUE_S:
4991
case XML_TOK_DATA_NEWLINE:
4992
if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4994
if (!poolAppendChar(pool, 0x20))
4995
return XML_ERROR_NO_MEMORY;
4997
case XML_TOK_ENTITY_REF:
4999
const XML_Char *name;
5001
char checkEntityDecl;
5002
XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
5003
ptr + enc->minBytesPerChar,
5004
next - enc->minBytesPerChar);
5006
if (!poolAppendChar(pool, ch))
5007
return XML_ERROR_NO_MEMORY;
5010
name = poolStoreString(&temp2Pool, enc,
5011
ptr + enc->minBytesPerChar,
5012
next - enc->minBytesPerChar);
5014
return XML_ERROR_NO_MEMORY;
5015
entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5016
poolDiscard(&temp2Pool);
5017
/* First, determine if a check for an existing declaration is needed;
5018
if yes, check that the entity exists, and that it is internal.
5020
if (pool == &dtd->pool) /* are we called from prolog? */
5023
prologState.documentEntity &&
5024
#endif /* XML_DTD */
5026
? !openInternalEntities
5027
: !dtd->hasParamEntityRefs);
5028
else /* if (pool == &tempPool): we are called from content */
5029
checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
5030
if (checkEntityDecl) {
5032
return XML_ERROR_UNDEFINED_ENTITY;
5033
else if (!entity->is_internal)
5034
return XML_ERROR_ENTITY_DECLARED_IN_PE;
5037
/* Cannot report skipped entity here - see comments on
5038
skippedEntityHandler.
5039
if (skippedEntityHandler)
5040
skippedEntityHandler(handlerArg, name, 0);
5042
/* Cannot call the default handler because this would be
5043
out of sync with the call to the startElementHandler.
5044
if ((pool == &tempPool) && defaultHandler)
5045
reportDefault(parser, enc, ptr, next);
5050
if (enc == encoding)
5052
return XML_ERROR_RECURSIVE_ENTITY_REF;
5054
if (entity->notation) {
5055
if (enc == encoding)
5057
return XML_ERROR_BINARY_ENTITY_REF;
5059
if (!entity->textPtr) {
5060
if (enc == encoding)
5062
return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5065
enum XML_Error result;
5066
const XML_Char *textEnd = entity->textPtr + entity->textLen;
5067
entity->open = XML_TRUE;
5068
result = appendAttributeValue(parser, internalEncoding, isCdata,
5069
(char *)entity->textPtr,
5070
(char *)textEnd, pool);
5071
entity->open = XML_FALSE;
5078
if (enc == encoding)
5080
return XML_ERROR_UNEXPECTED_STATE;
5087
static enum XML_Error
5088
storeEntityValue(XML_Parser parser,
5089
const ENCODING *enc,
5090
const char *entityTextPtr,
5091
const char *entityTextEnd)
5093
DTD * const dtd = _dtd; /* save one level of indirection */
5094
STRING_POOL *pool = &(dtd->entityValuePool);
5095
enum XML_Error result = XML_ERROR_NONE;
5097
int oldInEntityValue = prologState.inEntityValue;
5098
prologState.inEntityValue = 1;
5099
#endif /* XML_DTD */
5100
/* never return Null for the value argument in EntityDeclHandler,
5101
since this would indicate an external entity; therefore we
5102
have to make sure that entityValuePool.start is not null */
5103
if (!pool->blocks) {
5104
if (!poolGrow(pool))
5105
return XML_ERROR_NO_MEMORY;
5110
int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5112
case XML_TOK_PARAM_ENTITY_REF:
5114
if (isParamEntity || enc != encoding) {
5115
const XML_Char *name;
5117
name = poolStoreString(&tempPool, enc,
5118
entityTextPtr + enc->minBytesPerChar,
5119
next - enc->minBytesPerChar);
5121
result = XML_ERROR_NO_MEMORY;
5122
goto endEntityValue;
5124
entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
5125
poolDiscard(&tempPool);
5127
/* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5128
/* cannot report skipped entity here - see comments on
5129
skippedEntityHandler
5130
if (skippedEntityHandler)
5131
skippedEntityHandler(handlerArg, name, 0);
5133
dtd->keepProcessing = dtd->standalone;
5134
goto endEntityValue;
5137
if (enc == encoding)
5138
eventPtr = entityTextPtr;
5139
result = XML_ERROR_RECURSIVE_ENTITY_REF;
5140
goto endEntityValue;
5142
if (entity->systemId) {
5143
if (externalEntityRefHandler) {
5144
dtd->paramEntityRead = XML_FALSE;
5145
entity->open = XML_TRUE;
5146
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5150
entity->publicId)) {
5151
entity->open = XML_FALSE;
5152
result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5153
goto endEntityValue;
5155
entity->open = XML_FALSE;
5156
if (!dtd->paramEntityRead)
5157
dtd->keepProcessing = dtd->standalone;
5160
dtd->keepProcessing = dtd->standalone;
5163
entity->open = XML_TRUE;
5164
result = storeEntityValue(parser,
5166
(char *)entity->textPtr,
5167
(char *)(entity->textPtr
5168
+ entity->textLen));
5169
entity->open = XML_FALSE;
5171
goto endEntityValue;
5175
#endif /* XML_DTD */
5176
/* In the internal subset, PE references are not legal
5177
within markup declarations, e.g entity values in this case. */
5178
eventPtr = entityTextPtr;
5179
result = XML_ERROR_PARAM_ENTITY_REF;
5180
goto endEntityValue;
5182
result = XML_ERROR_NONE;
5183
goto endEntityValue;
5184
case XML_TOK_ENTITY_REF:
5185
case XML_TOK_DATA_CHARS:
5186
if (!poolAppend(pool, enc, entityTextPtr, next)) {
5187
result = XML_ERROR_NO_MEMORY;
5188
goto endEntityValue;
5191
case XML_TOK_TRAILING_CR:
5192
next = entityTextPtr + enc->minBytesPerChar;
5194
case XML_TOK_DATA_NEWLINE:
5195
if (pool->end == pool->ptr && !poolGrow(pool)) {
5196
result = XML_ERROR_NO_MEMORY;
5197
goto endEntityValue;
5199
*(pool->ptr)++ = 0xA;
5201
case XML_TOK_CHAR_REF:
5203
XML_Char buf[XML_ENCODE_MAX];
5205
int n = XmlCharRefNumber(enc, entityTextPtr);
5207
if (enc == encoding)
5208
eventPtr = entityTextPtr;
5209
result = XML_ERROR_BAD_CHAR_REF;
5210
goto endEntityValue;
5212
n = XmlEncode(n, (ICHAR *)buf);
5214
if (enc == encoding)
5215
eventPtr = entityTextPtr;
5216
result = XML_ERROR_BAD_CHAR_REF;
5217
goto endEntityValue;
5219
for (i = 0; i < n; i++) {
5220
if (pool->end == pool->ptr && !poolGrow(pool)) {
5221
result = XML_ERROR_NO_MEMORY;
5222
goto endEntityValue;
5224
*(pool->ptr)++ = buf[i];
5228
case XML_TOK_PARTIAL:
5229
if (enc == encoding)
5230
eventPtr = entityTextPtr;
5231
result = XML_ERROR_INVALID_TOKEN;
5232
goto endEntityValue;
5233
case XML_TOK_INVALID:
5234
if (enc == encoding)
5236
result = XML_ERROR_INVALID_TOKEN;
5237
goto endEntityValue;
5239
if (enc == encoding)
5240
eventPtr = entityTextPtr;
5241
result = XML_ERROR_UNEXPECTED_STATE;
5242
goto endEntityValue;
5244
entityTextPtr = next;
5248
prologState.inEntityValue = oldInEntityValue;
5249
#endif /* XML_DTD */
5253
static void FASTCALL
5254
normalizeLines(XML_Char *s)
5258
if (*s == XML_T('\0'))
5277
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5278
const char *start, const char *end)
5280
const XML_Char *target;
5283
if (!processingInstructionHandler) {
5285
reportDefault(parser, enc, start, end);
5288
start += enc->minBytesPerChar * 2;
5289
tem = start + XmlNameLength(enc, start);
5290
target = poolStoreString(&tempPool, enc, start, tem);
5293
poolFinish(&tempPool);
5294
data = poolStoreString(&tempPool, enc,
5296
end - enc->minBytesPerChar*2);
5299
normalizeLines(data);
5300
processingInstructionHandler(handlerArg, target, data);
5301
poolClear(&tempPool);
5306
reportComment(XML_Parser parser, const ENCODING *enc,
5307
const char *start, const char *end)
5310
if (!commentHandler) {
5312
reportDefault(parser, enc, start, end);
5315
data = poolStoreString(&tempPool,
5317
start + enc->minBytesPerChar * 4,
5318
end - enc->minBytesPerChar * 3);
5321
normalizeLines(data);
5322
commentHandler(handlerArg, data);
5323
poolClear(&tempPool);
5328
reportDefault(XML_Parser parser, const ENCODING *enc,
5329
const char *s, const char *end)
5331
if (MUST_CONVERT(enc, s)) {
5332
const char **eventPP;
5333
const char **eventEndPP;
5334
if (enc == encoding) {
5335
eventPP = &eventPtr;
5336
eventEndPP = &eventEndPtr;
5339
eventPP = &(openInternalEntities->internalEventPtr);
5340
eventEndPP = &(openInternalEntities->internalEventEndPtr);
5343
ICHAR *dataPtr = (ICHAR *)dataBuf;
5344
XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5346
defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
5351
defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5356
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5357
XML_Bool isId, const XML_Char *value, XML_Parser parser)
5359
DEFAULT_ATTRIBUTE *att;
5360
if (value || isId) {
5361
/* The handling of default attributes gets messed up if we have
5362
a default which duplicates a non-default. */
5364
for (i = 0; i < type->nDefaultAtts; i++)
5365
if (attId == type->defaultAtts[i].id)
5367
if (isId && !type->idAtt && !attId->xmlns)
5368
type->idAtt = attId;
5370
if (type->nDefaultAtts == type->allocDefaultAtts) {
5371
if (type->allocDefaultAtts == 0) {
5372
type->allocDefaultAtts = 8;
5373
type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
5374
* sizeof(DEFAULT_ATTRIBUTE));
5375
if (!type->defaultAtts)
5379
DEFAULT_ATTRIBUTE *temp;
5380
int count = type->allocDefaultAtts * 2;
5381
temp = (DEFAULT_ATTRIBUTE *)
5382
REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5385
type->allocDefaultAtts = count;
5386
type->defaultAtts = temp;
5389
att = type->defaultAtts + type->nDefaultAtts;
5392
att->isCdata = isCdata;
5394
attId->maybeTokenized = XML_TRUE;
5395
type->nDefaultAtts += 1;
5400
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
5402
DTD * const dtd = _dtd; /* save one level of indirection */
5403
const XML_Char *name;
5404
for (name = elementType->name; *name; name++) {
5405
if (*name == XML_T(ASCII_COLON)) {
5408
for (s = elementType->name; s != name; s++) {
5409
if (!poolAppendChar(&dtd->pool, *s))
5412
if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5414
prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5418
if (prefix->name == poolStart(&dtd->pool))
5419
poolFinish(&dtd->pool);
5421
poolDiscard(&dtd->pool);
5422
elementType->prefix = prefix;
5429
static ATTRIBUTE_ID *
5430
getAttributeId(XML_Parser parser, const ENCODING *enc,
5431
const char *start, const char *end)
5433
DTD * const dtd = _dtd; /* save one level of indirection */
5435
const XML_Char *name;
5436
if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5438
name = poolStoreString(&dtd->pool, enc, start, end);
5441
/* skip quotation mark - its storage will be re-used (like in name[-1]) */
5443
id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
5446
if (id->name != name)
5447
poolDiscard(&dtd->pool);
5449
poolFinish(&dtd->pool);
5452
else if (name[0] == XML_T(ASCII_x)
5453
&& name[1] == XML_T(ASCII_m)
5454
&& name[2] == XML_T(ASCII_l)
5455
&& name[3] == XML_T(ASCII_n)
5456
&& name[4] == XML_T(ASCII_s)
5457
&& (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
5458
if (name[5] == XML_T('\0'))
5459
id->prefix = &dtd->defaultPrefix;
5461
id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
5462
id->xmlns = XML_TRUE;
5466
for (i = 0; name[i]; i++) {
5467
/* attributes without prefix are *not* in the default namespace */
5468
if (name[i] == XML_T(ASCII_COLON)) {
5470
for (j = 0; j < i; j++) {
5471
if (!poolAppendChar(&dtd->pool, name[j]))
5474
if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5476
id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5478
if (id->prefix->name == poolStart(&dtd->pool))
5479
poolFinish(&dtd->pool);
5481
poolDiscard(&dtd->pool);
5490
#define CONTEXT_SEP XML_T(ASCII_FF)
5492
static const XML_Char *
5493
getContext(XML_Parser parser)
5495
DTD * const dtd = _dtd; /* save one level of indirection */
5496
HASH_TABLE_ITER iter;
5497
XML_Bool needSep = XML_FALSE;
5499
if (dtd->defaultPrefix.binding) {
5502
if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5504
len = dtd->defaultPrefix.binding->uriLen;
5505
if (namespaceSeparator)
5507
for (i = 0; i < len; i++)
5508
if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5513
hashTableIterInit(&iter, &(dtd->prefixes));
5518
PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5521
if (!prefix->binding)
5523
if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5525
for (s = prefix->name; *s; s++)
5526
if (!poolAppendChar(&tempPool, *s))
5528
if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5530
len = prefix->binding->uriLen;
5531
if (namespaceSeparator)
5533
for (i = 0; i < len; i++)
5534
if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
5540
hashTableIterInit(&iter, &(dtd->generalEntities));
5543
ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5548
if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5550
for (s = e->name; *s; s++)
5551
if (!poolAppendChar(&tempPool, *s))
5556
if (!poolAppendChar(&tempPool, XML_T('\0')))
5558
return tempPool.start;
5562
setContext(XML_Parser parser, const XML_Char *context)
5564
DTD * const dtd = _dtd; /* save one level of indirection */
5565
const XML_Char *s = context;
5567
while (*context != XML_T('\0')) {
5568
if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5570
if (!poolAppendChar(&tempPool, XML_T('\0')))
5572
e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
5575
if (*s != XML_T('\0'))
5578
poolDiscard(&tempPool);
5580
else if (*s == XML_T(ASCII_EQUALS)) {
5582
if (poolLength(&tempPool) == 0)
5583
prefix = &dtd->defaultPrefix;
5585
if (!poolAppendChar(&tempPool, XML_T('\0')))
5587
prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
5591
if (prefix->name == poolStart(&tempPool)) {
5592
prefix->name = poolCopyString(&dtd->pool, prefix->name);
5596
poolDiscard(&tempPool);
5598
for (context = s + 1;
5599
*context != CONTEXT_SEP && *context != XML_T('\0');
5601
if (!poolAppendChar(&tempPool, *context))
5603
if (!poolAppendChar(&tempPool, XML_T('\0')))
5605
if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
5606
&inheritedBindings) != XML_ERROR_NONE)
5608
poolDiscard(&tempPool);
5609
if (*context != XML_T('\0'))
5614
if (!poolAppendChar(&tempPool, *s))
5622
static void FASTCALL
5623
normalizePublicId(XML_Char *publicId)
5625
XML_Char *p = publicId;
5627
for (s = publicId; *s; s++) {
5632
if (p != publicId && p[-1] != 0x20)
5639
if (p != publicId && p[-1] == 0x20)
5645
dtdCreate(const XML_Memory_Handling_Suite *ms)
5647
DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5650
poolInit(&(p->pool), ms);
5651
poolInit(&(p->entityValuePool), ms);
5652
hashTableInit(&(p->generalEntities), ms);
5653
hashTableInit(&(p->elementTypes), ms);
5654
hashTableInit(&(p->attributeIds), ms);
5655
hashTableInit(&(p->prefixes), ms);
5657
p->paramEntityRead = XML_FALSE;
5658
hashTableInit(&(p->paramEntities), ms);
5659
#endif /* XML_DTD */
5660
p->defaultPrefix.name = NULL;
5661
p->defaultPrefix.binding = NULL;
5663
p->in_eldecl = XML_FALSE;
5664
p->scaffIndex = NULL;
5669
p->contentStringLen = 0;
5671
p->keepProcessing = XML_TRUE;
5672
p->hasParamEntityRefs = XML_FALSE;
5673
p->standalone = XML_FALSE;
5678
dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
5680
HASH_TABLE_ITER iter;
5681
hashTableIterInit(&iter, &(p->elementTypes));
5683
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5686
if (e->allocDefaultAtts != 0)
5687
ms->free_fcn(e->defaultAtts);
5689
hashTableClear(&(p->generalEntities));
5691
p->paramEntityRead = XML_FALSE;
5692
hashTableClear(&(p->paramEntities));
5693
#endif /* XML_DTD */
5694
hashTableClear(&(p->elementTypes));
5695
hashTableClear(&(p->attributeIds));
5696
hashTableClear(&(p->prefixes));
5697
poolClear(&(p->pool));
5698
poolClear(&(p->entityValuePool));
5699
p->defaultPrefix.name = NULL;
5700
p->defaultPrefix.binding = NULL;
5702
p->in_eldecl = XML_FALSE;
5704
ms->free_fcn(p->scaffIndex);
5705
p->scaffIndex = NULL;
5706
ms->free_fcn(p->scaffold);
5712
p->contentStringLen = 0;
5714
p->keepProcessing = XML_TRUE;
5715
p->hasParamEntityRefs = XML_FALSE;
5716
p->standalone = XML_FALSE;
5720
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5722
HASH_TABLE_ITER iter;
5723
hashTableIterInit(&iter, &(p->elementTypes));
5725
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5728
if (e->allocDefaultAtts != 0)
5729
ms->free_fcn(e->defaultAtts);
5731
hashTableDestroy(&(p->generalEntities));
5733
hashTableDestroy(&(p->paramEntities));
5734
#endif /* XML_DTD */
5735
hashTableDestroy(&(p->elementTypes));
5736
hashTableDestroy(&(p->attributeIds));
5737
hashTableDestroy(&(p->prefixes));
5738
poolDestroy(&(p->pool));
5739
poolDestroy(&(p->entityValuePool));
5741
ms->free_fcn(p->scaffIndex);
5742
ms->free_fcn(p->scaffold);
5747
/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5748
The new DTD has already been initialized.
5751
dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5753
HASH_TABLE_ITER iter;
5755
/* Copy the prefix table. */
5757
hashTableIterInit(&iter, &(oldDtd->prefixes));
5759
const XML_Char *name;
5760
const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5763
name = poolCopyString(&(newDtd->pool), oldP->name);
5766
if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
5770
hashTableIterInit(&iter, &(oldDtd->attributeIds));
5772
/* Copy the attribute id table. */
5776
const XML_Char *name;
5777
const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5781
/* Remember to allocate the scratch byte before the name. */
5782
if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5784
name = poolCopyString(&(newDtd->pool), oldA->name);
5788
newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
5789
sizeof(ATTRIBUTE_ID));
5792
newA->maybeTokenized = oldA->maybeTokenized;
5794
newA->xmlns = oldA->xmlns;
5795
if (oldA->prefix == &oldDtd->defaultPrefix)
5796
newA->prefix = &newDtd->defaultPrefix;
5798
newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
5799
oldA->prefix->name, 0);
5803
/* Copy the element type table. */
5805
hashTableIterInit(&iter, &(oldDtd->elementTypes));
5810
const XML_Char *name;
5811
const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5814
name = poolCopyString(&(newDtd->pool), oldE->name);
5817
newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
5818
sizeof(ELEMENT_TYPE));
5821
if (oldE->nDefaultAtts) {
5822
newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5823
ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5824
if (!newE->defaultAtts) {
5830
newE->idAtt = (ATTRIBUTE_ID *)
5831
lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
5832
newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5834
newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
5835
oldE->prefix->name, 0);
5836
for (i = 0; i < newE->nDefaultAtts; i++) {
5837
newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5838
lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5839
newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5840
if (oldE->defaultAtts[i].value) {
5841
newE->defaultAtts[i].value
5842
= poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5843
if (!newE->defaultAtts[i].value)
5847
newE->defaultAtts[i].value = NULL;
5851
/* Copy the entity tables. */
5852
if (!copyEntityTable(oldParser,
5853
&(newDtd->generalEntities),
5855
&(oldDtd->generalEntities)))
5859
if (!copyEntityTable(oldParser,
5860
&(newDtd->paramEntities),
5862
&(oldDtd->paramEntities)))
5864
newDtd->paramEntityRead = oldDtd->paramEntityRead;
5865
#endif /* XML_DTD */
5867
newDtd->keepProcessing = oldDtd->keepProcessing;
5868
newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5869
newDtd->standalone = oldDtd->standalone;
5871
/* Don't want deep copying for scaffolding */
5872
newDtd->in_eldecl = oldDtd->in_eldecl;
5873
newDtd->scaffold = oldDtd->scaffold;
5874
newDtd->contentStringLen = oldDtd->contentStringLen;
5875
newDtd->scaffSize = oldDtd->scaffSize;
5876
newDtd->scaffLevel = oldDtd->scaffLevel;
5877
newDtd->scaffIndex = oldDtd->scaffIndex;
5883
copyEntityTable(XML_Parser oldParser,
5884
HASH_TABLE *newTable,
5885
STRING_POOL *newPool,
5886
const HASH_TABLE *oldTable)
5888
HASH_TABLE_ITER iter;
5889
const XML_Char *cachedOldBase = NULL;
5890
const XML_Char *cachedNewBase = NULL;
5892
hashTableIterInit(&iter, oldTable);
5896
const XML_Char *name;
5897
const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5900
name = poolCopyString(newPool, oldE->name);
5903
newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
5906
if (oldE->systemId) {
5907
const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5910
newE->systemId = tem;
5912
if (oldE->base == cachedOldBase)
5913
newE->base = cachedNewBase;
5915
cachedOldBase = oldE->base;
5916
tem = poolCopyString(newPool, cachedOldBase);
5919
cachedNewBase = newE->base = tem;
5922
if (oldE->publicId) {
5923
tem = poolCopyString(newPool, oldE->publicId);
5926
newE->publicId = tem;
5930
const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5934
newE->textPtr = tem;
5935
newE->textLen = oldE->textLen;
5937
if (oldE->notation) {
5938
const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5941
newE->notation = tem;
5943
newE->is_param = oldE->is_param;
5944
newE->is_internal = oldE->is_internal;
5949
#define INIT_POWER 6
5951
static XML_Bool FASTCALL
5952
keyeq(KEY s1, KEY s2)
5954
for (; *s1 == *s2; s1++, s2++)
5960
static unsigned long FASTCALL
5961
hash(XML_Parser parser, KEY s)
5963
unsigned long h = hash_secret_salt;
5965
h = CHAR_HASH(h, *s++);
5970
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
5973
if (table->size == 0) {
5977
table->power = INIT_POWER;
5978
/* table->size is a power of 2 */
5979
table->size = (size_t)1 << INIT_POWER;
5980
tsize = table->size * sizeof(NAMED *);
5981
table->v = (NAMED **)table->mem->malloc_fcn(tsize);
5986
memset(table->v, 0, tsize);
5987
i = hash(parser, name) & ((unsigned long)table->size - 1);
5990
unsigned long h = hash(parser, name);
5991
unsigned long mask = (unsigned long)table->size - 1;
5992
unsigned char step = 0;
5994
while (table->v[i]) {
5995
if (keyeq(name, table->v[i]->name))
5998
step = PROBE_STEP(h, mask, table->power);
5999
i < step ? (i += table->size - step) : (i -= step);
6004
/* check for overflow (table is half full) */
6005
if (table->used >> (table->power - 1)) {
6006
unsigned char newPower = table->power + 1;
6007
size_t newSize = (size_t)1 << newPower;
6008
unsigned long newMask = (unsigned long)newSize - 1;
6009
size_t tsize = newSize * sizeof(NAMED *);
6010
NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
6013
memset(newV, 0, tsize);
6014
for (i = 0; i < table->size; i++)
6016
unsigned long newHash = hash(parser, table->v[i]->name);
6017
size_t j = newHash & newMask;
6021
step = PROBE_STEP(newHash, newMask, newPower);
6022
j < step ? (j += newSize - step) : (j -= step);
6024
newV[j] = table->v[i];
6026
table->mem->free_fcn(table->v);
6028
table->power = newPower;
6029
table->size = newSize;
6032
while (table->v[i]) {
6034
step = PROBE_STEP(h, newMask, newPower);
6035
i < step ? (i += newSize - step) : (i -= step);
6039
table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
6042
memset(table->v[i], 0, createSize);
6043
table->v[i]->name = name;
6048
static void FASTCALL
6049
hashTableClear(HASH_TABLE *table)
6052
for (i = 0; i < table->size; i++) {
6053
table->mem->free_fcn(table->v[i]);
6059
static void FASTCALL
6060
hashTableDestroy(HASH_TABLE *table)
6063
for (i = 0; i < table->size; i++)
6064
table->mem->free_fcn(table->v[i]);
6065
table->mem->free_fcn(table->v);
6068
static void FASTCALL
6069
hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
6078
static void FASTCALL
6079
hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
6082
iter->end = iter->p + table->size;
6085
static NAMED * FASTCALL
6086
hashTableIterNext(HASH_TABLE_ITER *iter)
6088
while (iter->p != iter->end) {
6089
NAMED *tem = *(iter->p)++;
6096
static void FASTCALL
6097
poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
6099
pool->blocks = NULL;
6100
pool->freeBlocks = NULL;
6107
static void FASTCALL
6108
poolClear(STRING_POOL *pool)
6110
if (!pool->freeBlocks)
6111
pool->freeBlocks = pool->blocks;
6113
BLOCK *p = pool->blocks;
6115
BLOCK *tem = p->next;
6116
p->next = pool->freeBlocks;
6117
pool->freeBlocks = p;
6121
pool->blocks = NULL;
6127
static void FASTCALL
6128
poolDestroy(STRING_POOL *pool)
6130
BLOCK *p = pool->blocks;
6132
BLOCK *tem = p->next;
6133
pool->mem->free_fcn(p);
6136
p = pool->freeBlocks;
6138
BLOCK *tem = p->next;
6139
pool->mem->free_fcn(p);
6145
poolAppend(STRING_POOL *pool, const ENCODING *enc,
6146
const char *ptr, const char *end)
6148
if (!pool->ptr && !poolGrow(pool))
6151
XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6154
if (!poolGrow(pool))
6160
static const XML_Char * FASTCALL
6161
poolCopyString(STRING_POOL *pool, const XML_Char *s)
6164
if (!poolAppendChar(pool, *s))
6172
static const XML_Char *
6173
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
6175
if (!pool->ptr && !poolGrow(pool))
6177
for (; n > 0; --n, s++) {
6178
if (!poolAppendChar(pool, *s))
6186
static const XML_Char * FASTCALL
6187
poolAppendString(STRING_POOL *pool, const XML_Char *s)
6190
if (!poolAppendChar(pool, *s))
6198
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6199
const char *ptr, const char *end)
6201
if (!poolAppend(pool, enc, ptr, end))
6203
if (pool->ptr == pool->end && !poolGrow(pool))
6209
static XML_Bool FASTCALL
6210
poolGrow(STRING_POOL *pool)
6212
if (pool->freeBlocks) {
6213
if (pool->start == 0) {
6214
pool->blocks = pool->freeBlocks;
6215
pool->freeBlocks = pool->freeBlocks->next;
6216
pool->blocks->next = NULL;
6217
pool->start = pool->blocks->s;
6218
pool->end = pool->start + pool->blocks->size;
6219
pool->ptr = pool->start;
6222
if (pool->end - pool->start < pool->freeBlocks->size) {
6223
BLOCK *tem = pool->freeBlocks->next;
6224
pool->freeBlocks->next = pool->blocks;
6225
pool->blocks = pool->freeBlocks;
6226
pool->freeBlocks = tem;
6227
memcpy(pool->blocks->s, pool->start,
6228
(pool->end - pool->start) * sizeof(XML_Char));
6229
pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6230
pool->start = pool->blocks->s;
6231
pool->end = pool->start + pool->blocks->size;
6235
if (pool->blocks && pool->start == pool->blocks->s) {
6236
int blockSize = (int)(pool->end - pool->start)*2;
6237
BLOCK *temp = (BLOCK *)
6238
pool->mem->realloc_fcn(pool->blocks,
6240
+ blockSize * sizeof(XML_Char)));
6243
pool->blocks = temp;
6244
pool->blocks->size = blockSize;
6245
pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6246
pool->start = pool->blocks->s;
6247
pool->end = pool->start + blockSize;
6251
int blockSize = (int)(pool->end - pool->start);
6252
if (blockSize < INIT_BLOCK_SIZE)
6253
blockSize = INIT_BLOCK_SIZE;
6256
tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
6257
+ blockSize * sizeof(XML_Char));
6260
tem->size = blockSize;
6261
tem->next = pool->blocks;
6263
if (pool->ptr != pool->start)
6264
memcpy(tem->s, pool->start,
6265
(pool->ptr - pool->start) * sizeof(XML_Char));
6266
pool->ptr = tem->s + (pool->ptr - pool->start);
6267
pool->start = tem->s;
6268
pool->end = tem->s + blockSize;
6274
nextScaffoldPart(XML_Parser parser)
6276
DTD * const dtd = _dtd; /* save one level of indirection */
6277
CONTENT_SCAFFOLD * me;
6280
if (!dtd->scaffIndex) {
6281
dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6282
if (!dtd->scaffIndex)
6284
dtd->scaffIndex[0] = 0;
6287
if (dtd->scaffCount >= dtd->scaffSize) {
6288
CONTENT_SCAFFOLD *temp;
6289
if (dtd->scaffold) {
6290
temp = (CONTENT_SCAFFOLD *)
6291
REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6294
dtd->scaffSize *= 2;
6297
temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6298
* sizeof(CONTENT_SCAFFOLD));
6301
dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6303
dtd->scaffold = temp;
6305
next = dtd->scaffCount++;
6306
me = &dtd->scaffold[next];
6307
if (dtd->scaffLevel) {
6308
CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
6309
if (parent->lastchild) {
6310
dtd->scaffold[parent->lastchild].nextsib = next;
6312
if (!parent->childcnt)
6313
parent->firstchild = next;
6314
parent->lastchild = next;
6317
me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6322
build_node(XML_Parser parser,
6325
XML_Content **contpos,
6328
DTD * const dtd = _dtd; /* save one level of indirection */
6329
dest->type = dtd->scaffold[src_node].type;
6330
dest->quant = dtd->scaffold[src_node].quant;
6331
if (dest->type == XML_CTYPE_NAME) {
6332
const XML_Char *src;
6333
dest->name = *strpos;
6334
src = dtd->scaffold[src_node].name;
6336
*(*strpos)++ = *src;
6341
dest->numchildren = 0;
6342
dest->children = NULL;
6347
dest->numchildren = dtd->scaffold[src_node].childcnt;
6348
dest->children = *contpos;
6349
*contpos += dest->numchildren;
6350
for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6351
i < dest->numchildren;
6352
i++, cn = dtd->scaffold[cn].nextsib) {
6353
build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6359
static XML_Content *
6360
build_model (XML_Parser parser)
6362
DTD * const dtd = _dtd; /* save one level of indirection */
6366
int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6367
+ (dtd->contentStringLen * sizeof(XML_Char)));
6369
ret = (XML_Content *)MALLOC(allocsize);
6373
str = (XML_Char *) (&ret[dtd->scaffCount]);
6376
build_node(parser, 0, ret, &cpos, &str);
6380
static ELEMENT_TYPE *
6381
getElementType(XML_Parser parser,
6382
const ENCODING *enc,
6386
DTD * const dtd = _dtd; /* save one level of indirection */
6387
const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6392
ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6395
if (ret->name != name)
6396
poolDiscard(&dtd->pool);
6398
poolFinish(&dtd->pool);
6399
if (!setElementTypePrefix(parser, ret))