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 /* BEGIN MOZILLA CHANGE (sanity check len) */
1683 errorCode
= XML_ERROR_NO_MEMORY
;
1686 /* END MOZILLA CHANGE */
1687 switch (ps_parsing
) {
1689 errorCode
= XML_ERROR_SUSPENDED
;
1692 errorCode
= XML_ERROR_FINISHED
;
1697 if (len
> bufferLim
- bufferEnd
) {
1698 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1699 /* BEGIN MOZILLA CHANGE (sanity check neededSize) */
1700 if (neededSize
< 0) {
1701 errorCode
= XML_ERROR_NO_MEMORY
;
1704 /* END MOZILLA CHANGE */
1705 #ifdef XML_CONTEXT_BYTES
1706 int keep
= (int)(bufferPtr
- buffer
);
1708 if (keep
> XML_CONTEXT_BYTES
)
1709 keep
= XML_CONTEXT_BYTES
;
1711 #endif /* defined XML_CONTEXT_BYTES */
1712 if (neededSize
<= bufferLim
- buffer
) {
1713 #ifdef XML_CONTEXT_BYTES
1714 if (keep
< bufferPtr
- buffer
) {
1715 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1716 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1717 bufferEnd
-= offset
;
1718 bufferPtr
-= offset
;
1721 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1722 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1724 #endif /* not defined XML_CONTEXT_BYTES */
1728 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1729 if (bufferSize
== 0)
1730 bufferSize
= INIT_BUFFER_SIZE
;
1733 /* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */
1734 } while (bufferSize
< neededSize
&& bufferSize
> 0);
1735 /* END MOZILLA CHANGE */
1736 /* BEGIN MOZILLA CHANGE (sanity check bufferSize) */
1737 if (bufferSize
<= 0) {
1738 errorCode
= XML_ERROR_NO_MEMORY
;
1741 /* END MOZILLA CHANGE */
1742 newBuf
= (char *)MALLOC(bufferSize
);
1744 errorCode
= XML_ERROR_NO_MEMORY
;
1747 bufferLim
= newBuf
+ bufferSize
;
1748 #ifdef XML_CONTEXT_BYTES
1750 int keep
= (int)(bufferPtr
- buffer
);
1751 if (keep
> XML_CONTEXT_BYTES
)
1752 keep
= XML_CONTEXT_BYTES
;
1753 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1756 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1757 bufferPtr
= buffer
+ keep
;
1760 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1761 bufferPtr
= buffer
= newBuf
;
1765 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1768 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1769 bufferPtr
= buffer
= newBuf
;
1770 #endif /* not defined XML_CONTEXT_BYTES */
1772 eventPtr
= eventEndPtr
= NULL
;
1778 enum XML_Status XMLCALL
1779 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1781 switch (ps_parsing
) {
1784 errorCode
= XML_ERROR_SUSPENDED
;
1785 return XML_STATUS_ERROR
;
1787 ps_parsing
= XML_FINISHED
;
1790 errorCode
= XML_ERROR_FINISHED
;
1791 return XML_STATUS_ERROR
;
1795 if (isParamEntity
) {
1796 errorCode
= XML_ERROR_SUSPEND_PE
;
1797 return XML_STATUS_ERROR
;
1800 ps_parsing
= XML_SUSPENDED
;
1803 ps_parsing
= XML_FINISHED
;
1805 return XML_STATUS_OK
;
1808 enum XML_Status XMLCALL
1809 XML_ResumeParser(XML_Parser parser
)
1811 enum XML_Status result
= XML_STATUS_OK
;
1813 if (ps_parsing
!= XML_SUSPENDED
) {
1814 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1815 return XML_STATUS_ERROR
;
1817 ps_parsing
= XML_PARSING
;
1819 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1821 if (errorCode
!= XML_ERROR_NONE
) {
1822 eventEndPtr
= eventPtr
;
1823 processor
= errorProcessor
;
1824 return XML_STATUS_ERROR
;
1827 switch (ps_parsing
) {
1829 result
= XML_STATUS_SUSPENDED
;
1831 case XML_INITIALIZED
:
1833 if (ps_finalBuffer
) {
1834 ps_parsing
= XML_FINISHED
;
1841 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1842 positionPtr
= bufferPtr
;
1847 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1849 assert(status
!= NULL
);
1850 *status
= parser
->m_parsingStatus
;
1853 enum XML_Error XMLCALL
1854 XML_GetErrorCode(XML_Parser parser
)
1860 XML_GetCurrentByteIndex(XML_Parser parser
)
1863 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1868 XML_GetCurrentByteCount(XML_Parser parser
)
1870 if (eventEndPtr
&& eventPtr
)
1871 return (int)(eventEndPtr
- eventPtr
);
1875 const char * XMLCALL
1876 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1878 #ifdef XML_CONTEXT_BYTES
1879 if (eventPtr
&& buffer
) {
1880 *offset
= (int)(eventPtr
- buffer
);
1881 *size
= (int)(bufferEnd
- buffer
);
1884 #endif /* defined XML_CONTEXT_BYTES */
1889 XML_GetCurrentLineNumber(XML_Parser parser
)
1891 if (eventPtr
&& eventPtr
>= positionPtr
) {
1892 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1893 positionPtr
= eventPtr
;
1895 return position
.lineNumber
+ 1;
1899 XML_GetCurrentColumnNumber(XML_Parser parser
)
1901 if (eventPtr
&& eventPtr
>= positionPtr
) {
1902 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1903 positionPtr
= eventPtr
;
1905 return position
.columnNumber
;
1909 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1915 XML_MemMalloc(XML_Parser parser
, size_t size
)
1917 return MALLOC(size
);
1921 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1923 return REALLOC(ptr
, size
);
1927 XML_MemFree(XML_Parser parser
, void *ptr
)
1933 XML_DefaultCurrent(XML_Parser parser
)
1935 if (defaultHandler
) {
1936 if (openInternalEntities
)
1937 reportDefault(parser
,
1939 openInternalEntities
->internalEventPtr
,
1940 openInternalEntities
->internalEventEndPtr
);
1942 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1946 const XML_LChar
* XMLCALL
1947 XML_ErrorString(enum XML_Error code
)
1949 static const XML_LChar
* const message
[] = {
1951 XML_L("out of memory"),
1952 XML_L("syntax error"),
1953 XML_L("no element found"),
1954 XML_L("not well-formed (invalid token)"),
1955 XML_L("unclosed token"),
1956 XML_L("partial character"),
1957 XML_L("mismatched tag"),
1958 XML_L("duplicate attribute"),
1959 XML_L("junk after document element"),
1960 XML_L("illegal parameter entity reference"),
1961 XML_L("undefined entity"),
1962 XML_L("recursive entity reference"),
1963 XML_L("asynchronous entity"),
1964 XML_L("reference to invalid character number"),
1965 XML_L("reference to binary entity"),
1966 XML_L("reference to external entity in attribute"),
1967 XML_L("XML or text declaration not at start of entity"),
1968 XML_L("unknown encoding"),
1969 XML_L("encoding specified in XML declaration is incorrect"),
1970 XML_L("unclosed CDATA section"),
1971 XML_L("error in processing external entity reference"),
1972 XML_L("document is not standalone"),
1973 XML_L("unexpected parser state - please send a bug report"),
1974 XML_L("entity declared in parameter entity"),
1975 XML_L("requested feature requires XML_DTD support in Expat"),
1976 XML_L("cannot change setting once parsing has begun"),
1977 XML_L("unbound prefix"),
1978 XML_L("must not undeclare prefix"),
1979 XML_L("incomplete markup in parameter entity"),
1980 XML_L("XML declaration not well-formed"),
1981 XML_L("text declaration not well-formed"),
1982 XML_L("illegal character(s) in public id"),
1983 XML_L("parser suspended"),
1984 XML_L("parser not suspended"),
1985 XML_L("parsing aborted"),
1986 XML_L("parsing finished"),
1987 XML_L("cannot suspend in external parameter entity"),
1988 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1989 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1990 XML_L("prefix must not be bound to one of the reserved namespace names")
1992 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1993 return message
[code
];
1997 const XML_LChar
* XMLCALL
1998 XML_ExpatVersion(void) {
2000 /* V1 is used to string-ize the version number. However, it would
2001 string-ize the actual version macro *names* unless we get them
2002 substituted before being passed to V1. CPP is defined to expand
2003 a macro, then rescan for more expansions. Thus, we use V2 to expand
2004 the version macros, then CPP will expand the resulting V1() macro
2005 with the correct numerals. */
2006 /* ### I'm assuming cpp is portable in this respect... */
2008 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
2009 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
2011 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
2017 XML_Expat_Version XMLCALL
2018 XML_ExpatVersionInfo(void)
2020 XML_Expat_Version version
;
2022 version
.major
= XML_MAJOR_VERSION
;
2023 version
.minor
= XML_MINOR_VERSION
;
2024 version
.micro
= XML_MICRO_VERSION
;
2029 const XML_Feature
* XMLCALL
2030 XML_GetFeatureList(void)
2032 static const XML_Feature features
[] = {
2033 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
2035 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
2038 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
2040 #ifdef XML_UNICODE_WCHAR_T
2041 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
2044 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
2046 #ifdef XML_CONTEXT_BYTES
2047 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
2051 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
2054 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
2056 #ifdef XML_LARGE_SIZE
2057 {XML_FEATURE_LARGE_SIZE
, XML_L("XML_LARGE_SIZE"), 0},
2059 #ifdef XML_ATTR_INFO
2060 {XML_FEATURE_ATTR_INFO
, XML_L("XML_ATTR_INFO"), 0},
2062 {XML_FEATURE_END
, NULL
, 0}
2068 /* Initially tag->rawName always points into the parse buffer;
2069 for those TAG instances opened while the current parse buffer was
2070 processed, and not yet closed, we need to store tag->rawName in a more
2071 permanent location, since the parse buffer is about to be discarded.
2074 storeRawNames(XML_Parser parser
)
2076 TAG
*tag
= tagStack
;
2079 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
2080 char *rawNameBuf
= tag
->buf
+ nameLen
;
2081 /* Stop if already stored. Since tagStack is a stack, we can stop
2082 at the first entry that has already been copied; everything
2083 below it in the stack is already been accounted for in a
2084 previous call to this function.
2086 if (tag
->rawName
== rawNameBuf
)
2088 /* For re-use purposes we need to ensure that the
2089 size of tag->buf is a multiple of sizeof(XML_Char).
2091 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
2092 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
2093 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2096 /* if tag->name.str points to tag->buf (only when namespace
2097 processing is off) then we have to update it
2099 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
2100 tag
->name
.str
= (XML_Char
*)temp
;
2101 /* if tag->name.localPart is set (when namespace processing is on)
2102 then update it as well, since it will always point into tag->buf
2104 if (tag
->name
.localPart
)
2105 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
2106 (XML_Char
*)tag
->buf
);
2108 tag
->bufEnd
= temp
+ bufSize
;
2109 rawNameBuf
= temp
+ nameLen
;
2111 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2112 tag
->rawName
= rawNameBuf
;
2118 static enum XML_Error PTRCALL
2119 contentProcessor(XML_Parser parser
,
2122 const char **endPtr
)
2124 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2125 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2126 if (result
== XML_ERROR_NONE
) {
2127 if (!storeRawNames(parser
))
2128 return XML_ERROR_NO_MEMORY
;
2133 static enum XML_Error PTRCALL
2134 externalEntityInitProcessor(XML_Parser parser
,
2137 const char **endPtr
)
2139 enum XML_Error result
= initializeEncoding(parser
);
2140 if (result
!= XML_ERROR_NONE
)
2142 processor
= externalEntityInitProcessor2
;
2143 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2146 static enum XML_Error PTRCALL
2147 externalEntityInitProcessor2(XML_Parser parser
,
2150 const char **endPtr
)
2152 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2153 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2156 /* If we are at the end of the buffer, this would cause the next stage,
2157 i.e. externalEntityInitProcessor3, to pass control directly to
2158 doContent (by detecting XML_TOK_NONE) without processing any xml text
2159 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2161 if (next
== end
&& !ps_finalBuffer
) {
2163 return XML_ERROR_NONE
;
2167 case XML_TOK_PARTIAL
:
2168 if (!ps_finalBuffer
) {
2170 return XML_ERROR_NONE
;
2173 return XML_ERROR_UNCLOSED_TOKEN
;
2174 case XML_TOK_PARTIAL_CHAR
:
2175 if (!ps_finalBuffer
) {
2177 return XML_ERROR_NONE
;
2180 return XML_ERROR_PARTIAL_CHAR
;
2182 processor
= externalEntityInitProcessor3
;
2183 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2186 static enum XML_Error PTRCALL
2187 externalEntityInitProcessor3(XML_Parser parser
,
2190 const char **endPtr
)
2193 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2195 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2199 case XML_TOK_XML_DECL
:
2201 enum XML_Error result
;
2202 result
= processXmlDecl(parser
, 1, start
, next
);
2203 if (result
!= XML_ERROR_NONE
)
2205 switch (ps_parsing
) {
2208 return XML_ERROR_NONE
;
2210 return XML_ERROR_ABORTED
;
2216 case XML_TOK_PARTIAL
:
2217 if (!ps_finalBuffer
) {
2219 return XML_ERROR_NONE
;
2221 return XML_ERROR_UNCLOSED_TOKEN
;
2222 case XML_TOK_PARTIAL_CHAR
:
2223 if (!ps_finalBuffer
) {
2225 return XML_ERROR_NONE
;
2227 return XML_ERROR_PARTIAL_CHAR
;
2229 processor
= externalEntityContentProcessor
;
2231 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2234 static enum XML_Error PTRCALL
2235 externalEntityContentProcessor(XML_Parser parser
,
2238 const char **endPtr
)
2240 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2241 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2242 if (result
== XML_ERROR_NONE
) {
2243 if (!storeRawNames(parser
))
2244 return XML_ERROR_NO_MEMORY
;
2249 static enum XML_Error
2250 doContent(XML_Parser parser
,
2252 const ENCODING
*enc
,
2255 const char **nextPtr
,
2258 /* save one level of indirection */
2259 DTD
* const dtd
= _dtd
;
2261 const char **eventPP
;
2262 const char **eventEndPP
;
2263 if (enc
== encoding
) {
2264 eventPP
= &eventPtr
;
2265 eventEndPP
= &eventEndPtr
;
2268 eventPP
= &(openInternalEntities
->internalEventPtr
);
2269 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2274 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2275 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2278 case XML_TOK_TRAILING_CR
:
2281 return XML_ERROR_NONE
;
2284 if (characterDataHandler
) {
2286 characterDataHandler(handlerArg
, &c
, 1);
2288 else if (defaultHandler
)
2289 reportDefault(parser
, enc
, s
, end
);
2290 /* We are at the end of the final buffer, should we check for
2291 XML_SUSPENDED, XML_FINISHED?
2293 if (startTagLevel
== 0)
2294 return XML_ERROR_NO_ELEMENTS
;
2295 if (tagLevel
!= startTagLevel
)
2296 return XML_ERROR_ASYNC_ENTITY
;
2298 return XML_ERROR_NONE
;
2302 return XML_ERROR_NONE
;
2304 if (startTagLevel
> 0) {
2305 if (tagLevel
!= startTagLevel
)
2306 return XML_ERROR_ASYNC_ENTITY
;
2308 return XML_ERROR_NONE
;
2310 return XML_ERROR_NO_ELEMENTS
;
2311 case XML_TOK_INVALID
:
2313 return XML_ERROR_INVALID_TOKEN
;
2314 case XML_TOK_PARTIAL
:
2317 return XML_ERROR_NONE
;
2319 return XML_ERROR_UNCLOSED_TOKEN
;
2320 case XML_TOK_PARTIAL_CHAR
:
2323 return XML_ERROR_NONE
;
2325 return XML_ERROR_PARTIAL_CHAR
;
2326 case XML_TOK_ENTITY_REF
:
2328 const XML_Char
*name
;
2330 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2331 s
+ enc
->minBytesPerChar
,
2332 next
- enc
->minBytesPerChar
);
2334 if (characterDataHandler
)
2335 characterDataHandler(handlerArg
, &ch
, 1);
2336 else if (defaultHandler
)
2337 reportDefault(parser
, enc
, s
, next
);
2340 name
= poolStoreString(&dtd
->pool
, enc
,
2341 s
+ enc
->minBytesPerChar
,
2342 next
- enc
->minBytesPerChar
);
2344 return XML_ERROR_NO_MEMORY
;
2345 entity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
, 0);
2346 poolDiscard(&dtd
->pool
);
2347 /* First, determine if a check for an existing declaration is needed;
2348 if yes, check that the entity exists, and that it is internal,
2349 otherwise call the skipped entity or default handler.
2351 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2353 return XML_ERROR_UNDEFINED_ENTITY
;
2354 else if (!entity
->is_internal
)
2355 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2358 if (skippedEntityHandler
)
2359 skippedEntityHandler(handlerArg
, name
, 0);
2360 else if (defaultHandler
)
2361 reportDefault(parser
, enc
, s
, next
);
2365 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2366 if (entity
->notation
)
2367 return XML_ERROR_BINARY_ENTITY_REF
;
2368 if (entity
->textPtr
) {
2369 enum XML_Error result
;
2370 if (!defaultExpandInternalEntities
) {
2371 if (skippedEntityHandler
)
2372 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2373 else if (defaultHandler
)
2374 reportDefault(parser
, enc
, s
, next
);
2377 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2378 if (result
!= XML_ERROR_NONE
)
2381 else if (externalEntityRefHandler
) {
2382 const XML_Char
*context
;
2383 entity
->open
= XML_TRUE
;
2384 context
= getContext(parser
);
2385 entity
->open
= XML_FALSE
;
2387 return XML_ERROR_NO_MEMORY
;
2388 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2393 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2394 poolDiscard(&tempPool
);
2396 else if (defaultHandler
)
2397 reportDefault(parser
, enc
, s
, next
);
2400 case XML_TOK_START_TAG_NO_ATTS
:
2402 case XML_TOK_START_TAG_WITH_ATTS
:
2405 enum XML_Error result
;
2409 freeTagList
= freeTagList
->parent
;
2412 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2414 return XML_ERROR_NO_MEMORY
;
2415 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2418 return XML_ERROR_NO_MEMORY
;
2420 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2422 tag
->bindings
= NULL
;
2423 tag
->parent
= tagStack
;
2425 tag
->name
.localPart
= NULL
;
2426 tag
->name
.prefix
= NULL
;
2427 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2428 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2431 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2432 const char *fromPtr
= tag
->rawName
;
2433 toPtr
= (XML_Char
*)tag
->buf
;
2438 &fromPtr
, rawNameEnd
,
2439 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2440 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2441 if (fromPtr
== rawNameEnd
) {
2442 tag
->name
.strLen
= convLen
;
2445 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2447 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2449 return XML_ERROR_NO_MEMORY
;
2451 tag
->bufEnd
= temp
+ bufSize
;
2452 toPtr
= (XML_Char
*)temp
+ convLen
;
2456 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2457 *toPtr
= XML_T('\0');
2458 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2461 if (startElementHandler
)
2462 startElementHandler(handlerArg
, tag
->name
.str
,
2463 (const XML_Char
**)atts
);
2464 else if (defaultHandler
)
2465 reportDefault(parser
, enc
, s
, next
);
2466 poolClear(&tempPool
);
2469 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2471 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2473 const char *rawName
= s
+ enc
->minBytesPerChar
;
2474 enum XML_Error result
;
2475 BINDING
*bindings
= NULL
;
2476 XML_Bool noElmHandlers
= XML_TRUE
;
2478 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2479 rawName
+ XmlNameLength(enc
, rawName
));
2481 return XML_ERROR_NO_MEMORY
;
2482 poolFinish(&tempPool
);
2483 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2486 poolFinish(&tempPool
);
2487 if (startElementHandler
) {
2488 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2489 noElmHandlers
= XML_FALSE
;
2491 if (endElementHandler
) {
2492 if (startElementHandler
)
2493 *eventPP
= *eventEndPP
;
2494 endElementHandler(handlerArg
, name
.str
);
2495 noElmHandlers
= XML_FALSE
;
2497 if (noElmHandlers
&& defaultHandler
)
2498 reportDefault(parser
, enc
, s
, next
);
2499 poolClear(&tempPool
);
2501 BINDING
*b
= bindings
;
2502 if (endNamespaceDeclHandler
)
2503 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2504 bindings
= bindings
->nextTagBinding
;
2505 b
->nextTagBinding
= freeBindingList
;
2506 freeBindingList
= b
;
2507 b
->prefix
->binding
= b
->prevPrefixBinding
;
2511 return epilogProcessor(parser
, next
, end
, nextPtr
);
2513 case XML_TOK_END_TAG
:
2514 if (tagLevel
== startTagLevel
)
2515 return XML_ERROR_ASYNC_ENTITY
;
2518 const char *rawName
;
2519 TAG
*tag
= tagStack
;
2520 tagStack
= tag
->parent
;
2521 tag
->parent
= freeTagList
;
2523 rawName
= s
+ enc
->minBytesPerChar
*2;
2524 len
= XmlNameLength(enc
, rawName
);
2525 if (len
!= tag
->rawNameLength
2526 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2528 return XML_ERROR_TAG_MISMATCH
;
2531 if (endElementHandler
) {
2532 const XML_Char
*localPart
;
2533 const XML_Char
*prefix
;
2535 localPart
= tag
->name
.localPart
;
2536 if (ns
&& localPart
) {
2537 /* localPart and prefix may have been overwritten in
2538 tag->name.str, since this points to the binding->uri
2539 buffer which gets re-used; so we have to add them again
2541 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2542 /* don't need to check for space - already done in storeAtts() */
2543 while (*localPart
) *uri
++ = *localPart
++;
2544 prefix
= (XML_Char
*)tag
->name
.prefix
;
2545 if (ns_triplets
&& prefix
) {
2546 *uri
++ = namespaceSeparator
;
2547 while (*prefix
) *uri
++ = *prefix
++;
2551 endElementHandler(handlerArg
, tag
->name
.str
);
2553 else if (defaultHandler
)
2554 reportDefault(parser
, enc
, s
, next
);
2555 while (tag
->bindings
) {
2556 BINDING
*b
= tag
->bindings
;
2557 if (endNamespaceDeclHandler
)
2558 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2559 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2560 b
->nextTagBinding
= freeBindingList
;
2561 freeBindingList
= b
;
2562 b
->prefix
->binding
= b
->prevPrefixBinding
;
2565 return epilogProcessor(parser
, next
, end
, nextPtr
);
2568 case XML_TOK_CHAR_REF
:
2570 int n
= XmlCharRefNumber(enc
, s
);
2572 return XML_ERROR_BAD_CHAR_REF
;
2573 if (characterDataHandler
) {
2574 XML_Char buf
[XML_ENCODE_MAX
];
2575 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2577 else if (defaultHandler
)
2578 reportDefault(parser
, enc
, s
, next
);
2581 case XML_TOK_XML_DECL
:
2582 return XML_ERROR_MISPLACED_XML_PI
;
2583 case XML_TOK_DATA_NEWLINE
:
2584 if (characterDataHandler
) {
2586 characterDataHandler(handlerArg
, &c
, 1);
2588 else if (defaultHandler
)
2589 reportDefault(parser
, enc
, s
, next
);
2591 case XML_TOK_CDATA_SECT_OPEN
:
2593 enum XML_Error result
;
2594 if (startCdataSectionHandler
)
2595 startCdataSectionHandler(handlerArg
);
2597 /* Suppose you doing a transformation on a document that involves
2598 changing only the character data. You set up a defaultHandler
2599 and a characterDataHandler. The defaultHandler simply copies
2600 characters through. The characterDataHandler does the
2601 transformation and writes the characters out escaping them as
2602 necessary. This case will fail to work if we leave out the
2603 following two lines (because & and < inside CDATA sections will
2604 be incorrectly escaped).
2606 However, now we have a start/endCdataSectionHandler, so it seems
2607 easier to let the user deal with this.
2609 else if (characterDataHandler
)
2610 characterDataHandler(handlerArg
, dataBuf
, 0);
2612 else if (defaultHandler
)
2613 reportDefault(parser
, enc
, s
, next
);
2614 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2615 if (result
!= XML_ERROR_NONE
)
2618 processor
= cdataSectionProcessor
;
2623 case XML_TOK_TRAILING_RSQB
:
2626 return XML_ERROR_NONE
;
2628 if (characterDataHandler
) {
2629 if (MUST_CONVERT(enc
, s
)) {
2630 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2631 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2632 characterDataHandler(handlerArg
, dataBuf
,
2633 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2636 characterDataHandler(handlerArg
,
2638 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2640 else if (defaultHandler
)
2641 reportDefault(parser
, enc
, s
, end
);
2642 /* We are at the end of the final buffer, should we check for
2643 XML_SUSPENDED, XML_FINISHED?
2645 if (startTagLevel
== 0) {
2647 return XML_ERROR_NO_ELEMENTS
;
2649 if (tagLevel
!= startTagLevel
) {
2651 return XML_ERROR_ASYNC_ENTITY
;
2654 return XML_ERROR_NONE
;
2655 case XML_TOK_DATA_CHARS
:
2657 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
2658 if (charDataHandler
) {
2659 if (MUST_CONVERT(enc
, s
)) {
2661 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2662 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2664 charDataHandler(handlerArg
, dataBuf
,
2665 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2672 charDataHandler(handlerArg
,
2674 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2676 else if (defaultHandler
)
2677 reportDefault(parser
, enc
, s
, next
);
2681 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2682 return XML_ERROR_NO_MEMORY
;
2684 case XML_TOK_COMMENT
:
2685 if (!reportComment(parser
, enc
, s
, next
))
2686 return XML_ERROR_NO_MEMORY
;
2690 reportDefault(parser
, enc
, s
, next
);
2693 *eventPP
= s
= next
;
2694 switch (ps_parsing
) {
2697 return XML_ERROR_NONE
;
2699 return XML_ERROR_ABORTED
;
2706 /* Precondition: all arguments must be non-NULL;
2708 - normalize attributes
2709 - check attributes for well-formedness
2710 - generate namespace aware attribute names (URI, prefix)
2711 - build list of attributes for startElementHandler
2712 - default attributes
2713 - process namespace declarations (check and report them)
2714 - generate namespace aware element name (URI, prefix)
2716 static enum XML_Error
2717 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2718 const char *attStr
, TAG_NAME
*tagNamePtr
,
2719 BINDING
**bindingsPtr
)
2721 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2722 ELEMENT_TYPE
*elementType
;
2724 const XML_Char
**appAtts
; /* the attribute list for the application */
2732 const XML_Char
*localPart
;
2734 /* lookup the element type name */
2735 elementType
= (ELEMENT_TYPE
*)lookup(parser
, &dtd
->elementTypes
, tagNamePtr
->str
,0);
2737 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2739 return XML_ERROR_NO_MEMORY
;
2740 elementType
= (ELEMENT_TYPE
*)lookup(parser
, &dtd
->elementTypes
, name
,
2741 sizeof(ELEMENT_TYPE
));
2743 return XML_ERROR_NO_MEMORY
;
2744 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2745 return XML_ERROR_NO_MEMORY
;
2747 nDefaultAtts
= elementType
->nDefaultAtts
;
2749 /* get the attributes from the tokenizer */
2750 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2751 if (n
+ nDefaultAtts
> attsSize
) {
2752 int oldAttsSize
= attsSize
;
2754 #ifdef XML_ATTR_INFO
2755 XML_AttrInfo
*temp2
;
2757 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2758 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2760 return XML_ERROR_NO_MEMORY
;
2762 #ifdef XML_ATTR_INFO
2763 temp2
= (XML_AttrInfo
*)REALLOC((void *)attInfo
, attsSize
* sizeof(XML_AttrInfo
));
2765 return XML_ERROR_NO_MEMORY
;
2768 if (n
> oldAttsSize
)
2769 XmlGetAttributes(enc
, attStr
, n
, atts
);
2772 appAtts
= (const XML_Char
**)atts
;
2773 for (i
= 0; i
< n
; i
++) {
2774 ATTRIBUTE
*currAtt
= &atts
[i
];
2775 #ifdef XML_ATTR_INFO
2776 XML_AttrInfo
*currAttInfo
= &attInfo
[i
];
2778 /* add the name and value to the attribute list */
2779 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, currAtt
->name
,
2781 + XmlNameLength(enc
, currAtt
->name
));
2783 return XML_ERROR_NO_MEMORY
;
2784 #ifdef XML_ATTR_INFO
2785 currAttInfo
->nameStart
= parseEndByteIndex
- (parseEndPtr
- currAtt
->name
);
2786 currAttInfo
->nameEnd
= currAttInfo
->nameStart
+
2787 XmlNameLength(enc
, currAtt
->name
);
2788 currAttInfo
->valueStart
= parseEndByteIndex
-
2789 (parseEndPtr
- currAtt
->valuePtr
);
2790 currAttInfo
->valueEnd
= parseEndByteIndex
- (parseEndPtr
- currAtt
->valueEnd
);
2792 /* Detect duplicate attributes by their QNames. This does not work when
2793 namespace processing is turned on and different prefixes for the same
2794 namespace are used. For this case we have a check further down.
2796 if ((attId
->name
)[-1]) {
2797 if (enc
== encoding
)
2798 eventPtr
= atts
[i
].name
;
2799 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2801 (attId
->name
)[-1] = 1;
2802 appAtts
[attIndex
++] = attId
->name
;
2803 if (!atts
[i
].normalized
) {
2804 enum XML_Error result
;
2805 XML_Bool isCdata
= XML_TRUE
;
2807 /* figure out whether declared as other than CDATA */
2808 if (attId
->maybeTokenized
) {
2810 for (j
= 0; j
< nDefaultAtts
; j
++) {
2811 if (attId
== elementType
->defaultAtts
[j
].id
) {
2812 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2818 /* normalize the attribute value */
2819 result
= storeAttributeValue(parser
, enc
, isCdata
,
2820 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2824 appAtts
[attIndex
] = poolStart(&tempPool
);
2825 poolFinish(&tempPool
);
2828 /* the value did not need normalizing */
2829 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2831 if (appAtts
[attIndex
] == 0)
2832 return XML_ERROR_NO_MEMORY
;
2833 poolFinish(&tempPool
);
2835 /* handle prefixed attribute names */
2836 if (attId
->prefix
) {
2838 /* deal with namespace declarations here */
2839 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2840 appAtts
[attIndex
], bindingsPtr
);
2846 /* deal with other prefixed names later */
2849 (attId
->name
)[-1] = 2;
2856 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2857 nSpecifiedAtts
= attIndex
;
2858 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2859 for (i
= 0; i
< attIndex
; i
+= 2)
2860 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2868 /* do attribute defaulting */
2869 for (i
= 0; i
< nDefaultAtts
; i
++) {
2870 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2871 if (!(da
->id
->name
)[-1] && da
->value
) {
2872 if (da
->id
->prefix
) {
2873 if (da
->id
->xmlns
) {
2874 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2875 da
->value
, bindingsPtr
);
2880 (da
->id
->name
)[-1] = 2;
2882 appAtts
[attIndex
++] = da
->id
->name
;
2883 appAtts
[attIndex
++] = da
->value
;
2887 (da
->id
->name
)[-1] = 1;
2888 appAtts
[attIndex
++] = da
->id
->name
;
2889 appAtts
[attIndex
++] = da
->value
;
2893 appAtts
[attIndex
] = 0;
2895 /* expand prefixed attribute names, check for duplicates,
2896 and clear flags that say whether attributes were specified */
2899 int j
; /* hash table index */
2900 unsigned long version
= nsAttsVersion
;
2901 int nsAttsSize
= (int)1 << nsAttsPower
;
2902 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2903 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2905 /* hash table size must also be a power of 2 and >= 8 */
2906 while (nPrefixes
>> nsAttsPower
++);
2907 if (nsAttsPower
< 3)
2909 nsAttsSize
= (int)1 << nsAttsPower
;
2910 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2912 return XML_ERROR_NO_MEMORY
;
2914 version
= 0; /* force re-initialization of nsAtts hash table */
2916 /* using a version flag saves us from initializing nsAtts every time */
2917 if (!version
) { /* initialize version flags when version wraps around */
2918 version
= INIT_ATTS_VERSION
;
2919 for (j
= nsAttsSize
; j
!= 0; )
2920 nsAtts
[--j
].version
= version
;
2922 nsAttsVersion
= --version
;
2924 /* expand prefixed names and check for duplicates */
2925 for (; i
< attIndex
; i
+= 2) {
2926 const XML_Char
*s
= appAtts
[i
];
2927 if (s
[-1] == 2) { /* prefixed */
2930 unsigned long uriHash
= hash_secret_salt
;
2931 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2932 id
= (ATTRIBUTE_ID
*)lookup(parser
, &dtd
->attributeIds
, s
, 0);
2933 b
= id
->prefix
->binding
;
2935 return XML_ERROR_UNBOUND_PREFIX
;
2937 /* as we expand the name we also calculate its hash value */
2938 for (j
= 0; j
< b
->uriLen
; j
++) {
2939 const XML_Char c
= b
->uri
[j
];
2940 if (!poolAppendChar(&tempPool
, c
))
2941 return XML_ERROR_NO_MEMORY
;
2942 uriHash
= CHAR_HASH(uriHash
, c
);
2944 while (*s
++ != XML_T(ASCII_COLON
))
2946 do { /* copies null terminator */
2947 const XML_Char c
= *s
;
2948 if (!poolAppendChar(&tempPool
, *s
))
2949 return XML_ERROR_NO_MEMORY
;
2950 uriHash
= CHAR_HASH(uriHash
, c
);
2953 { /* Check hash table for duplicate of expanded name (uriName).
2954 Derived from code in lookup(parser, HASH_TABLE *table, ...).
2956 unsigned char step
= 0;
2957 unsigned long mask
= nsAttsSize
- 1;
2958 j
= uriHash
& mask
; /* index into hash table */
2959 while (nsAtts
[j
].version
== version
) {
2960 /* for speed we compare stored hash values first */
2961 if (uriHash
== nsAtts
[j
].hash
) {
2962 const XML_Char
*s1
= poolStart(&tempPool
);
2963 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2964 /* s1 is null terminated, but not s2 */
2965 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2967 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2970 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2971 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2975 if (ns_triplets
) { /* append namespace separator and prefix */
2976 tempPool
.ptr
[-1] = namespaceSeparator
;
2977 s
= b
->prefix
->name
;
2979 if (!poolAppendChar(&tempPool
, *s
))
2980 return XML_ERROR_NO_MEMORY
;
2984 /* store expanded name in attribute list */
2985 s
= poolStart(&tempPool
);
2986 poolFinish(&tempPool
);
2989 /* fill empty slot with new version, uriName and hash value */
2990 nsAtts
[j
].version
= version
;
2991 nsAtts
[j
].hash
= uriHash
;
2992 nsAtts
[j
].uriName
= s
;
2999 else /* not prefixed */
3000 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
3003 /* clear flags for the remaining attributes */
3004 for (; i
< attIndex
; i
+= 2)
3005 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
3006 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
3007 binding
->attId
->name
[-1] = 0;
3010 return XML_ERROR_NONE
;
3012 /* expand the element type name */
3013 if (elementType
->prefix
) {
3014 binding
= elementType
->prefix
->binding
;
3016 return XML_ERROR_UNBOUND_PREFIX
;
3017 localPart
= tagNamePtr
->str
;
3018 while (*localPart
++ != XML_T(ASCII_COLON
))
3021 else if (dtd
->defaultPrefix
.binding
) {
3022 binding
= dtd
->defaultPrefix
.binding
;
3023 localPart
= tagNamePtr
->str
;
3026 return XML_ERROR_NONE
;
3028 if (ns_triplets
&& binding
->prefix
->name
) {
3029 for (; binding
->prefix
->name
[prefixLen
++];)
3030 ; /* prefixLen includes null terminator */
3032 tagNamePtr
->localPart
= localPart
;
3033 tagNamePtr
->uriLen
= binding
->uriLen
;
3034 tagNamePtr
->prefix
= binding
->prefix
->name
;
3035 tagNamePtr
->prefixLen
= prefixLen
;
3036 for (i
= 0; localPart
[i
++];)
3037 ; /* i includes null terminator */
3038 n
= i
+ binding
->uriLen
+ prefixLen
;
3039 if (n
> binding
->uriAlloc
) {
3041 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
3043 return XML_ERROR_NO_MEMORY
;
3044 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
3045 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
3046 for (p
= tagStack
; p
; p
= p
->parent
)
3047 if (p
->name
.str
== binding
->uri
)
3052 /* if namespaceSeparator != '\0' then uri includes it already */
3053 uri
= binding
->uri
+ binding
->uriLen
;
3054 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
3055 /* we always have a namespace separator between localPart and prefix */
3058 *uri
= namespaceSeparator
; /* replace null terminator */
3059 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
3061 tagNamePtr
->str
= binding
->uri
;
3062 return XML_ERROR_NONE
;
3065 /* addBinding() overwrites the value of prefix->binding without checking.
3066 Therefore one must keep track of the old value outside of addBinding().
3068 static enum XML_Error
3069 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
3070 const XML_Char
*uri
, BINDING
**bindingsPtr
)
3072 static const XML_Char xmlNamespace
[] = {
3073 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
3074 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
3075 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
,
3076 ASCII_SLASH
, ASCII_1
, ASCII_9
, ASCII_9
, ASCII_8
, ASCII_SLASH
,
3077 ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
, ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
,
3080 static const int xmlLen
=
3081 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
3082 static const XML_Char xmlnsNamespace
[] = {
3083 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
3084 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
3085 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_2
, ASCII_0
, ASCII_0
,
3086 ASCII_0
, ASCII_SLASH
, ASCII_x
, ASCII_m
, ASCII_l
, ASCII_n
, ASCII_s
,
3089 static const int xmlnsLen
=
3090 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
3092 XML_Bool mustBeXML
= XML_FALSE
;
3093 XML_Bool isXML
= XML_TRUE
;
3094 XML_Bool isXMLNS
= XML_TRUE
;
3099 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3100 if (*uri
== XML_T('\0') && prefix
->name
)
3101 return XML_ERROR_UNDECLARING_PREFIX
;
3104 && prefix
->name
[0] == XML_T(ASCII_x
)
3105 && prefix
->name
[1] == XML_T(ASCII_m
)
3106 && prefix
->name
[2] == XML_T(ASCII_l
)) {
3108 /* Not allowed to bind xmlns */
3109 if (prefix
->name
[3] == XML_T(ASCII_n
)
3110 && prefix
->name
[4] == XML_T(ASCII_s
)
3111 && prefix
->name
[5] == XML_T('\0'))
3112 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
3114 if (prefix
->name
[3] == XML_T('\0'))
3115 mustBeXML
= XML_TRUE
;
3118 for (len
= 0; uri
[len
]; len
++) {
3119 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
3122 if (!mustBeXML
&& isXMLNS
3123 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
3124 isXMLNS
= XML_FALSE
;
3126 isXML
= isXML
&& len
== xmlLen
;
3127 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
3129 if (mustBeXML
!= isXML
)
3130 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
3131 : XML_ERROR_RESERVED_NAMESPACE_URI
;
3134 return XML_ERROR_RESERVED_NAMESPACE_URI
;
3136 if (namespaceSeparator
)
3138 if (freeBindingList
) {
3139 b
= freeBindingList
;
3140 if (len
> b
->uriAlloc
) {
3141 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3142 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3144 return XML_ERROR_NO_MEMORY
;
3146 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3148 freeBindingList
= b
->nextTagBinding
;
3151 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3153 return XML_ERROR_NO_MEMORY
;
3154 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3157 return XML_ERROR_NO_MEMORY
;
3159 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3162 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3163 if (namespaceSeparator
)
3164 b
->uri
[len
- 1] = namespaceSeparator
;
3167 b
->prevPrefixBinding
= prefix
->binding
;
3168 /* NULL binding when default namespace undeclared */
3169 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3170 prefix
->binding
= NULL
;
3172 prefix
->binding
= b
;
3173 b
->nextTagBinding
= *bindingsPtr
;
3175 /* if attId == NULL then we are not starting a namespace scope */
3176 if (attId
&& startNamespaceDeclHandler
)
3177 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3178 prefix
->binding
? uri
: 0);
3179 return XML_ERROR_NONE
;
3182 /* The idea here is to avoid using stack for each CDATA section when
3183 the whole file is parsed with one call.
3185 static enum XML_Error PTRCALL
3186 cdataSectionProcessor(XML_Parser parser
,
3189 const char **endPtr
)
3191 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3192 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3193 if (result
!= XML_ERROR_NONE
)
3196 if (parentParser
) { /* we are parsing an external entity */
3197 processor
= externalEntityContentProcessor
;
3198 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3201 processor
= contentProcessor
;
3202 return contentProcessor(parser
, start
, end
, endPtr
);
3208 /* startPtr gets set to non-null if the section is closed, and to null if
3209 the section is not yet closed.
3211 static enum XML_Error
3212 doCdataSection(XML_Parser parser
,
3213 const ENCODING
*enc
,
3214 const char **startPtr
,
3216 const char **nextPtr
,
3219 const char *s
= *startPtr
;
3220 const char **eventPP
;
3221 const char **eventEndPP
;
3222 if (enc
== encoding
) {
3223 eventPP
= &eventPtr
;
3225 eventEndPP
= &eventEndPtr
;
3228 eventPP
= &(openInternalEntities
->internalEventPtr
);
3229 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3236 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3239 case XML_TOK_CDATA_SECT_CLOSE
:
3240 if (endCdataSectionHandler
)
3241 endCdataSectionHandler(handlerArg
);
3243 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3244 else if (characterDataHandler
)
3245 characterDataHandler(handlerArg
, dataBuf
, 0);
3247 else if (defaultHandler
)
3248 reportDefault(parser
, enc
, s
, next
);
3251 if (ps_parsing
== XML_FINISHED
)
3252 return XML_ERROR_ABORTED
;
3254 return XML_ERROR_NONE
;
3255 case XML_TOK_DATA_NEWLINE
:
3256 if (characterDataHandler
) {
3258 characterDataHandler(handlerArg
, &c
, 1);
3260 else if (defaultHandler
)
3261 reportDefault(parser
, enc
, s
, next
);
3263 case XML_TOK_DATA_CHARS
:
3265 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
3266 if (charDataHandler
) {
3267 if (MUST_CONVERT(enc
, s
)) {
3269 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3270 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3272 charDataHandler(handlerArg
, dataBuf
,
3273 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3280 charDataHandler(handlerArg
,
3282 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3284 else if (defaultHandler
)
3285 reportDefault(parser
, enc
, s
, next
);
3288 case XML_TOK_INVALID
:
3290 return XML_ERROR_INVALID_TOKEN
;
3291 case XML_TOK_PARTIAL_CHAR
:
3294 return XML_ERROR_NONE
;
3296 return XML_ERROR_PARTIAL_CHAR
;
3297 case XML_TOK_PARTIAL
:
3301 return XML_ERROR_NONE
;
3303 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3306 return XML_ERROR_UNEXPECTED_STATE
;
3309 *eventPP
= s
= next
;
3310 switch (ps_parsing
) {
3313 return XML_ERROR_NONE
;
3315 return XML_ERROR_ABORTED
;
3324 /* The idea here is to avoid using stack for each IGNORE section when
3325 the whole file is parsed with one call.
3327 static enum XML_Error PTRCALL
3328 ignoreSectionProcessor(XML_Parser parser
,
3331 const char **endPtr
)
3333 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3334 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3335 if (result
!= XML_ERROR_NONE
)
3338 processor
= prologProcessor
;
3339 return prologProcessor(parser
, start
, end
, endPtr
);
3344 /* startPtr gets set to non-null is the section is closed, and to null
3345 if the section is not yet closed.
3347 static enum XML_Error
3348 doIgnoreSection(XML_Parser parser
,
3349 const ENCODING
*enc
,
3350 const char **startPtr
,
3352 const char **nextPtr
,
3357 const char *s
= *startPtr
;
3358 const char **eventPP
;
3359 const char **eventEndPP
;
3360 if (enc
== encoding
) {
3361 eventPP
= &eventPtr
;
3363 eventEndPP
= &eventEndPtr
;
3366 eventPP
= &(openInternalEntities
->internalEventPtr
);
3367 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3371 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3374 case XML_TOK_IGNORE_SECT
:
3376 reportDefault(parser
, enc
, s
, next
);
3379 if (ps_parsing
== XML_FINISHED
)
3380 return XML_ERROR_ABORTED
;
3382 return XML_ERROR_NONE
;
3383 case XML_TOK_INVALID
:
3385 return XML_ERROR_INVALID_TOKEN
;
3386 case XML_TOK_PARTIAL_CHAR
:
3389 return XML_ERROR_NONE
;
3391 return XML_ERROR_PARTIAL_CHAR
;
3392 case XML_TOK_PARTIAL
:
3396 return XML_ERROR_NONE
;
3398 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3401 return XML_ERROR_UNEXPECTED_STATE
;
3406 #endif /* XML_DTD */
3408 static enum XML_Error
3409 initializeEncoding(XML_Parser parser
)
3413 char encodingBuf
[128];
3414 if (!protocolEncodingName
)
3418 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3419 if (i
== sizeof(encodingBuf
) - 1
3420 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3421 encodingBuf
[0] = '\0';
3424 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3426 encodingBuf
[i
] = '\0';
3430 s
= protocolEncodingName
;
3432 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3433 return XML_ERROR_NONE
;
3434 return handleUnknownEncoding(parser
, protocolEncodingName
);
3437 static enum XML_Error
3438 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3439 const char *s
, const char *next
)
3441 const char *encodingName
= NULL
;
3442 const XML_Char
*storedEncName
= NULL
;
3443 const ENCODING
*newEncoding
= NULL
;
3444 const char *version
= NULL
;
3445 const char *versionend
;
3446 const XML_Char
*storedversion
= NULL
;
3447 int standalone
= -1;
3450 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3460 if (isGeneralTextEntity
)
3461 return XML_ERROR_TEXT_DECL
;
3463 return XML_ERROR_XML_DECL
;
3465 if (!isGeneralTextEntity
&& standalone
== 1) {
3466 _dtd
->standalone
= XML_TRUE
;
3468 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3469 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3470 #endif /* XML_DTD */
3472 if (xmlDeclHandler
) {
3473 if (encodingName
!= NULL
) {
3474 storedEncName
= poolStoreString(&temp2Pool
,
3478 + XmlNameLength(encoding
, encodingName
));
3480 return XML_ERROR_NO_MEMORY
;
3481 poolFinish(&temp2Pool
);
3484 storedversion
= poolStoreString(&temp2Pool
,
3487 versionend
- encoding
->minBytesPerChar
);
3489 return XML_ERROR_NO_MEMORY
;
3491 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3493 else if (defaultHandler
)
3494 reportDefault(parser
, encoding
, s
, next
);
3495 if (protocolEncodingName
== NULL
) {
3497 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3498 eventPtr
= encodingName
;
3499 return XML_ERROR_INCORRECT_ENCODING
;
3501 encoding
= newEncoding
;
3503 else if (encodingName
) {
3504 enum XML_Error result
;
3505 if (!storedEncName
) {
3506 storedEncName
= poolStoreString(
3507 &temp2Pool
, encoding
, encodingName
,
3508 encodingName
+ XmlNameLength(encoding
, encodingName
));
3510 return XML_ERROR_NO_MEMORY
;
3512 result
= handleUnknownEncoding(parser
, storedEncName
);
3513 poolClear(&temp2Pool
);
3514 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3515 eventPtr
= encodingName
;
3520 if (storedEncName
|| storedversion
)
3521 poolClear(&temp2Pool
);
3523 return XML_ERROR_NONE
;
3526 static enum XML_Error
3527 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3529 if (unknownEncodingHandler
) {
3532 for (i
= 0; i
< 256; i
++)
3534 info
.convert
= NULL
;
3536 info
.release
= NULL
;
3537 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3540 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3541 if (!unknownEncodingMem
) {
3543 info
.release(info
.data
);
3544 return XML_ERROR_NO_MEMORY
;
3547 ? XmlInitUnknownEncodingNS
3548 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3553 unknownEncodingData
= info
.data
;
3554 unknownEncodingRelease
= info
.release
;
3556 return XML_ERROR_NONE
;
3559 if (info
.release
!= NULL
)
3560 info
.release(info
.data
);
3562 return XML_ERROR_UNKNOWN_ENCODING
;
3565 static enum XML_Error PTRCALL
3566 prologInitProcessor(XML_Parser parser
,
3569 const char **nextPtr
)
3571 enum XML_Error result
= initializeEncoding(parser
);
3572 if (result
!= XML_ERROR_NONE
)
3574 processor
= prologProcessor
;
3575 return prologProcessor(parser
, s
, end
, nextPtr
);
3580 static enum XML_Error PTRCALL
3581 externalParEntInitProcessor(XML_Parser parser
,
3584 const char **nextPtr
)
3586 enum XML_Error result
= initializeEncoding(parser
);
3587 if (result
!= XML_ERROR_NONE
)
3590 /* we know now that XML_Parse(Buffer) has been called,
3591 so we consider the external parameter entity read */
3592 _dtd
->paramEntityRead
= XML_TRUE
;
3594 if (prologState
.inEntityValue
) {
3595 processor
= entityValueInitProcessor
;
3596 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3599 processor
= externalParEntProcessor
;
3600 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3604 static enum XML_Error PTRCALL
3605 entityValueInitProcessor(XML_Parser parser
,
3608 const char **nextPtr
)
3611 const char *start
= s
;
3612 const char *next
= start
;
3616 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3619 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3621 return XML_ERROR_NONE
;
3624 case XML_TOK_INVALID
:
3625 return XML_ERROR_INVALID_TOKEN
;
3626 case XML_TOK_PARTIAL
:
3627 return XML_ERROR_UNCLOSED_TOKEN
;
3628 case XML_TOK_PARTIAL_CHAR
:
3629 return XML_ERROR_PARTIAL_CHAR
;
3630 case XML_TOK_NONE
: /* start == end */
3634 /* found end of entity value - can store it now */
3635 return storeEntityValue(parser
, encoding
, s
, end
);
3637 else if (tok
== XML_TOK_XML_DECL
) {
3638 enum XML_Error result
;
3639 result
= processXmlDecl(parser
, 0, start
, next
);
3640 if (result
!= XML_ERROR_NONE
)
3642 switch (ps_parsing
) {
3645 return XML_ERROR_NONE
;
3647 return XML_ERROR_ABORTED
;
3651 /* stop scanning for text declaration - we found one */
3652 processor
= entityValueProcessor
;
3653 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3655 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3656 return XML_TOK_NONE on the next call, which would then cause the
3657 function to exit with *nextPtr set to s - that is what we want for other
3658 tokens, but not for the BOM - we would rather like to skip it;
3659 then, when this routine is entered the next time, XmlPrologTok will
3660 return XML_TOK_INVALID, since the BOM is still in the buffer
3662 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3664 return XML_ERROR_NONE
;
3671 static enum XML_Error PTRCALL
3672 externalParEntProcessor(XML_Parser parser
,
3675 const char **nextPtr
)
3677 const char *next
= s
;
3680 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3682 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3684 return XML_ERROR_NONE
;
3687 case XML_TOK_INVALID
:
3688 return XML_ERROR_INVALID_TOKEN
;
3689 case XML_TOK_PARTIAL
:
3690 return XML_ERROR_UNCLOSED_TOKEN
;
3691 case XML_TOK_PARTIAL_CHAR
:
3692 return XML_ERROR_PARTIAL_CHAR
;
3693 case XML_TOK_NONE
: /* start == end */
3698 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3699 However, when parsing an external subset, doProlog will not accept a BOM
3700 as valid, and report a syntax error, so we have to skip the BOM
3702 else if (tok
== XML_TOK_BOM
) {
3704 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3707 processor
= prologProcessor
;
3708 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3709 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3712 static enum XML_Error PTRCALL
3713 entityValueProcessor(XML_Parser parser
,
3716 const char **nextPtr
)
3718 const char *start
= s
;
3719 const char *next
= s
;
3720 const ENCODING
*enc
= encoding
;
3724 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3726 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3728 return XML_ERROR_NONE
;
3731 case XML_TOK_INVALID
:
3732 return XML_ERROR_INVALID_TOKEN
;
3733 case XML_TOK_PARTIAL
:
3734 return XML_ERROR_UNCLOSED_TOKEN
;
3735 case XML_TOK_PARTIAL_CHAR
:
3736 return XML_ERROR_PARTIAL_CHAR
;
3737 case XML_TOK_NONE
: /* start == end */
3741 /* found end of entity value - can store it now */
3742 return storeEntityValue(parser
, enc
, s
, end
);
3748 #endif /* XML_DTD */
3750 static enum XML_Error PTRCALL
3751 prologProcessor(XML_Parser parser
,
3754 const char **nextPtr
)
3756 const char *next
= s
;
3757 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3758 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3759 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3762 static enum XML_Error
3763 doProlog(XML_Parser parser
,
3764 const ENCODING
*enc
,
3769 const char **nextPtr
,
3773 static const XML_Char externalSubsetName
[] = { ASCII_HASH
, '\0' };
3774 #endif /* XML_DTD */
3775 static const XML_Char atypeCDATA
[] =
3776 { ASCII_C
, ASCII_D
, ASCII_A
, ASCII_T
, ASCII_A
, '\0' };
3777 static const XML_Char atypeID
[] = { ASCII_I
, ASCII_D
, '\0' };
3778 static const XML_Char atypeIDREF
[] =
3779 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, '\0' };
3780 static const XML_Char atypeIDREFS
[] =
3781 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, ASCII_S
, '\0' };
3782 static const XML_Char atypeENTITY
[] =
3783 { ASCII_E
, ASCII_N
, ASCII_T
, ASCII_I
, ASCII_T
, ASCII_Y
, '\0' };
3784 static const XML_Char atypeENTITIES
[] = { ASCII_E
, ASCII_N
,
3785 ASCII_T
, ASCII_I
, ASCII_T
, ASCII_I
, ASCII_E
, ASCII_S
, '\0' };
3786 static const XML_Char atypeNMTOKEN
[] = {
3787 ASCII_N
, ASCII_M
, ASCII_T
, ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, '\0' };
3788 static const XML_Char atypeNMTOKENS
[] = { ASCII_N
, ASCII_M
, ASCII_T
,
3789 ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, ASCII_S
, '\0' };
3790 static const XML_Char notationPrefix
[] = { ASCII_N
, ASCII_O
, ASCII_T
,
3791 ASCII_A
, ASCII_T
, ASCII_I
, ASCII_O
, ASCII_N
, ASCII_LPAREN
, '\0' };
3792 static const XML_Char enumValueSep
[] = { ASCII_PIPE
, '\0' };
3793 static const XML_Char enumValueStart
[] = { ASCII_LPAREN
, '\0' };
3795 /* save one level of indirection */
3796 DTD
* const dtd
= _dtd
;
3798 const char **eventPP
;
3799 const char **eventEndPP
;
3800 enum XML_Content_Quant quant
;
3802 if (enc
== encoding
) {
3803 eventPP
= &eventPtr
;
3804 eventEndPP
= &eventEndPtr
;
3807 eventPP
= &(openInternalEntities
->internalEventPtr
);
3808 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3813 XML_Bool handleDefault
= XML_TRUE
;
3817 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3819 return XML_ERROR_NONE
;
3822 case XML_TOK_INVALID
:
3824 return XML_ERROR_INVALID_TOKEN
;
3825 case XML_TOK_PARTIAL
:
3826 return XML_ERROR_UNCLOSED_TOKEN
;
3827 case XML_TOK_PARTIAL_CHAR
:
3828 return XML_ERROR_PARTIAL_CHAR
;
3829 case -XML_TOK_PROLOG_S
:
3834 /* for internal PE NOT referenced between declarations */
3835 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3837 return XML_ERROR_NONE
;
3839 /* WFC: PE Between Declarations - must check that PE contains
3840 complete markup, not only for external PEs, but also for
3841 internal PEs if the reference occurs between declarations.
3843 if (isParamEntity
|| enc
!= encoding
) {
3844 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3846 return XML_ERROR_INCOMPLETE_PE
;
3848 return XML_ERROR_NONE
;
3850 #endif /* XML_DTD */
3851 return XML_ERROR_NO_ELEMENTS
;
3858 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3860 case XML_ROLE_XML_DECL
:
3862 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3863 if (result
!= XML_ERROR_NONE
)
3866 handleDefault
= XML_FALSE
;
3869 case XML_ROLE_DOCTYPE_NAME
:
3870 if (startDoctypeDeclHandler
) {
3871 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3873 return XML_ERROR_NO_MEMORY
;
3874 poolFinish(&tempPool
);
3875 doctypePubid
= NULL
;
3876 handleDefault
= XML_FALSE
;
3878 doctypeSysid
= NULL
; /* always initialize to NULL */
3880 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3881 if (startDoctypeDeclHandler
) {
3882 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3885 poolClear(&tempPool
);
3886 handleDefault
= XML_FALSE
;
3890 case XML_ROLE_TEXT_DECL
:
3892 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3893 if (result
!= XML_ERROR_NONE
)
3896 handleDefault
= XML_FALSE
;
3899 #endif /* XML_DTD */
3900 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3902 useForeignDTD
= XML_FALSE
;
3903 declEntity
= (ENTITY
*)lookup(parser
,
3904 &dtd
->paramEntities
,
3908 return XML_ERROR_NO_MEMORY
;
3909 #endif /* XML_DTD */
3910 dtd
->hasParamEntityRefs
= XML_TRUE
;
3911 if (startDoctypeDeclHandler
) {
3913 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3914 return XML_ERROR_PUBLICID
;
3915 pubId
= poolStoreString(&tempPool
, enc
,
3916 s
+ enc
->minBytesPerChar
,
3917 next
- enc
->minBytesPerChar
);
3919 return XML_ERROR_NO_MEMORY
;
3920 normalizePublicId(pubId
);
3921 poolFinish(&tempPool
);
3922 doctypePubid
= pubId
;
3923 handleDefault
= XML_FALSE
;
3924 goto alreadyChecked
;
3927 case XML_ROLE_ENTITY_PUBLIC_ID
:
3928 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3929 return XML_ERROR_PUBLICID
;
3931 if (dtd
->keepProcessing
&& declEntity
) {
3932 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3934 s
+ enc
->minBytesPerChar
,
3935 next
- enc
->minBytesPerChar
);
3937 return XML_ERROR_NO_MEMORY
;
3938 normalizePublicId(tem
);
3939 declEntity
->publicId
= tem
;
3940 poolFinish(&dtd
->pool
);
3941 if (entityDeclHandler
)
3942 handleDefault
= XML_FALSE
;
3945 case XML_ROLE_DOCTYPE_CLOSE
:
3947 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3948 doctypeSysid
, doctypePubid
, 0);
3949 poolClear(&tempPool
);
3950 handleDefault
= XML_FALSE
;
3952 /* doctypeSysid will be non-NULL in the case of a previous
3953 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3954 was not set, indicating an external subset
3957 if (doctypeSysid
|| useForeignDTD
) {
3958 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3959 dtd
->hasParamEntityRefs
= XML_TRUE
;
3960 if (paramEntityParsing
&& externalEntityRefHandler
) {
3961 ENTITY
*entity
= (ENTITY
*)lookup(parser
,
3962 &dtd
->paramEntities
,
3966 return XML_ERROR_NO_MEMORY
;
3968 entity
->base
= curBase
;
3969 dtd
->paramEntityRead
= XML_FALSE
;
3970 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3975 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3976 if (dtd
->paramEntityRead
) {
3977 if (!dtd
->standalone
&&
3978 notStandaloneHandler
&&
3979 !notStandaloneHandler(handlerArg
))
3980 return XML_ERROR_NOT_STANDALONE
;
3982 /* if we didn't read the foreign DTD then this means that there
3983 is no external subset and we must reset dtd->hasParamEntityRefs
3985 else if (!doctypeSysid
)
3986 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3987 /* end of DTD - no need to update dtd->keepProcessing */
3989 useForeignDTD
= XML_FALSE
;
3991 #endif /* XML_DTD */
3992 if (endDoctypeDeclHandler
) {
3993 endDoctypeDeclHandler(handlerArg
);
3994 handleDefault
= XML_FALSE
;
3997 case XML_ROLE_INSTANCE_START
:
3999 /* if there is no DOCTYPE declaration then now is the
4000 last chance to read the foreign DTD
4002 if (useForeignDTD
) {
4003 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
4004 dtd
->hasParamEntityRefs
= XML_TRUE
;
4005 if (paramEntityParsing
&& externalEntityRefHandler
) {
4006 ENTITY
*entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
,
4010 return XML_ERROR_NO_MEMORY
;
4011 entity
->base
= curBase
;
4012 dtd
->paramEntityRead
= XML_FALSE
;
4013 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4018 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4019 if (dtd
->paramEntityRead
) {
4020 if (!dtd
->standalone
&&
4021 notStandaloneHandler
&&
4022 !notStandaloneHandler(handlerArg
))
4023 return XML_ERROR_NOT_STANDALONE
;
4025 /* if we didn't read the foreign DTD then this means that there
4026 is no external subset and we must reset dtd->hasParamEntityRefs
4029 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
4030 /* end of DTD - no need to update dtd->keepProcessing */
4033 #endif /* XML_DTD */
4034 processor
= contentProcessor
;
4035 return contentProcessor(parser
, s
, end
, nextPtr
);
4036 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
4037 declElementType
= getElementType(parser
, enc
, s
, next
);
4038 if (!declElementType
)
4039 return XML_ERROR_NO_MEMORY
;
4040 goto checkAttListDeclHandler
;
4041 case XML_ROLE_ATTRIBUTE_NAME
:
4042 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
4043 if (!declAttributeId
)
4044 return XML_ERROR_NO_MEMORY
;
4045 declAttributeIsCdata
= XML_FALSE
;
4046 declAttributeType
= NULL
;
4047 declAttributeIsId
= XML_FALSE
;
4048 goto checkAttListDeclHandler
;
4049 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
4050 declAttributeIsCdata
= XML_TRUE
;
4051 declAttributeType
= atypeCDATA
;
4052 goto checkAttListDeclHandler
;
4053 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
4054 declAttributeIsId
= XML_TRUE
;
4055 declAttributeType
= atypeID
;
4056 goto checkAttListDeclHandler
;
4057 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
4058 declAttributeType
= atypeIDREF
;
4059 goto checkAttListDeclHandler
;
4060 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
4061 declAttributeType
= atypeIDREFS
;
4062 goto checkAttListDeclHandler
;
4063 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
4064 declAttributeType
= atypeENTITY
;
4065 goto checkAttListDeclHandler
;
4066 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
4067 declAttributeType
= atypeENTITIES
;
4068 goto checkAttListDeclHandler
;
4069 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
4070 declAttributeType
= atypeNMTOKEN
;
4071 goto checkAttListDeclHandler
;
4072 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
4073 declAttributeType
= atypeNMTOKENS
;
4074 checkAttListDeclHandler
:
4075 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4076 handleDefault
= XML_FALSE
;
4078 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
4079 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
4080 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
4081 const XML_Char
*prefix
;
4082 if (declAttributeType
) {
4083 prefix
= enumValueSep
;
4086 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4090 if (!poolAppendString(&tempPool
, prefix
))
4091 return XML_ERROR_NO_MEMORY
;
4092 if (!poolAppend(&tempPool
, enc
, s
, next
))
4093 return XML_ERROR_NO_MEMORY
;
4094 declAttributeType
= tempPool
.start
;
4095 handleDefault
= XML_FALSE
;
4098 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
4099 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
4100 if (dtd
->keepProcessing
) {
4101 if (!defineAttribute(declElementType
, declAttributeId
,
4102 declAttributeIsCdata
, declAttributeIsId
,
4104 return XML_ERROR_NO_MEMORY
;
4105 if (attlistDeclHandler
&& declAttributeType
) {
4106 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4107 || (*declAttributeType
== XML_T(ASCII_N
)
4108 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4109 /* Enumerated or Notation type */
4110 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4111 || !poolAppendChar(&tempPool
, XML_T('\0')))
4112 return XML_ERROR_NO_MEMORY
;
4113 declAttributeType
= tempPool
.start
;
4114 poolFinish(&tempPool
);
4117 attlistDeclHandler(handlerArg
, declElementType
->name
,
4118 declAttributeId
->name
, declAttributeType
,
4119 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
4120 poolClear(&tempPool
);
4121 handleDefault
= XML_FALSE
;
4125 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
4126 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
4127 if (dtd
->keepProcessing
) {
4128 const XML_Char
*attVal
;
4129 enum XML_Error result
=
4130 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
4131 s
+ enc
->minBytesPerChar
,
4132 next
- enc
->minBytesPerChar
,
4136 attVal
= poolStart(&dtd
->pool
);
4137 poolFinish(&dtd
->pool
);
4138 /* ID attributes aren't allowed to have a default */
4139 if (!defineAttribute(declElementType
, declAttributeId
,
4140 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
4141 return XML_ERROR_NO_MEMORY
;
4142 if (attlistDeclHandler
&& declAttributeType
) {
4143 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4144 || (*declAttributeType
== XML_T(ASCII_N
)
4145 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4146 /* Enumerated or Notation type */
4147 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4148 || !poolAppendChar(&tempPool
, XML_T('\0')))
4149 return XML_ERROR_NO_MEMORY
;
4150 declAttributeType
= tempPool
.start
;
4151 poolFinish(&tempPool
);
4154 attlistDeclHandler(handlerArg
, declElementType
->name
,
4155 declAttributeId
->name
, declAttributeType
,
4157 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4158 poolClear(&tempPool
);
4159 handleDefault
= XML_FALSE
;
4163 case XML_ROLE_ENTITY_VALUE
:
4164 if (dtd
->keepProcessing
) {
4165 enum XML_Error result
= storeEntityValue(parser
, enc
,
4166 s
+ enc
->minBytesPerChar
,
4167 next
- enc
->minBytesPerChar
);
4169 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4170 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4171 poolFinish(&dtd
->entityValuePool
);
4172 if (entityDeclHandler
) {
4174 entityDeclHandler(handlerArg
,
4176 declEntity
->is_param
,
4177 declEntity
->textPtr
,
4178 declEntity
->textLen
,
4180 handleDefault
= XML_FALSE
;
4184 poolDiscard(&dtd
->entityValuePool
);
4185 if (result
!= XML_ERROR_NONE
)
4189 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4191 useForeignDTD
= XML_FALSE
;
4192 #endif /* XML_DTD */
4193 dtd
->hasParamEntityRefs
= XML_TRUE
;
4194 if (startDoctypeDeclHandler
) {
4195 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4196 s
+ enc
->minBytesPerChar
,
4197 next
- enc
->minBytesPerChar
);
4198 if (doctypeSysid
== NULL
)
4199 return XML_ERROR_NO_MEMORY
;
4200 poolFinish(&tempPool
);
4201 handleDefault
= XML_FALSE
;
4205 /* use externalSubsetName to make doctypeSysid non-NULL
4206 for the case where no startDoctypeDeclHandler is set */
4207 doctypeSysid
= externalSubsetName
;
4208 #endif /* XML_DTD */
4209 if (!dtd
->standalone
4211 && !paramEntityParsing
4212 #endif /* XML_DTD */
4213 && notStandaloneHandler
4214 && !notStandaloneHandler(handlerArg
))
4215 return XML_ERROR_NOT_STANDALONE
;
4220 declEntity
= (ENTITY
*)lookup(parser
,
4221 &dtd
->paramEntities
,
4225 return XML_ERROR_NO_MEMORY
;
4226 declEntity
->publicId
= NULL
;
4229 #endif /* XML_DTD */
4230 case XML_ROLE_ENTITY_SYSTEM_ID
:
4231 if (dtd
->keepProcessing
&& declEntity
) {
4232 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4233 s
+ enc
->minBytesPerChar
,
4234 next
- enc
->minBytesPerChar
);
4235 if (!declEntity
->systemId
)
4236 return XML_ERROR_NO_MEMORY
;
4237 declEntity
->base
= curBase
;
4238 poolFinish(&dtd
->pool
);
4239 if (entityDeclHandler
)
4240 handleDefault
= XML_FALSE
;
4243 case XML_ROLE_ENTITY_COMPLETE
:
4244 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4246 entityDeclHandler(handlerArg
,
4248 declEntity
->is_param
,
4251 declEntity
->systemId
,
4252 declEntity
->publicId
,
4254 handleDefault
= XML_FALSE
;
4257 case XML_ROLE_ENTITY_NOTATION_NAME
:
4258 if (dtd
->keepProcessing
&& declEntity
) {
4259 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4260 if (!declEntity
->notation
)
4261 return XML_ERROR_NO_MEMORY
;
4262 poolFinish(&dtd
->pool
);
4263 if (unparsedEntityDeclHandler
) {
4265 unparsedEntityDeclHandler(handlerArg
,
4268 declEntity
->systemId
,
4269 declEntity
->publicId
,
4270 declEntity
->notation
);
4271 handleDefault
= XML_FALSE
;
4273 else if (entityDeclHandler
) {
4275 entityDeclHandler(handlerArg
,
4279 declEntity
->systemId
,
4280 declEntity
->publicId
,
4281 declEntity
->notation
);
4282 handleDefault
= XML_FALSE
;
4286 case XML_ROLE_GENERAL_ENTITY_NAME
:
4288 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4292 if (dtd
->keepProcessing
) {
4293 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4295 return XML_ERROR_NO_MEMORY
;
4296 declEntity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
,
4299 return XML_ERROR_NO_MEMORY
;
4300 if (declEntity
->name
!= name
) {
4301 poolDiscard(&dtd
->pool
);
4305 poolFinish(&dtd
->pool
);
4306 declEntity
->publicId
= NULL
;
4307 declEntity
->is_param
= XML_FALSE
;
4308 /* if we have a parent parser or are reading an internal parameter
4309 entity, then the entity declaration is not considered "internal"
4311 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4312 if (entityDeclHandler
)
4313 handleDefault
= XML_FALSE
;
4317 poolDiscard(&dtd
->pool
);
4322 case XML_ROLE_PARAM_ENTITY_NAME
:
4324 if (dtd
->keepProcessing
) {
4325 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4327 return XML_ERROR_NO_MEMORY
;
4328 declEntity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
,
4329 name
, sizeof(ENTITY
));
4331 return XML_ERROR_NO_MEMORY
;
4332 if (declEntity
->name
!= name
) {
4333 poolDiscard(&dtd
->pool
);
4337 poolFinish(&dtd
->pool
);
4338 declEntity
->publicId
= NULL
;
4339 declEntity
->is_param
= XML_TRUE
;
4340 /* if we have a parent parser or are reading an internal parameter
4341 entity, then the entity declaration is not considered "internal"
4343 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4344 if (entityDeclHandler
)
4345 handleDefault
= XML_FALSE
;
4349 poolDiscard(&dtd
->pool
);
4352 #else /* not XML_DTD */
4354 #endif /* XML_DTD */
4356 case XML_ROLE_NOTATION_NAME
:
4357 declNotationPublicId
= NULL
;
4358 declNotationName
= NULL
;
4359 if (notationDeclHandler
) {
4360 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4361 if (!declNotationName
)
4362 return XML_ERROR_NO_MEMORY
;
4363 poolFinish(&tempPool
);
4364 handleDefault
= XML_FALSE
;
4367 case XML_ROLE_NOTATION_PUBLIC_ID
:
4368 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4369 return XML_ERROR_PUBLICID
;
4370 if (declNotationName
) { /* means notationDeclHandler != NULL */
4371 XML_Char
*tem
= poolStoreString(&tempPool
,
4373 s
+ enc
->minBytesPerChar
,
4374 next
- enc
->minBytesPerChar
);
4376 return XML_ERROR_NO_MEMORY
;
4377 normalizePublicId(tem
);
4378 declNotationPublicId
= tem
;
4379 poolFinish(&tempPool
);
4380 handleDefault
= XML_FALSE
;
4383 case XML_ROLE_NOTATION_SYSTEM_ID
:
4384 if (declNotationName
&& notationDeclHandler
) {
4385 const XML_Char
*systemId
4386 = poolStoreString(&tempPool
, enc
,
4387 s
+ enc
->minBytesPerChar
,
4388 next
- enc
->minBytesPerChar
);
4390 return XML_ERROR_NO_MEMORY
;
4392 notationDeclHandler(handlerArg
,
4396 declNotationPublicId
);
4397 handleDefault
= XML_FALSE
;
4399 poolClear(&tempPool
);
4401 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4402 if (declNotationPublicId
&& notationDeclHandler
) {
4404 notationDeclHandler(handlerArg
,
4408 declNotationPublicId
);
4409 handleDefault
= XML_FALSE
;
4411 poolClear(&tempPool
);
4413 case XML_ROLE_ERROR
:
4415 case XML_TOK_PARAM_ENTITY_REF
:
4416 /* PE references in internal subset are
4417 not allowed within declarations. */
4418 return XML_ERROR_PARAM_ENTITY_REF
;
4419 case XML_TOK_XML_DECL
:
4420 return XML_ERROR_MISPLACED_XML_PI
;
4422 return XML_ERROR_SYNTAX
;
4425 case XML_ROLE_IGNORE_SECT
:
4427 enum XML_Error result
;
4429 reportDefault(parser
, enc
, s
, next
);
4430 handleDefault
= XML_FALSE
;
4431 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4432 if (result
!= XML_ERROR_NONE
)
4435 processor
= ignoreSectionProcessor
;
4440 #endif /* XML_DTD */
4441 case XML_ROLE_GROUP_OPEN
:
4442 if (prologState
.level
>= groupSize
) {
4444 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4446 return XML_ERROR_NO_MEMORY
;
4447 groupConnector
= temp
;
4448 if (dtd
->scaffIndex
) {
4449 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4450 groupSize
* sizeof(int));
4452 return XML_ERROR_NO_MEMORY
;
4453 dtd
->scaffIndex
= temp
;
4457 groupConnector
= (char *)MALLOC(groupSize
= 32);
4458 if (!groupConnector
)
4459 return XML_ERROR_NO_MEMORY
;
4462 groupConnector
[prologState
.level
] = 0;
4463 if (dtd
->in_eldecl
) {
4464 int myindex
= nextScaffoldPart(parser
);
4466 return XML_ERROR_NO_MEMORY
;
4467 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4469 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4470 if (elementDeclHandler
)
4471 handleDefault
= XML_FALSE
;
4474 case XML_ROLE_GROUP_SEQUENCE
:
4475 if (groupConnector
[prologState
.level
] == ASCII_PIPE
)
4476 return XML_ERROR_SYNTAX
;
4477 groupConnector
[prologState
.level
] = ASCII_COMMA
;
4478 if (dtd
->in_eldecl
&& elementDeclHandler
)
4479 handleDefault
= XML_FALSE
;
4481 case XML_ROLE_GROUP_CHOICE
:
4482 if (groupConnector
[prologState
.level
] == ASCII_COMMA
)
4483 return XML_ERROR_SYNTAX
;
4485 && !groupConnector
[prologState
.level
]
4486 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4489 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4491 if (elementDeclHandler
)
4492 handleDefault
= XML_FALSE
;
4494 groupConnector
[prologState
.level
] = ASCII_PIPE
;
4496 case XML_ROLE_PARAM_ENTITY_REF
:
4498 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4499 dtd
->hasParamEntityRefs
= XML_TRUE
;
4500 if (!paramEntityParsing
)
4501 dtd
->keepProcessing
= dtd
->standalone
;
4503 const XML_Char
*name
;
4505 name
= poolStoreString(&dtd
->pool
, enc
,
4506 s
+ enc
->minBytesPerChar
,
4507 next
- enc
->minBytesPerChar
);
4509 return XML_ERROR_NO_MEMORY
;
4510 entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
, name
, 0);
4511 poolDiscard(&dtd
->pool
);
4512 /* first, determine if a check for an existing declaration is needed;
4513 if yes, check that the entity exists, and that it is internal,
4514 otherwise call the skipped entity handler
4516 if (prologState
.documentEntity
&&
4518 ? !openInternalEntities
4519 : !dtd
->hasParamEntityRefs
)) {
4521 return XML_ERROR_UNDEFINED_ENTITY
;
4522 else if (!entity
->is_internal
)
4523 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4526 dtd
->keepProcessing
= dtd
->standalone
;
4527 /* cannot report skipped entities in declarations */
4528 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4529 skippedEntityHandler(handlerArg
, name
, 1);
4530 handleDefault
= XML_FALSE
;
4535 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4536 if (entity
->textPtr
) {
4537 enum XML_Error result
;
4538 XML_Bool betweenDecl
=
4539 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4540 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4541 if (result
!= XML_ERROR_NONE
)
4543 handleDefault
= XML_FALSE
;
4546 if (externalEntityRefHandler
) {
4547 dtd
->paramEntityRead
= XML_FALSE
;
4548 entity
->open
= XML_TRUE
;
4549 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4553 entity
->publicId
)) {
4554 entity
->open
= XML_FALSE
;
4555 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4557 entity
->open
= XML_FALSE
;
4558 handleDefault
= XML_FALSE
;
4559 if (!dtd
->paramEntityRead
) {
4560 dtd
->keepProcessing
= dtd
->standalone
;
4565 dtd
->keepProcessing
= dtd
->standalone
;
4569 #endif /* XML_DTD */
4570 if (!dtd
->standalone
&&
4571 notStandaloneHandler
&&
4572 !notStandaloneHandler(handlerArg
))
4573 return XML_ERROR_NOT_STANDALONE
;
4576 /* Element declaration stuff */
4578 case XML_ROLE_ELEMENT_NAME
:
4579 if (elementDeclHandler
) {
4580 declElementType
= getElementType(parser
, enc
, s
, next
);
4581 if (!declElementType
)
4582 return XML_ERROR_NO_MEMORY
;
4583 dtd
->scaffLevel
= 0;
4584 dtd
->scaffCount
= 0;
4585 dtd
->in_eldecl
= XML_TRUE
;
4586 handleDefault
= XML_FALSE
;
4590 case XML_ROLE_CONTENT_ANY
:
4591 case XML_ROLE_CONTENT_EMPTY
:
4592 if (dtd
->in_eldecl
) {
4593 if (elementDeclHandler
) {
4594 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4596 return XML_ERROR_NO_MEMORY
;
4597 content
->quant
= XML_CQUANT_NONE
;
4598 content
->name
= NULL
;
4599 content
->numchildren
= 0;
4600 content
->children
= NULL
;
4601 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4605 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4606 handleDefault
= XML_FALSE
;
4608 dtd
->in_eldecl
= XML_FALSE
;
4612 case XML_ROLE_CONTENT_PCDATA
:
4613 if (dtd
->in_eldecl
) {
4614 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4616 if (elementDeclHandler
)
4617 handleDefault
= XML_FALSE
;
4621 case XML_ROLE_CONTENT_ELEMENT
:
4622 quant
= XML_CQUANT_NONE
;
4623 goto elementContent
;
4624 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4625 quant
= XML_CQUANT_OPT
;
4626 goto elementContent
;
4627 case XML_ROLE_CONTENT_ELEMENT_REP
:
4628 quant
= XML_CQUANT_REP
;
4629 goto elementContent
;
4630 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4631 quant
= XML_CQUANT_PLUS
;
4633 if (dtd
->in_eldecl
) {
4635 const XML_Char
*name
;
4637 const char *nxt
= (quant
== XML_CQUANT_NONE
4639 : next
- enc
->minBytesPerChar
);
4640 int myindex
= nextScaffoldPart(parser
);
4642 return XML_ERROR_NO_MEMORY
;
4643 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4644 dtd
->scaffold
[myindex
].quant
= quant
;
4645 el
= getElementType(parser
, enc
, s
, nxt
);
4647 return XML_ERROR_NO_MEMORY
;
4649 dtd
->scaffold
[myindex
].name
= name
;
4651 for (; name
[nameLen
++]; );
4652 dtd
->contentStringLen
+= nameLen
;
4653 if (elementDeclHandler
)
4654 handleDefault
= XML_FALSE
;
4658 case XML_ROLE_GROUP_CLOSE
:
4659 quant
= XML_CQUANT_NONE
;
4661 case XML_ROLE_GROUP_CLOSE_OPT
:
4662 quant
= XML_CQUANT_OPT
;
4664 case XML_ROLE_GROUP_CLOSE_REP
:
4665 quant
= XML_CQUANT_REP
;
4667 case XML_ROLE_GROUP_CLOSE_PLUS
:
4668 quant
= XML_CQUANT_PLUS
;
4670 if (dtd
->in_eldecl
) {
4671 if (elementDeclHandler
)
4672 handleDefault
= XML_FALSE
;
4674 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4675 if (dtd
->scaffLevel
== 0) {
4676 if (!handleDefault
) {
4677 XML_Content
*model
= build_model(parser
);
4679 return XML_ERROR_NO_MEMORY
;
4681 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4683 dtd
->in_eldecl
= XML_FALSE
;
4684 dtd
->contentStringLen
= 0;
4688 /* End element declaration stuff */
4691 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4692 return XML_ERROR_NO_MEMORY
;
4693 handleDefault
= XML_FALSE
;
4695 case XML_ROLE_COMMENT
:
4696 if (!reportComment(parser
, enc
, s
, next
))
4697 return XML_ERROR_NO_MEMORY
;
4698 handleDefault
= XML_FALSE
;
4703 handleDefault
= XML_FALSE
;
4707 case XML_ROLE_DOCTYPE_NONE
:
4708 if (startDoctypeDeclHandler
)
4709 handleDefault
= XML_FALSE
;
4711 case XML_ROLE_ENTITY_NONE
:
4712 if (dtd
->keepProcessing
&& entityDeclHandler
)
4713 handleDefault
= XML_FALSE
;
4715 case XML_ROLE_NOTATION_NONE
:
4716 if (notationDeclHandler
)
4717 handleDefault
= XML_FALSE
;
4719 case XML_ROLE_ATTLIST_NONE
:
4720 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4721 handleDefault
= XML_FALSE
;
4723 case XML_ROLE_ELEMENT_NONE
:
4724 if (elementDeclHandler
)
4725 handleDefault
= XML_FALSE
;
4727 } /* end of big switch */
4729 if (handleDefault
&& defaultHandler
)
4730 reportDefault(parser
, enc
, s
, next
);
4732 switch (ps_parsing
) {
4735 return XML_ERROR_NONE
;
4737 return XML_ERROR_ABORTED
;
4740 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4746 static enum XML_Error PTRCALL
4747 epilogProcessor(XML_Parser parser
,
4750 const char **nextPtr
)
4752 processor
= epilogProcessor
;
4755 const char *next
= NULL
;
4756 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4759 /* report partial linebreak - it might be the last token */
4760 case -XML_TOK_PROLOG_S
:
4761 if (defaultHandler
) {
4762 reportDefault(parser
, encoding
, s
, next
);
4763 if (ps_parsing
== XML_FINISHED
)
4764 return XML_ERROR_ABORTED
;
4767 return XML_ERROR_NONE
;
4770 return XML_ERROR_NONE
;
4771 case XML_TOK_PROLOG_S
:
4773 reportDefault(parser
, encoding
, s
, next
);
4776 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4777 return XML_ERROR_NO_MEMORY
;
4779 case XML_TOK_COMMENT
:
4780 if (!reportComment(parser
, encoding
, s
, next
))
4781 return XML_ERROR_NO_MEMORY
;
4783 case XML_TOK_INVALID
:
4785 return XML_ERROR_INVALID_TOKEN
;
4786 case XML_TOK_PARTIAL
:
4787 if (!ps_finalBuffer
) {
4789 return XML_ERROR_NONE
;
4791 return XML_ERROR_UNCLOSED_TOKEN
;
4792 case XML_TOK_PARTIAL_CHAR
:
4793 if (!ps_finalBuffer
) {
4795 return XML_ERROR_NONE
;
4797 return XML_ERROR_PARTIAL_CHAR
;
4799 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4801 eventPtr
= s
= next
;
4802 switch (ps_parsing
) {
4805 return XML_ERROR_NONE
;
4807 return XML_ERROR_ABORTED
;
4813 static enum XML_Error
4814 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4815 XML_Bool betweenDecl
)
4817 const char *textStart
, *textEnd
;
4819 enum XML_Error result
;
4820 OPEN_INTERNAL_ENTITY
*openEntity
;
4822 if (freeInternalEntities
) {
4823 openEntity
= freeInternalEntities
;
4824 freeInternalEntities
= openEntity
->next
;
4827 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4829 return XML_ERROR_NO_MEMORY
;
4831 entity
->open
= XML_TRUE
;
4832 entity
->processed
= 0;
4833 openEntity
->next
= openInternalEntities
;
4834 openInternalEntities
= openEntity
;
4835 openEntity
->entity
= entity
;
4836 openEntity
->startTagLevel
= tagLevel
;
4837 openEntity
->betweenDecl
= betweenDecl
;
4838 openEntity
->internalEventPtr
= NULL
;
4839 openEntity
->internalEventEndPtr
= NULL
;
4840 textStart
= (char *)entity
->textPtr
;
4841 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4844 if (entity
->is_param
) {
4845 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4846 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4847 next
, &next
, XML_FALSE
);
4850 #endif /* XML_DTD */
4851 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4852 textEnd
, &next
, XML_FALSE
);
4854 if (result
== XML_ERROR_NONE
) {
4855 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4856 entity
->processed
= (int)(next
- textStart
);
4857 processor
= internalEntityProcessor
;
4860 entity
->open
= XML_FALSE
;
4861 openInternalEntities
= openEntity
->next
;
4862 /* put openEntity back in list of free instances */
4863 openEntity
->next
= freeInternalEntities
;
4864 freeInternalEntities
= openEntity
;
4870 static enum XML_Error PTRCALL
4871 internalEntityProcessor(XML_Parser parser
,
4874 const char **nextPtr
)
4877 const char *textStart
, *textEnd
;
4879 enum XML_Error result
;
4880 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4882 return XML_ERROR_UNEXPECTED_STATE
;
4884 entity
= openEntity
->entity
;
4885 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4886 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4889 if (entity
->is_param
) {
4890 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4891 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4892 next
, &next
, XML_FALSE
);
4895 #endif /* XML_DTD */
4896 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4897 textStart
, textEnd
, &next
, XML_FALSE
);
4899 if (result
!= XML_ERROR_NONE
)
4901 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4902 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4906 entity
->open
= XML_FALSE
;
4907 openInternalEntities
= openEntity
->next
;
4908 /* put openEntity back in list of free instances */
4909 openEntity
->next
= freeInternalEntities
;
4910 freeInternalEntities
= openEntity
;
4914 if (entity
->is_param
) {
4916 processor
= prologProcessor
;
4917 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4918 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4919 (XML_Bool
)!ps_finalBuffer
);
4922 #endif /* XML_DTD */
4924 processor
= contentProcessor
;
4925 /* see externalEntityContentProcessor vs contentProcessor */
4926 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4927 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4931 static enum XML_Error PTRCALL
4932 errorProcessor(XML_Parser parser
,
4935 const char **nextPtr
)
4940 static enum XML_Error
4941 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4942 const char *ptr
, const char *end
,
4945 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4949 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4951 if (!poolAppendChar(pool
, XML_T('\0')))
4952 return XML_ERROR_NO_MEMORY
;
4953 return XML_ERROR_NONE
;
4956 static enum XML_Error
4957 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4958 const char *ptr
, const char *end
,
4961 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4964 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4967 return XML_ERROR_NONE
;
4968 case XML_TOK_INVALID
:
4969 if (enc
== encoding
)
4971 return XML_ERROR_INVALID_TOKEN
;
4972 case XML_TOK_PARTIAL
:
4973 if (enc
== encoding
)
4975 return XML_ERROR_INVALID_TOKEN
;
4976 case XML_TOK_CHAR_REF
:
4978 XML_Char buf
[XML_ENCODE_MAX
];
4980 int n
= XmlCharRefNumber(enc
, ptr
);
4982 if (enc
== encoding
)
4984 return XML_ERROR_BAD_CHAR_REF
;
4987 && n
== 0x20 /* space */
4988 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4990 n
= XmlEncode(n
, (ICHAR
*)buf
);
4992 if (enc
== encoding
)
4994 return XML_ERROR_BAD_CHAR_REF
;
4996 for (i
= 0; i
< n
; i
++) {
4997 if (!poolAppendChar(pool
, buf
[i
]))
4998 return XML_ERROR_NO_MEMORY
;
5002 case XML_TOK_DATA_CHARS
:
5003 if (!poolAppend(pool
, enc
, ptr
, next
))
5004 return XML_ERROR_NO_MEMORY
;
5006 case XML_TOK_TRAILING_CR
:
5007 next
= ptr
+ enc
->minBytesPerChar
;
5009 case XML_TOK_ATTRIBUTE_VALUE_S
:
5010 case XML_TOK_DATA_NEWLINE
:
5011 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
5013 if (!poolAppendChar(pool
, 0x20))
5014 return XML_ERROR_NO_MEMORY
;
5016 case XML_TOK_ENTITY_REF
:
5018 const XML_Char
*name
;
5020 char checkEntityDecl
;
5021 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
5022 ptr
+ enc
->minBytesPerChar
,
5023 next
- enc
->minBytesPerChar
);
5025 if (!poolAppendChar(pool
, ch
))
5026 return XML_ERROR_NO_MEMORY
;
5029 name
= poolStoreString(&temp2Pool
, enc
,
5030 ptr
+ enc
->minBytesPerChar
,
5031 next
- enc
->minBytesPerChar
);
5033 return XML_ERROR_NO_MEMORY
;
5034 entity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
, 0);
5035 poolDiscard(&temp2Pool
);
5036 /* First, determine if a check for an existing declaration is needed;
5037 if yes, check that the entity exists, and that it is internal.
5039 if (pool
== &dtd
->pool
) /* are we called from prolog? */
5042 prologState
.documentEntity
&&
5043 #endif /* XML_DTD */
5045 ? !openInternalEntities
5046 : !dtd
->hasParamEntityRefs
);
5047 else /* if (pool == &tempPool): we are called from content */
5048 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
5049 if (checkEntityDecl
) {
5051 return XML_ERROR_UNDEFINED_ENTITY
;
5052 else if (!entity
->is_internal
)
5053 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
5056 /* Cannot report skipped entity here - see comments on
5057 skippedEntityHandler.
5058 if (skippedEntityHandler)
5059 skippedEntityHandler(handlerArg, name, 0);
5061 /* Cannot call the default handler because this would be
5062 out of sync with the call to the startElementHandler.
5063 if ((pool == &tempPool) && defaultHandler)
5064 reportDefault(parser, enc, ptr, next);
5069 if (enc
== encoding
)
5071 return XML_ERROR_RECURSIVE_ENTITY_REF
;
5073 if (entity
->notation
) {
5074 if (enc
== encoding
)
5076 return XML_ERROR_BINARY_ENTITY_REF
;
5078 if (!entity
->textPtr
) {
5079 if (enc
== encoding
)
5081 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
5084 enum XML_Error result
;
5085 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
5086 entity
->open
= XML_TRUE
;
5087 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
5088 (char *)entity
->textPtr
,
5089 (char *)textEnd
, pool
);
5090 entity
->open
= XML_FALSE
;
5097 if (enc
== encoding
)
5099 return XML_ERROR_UNEXPECTED_STATE
;
5106 static enum XML_Error
5107 storeEntityValue(XML_Parser parser
,
5108 const ENCODING
*enc
,
5109 const char *entityTextPtr
,
5110 const char *entityTextEnd
)
5112 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5113 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
5114 enum XML_Error result
= XML_ERROR_NONE
;
5116 int oldInEntityValue
= prologState
.inEntityValue
;
5117 prologState
.inEntityValue
= 1;
5118 #endif /* XML_DTD */
5119 /* never return Null for the value argument in EntityDeclHandler,
5120 since this would indicate an external entity; therefore we
5121 have to make sure that entityValuePool.start is not null */
5122 if (!pool
->blocks
) {
5123 if (!poolGrow(pool
))
5124 return XML_ERROR_NO_MEMORY
;
5129 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
5131 case XML_TOK_PARAM_ENTITY_REF
:
5133 if (isParamEntity
|| enc
!= encoding
) {
5134 const XML_Char
*name
;
5136 name
= poolStoreString(&tempPool
, enc
,
5137 entityTextPtr
+ enc
->minBytesPerChar
,
5138 next
- enc
->minBytesPerChar
);
5140 result
= XML_ERROR_NO_MEMORY
;
5141 goto endEntityValue
;
5143 entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
, name
, 0);
5144 poolDiscard(&tempPool
);
5146 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5147 /* cannot report skipped entity here - see comments on
5148 skippedEntityHandler
5149 if (skippedEntityHandler)
5150 skippedEntityHandler(handlerArg, name, 0);
5152 dtd
->keepProcessing
= dtd
->standalone
;
5153 goto endEntityValue
;
5156 if (enc
== encoding
)
5157 eventPtr
= entityTextPtr
;
5158 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5159 goto endEntityValue
;
5161 if (entity
->systemId
) {
5162 if (externalEntityRefHandler
) {
5163 dtd
->paramEntityRead
= XML_FALSE
;
5164 entity
->open
= XML_TRUE
;
5165 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5169 entity
->publicId
)) {
5170 entity
->open
= XML_FALSE
;
5171 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5172 goto endEntityValue
;
5174 entity
->open
= XML_FALSE
;
5175 if (!dtd
->paramEntityRead
)
5176 dtd
->keepProcessing
= dtd
->standalone
;
5179 dtd
->keepProcessing
= dtd
->standalone
;
5182 entity
->open
= XML_TRUE
;
5183 result
= storeEntityValue(parser
,
5185 (char *)entity
->textPtr
,
5186 (char *)(entity
->textPtr
5187 + entity
->textLen
));
5188 entity
->open
= XML_FALSE
;
5190 goto endEntityValue
;
5194 #endif /* XML_DTD */
5195 /* In the internal subset, PE references are not legal
5196 within markup declarations, e.g entity values in this case. */
5197 eventPtr
= entityTextPtr
;
5198 result
= XML_ERROR_PARAM_ENTITY_REF
;
5199 goto endEntityValue
;
5201 result
= XML_ERROR_NONE
;
5202 goto endEntityValue
;
5203 case XML_TOK_ENTITY_REF
:
5204 case XML_TOK_DATA_CHARS
:
5205 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5206 result
= XML_ERROR_NO_MEMORY
;
5207 goto endEntityValue
;
5210 case XML_TOK_TRAILING_CR
:
5211 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5213 case XML_TOK_DATA_NEWLINE
:
5214 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5215 result
= XML_ERROR_NO_MEMORY
;
5216 goto endEntityValue
;
5218 *(pool
->ptr
)++ = 0xA;
5220 case XML_TOK_CHAR_REF
:
5222 XML_Char buf
[XML_ENCODE_MAX
];
5224 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5226 if (enc
== encoding
)
5227 eventPtr
= entityTextPtr
;
5228 result
= XML_ERROR_BAD_CHAR_REF
;
5229 goto endEntityValue
;
5231 n
= XmlEncode(n
, (ICHAR
*)buf
);
5233 if (enc
== encoding
)
5234 eventPtr
= entityTextPtr
;
5235 result
= XML_ERROR_BAD_CHAR_REF
;
5236 goto endEntityValue
;
5238 for (i
= 0; i
< n
; i
++) {
5239 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5240 result
= XML_ERROR_NO_MEMORY
;
5241 goto endEntityValue
;
5243 *(pool
->ptr
)++ = buf
[i
];
5247 case XML_TOK_PARTIAL
:
5248 if (enc
== encoding
)
5249 eventPtr
= entityTextPtr
;
5250 result
= XML_ERROR_INVALID_TOKEN
;
5251 goto endEntityValue
;
5252 case XML_TOK_INVALID
:
5253 if (enc
== encoding
)
5255 result
= XML_ERROR_INVALID_TOKEN
;
5256 goto endEntityValue
;
5258 if (enc
== encoding
)
5259 eventPtr
= entityTextPtr
;
5260 result
= XML_ERROR_UNEXPECTED_STATE
;
5261 goto endEntityValue
;
5263 entityTextPtr
= next
;
5267 prologState
.inEntityValue
= oldInEntityValue
;
5268 #endif /* XML_DTD */
5272 static void FASTCALL
5273 normalizeLines(XML_Char
*s
)
5277 if (*s
== XML_T('\0'))
5296 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5297 const char *start
, const char *end
)
5299 const XML_Char
*target
;
5302 if (!processingInstructionHandler
) {
5304 reportDefault(parser
, enc
, start
, end
);
5307 start
+= enc
->minBytesPerChar
* 2;
5308 tem
= start
+ XmlNameLength(enc
, start
);
5309 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5312 poolFinish(&tempPool
);
5313 data
= poolStoreString(&tempPool
, enc
,
5315 end
- enc
->minBytesPerChar
*2);
5318 normalizeLines(data
);
5319 processingInstructionHandler(handlerArg
, target
, data
);
5320 poolClear(&tempPool
);
5325 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5326 const char *start
, const char *end
)
5329 if (!commentHandler
) {
5331 reportDefault(parser
, enc
, start
, end
);
5334 data
= poolStoreString(&tempPool
,
5336 start
+ enc
->minBytesPerChar
* 4,
5337 end
- enc
->minBytesPerChar
* 3);
5340 normalizeLines(data
);
5341 commentHandler(handlerArg
, data
);
5342 poolClear(&tempPool
);
5347 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5348 const char *s
, const char *end
)
5350 if (MUST_CONVERT(enc
, s
)) {
5351 const char **eventPP
;
5352 const char **eventEndPP
;
5353 if (enc
== encoding
) {
5354 eventPP
= &eventPtr
;
5355 eventEndPP
= &eventEndPtr
;
5358 eventPP
= &(openInternalEntities
->internalEventPtr
);
5359 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5362 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5363 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5365 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5370 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5375 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5376 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5378 DEFAULT_ATTRIBUTE
*att
;
5379 if (value
|| isId
) {
5380 /* The handling of default attributes gets messed up if we have
5381 a default which duplicates a non-default. */
5383 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5384 if (attId
== type
->defaultAtts
[i
].id
)
5386 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5387 type
->idAtt
= attId
;
5389 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5390 if (type
->allocDefaultAtts
== 0) {
5391 type
->allocDefaultAtts
= 8;
5392 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5393 * sizeof(DEFAULT_ATTRIBUTE
));
5394 if (!type
->defaultAtts
)
5398 DEFAULT_ATTRIBUTE
*temp
;
5399 int count
= type
->allocDefaultAtts
* 2;
5400 temp
= (DEFAULT_ATTRIBUTE
*)
5401 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5404 type
->allocDefaultAtts
= count
;
5405 type
->defaultAtts
= temp
;
5408 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5411 att
->isCdata
= isCdata
;
5413 attId
->maybeTokenized
= XML_TRUE
;
5414 type
->nDefaultAtts
+= 1;
5419 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5421 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5422 const XML_Char
*name
;
5423 for (name
= elementType
->name
; *name
; name
++) {
5424 if (*name
== XML_T(ASCII_COLON
)) {
5427 for (s
= elementType
->name
; s
!= name
; s
++) {
5428 if (!poolAppendChar(&dtd
->pool
, *s
))
5431 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5433 prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&dtd
->pool
),
5437 if (prefix
->name
== poolStart(&dtd
->pool
))
5438 poolFinish(&dtd
->pool
);
5440 poolDiscard(&dtd
->pool
);
5441 elementType
->prefix
= prefix
;
5448 static ATTRIBUTE_ID
*
5449 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5450 const char *start
, const char *end
)
5452 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5454 const XML_Char
*name
;
5455 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5457 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5460 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5462 id
= (ATTRIBUTE_ID
*)lookup(parser
, &dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5465 if (id
->name
!= name
)
5466 poolDiscard(&dtd
->pool
);
5468 poolFinish(&dtd
->pool
);
5471 else if (name
[0] == XML_T(ASCII_x
)
5472 && name
[1] == XML_T(ASCII_m
)
5473 && name
[2] == XML_T(ASCII_l
)
5474 && name
[3] == XML_T(ASCII_n
)
5475 && name
[4] == XML_T(ASCII_s
)
5476 && (name
[5] == XML_T('\0') || name
[5] == XML_T(ASCII_COLON
))) {
5477 if (name
[5] == XML_T('\0'))
5478 id
->prefix
= &dtd
->defaultPrefix
;
5480 id
->prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5481 id
->xmlns
= XML_TRUE
;
5485 for (i
= 0; name
[i
]; i
++) {
5486 /* attributes without prefix are *not* in the default namespace */
5487 if (name
[i
] == XML_T(ASCII_COLON
)) {
5489 for (j
= 0; j
< i
; j
++) {
5490 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5493 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5495 id
->prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&dtd
->pool
),
5497 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5498 poolFinish(&dtd
->pool
);
5500 poolDiscard(&dtd
->pool
);
5509 #define CONTEXT_SEP XML_T(ASCII_FF)
5511 static const XML_Char
*
5512 getContext(XML_Parser parser
)
5514 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5515 HASH_TABLE_ITER iter
;
5516 XML_Bool needSep
= XML_FALSE
;
5518 if (dtd
->defaultPrefix
.binding
) {
5521 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5523 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5524 if (namespaceSeparator
)
5526 for (i
= 0; i
< len
; i
++)
5527 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5532 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5537 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5540 if (!prefix
->binding
)
5542 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5544 for (s
= prefix
->name
; *s
; s
++)
5545 if (!poolAppendChar(&tempPool
, *s
))
5547 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5549 len
= prefix
->binding
->uriLen
;
5550 if (namespaceSeparator
)
5552 for (i
= 0; i
< len
; i
++)
5553 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5559 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5562 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5567 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5569 for (s
= e
->name
; *s
; s
++)
5570 if (!poolAppendChar(&tempPool
, *s
))
5575 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5577 return tempPool
.start
;
5581 setContext(XML_Parser parser
, const XML_Char
*context
)
5583 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5584 const XML_Char
*s
= context
;
5586 while (*context
!= XML_T('\0')) {
5587 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5589 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5591 e
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, poolStart(&tempPool
), 0);
5594 if (*s
!= XML_T('\0'))
5597 poolDiscard(&tempPool
);
5599 else if (*s
== XML_T(ASCII_EQUALS
)) {
5601 if (poolLength(&tempPool
) == 0)
5602 prefix
= &dtd
->defaultPrefix
;
5604 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5606 prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&tempPool
),
5610 if (prefix
->name
== poolStart(&tempPool
)) {
5611 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5615 poolDiscard(&tempPool
);
5617 for (context
= s
+ 1;
5618 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5620 if (!poolAppendChar(&tempPool
, *context
))
5622 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5624 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5625 &inheritedBindings
) != XML_ERROR_NONE
)
5627 poolDiscard(&tempPool
);
5628 if (*context
!= XML_T('\0'))
5633 if (!poolAppendChar(&tempPool
, *s
))
5641 static void FASTCALL
5642 normalizePublicId(XML_Char
*publicId
)
5644 XML_Char
*p
= publicId
;
5646 for (s
= publicId
; *s
; s
++) {
5651 if (p
!= publicId
&& p
[-1] != 0x20)
5658 if (p
!= publicId
&& p
[-1] == 0x20)
5664 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5666 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5669 poolInit(&(p
->pool
), ms
);
5670 poolInit(&(p
->entityValuePool
), ms
);
5671 hashTableInit(&(p
->generalEntities
), ms
);
5672 hashTableInit(&(p
->elementTypes
), ms
);
5673 hashTableInit(&(p
->attributeIds
), ms
);
5674 hashTableInit(&(p
->prefixes
), ms
);
5676 p
->paramEntityRead
= XML_FALSE
;
5677 hashTableInit(&(p
->paramEntities
), ms
);
5678 #endif /* XML_DTD */
5679 p
->defaultPrefix
.name
= NULL
;
5680 p
->defaultPrefix
.binding
= NULL
;
5682 p
->in_eldecl
= XML_FALSE
;
5683 p
->scaffIndex
= NULL
;
5688 p
->contentStringLen
= 0;
5690 p
->keepProcessing
= XML_TRUE
;
5691 p
->hasParamEntityRefs
= XML_FALSE
;
5692 p
->standalone
= XML_FALSE
;
5697 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5699 HASH_TABLE_ITER iter
;
5700 hashTableIterInit(&iter
, &(p
->elementTypes
));
5702 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5705 if (e
->allocDefaultAtts
!= 0)
5706 ms
->free_fcn(e
->defaultAtts
);
5708 hashTableClear(&(p
->generalEntities
));
5710 p
->paramEntityRead
= XML_FALSE
;
5711 hashTableClear(&(p
->paramEntities
));
5712 #endif /* XML_DTD */
5713 hashTableClear(&(p
->elementTypes
));
5714 hashTableClear(&(p
->attributeIds
));
5715 hashTableClear(&(p
->prefixes
));
5716 poolClear(&(p
->pool
));
5717 poolClear(&(p
->entityValuePool
));
5718 p
->defaultPrefix
.name
= NULL
;
5719 p
->defaultPrefix
.binding
= NULL
;
5721 p
->in_eldecl
= XML_FALSE
;
5723 ms
->free_fcn(p
->scaffIndex
);
5724 p
->scaffIndex
= NULL
;
5725 ms
->free_fcn(p
->scaffold
);
5731 p
->contentStringLen
= 0;
5733 p
->keepProcessing
= XML_TRUE
;
5734 p
->hasParamEntityRefs
= XML_FALSE
;
5735 p
->standalone
= XML_FALSE
;
5739 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5741 HASH_TABLE_ITER iter
;
5742 hashTableIterInit(&iter
, &(p
->elementTypes
));
5744 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5747 if (e
->allocDefaultAtts
!= 0)
5748 ms
->free_fcn(e
->defaultAtts
);
5750 hashTableDestroy(&(p
->generalEntities
));
5752 hashTableDestroy(&(p
->paramEntities
));
5753 #endif /* XML_DTD */
5754 hashTableDestroy(&(p
->elementTypes
));
5755 hashTableDestroy(&(p
->attributeIds
));
5756 hashTableDestroy(&(p
->prefixes
));
5757 poolDestroy(&(p
->pool
));
5758 poolDestroy(&(p
->entityValuePool
));
5760 ms
->free_fcn(p
->scaffIndex
);
5761 ms
->free_fcn(p
->scaffold
);
5766 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5767 The new DTD has already been initialized.
5770 dtdCopy(XML_Parser oldParser
, DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5772 HASH_TABLE_ITER iter
;
5774 /* Copy the prefix table. */
5776 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5778 const XML_Char
*name
;
5779 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5782 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5785 if (!lookup(oldParser
, &(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5789 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5791 /* Copy the attribute id table. */
5795 const XML_Char
*name
;
5796 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5800 /* Remember to allocate the scratch byte before the name. */
5801 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5803 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5807 newA
= (ATTRIBUTE_ID
*)lookup(oldParser
, &(newDtd
->attributeIds
), name
,
5808 sizeof(ATTRIBUTE_ID
));
5811 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5813 newA
->xmlns
= oldA
->xmlns
;
5814 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5815 newA
->prefix
= &newDtd
->defaultPrefix
;
5817 newA
->prefix
= (PREFIX
*)lookup(oldParser
, &(newDtd
->prefixes
),
5818 oldA
->prefix
->name
, 0);
5822 /* Copy the element type table. */
5824 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5829 const XML_Char
*name
;
5830 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5833 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5836 newE
= (ELEMENT_TYPE
*)lookup(oldParser
, &(newDtd
->elementTypes
), name
,
5837 sizeof(ELEMENT_TYPE
));
5840 if (oldE
->nDefaultAtts
) {
5841 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5842 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5843 if (!newE
->defaultAtts
) {
5849 newE
->idAtt
= (ATTRIBUTE_ID
*)
5850 lookup(oldParser
, &(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5851 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5853 newE
->prefix
= (PREFIX
*)lookup(oldParser
, &(newDtd
->prefixes
),
5854 oldE
->prefix
->name
, 0);
5855 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5856 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5857 lookup(oldParser
, &(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5858 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5859 if (oldE
->defaultAtts
[i
].value
) {
5860 newE
->defaultAtts
[i
].value
5861 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5862 if (!newE
->defaultAtts
[i
].value
)
5866 newE
->defaultAtts
[i
].value
= NULL
;
5870 /* Copy the entity tables. */
5871 if (!copyEntityTable(oldParser
,
5872 &(newDtd
->generalEntities
),
5874 &(oldDtd
->generalEntities
)))
5878 if (!copyEntityTable(oldParser
,
5879 &(newDtd
->paramEntities
),
5881 &(oldDtd
->paramEntities
)))
5883 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5884 #endif /* XML_DTD */
5886 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5887 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5888 newDtd
->standalone
= oldDtd
->standalone
;
5890 /* Don't want deep copying for scaffolding */
5891 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5892 newDtd
->scaffold
= oldDtd
->scaffold
;
5893 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5894 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5895 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5896 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5902 copyEntityTable(XML_Parser oldParser
,
5903 HASH_TABLE
*newTable
,
5904 STRING_POOL
*newPool
,
5905 const HASH_TABLE
*oldTable
)
5907 HASH_TABLE_ITER iter
;
5908 const XML_Char
*cachedOldBase
= NULL
;
5909 const XML_Char
*cachedNewBase
= NULL
;
5911 hashTableIterInit(&iter
, oldTable
);
5915 const XML_Char
*name
;
5916 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5919 name
= poolCopyString(newPool
, oldE
->name
);
5922 newE
= (ENTITY
*)lookup(oldParser
, newTable
, name
, sizeof(ENTITY
));
5925 if (oldE
->systemId
) {
5926 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5929 newE
->systemId
= tem
;
5931 if (oldE
->base
== cachedOldBase
)
5932 newE
->base
= cachedNewBase
;
5934 cachedOldBase
= oldE
->base
;
5935 tem
= poolCopyString(newPool
, cachedOldBase
);
5938 cachedNewBase
= newE
->base
= tem
;
5941 if (oldE
->publicId
) {
5942 tem
= poolCopyString(newPool
, oldE
->publicId
);
5945 newE
->publicId
= tem
;
5949 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5953 newE
->textPtr
= tem
;
5954 newE
->textLen
= oldE
->textLen
;
5956 if (oldE
->notation
) {
5957 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5960 newE
->notation
= tem
;
5962 newE
->is_param
= oldE
->is_param
;
5963 newE
->is_internal
= oldE
->is_internal
;
5968 #define INIT_POWER 6
5970 static XML_Bool FASTCALL
5971 keyeq(KEY s1
, KEY s2
)
5973 for (; *s1
== *s2
; s1
++, s2
++)
5979 static unsigned long FASTCALL
5980 hash(XML_Parser parser
, KEY s
)
5982 unsigned long h
= hash_secret_salt
;
5984 h
= CHAR_HASH(h
, *s
++);
5989 lookup(XML_Parser parser
, HASH_TABLE
*table
, KEY name
, size_t createSize
)
5992 if (table
->size
== 0) {
5996 table
->power
= INIT_POWER
;
5997 /* table->size is a power of 2 */
5998 table
->size
= (size_t)1 << INIT_POWER
;
5999 tsize
= table
->size
* sizeof(NAMED
*);
6000 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
6005 memset(table
->v
, 0, tsize
);
6006 i
= hash(parser
, name
) & ((unsigned long)table
->size
- 1);
6009 unsigned long h
= hash(parser
, name
);
6010 unsigned long mask
= (unsigned long)table
->size
- 1;
6011 unsigned char step
= 0;
6013 while (table
->v
[i
]) {
6014 if (keyeq(name
, table
->v
[i
]->name
))
6017 step
= PROBE_STEP(h
, mask
, table
->power
);
6018 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
6023 /* check for overflow (table is half full) */
6024 if (table
->used
>> (table
->power
- 1)) {
6025 unsigned char newPower
= table
->power
+ 1;
6026 size_t newSize
= (size_t)1 << newPower
;
6027 unsigned long newMask
= (unsigned long)newSize
- 1;
6028 size_t tsize
= newSize
* sizeof(NAMED
*);
6029 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
6032 memset(newV
, 0, tsize
);
6033 for (i
= 0; i
< table
->size
; i
++)
6035 unsigned long newHash
= hash(parser
, table
->v
[i
]->name
);
6036 size_t j
= newHash
& newMask
;
6040 step
= PROBE_STEP(newHash
, newMask
, newPower
);
6041 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
6043 newV
[j
] = table
->v
[i
];
6045 table
->mem
->free_fcn(table
->v
);
6047 table
->power
= newPower
;
6048 table
->size
= newSize
;
6051 while (table
->v
[i
]) {
6053 step
= PROBE_STEP(h
, newMask
, newPower
);
6054 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
6058 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
6061 memset(table
->v
[i
], 0, createSize
);
6062 table
->v
[i
]->name
= name
;
6067 static void FASTCALL
6068 hashTableClear(HASH_TABLE
*table
)
6071 for (i
= 0; i
< table
->size
; i
++) {
6072 table
->mem
->free_fcn(table
->v
[i
]);
6078 static void FASTCALL
6079 hashTableDestroy(HASH_TABLE
*table
)
6082 for (i
= 0; i
< table
->size
; i
++)
6083 table
->mem
->free_fcn(table
->v
[i
]);
6084 table
->mem
->free_fcn(table
->v
);
6087 static void FASTCALL
6088 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
6097 static void FASTCALL
6098 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
6101 iter
->end
= iter
->p
+ table
->size
;
6104 static NAMED
* FASTCALL
6105 hashTableIterNext(HASH_TABLE_ITER
*iter
)
6107 while (iter
->p
!= iter
->end
) {
6108 NAMED
*tem
= *(iter
->p
)++;
6115 static void FASTCALL
6116 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
6118 pool
->blocks
= NULL
;
6119 pool
->freeBlocks
= NULL
;
6126 static void FASTCALL
6127 poolClear(STRING_POOL
*pool
)
6129 if (!pool
->freeBlocks
)
6130 pool
->freeBlocks
= pool
->blocks
;
6132 BLOCK
*p
= pool
->blocks
;
6134 BLOCK
*tem
= p
->next
;
6135 p
->next
= pool
->freeBlocks
;
6136 pool
->freeBlocks
= p
;
6140 pool
->blocks
= NULL
;
6146 static void FASTCALL
6147 poolDestroy(STRING_POOL
*pool
)
6149 BLOCK
*p
= pool
->blocks
;
6151 BLOCK
*tem
= p
->next
;
6152 pool
->mem
->free_fcn(p
);
6155 p
= pool
->freeBlocks
;
6157 BLOCK
*tem
= p
->next
;
6158 pool
->mem
->free_fcn(p
);
6164 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6165 const char *ptr
, const char *end
)
6167 if (!pool
->ptr
&& !poolGrow(pool
))
6170 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6173 if (!poolGrow(pool
))
6179 static const XML_Char
* FASTCALL
6180 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6183 if (!poolAppendChar(pool
, *s
))
6191 static const XML_Char
*
6192 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6194 if (!pool
->ptr
&& !poolGrow(pool
))
6196 for (; n
> 0; --n
, s
++) {
6197 if (!poolAppendChar(pool
, *s
))
6205 static const XML_Char
* FASTCALL
6206 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6209 if (!poolAppendChar(pool
, *s
))
6217 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6218 const char *ptr
, const char *end
)
6220 if (!poolAppend(pool
, enc
, ptr
, end
))
6222 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6228 static XML_Bool FASTCALL
6229 poolGrow(STRING_POOL
*pool
)
6231 if (pool
->freeBlocks
) {
6232 if (pool
->start
== 0) {
6233 pool
->blocks
= pool
->freeBlocks
;
6234 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6235 pool
->blocks
->next
= NULL
;
6236 pool
->start
= pool
->blocks
->s
;
6237 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6238 pool
->ptr
= pool
->start
;
6241 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6242 BLOCK
*tem
= pool
->freeBlocks
->next
;
6243 pool
->freeBlocks
->next
= pool
->blocks
;
6244 pool
->blocks
= pool
->freeBlocks
;
6245 pool
->freeBlocks
= tem
;
6246 memcpy(pool
->blocks
->s
, pool
->start
,
6247 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6248 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6249 pool
->start
= pool
->blocks
->s
;
6250 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6254 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6255 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6256 BLOCK
*temp
= (BLOCK
*)
6257 pool
->mem
->realloc_fcn(pool
->blocks
,
6259 + blockSize
* sizeof(XML_Char
)));
6262 pool
->blocks
= temp
;
6263 pool
->blocks
->size
= blockSize
;
6264 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6265 pool
->start
= pool
->blocks
->s
;
6266 pool
->end
= pool
->start
+ blockSize
;
6270 int blockSize
= (int)(pool
->end
- pool
->start
);
6271 if (blockSize
< INIT_BLOCK_SIZE
)
6272 blockSize
= INIT_BLOCK_SIZE
;
6275 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6276 + blockSize
* sizeof(XML_Char
));
6279 tem
->size
= blockSize
;
6280 tem
->next
= pool
->blocks
;
6282 if (pool
->ptr
!= pool
->start
)
6283 memcpy(tem
->s
, pool
->start
,
6284 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6285 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6286 pool
->start
= tem
->s
;
6287 pool
->end
= tem
->s
+ blockSize
;
6293 nextScaffoldPart(XML_Parser parser
)
6295 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6296 CONTENT_SCAFFOLD
* me
;
6299 if (!dtd
->scaffIndex
) {
6300 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6301 if (!dtd
->scaffIndex
)
6303 dtd
->scaffIndex
[0] = 0;
6306 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6307 CONTENT_SCAFFOLD
*temp
;
6308 if (dtd
->scaffold
) {
6309 temp
= (CONTENT_SCAFFOLD
*)
6310 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6313 dtd
->scaffSize
*= 2;
6316 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6317 * sizeof(CONTENT_SCAFFOLD
));
6320 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6322 dtd
->scaffold
= temp
;
6324 next
= dtd
->scaffCount
++;
6325 me
= &dtd
->scaffold
[next
];
6326 if (dtd
->scaffLevel
) {
6327 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6328 if (parent
->lastchild
) {
6329 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6331 if (!parent
->childcnt
)
6332 parent
->firstchild
= next
;
6333 parent
->lastchild
= next
;
6336 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6341 build_node(XML_Parser parser
,
6344 XML_Content
**contpos
,
6347 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6348 dest
->type
= dtd
->scaffold
[src_node
].type
;
6349 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6350 if (dest
->type
== XML_CTYPE_NAME
) {
6351 const XML_Char
*src
;
6352 dest
->name
= *strpos
;
6353 src
= dtd
->scaffold
[src_node
].name
;
6355 *(*strpos
)++ = *src
;
6360 dest
->numchildren
= 0;
6361 dest
->children
= NULL
;
6366 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6367 dest
->children
= *contpos
;
6368 *contpos
+= dest
->numchildren
;
6369 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6370 i
< dest
->numchildren
;
6371 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6372 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6378 static XML_Content
*
6379 build_model (XML_Parser parser
)
6381 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6385 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6386 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6388 ret
= (XML_Content
*)MALLOC(allocsize
);
6392 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6395 build_node(parser
, 0, ret
, &cpos
, &str
);
6399 static ELEMENT_TYPE
*
6400 getElementType(XML_Parser parser
,
6401 const ENCODING
*enc
,
6405 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6406 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6411 ret
= (ELEMENT_TYPE
*) lookup(parser
, &dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6414 if (ret
->name
!= name
)
6415 poolDiscard(&dtd
->pool
);
6417 poolFinish(&dtd
->pool
);
6418 if (!setElementTypePrefix(parser
, ret
))