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"
17 #include "os2config.h"
20 #elif defined(__MSDOS__)
22 #include "dosconfig.h"
25 #elif defined(MACOS_CLASSIC)
26 #include "macconfig.h"
27 #elif defined(__amigaos__)
28 #include "amigaconfig.h"
29 #elif defined(__WATCOMC__)
30 #include "watcomconfig.h"
31 #elif defined(HAVE_EXPAT_CONFIG_H)
32 #include "expat_config.h"
33 #endif /* ndef COMPILED_FROM_DSP */
39 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
40 #define XmlConvert XmlUtf16Convert
41 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
42 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
43 #define XmlEncode XmlUtf16Encode
44 /* Using pointer subtraction to convert to integer type. */
45 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
46 typedef unsigned short ICHAR
;
48 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
49 #define XmlConvert XmlUtf8Convert
50 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
51 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
52 #define XmlEncode XmlUtf8Encode
53 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
60 #define XmlInitEncodingNS XmlInitEncoding
61 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
62 #undef XmlGetInternalEncodingNS
63 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
64 #define XmlParseXmlDeclNS XmlParseXmlDecl
70 #ifdef XML_UNICODE_WCHAR_T
71 #define XML_T(x) (const wchar_t)x
72 #define XML_L(x) L ## x
74 #define XML_T(x) (const unsigned short)x
85 /* Round up n to be a multiple of sz, where sz is a power of 2. */
86 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
88 /* Handle the case where memmove() doesn't exist. */
91 #define memmove(d,s,l) bcopy((s),(d),(l))
93 #error memmove does not exist on this platform, nor is a substitute available
94 #endif /* HAVE_BCOPY */
95 #endif /* HAVE_MEMMOVE */
101 typedef const XML_Char
*KEY
;
112 const XML_Memory_Handling_Suite
*mem
;
115 /* Basic character hash algorithm, taken from Python's string hash:
116 h = h * 1000003 ^ character, the constant being a prime number.
120 #define CHAR_HASH(h, c) \
121 (((h) * 0xF4243) ^ (unsigned short)(c))
123 #define CHAR_HASH(h, c) \
124 (((h) * 0xF4243) ^ (unsigned char)(c))
127 /* For probing (after a collision) we need a step size relative prime
128 to the hash table size, which is a power of 2. We use double-hashing,
129 since we can calculate a second hash value cheaply by taking those bits
130 of the first hash value that were discarded (masked out) when the table
131 index was calculated: index = hash & mask, where mask = table->size - 1.
132 We limit the maximum step size to table->size / 4 (mask >> 2) and make
133 it odd, since odd numbers are always relative prime to a power of 2.
135 #define SECOND_HASH(hash, mask, power) \
136 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
137 #define PROBE_STEP(hash, mask, power) \
138 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
145 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
146 #define INIT_DATA_BUF_SIZE 1024
147 #define INIT_ATTS_SIZE 16
148 #define INIT_ATTS_VERSION 0xFFFFFFFF
149 #define INIT_BLOCK_SIZE 1024
150 #define INIT_BUFFER_SIZE 1024
152 #define EXPAND_SPARE 24
154 typedef struct binding
{
155 struct prefix
*prefix
;
156 struct binding
*nextTagBinding
;
157 struct binding
*prevPrefixBinding
;
158 const struct attribute_id
*attId
;
164 typedef struct prefix
{
165 const XML_Char
*name
;
171 const XML_Char
*localPart
;
172 const XML_Char
*prefix
;
178 /* TAG represents an open element.
179 The name of the element is stored in both the document and API
180 encodings. The memory buffer 'buf' is a separately-allocated
181 memory area which stores the name. During the XML_Parse()/
182 XMLParseBuffer() when the element is open, the memory for the 'raw'
183 version of the name (in the document encoding) is shared with the
184 document buffer. If the element is open across calls to
185 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
186 contain the 'raw' name as well.
188 A parser re-uses these structures, maintaining a list of allocated
189 TAG objects in a free list.
192 struct tag
*parent
; /* parent of this element */
193 const char *rawName
; /* tagName in the original encoding */
195 TAG_NAME name
; /* tagName in the API encoding */
196 char *buf
; /* buffer for name components */
197 char *bufEnd
; /* end of the buffer */
202 const XML_Char
*name
;
203 const XML_Char
*textPtr
;
204 int textLen
; /* length in XML_Chars */
205 int processed
; /* # of processed bytes - when suspended */
206 const XML_Char
*systemId
;
207 const XML_Char
*base
;
208 const XML_Char
*publicId
;
209 const XML_Char
*notation
;
212 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
216 enum XML_Content_Type type
;
217 enum XML_Content_Quant quant
;
218 const XML_Char
* name
;
225 #define INIT_SCAFFOLD_ELEMENTS 32
227 typedef struct block
{
239 const XML_Memory_Handling_Suite
*mem
;
242 /* The XML_Char before the name is used to determine whether
243 an attribute has been specified. */
244 typedef struct attribute_id
{
247 XML_Bool maybeTokenized
;
252 const ATTRIBUTE_ID
*id
;
254 const XML_Char
*value
;
258 unsigned long version
;
260 const XML_Char
*uriName
;
264 const XML_Char
*name
;
266 const ATTRIBUTE_ID
*idAtt
;
268 int allocDefaultAtts
;
269 DEFAULT_ATTRIBUTE
*defaultAtts
;
273 HASH_TABLE generalEntities
;
274 HASH_TABLE elementTypes
;
275 HASH_TABLE attributeIds
;
278 STRING_POOL entityValuePool
;
279 /* false once a parameter entity reference has been skipped */
280 XML_Bool keepProcessing
;
281 /* true once an internal or external PE reference has been encountered;
282 this includes the reference to an external subset */
283 XML_Bool hasParamEntityRefs
;
286 /* indicates if external PE has been read */
287 XML_Bool paramEntityRead
;
288 HASH_TABLE paramEntities
;
290 PREFIX defaultPrefix
;
291 /* === scaffolding for building content model === */
293 CONTENT_SCAFFOLD
*scaffold
;
294 unsigned contentStringLen
;
301 typedef struct open_internal_entity
{
302 const char *internalEventPtr
;
303 const char *internalEventEndPtr
;
304 struct open_internal_entity
*next
;
307 XML_Bool betweenDecl
; /* WFC: PE Between Declarations */
308 } OPEN_INTERNAL_ENTITY
;
310 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
313 const char **endPtr
);
315 static Processor prologProcessor
;
316 static Processor prologInitProcessor
;
317 static Processor contentProcessor
;
318 static Processor cdataSectionProcessor
;
320 static Processor ignoreSectionProcessor
;
321 static Processor externalParEntProcessor
;
322 static Processor externalParEntInitProcessor
;
323 static Processor entityValueProcessor
;
324 static Processor entityValueInitProcessor
;
326 static Processor epilogProcessor
;
327 static Processor errorProcessor
;
328 static Processor externalEntityInitProcessor
;
329 static Processor externalEntityInitProcessor2
;
330 static Processor externalEntityInitProcessor3
;
331 static Processor externalEntityContentProcessor
;
332 static Processor internalEntityProcessor
;
334 static enum XML_Error
335 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
336 static enum XML_Error
337 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
338 const char *s
, const char *next
);
339 static enum XML_Error
340 initializeEncoding(XML_Parser parser
);
341 static enum XML_Error
342 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
343 const char *end
, int tok
, const char *next
, const char **nextPtr
,
345 static enum XML_Error
346 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
347 XML_Bool betweenDecl
);
348 static enum XML_Error
349 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
350 const char *start
, const char *end
, const char **endPtr
,
352 static enum XML_Error
353 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
354 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
356 static enum XML_Error
357 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
358 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
361 static enum XML_Error
362 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
363 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
364 static enum XML_Error
365 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
366 const XML_Char
*uri
, BINDING
**bindingsPtr
);
368 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*, XML_Bool isCdata
,
369 XML_Bool isId
, const XML_Char
*dfltValue
, XML_Parser parser
);
370 static enum XML_Error
371 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
372 const char *, const char *, STRING_POOL
*);
373 static enum XML_Error
374 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
375 const char *, const char *, STRING_POOL
*);
376 static ATTRIBUTE_ID
*
377 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
380 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
381 static enum XML_Error
382 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
385 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
386 const char *start
, const char *end
);
388 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
391 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
394 static const XML_Char
* getContext(XML_Parser parser
);
396 setContext(XML_Parser parser
, const XML_Char
*context
);
398 static void FASTCALL
normalizePublicId(XML_Char
*s
);
400 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
401 /* do not call if parentParser != NULL */
402 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
404 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
406 dtdCopy(XML_Parser oldParser
,
407 DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
409 copyEntityTable(XML_Parser oldParser
,
410 HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
412 lookup(XML_Parser parser
, HASH_TABLE
*table
, KEY name
, size_t createSize
);
414 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
415 static void FASTCALL
hashTableClear(HASH_TABLE
*);
416 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
418 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
419 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
422 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
423 static void FASTCALL
poolClear(STRING_POOL
*);
424 static void FASTCALL
poolDestroy(STRING_POOL
*);
426 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
427 const char *ptr
, const char *end
);
429 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
430 const char *ptr
, const char *end
);
431 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
432 static const XML_Char
* FASTCALL
433 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
434 static const XML_Char
*
435 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
436 static const XML_Char
* FASTCALL
437 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
439 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
440 static XML_Content
* build_model(XML_Parser parser
);
441 static ELEMENT_TYPE
*
442 getElementType(XML_Parser parser
, const ENCODING
*enc
,
443 const char *ptr
, const char *end
);
445 static unsigned long generate_hash_secret_salt(void);
446 static XML_Bool
startParsing(XML_Parser parser
);
449 parserCreate(const XML_Char
*encodingName
,
450 const XML_Memory_Handling_Suite
*memsuite
,
451 const XML_Char
*nameSep
,
455 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
457 #define poolStart(pool) ((pool)->start)
458 #define poolEnd(pool) ((pool)->ptr)
459 #define poolLength(pool) ((pool)->ptr - (pool)->start)
460 #define poolChop(pool) ((void)--(pool->ptr))
461 #define poolLastChar(pool) (((pool)->ptr)[-1])
462 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
463 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
464 #define poolAppendChar(pool, c) \
465 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
467 : ((*((pool)->ptr)++ = c), 1))
469 struct XML_ParserStruct
{
470 /* The first member must be userData so that the XML_GetUserData
475 const XML_Memory_Handling_Suite m_mem
;
476 /* first character to be parsed */
477 const char *m_bufferPtr
;
478 /* past last character to be parsed */
480 /* allocated end of buffer */
481 const char *m_bufferLim
;
482 XML_Index m_parseEndByteIndex
;
483 const char *m_parseEndPtr
;
485 XML_Char
*m_dataBufEnd
;
486 XML_StartElementHandler m_startElementHandler
;
487 XML_EndElementHandler m_endElementHandler
;
488 XML_CharacterDataHandler m_characterDataHandler
;
489 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
490 XML_CommentHandler m_commentHandler
;
491 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
492 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
493 XML_DefaultHandler m_defaultHandler
;
494 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
495 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
496 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
497 XML_NotationDeclHandler m_notationDeclHandler
;
498 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
499 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
500 XML_NotStandaloneHandler m_notStandaloneHandler
;
501 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
502 XML_Parser m_externalEntityRefHandlerArg
;
503 XML_SkippedEntityHandler m_skippedEntityHandler
;
504 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
505 XML_ElementDeclHandler m_elementDeclHandler
;
506 XML_AttlistDeclHandler m_attlistDeclHandler
;
507 XML_EntityDeclHandler m_entityDeclHandler
;
508 XML_XmlDeclHandler m_xmlDeclHandler
;
509 const ENCODING
*m_encoding
;
510 INIT_ENCODING m_initEncoding
;
511 const ENCODING
*m_internalEncoding
;
512 const XML_Char
*m_protocolEncodingName
;
514 XML_Bool m_ns_triplets
;
515 void *m_unknownEncodingMem
;
516 void *m_unknownEncodingData
;
517 void *m_unknownEncodingHandlerData
;
518 void (XMLCALL
*m_unknownEncodingRelease
)(void *);
519 PROLOG_STATE m_prologState
;
520 Processor
*m_processor
;
521 enum XML_Error m_errorCode
;
522 const char *m_eventPtr
;
523 const char *m_eventEndPtr
;
524 const char *m_positionPtr
;
525 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
526 OPEN_INTERNAL_ENTITY
*m_freeInternalEntities
;
527 XML_Bool m_defaultExpandInternalEntities
;
529 ENTITY
*m_declEntity
;
530 const XML_Char
*m_doctypeName
;
531 const XML_Char
*m_doctypeSysid
;
532 const XML_Char
*m_doctypePubid
;
533 const XML_Char
*m_declAttributeType
;
534 const XML_Char
*m_declNotationName
;
535 const XML_Char
*m_declNotationPublicId
;
536 ELEMENT_TYPE
*m_declElementType
;
537 ATTRIBUTE_ID
*m_declAttributeId
;
538 XML_Bool m_declAttributeIsCdata
;
539 XML_Bool m_declAttributeIsId
;
541 const XML_Char
*m_curBase
;
544 BINDING
*m_inheritedBindings
;
545 BINDING
*m_freeBindingList
;
547 int m_nSpecifiedAtts
;
551 unsigned long m_nsAttsVersion
;
552 unsigned char m_nsAttsPower
;
554 XML_AttrInfo
*m_attInfo
;
557 STRING_POOL m_tempPool
;
558 STRING_POOL m_temp2Pool
;
559 char *m_groupConnector
;
560 unsigned int m_groupSize
;
561 XML_Char m_namespaceSeparator
;
562 XML_Parser m_parentParser
;
563 XML_ParsingStatus m_parsingStatus
;
565 XML_Bool m_isParamEntity
;
566 XML_Bool m_useForeignDTD
;
567 enum XML_ParamEntityParsing m_paramEntityParsing
;
569 unsigned long m_hash_secret_salt
;
572 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
573 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
574 #define FREE(p) (parser->m_mem.free_fcn((p)))
576 #define userData (parser->m_userData)
577 #define handlerArg (parser->m_handlerArg)
578 #define startElementHandler (parser->m_startElementHandler)
579 #define endElementHandler (parser->m_endElementHandler)
580 #define characterDataHandler (parser->m_characterDataHandler)
581 #define processingInstructionHandler \
582 (parser->m_processingInstructionHandler)
583 #define commentHandler (parser->m_commentHandler)
584 #define startCdataSectionHandler \
585 (parser->m_startCdataSectionHandler)
586 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
587 #define defaultHandler (parser->m_defaultHandler)
588 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
589 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
590 #define unparsedEntityDeclHandler \
591 (parser->m_unparsedEntityDeclHandler)
592 #define notationDeclHandler (parser->m_notationDeclHandler)
593 #define startNamespaceDeclHandler \
594 (parser->m_startNamespaceDeclHandler)
595 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
596 #define notStandaloneHandler (parser->m_notStandaloneHandler)
597 #define externalEntityRefHandler \
598 (parser->m_externalEntityRefHandler)
599 #define externalEntityRefHandlerArg \
600 (parser->m_externalEntityRefHandlerArg)
601 #define internalEntityRefHandler \
602 (parser->m_internalEntityRefHandler)
603 #define skippedEntityHandler (parser->m_skippedEntityHandler)
604 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
605 #define elementDeclHandler (parser->m_elementDeclHandler)
606 #define attlistDeclHandler (parser->m_attlistDeclHandler)
607 #define entityDeclHandler (parser->m_entityDeclHandler)
608 #define xmlDeclHandler (parser->m_xmlDeclHandler)
609 #define encoding (parser->m_encoding)
610 #define initEncoding (parser->m_initEncoding)
611 #define internalEncoding (parser->m_internalEncoding)
612 #define unknownEncodingMem (parser->m_unknownEncodingMem)
613 #define unknownEncodingData (parser->m_unknownEncodingData)
614 #define unknownEncodingHandlerData \
615 (parser->m_unknownEncodingHandlerData)
616 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
617 #define protocolEncodingName (parser->m_protocolEncodingName)
618 #define ns (parser->m_ns)
619 #define ns_triplets (parser->m_ns_triplets)
620 #define prologState (parser->m_prologState)
621 #define processor (parser->m_processor)
622 #define errorCode (parser->m_errorCode)
623 #define eventPtr (parser->m_eventPtr)
624 #define eventEndPtr (parser->m_eventEndPtr)
625 #define positionPtr (parser->m_positionPtr)
626 #define position (parser->m_position)
627 #define openInternalEntities (parser->m_openInternalEntities)
628 #define freeInternalEntities (parser->m_freeInternalEntities)
629 #define defaultExpandInternalEntities \
630 (parser->m_defaultExpandInternalEntities)
631 #define tagLevel (parser->m_tagLevel)
632 #define buffer (parser->m_buffer)
633 #define bufferPtr (parser->m_bufferPtr)
634 #define bufferEnd (parser->m_bufferEnd)
635 #define parseEndByteIndex (parser->m_parseEndByteIndex)
636 #define parseEndPtr (parser->m_parseEndPtr)
637 #define bufferLim (parser->m_bufferLim)
638 #define dataBuf (parser->m_dataBuf)
639 #define dataBufEnd (parser->m_dataBufEnd)
640 #define _dtd (parser->m_dtd)
641 #define curBase (parser->m_curBase)
642 #define declEntity (parser->m_declEntity)
643 #define doctypeName (parser->m_doctypeName)
644 #define doctypeSysid (parser->m_doctypeSysid)
645 #define doctypePubid (parser->m_doctypePubid)
646 #define declAttributeType (parser->m_declAttributeType)
647 #define declNotationName (parser->m_declNotationName)
648 #define declNotationPublicId (parser->m_declNotationPublicId)
649 #define declElementType (parser->m_declElementType)
650 #define declAttributeId (parser->m_declAttributeId)
651 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
652 #define declAttributeIsId (parser->m_declAttributeIsId)
653 #define freeTagList (parser->m_freeTagList)
654 #define freeBindingList (parser->m_freeBindingList)
655 #define inheritedBindings (parser->m_inheritedBindings)
656 #define tagStack (parser->m_tagStack)
657 #define atts (parser->m_atts)
658 #define attsSize (parser->m_attsSize)
659 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
660 #define idAttIndex (parser->m_idAttIndex)
661 #define nsAtts (parser->m_nsAtts)
662 #define nsAttsVersion (parser->m_nsAttsVersion)
663 #define nsAttsPower (parser->m_nsAttsPower)
664 #define attInfo (parser->m_attInfo)
665 #define tempPool (parser->m_tempPool)
666 #define temp2Pool (parser->m_temp2Pool)
667 #define groupConnector (parser->m_groupConnector)
668 #define groupSize (parser->m_groupSize)
669 #define namespaceSeparator (parser->m_namespaceSeparator)
670 #define parentParser (parser->m_parentParser)
671 #define ps_parsing (parser->m_parsingStatus.parsing)
672 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
674 #define isParamEntity (parser->m_isParamEntity)
675 #define useForeignDTD (parser->m_useForeignDTD)
676 #define paramEntityParsing (parser->m_paramEntityParsing)
678 #define hash_secret_salt (parser->m_hash_secret_salt)
681 XML_ParserCreate(const XML_Char
*encodingName
)
683 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
687 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
691 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
694 static const XML_Char implicitContext
[] = {
695 ASCII_x
, ASCII_m
, ASCII_l
, ASCII_EQUALS
, ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
,
696 ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
, ASCII_w
, ASCII_w
, ASCII_w
,
697 ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
, ASCII_o
, ASCII_r
, ASCII_g
,
698 ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
, ASCII_SLASH
, ASCII_1
, ASCII_9
,
699 ASCII_9
, ASCII_8
, ASCII_SLASH
, ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
,
700 ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
, ASCII_e
, '\0'
704 generate_hash_secret_salt(void)
706 unsigned int seed
= time(NULL
) % UINT_MAX
;
711 static XML_Bool
/* only valid for root parser */
712 startParsing(XML_Parser parser
)
714 /* hash functions must be initialized before setContext() is called */
715 if (hash_secret_salt
== 0)
716 hash_secret_salt
= generate_hash_secret_salt();
718 /* implicit context only set for root parser, since child
719 parsers (i.e. external entity parsers) will inherit it
721 return setContext(parser
, implicitContext
);
727 XML_ParserCreate_MM(const XML_Char
*encodingName
,
728 const XML_Memory_Handling_Suite
*memsuite
,
729 const XML_Char
*nameSep
)
731 return parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
735 parserCreate(const XML_Char
*encodingName
,
736 const XML_Memory_Handling_Suite
*memsuite
,
737 const XML_Char
*nameSep
,
743 XML_Memory_Handling_Suite
*mtemp
;
744 parser
= (XML_Parser
)
745 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
746 if (parser
!= NULL
) {
747 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
748 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
749 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
750 mtemp
->free_fcn
= memsuite
->free_fcn
;
754 XML_Memory_Handling_Suite
*mtemp
;
755 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
756 if (parser
!= NULL
) {
757 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
758 mtemp
->malloc_fcn
= malloc
;
759 mtemp
->realloc_fcn
= realloc
;
760 mtemp
->free_fcn
= free
;
770 attsSize
= INIT_ATTS_SIZE
;
771 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
777 attInfo
= (XML_AttrInfo
*)MALLOC(attsSize
* sizeof(XML_AttrInfo
));
778 if (attInfo
== NULL
) {
784 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
785 if (dataBuf
== NULL
) {
793 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
798 _dtd
= dtdCreate(&parser
->m_mem
);
810 freeBindingList
= NULL
;
812 freeInternalEntities
= NULL
;
815 groupConnector
= NULL
;
817 unknownEncodingHandler
= NULL
;
818 unknownEncodingHandlerData
= NULL
;
820 namespaceSeparator
= ASCII_EXCL
;
822 ns_triplets
= XML_FALSE
;
828 poolInit(&tempPool
, &(parser
->m_mem
));
829 poolInit(&temp2Pool
, &(parser
->m_mem
));
830 parserInit(parser
, encodingName
);
832 if (encodingName
&& !protocolEncodingName
) {
833 XML_ParserFree(parser
);
839 internalEncoding
= XmlGetInternalEncodingNS();
840 namespaceSeparator
= *nameSep
;
843 internalEncoding
= XmlGetInternalEncoding();
850 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
852 processor
= prologInitProcessor
;
853 XmlPrologStateInit(&prologState
);
854 protocolEncodingName
= (encodingName
!= NULL
855 ? poolCopyString(&tempPool
, encodingName
)
858 XmlInitEncoding(&initEncoding
, &encoding
, 0);
861 startElementHandler
= NULL
;
862 endElementHandler
= NULL
;
863 characterDataHandler
= NULL
;
864 processingInstructionHandler
= NULL
;
865 commentHandler
= NULL
;
866 startCdataSectionHandler
= NULL
;
867 endCdataSectionHandler
= NULL
;
868 defaultHandler
= NULL
;
869 startDoctypeDeclHandler
= NULL
;
870 endDoctypeDeclHandler
= NULL
;
871 unparsedEntityDeclHandler
= NULL
;
872 notationDeclHandler
= NULL
;
873 startNamespaceDeclHandler
= NULL
;
874 endNamespaceDeclHandler
= NULL
;
875 notStandaloneHandler
= NULL
;
876 externalEntityRefHandler
= NULL
;
877 externalEntityRefHandlerArg
= parser
;
878 skippedEntityHandler
= NULL
;
879 elementDeclHandler
= NULL
;
880 attlistDeclHandler
= NULL
;
881 entityDeclHandler
= NULL
;
882 xmlDeclHandler
= NULL
;
885 parseEndByteIndex
= 0;
887 declElementType
= NULL
;
888 declAttributeId
= NULL
;
893 declAttributeType
= NULL
;
894 declNotationName
= NULL
;
895 declNotationPublicId
= NULL
;
896 declAttributeIsCdata
= XML_FALSE
;
897 declAttributeIsId
= XML_FALSE
;
898 memset(&position
, 0, sizeof(POSITION
));
899 errorCode
= XML_ERROR_NONE
;
903 openInternalEntities
= NULL
;
904 defaultExpandInternalEntities
= XML_TRUE
;
907 inheritedBindings
= NULL
;
909 unknownEncodingMem
= NULL
;
910 unknownEncodingRelease
= NULL
;
911 unknownEncodingData
= NULL
;
913 ps_parsing
= XML_INITIALIZED
;
915 isParamEntity
= XML_FALSE
;
916 useForeignDTD
= XML_FALSE
;
917 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
919 hash_secret_salt
= 0;
922 /* moves list of bindings to freeBindingList */
924 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
927 BINDING
*b
= bindings
;
928 bindings
= bindings
->nextTagBinding
;
929 b
->nextTagBinding
= freeBindingList
;
935 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
938 OPEN_INTERNAL_ENTITY
*openEntityList
;
941 /* move tagStack to freeTagList */
946 tag
->parent
= freeTagList
;
947 moveToFreeBindingList(parser
, tag
->bindings
);
948 tag
->bindings
= NULL
;
951 /* move openInternalEntities to freeInternalEntities */
952 openEntityList
= openInternalEntities
;
953 while (openEntityList
) {
954 OPEN_INTERNAL_ENTITY
*openEntity
= openEntityList
;
955 openEntityList
= openEntity
->next
;
956 openEntity
->next
= freeInternalEntities
;
957 freeInternalEntities
= openEntity
;
959 moveToFreeBindingList(parser
, inheritedBindings
);
960 FREE(unknownEncodingMem
);
961 if (unknownEncodingRelease
)
962 unknownEncodingRelease(unknownEncodingData
);
963 poolClear(&tempPool
);
964 poolClear(&temp2Pool
);
965 parserInit(parser
, encodingName
);
966 dtdReset(_dtd
, &parser
->m_mem
);
970 enum XML_Status XMLCALL
971 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
973 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
974 XXX There's no way for the caller to determine which of the
975 XXX possible error cases caused the XML_STATUS_ERROR return.
977 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
978 return XML_STATUS_ERROR
;
979 if (encodingName
== NULL
)
980 protocolEncodingName
= NULL
;
982 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
983 if (!protocolEncodingName
)
984 return XML_STATUS_ERROR
;
986 return XML_STATUS_OK
;
990 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
991 const XML_Char
*context
,
992 const XML_Char
*encodingName
)
994 XML_Parser parser
= oldParser
;
997 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
998 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
999 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
1000 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
1001 = processingInstructionHandler
;
1002 XML_CommentHandler oldCommentHandler
= commentHandler
;
1003 XML_StartCdataSectionHandler oldStartCdataSectionHandler
1004 = startCdataSectionHandler
;
1005 XML_EndCdataSectionHandler oldEndCdataSectionHandler
1006 = endCdataSectionHandler
;
1007 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
1008 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
1009 = unparsedEntityDeclHandler
;
1010 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
1011 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
1012 = startNamespaceDeclHandler
;
1013 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
1014 = endNamespaceDeclHandler
;
1015 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
1016 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
1017 = externalEntityRefHandler
;
1018 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
1019 XML_UnknownEncodingHandler oldUnknownEncodingHandler
1020 = unknownEncodingHandler
;
1021 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
1022 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
1023 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
1024 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
1025 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
1027 void *oldUserData
= userData
;
1028 void *oldHandlerArg
= handlerArg
;
1029 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
1030 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
1032 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
1033 int oldInEntityValue
= prologState
.inEntityValue
;
1035 XML_Bool oldns_triplets
= ns_triplets
;
1036 /* Note that the new parser shares the same hash secret as the old
1037 parser, so that dtdCopy and copyEntityTable can lookup values
1038 from hash tables associated with either parser without us having
1039 to worry which hash secrets each table has.
1041 unsigned long oldhash_secret_salt
= hash_secret_salt
;
1046 #endif /* XML_DTD */
1048 /* Note that the magical uses of the pre-processor to make field
1049 access look more like C++ require that `parser' be overwritten
1050 here. This makes this function more painful to follow than it
1055 *tmp
= namespaceSeparator
;
1056 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
1059 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
1065 startElementHandler
= oldStartElementHandler
;
1066 endElementHandler
= oldEndElementHandler
;
1067 characterDataHandler
= oldCharacterDataHandler
;
1068 processingInstructionHandler
= oldProcessingInstructionHandler
;
1069 commentHandler
= oldCommentHandler
;
1070 startCdataSectionHandler
= oldStartCdataSectionHandler
;
1071 endCdataSectionHandler
= oldEndCdataSectionHandler
;
1072 defaultHandler
= oldDefaultHandler
;
1073 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
1074 notationDeclHandler
= oldNotationDeclHandler
;
1075 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
1076 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
1077 notStandaloneHandler
= oldNotStandaloneHandler
;
1078 externalEntityRefHandler
= oldExternalEntityRefHandler
;
1079 skippedEntityHandler
= oldSkippedEntityHandler
;
1080 unknownEncodingHandler
= oldUnknownEncodingHandler
;
1081 elementDeclHandler
= oldElementDeclHandler
;
1082 attlistDeclHandler
= oldAttlistDeclHandler
;
1083 entityDeclHandler
= oldEntityDeclHandler
;
1084 xmlDeclHandler
= oldXmlDeclHandler
;
1085 declElementType
= oldDeclElementType
;
1086 userData
= oldUserData
;
1087 if (oldUserData
== oldHandlerArg
)
1088 handlerArg
= userData
;
1090 handlerArg
= parser
;
1091 if (oldExternalEntityRefHandlerArg
!= oldParser
)
1092 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
1093 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
1094 ns_triplets
= oldns_triplets
;
1095 hash_secret_salt
= oldhash_secret_salt
;
1096 parentParser
= oldParser
;
1098 paramEntityParsing
= oldParamEntityParsing
;
1099 prologState
.inEntityValue
= oldInEntityValue
;
1101 #endif /* XML_DTD */
1102 if (!dtdCopy(oldParser
, _dtd
, oldDtd
, &parser
->m_mem
)
1103 || !setContext(parser
, context
)) {
1104 XML_ParserFree(parser
);
1107 processor
= externalEntityInitProcessor
;
1111 /* The DTD instance referenced by _dtd is shared between the document's
1112 root parser and external PE parsers, therefore one does not need to
1113 call setContext. In addition, one also *must* not call setContext,
1114 because this would overwrite existing prefix->binding pointers in
1115 _dtd with ones that get destroyed with the external PE parser.
1116 This would leave those prefixes with dangling pointers.
1118 isParamEntity
= XML_TRUE
;
1119 XmlPrologStateInitExternalEntity(&prologState
);
1120 processor
= externalParEntInitProcessor
;
1122 #endif /* XML_DTD */
1126 static void FASTCALL
1127 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1130 BINDING
*b
= bindings
;
1133 bindings
= b
->nextTagBinding
;
1140 XML_ParserFree(XML_Parser parser
)
1143 OPEN_INTERNAL_ENTITY
*entityList
;
1146 /* free tagStack and freeTagList */
1150 if (tagList
== NULL
) {
1151 if (freeTagList
== NULL
)
1153 tagList
= freeTagList
;
1157 tagList
= tagList
->parent
;
1159 destroyBindings(p
->bindings
, parser
);
1162 /* free openInternalEntities and freeInternalEntities */
1163 entityList
= openInternalEntities
;
1165 OPEN_INTERNAL_ENTITY
*openEntity
;
1166 if (entityList
== NULL
) {
1167 if (freeInternalEntities
== NULL
)
1169 entityList
= freeInternalEntities
;
1170 freeInternalEntities
= NULL
;
1172 openEntity
= entityList
;
1173 entityList
= entityList
->next
;
1177 destroyBindings(freeBindingList
, parser
);
1178 destroyBindings(inheritedBindings
, parser
);
1179 poolDestroy(&tempPool
);
1180 poolDestroy(&temp2Pool
);
1182 /* external parameter entity parsers share the DTD structure
1183 parser->m_dtd with the root parser, so we must not destroy it
1185 if (!isParamEntity
&& _dtd
)
1188 #endif /* XML_DTD */
1189 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1191 #ifdef XML_ATTR_INFO
1192 FREE((void *)attInfo
);
1194 FREE(groupConnector
);
1198 FREE(unknownEncodingMem
);
1199 if (unknownEncodingRelease
)
1200 unknownEncodingRelease(unknownEncodingData
);
1205 XML_UseParserAsHandlerArg(XML_Parser parser
)
1207 handlerArg
= parser
;
1210 enum XML_Error XMLCALL
1211 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1214 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1215 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1216 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1217 useForeignDTD
= useDTD
;
1218 return XML_ERROR_NONE
;
1220 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1225 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1227 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1228 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1230 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1234 XML_SetUserData(XML_Parser parser
, void *p
)
1236 if (handlerArg
== userData
)
1237 handlerArg
= userData
= p
;
1242 enum XML_Status XMLCALL
1243 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1246 p
= poolCopyString(&_dtd
->pool
, p
);
1248 return XML_STATUS_ERROR
;
1253 return XML_STATUS_OK
;
1256 const XML_Char
* XMLCALL
1257 XML_GetBase(XML_Parser parser
)
1263 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1265 return nSpecifiedAtts
;
1269 XML_GetIdAttributeIndex(XML_Parser parser
)
1274 #ifdef XML_ATTR_INFO
1275 const XML_AttrInfo
* XMLCALL
1276 XML_GetAttributeInfo(XML_Parser parser
)
1283 XML_SetElementHandler(XML_Parser parser
,
1284 XML_StartElementHandler start
,
1285 XML_EndElementHandler end
)
1287 startElementHandler
= start
;
1288 endElementHandler
= end
;
1292 XML_SetStartElementHandler(XML_Parser parser
,
1293 XML_StartElementHandler start
) {
1294 startElementHandler
= start
;
1298 XML_SetEndElementHandler(XML_Parser parser
,
1299 XML_EndElementHandler end
) {
1300 endElementHandler
= end
;
1304 XML_SetCharacterDataHandler(XML_Parser parser
,
1305 XML_CharacterDataHandler handler
)
1307 characterDataHandler
= handler
;
1311 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1312 XML_ProcessingInstructionHandler handler
)
1314 processingInstructionHandler
= handler
;
1318 XML_SetCommentHandler(XML_Parser parser
,
1319 XML_CommentHandler handler
)
1321 commentHandler
= handler
;
1325 XML_SetCdataSectionHandler(XML_Parser parser
,
1326 XML_StartCdataSectionHandler start
,
1327 XML_EndCdataSectionHandler end
)
1329 startCdataSectionHandler
= start
;
1330 endCdataSectionHandler
= end
;
1334 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1335 XML_StartCdataSectionHandler start
) {
1336 startCdataSectionHandler
= start
;
1340 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1341 XML_EndCdataSectionHandler end
) {
1342 endCdataSectionHandler
= end
;
1346 XML_SetDefaultHandler(XML_Parser parser
,
1347 XML_DefaultHandler handler
)
1349 defaultHandler
= handler
;
1350 defaultExpandInternalEntities
= XML_FALSE
;
1354 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1355 XML_DefaultHandler handler
)
1357 defaultHandler
= handler
;
1358 defaultExpandInternalEntities
= XML_TRUE
;
1362 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1363 XML_StartDoctypeDeclHandler start
,
1364 XML_EndDoctypeDeclHandler end
)
1366 startDoctypeDeclHandler
= start
;
1367 endDoctypeDeclHandler
= end
;
1371 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1372 XML_StartDoctypeDeclHandler start
) {
1373 startDoctypeDeclHandler
= start
;
1377 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1378 XML_EndDoctypeDeclHandler end
) {
1379 endDoctypeDeclHandler
= end
;
1383 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1384 XML_UnparsedEntityDeclHandler handler
)
1386 unparsedEntityDeclHandler
= handler
;
1390 XML_SetNotationDeclHandler(XML_Parser parser
,
1391 XML_NotationDeclHandler handler
)
1393 notationDeclHandler
= handler
;
1397 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1398 XML_StartNamespaceDeclHandler start
,
1399 XML_EndNamespaceDeclHandler end
)
1401 startNamespaceDeclHandler
= start
;
1402 endNamespaceDeclHandler
= end
;
1406 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1407 XML_StartNamespaceDeclHandler start
) {
1408 startNamespaceDeclHandler
= start
;
1412 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1413 XML_EndNamespaceDeclHandler end
) {
1414 endNamespaceDeclHandler
= end
;
1418 XML_SetNotStandaloneHandler(XML_Parser parser
,
1419 XML_NotStandaloneHandler handler
)
1421 notStandaloneHandler
= handler
;
1425 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1426 XML_ExternalEntityRefHandler handler
)
1428 externalEntityRefHandler
= handler
;
1432 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1435 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1437 externalEntityRefHandlerArg
= parser
;
1441 XML_SetSkippedEntityHandler(XML_Parser parser
,
1442 XML_SkippedEntityHandler handler
)
1444 skippedEntityHandler
= handler
;
1448 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1449 XML_UnknownEncodingHandler handler
,
1452 unknownEncodingHandler
= handler
;
1453 unknownEncodingHandlerData
= data
;
1457 XML_SetElementDeclHandler(XML_Parser parser
,
1458 XML_ElementDeclHandler eldecl
)
1460 elementDeclHandler
= eldecl
;
1464 XML_SetAttlistDeclHandler(XML_Parser parser
,
1465 XML_AttlistDeclHandler attdecl
)
1467 attlistDeclHandler
= attdecl
;
1471 XML_SetEntityDeclHandler(XML_Parser parser
,
1472 XML_EntityDeclHandler handler
)
1474 entityDeclHandler
= handler
;
1478 XML_SetXmlDeclHandler(XML_Parser parser
,
1479 XML_XmlDeclHandler handler
) {
1480 xmlDeclHandler
= handler
;
1484 XML_SetParamEntityParsing(XML_Parser parser
,
1485 enum XML_ParamEntityParsing peParsing
)
1487 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1488 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1491 paramEntityParsing
= peParsing
;
1494 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1499 XML_SetHashSalt(XML_Parser parser
,
1500 unsigned long hash_salt
)
1502 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1503 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1505 hash_secret_salt
= hash_salt
;
1509 enum XML_Status XMLCALL
1510 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1512 switch (ps_parsing
) {
1514 errorCode
= XML_ERROR_SUSPENDED
;
1515 return XML_STATUS_ERROR
;
1517 errorCode
= XML_ERROR_FINISHED
;
1518 return XML_STATUS_ERROR
;
1519 case XML_INITIALIZED
:
1520 if (parentParser
== NULL
&& !startParsing(parser
)) {
1521 errorCode
= XML_ERROR_NO_MEMORY
;
1522 return XML_STATUS_ERROR
;
1525 ps_parsing
= XML_PARSING
;
1529 ps_finalBuffer
= (XML_Bool
)isFinal
;
1531 return XML_STATUS_OK
;
1532 positionPtr
= bufferPtr
;
1533 parseEndPtr
= bufferEnd
;
1535 /* If data are left over from last buffer, and we now know that these
1536 data are the final chunk of input, then we have to check them again
1537 to detect errors based on that fact.
1539 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1541 if (errorCode
== XML_ERROR_NONE
) {
1542 switch (ps_parsing
) {
1544 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1545 positionPtr
= bufferPtr
;
1546 return XML_STATUS_SUSPENDED
;
1547 case XML_INITIALIZED
:
1549 ps_parsing
= XML_FINISHED
;
1552 return XML_STATUS_OK
;
1555 eventEndPtr
= eventPtr
;
1556 processor
= errorProcessor
;
1557 return XML_STATUS_ERROR
;
1559 #ifndef XML_CONTEXT_BYTES
1560 else if (bufferPtr
== bufferEnd
) {
1563 enum XML_Error result
;
1564 parseEndByteIndex
+= len
;
1566 ps_finalBuffer
= (XML_Bool
)isFinal
;
1568 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1570 if (errorCode
!= XML_ERROR_NONE
) {
1571 eventEndPtr
= eventPtr
;
1572 processor
= errorProcessor
;
1573 return XML_STATUS_ERROR
;
1576 switch (ps_parsing
) {
1578 result
= XML_STATUS_SUSPENDED
;
1580 case XML_INITIALIZED
:
1583 ps_parsing
= XML_FINISHED
;
1584 return XML_STATUS_OK
;
1588 result
= XML_STATUS_OK
;
1592 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1593 nLeftOver
= s
+ len
- end
;
1595 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1596 /* FIXME avoid integer overflow */
1598 temp
= (buffer
== NULL
1599 ? (char *)MALLOC(len
* 2)
1600 : (char *)REALLOC(buffer
, len
* 2));
1602 errorCode
= XML_ERROR_NO_MEMORY
;
1603 eventPtr
= eventEndPtr
= NULL
;
1604 processor
= errorProcessor
;
1605 return XML_STATUS_ERROR
;
1608 bufferLim
= buffer
+ len
* 2;
1610 memcpy(buffer
, end
, nLeftOver
);
1613 bufferEnd
= buffer
+ nLeftOver
;
1614 positionPtr
= bufferPtr
;
1615 parseEndPtr
= bufferEnd
;
1616 eventPtr
= bufferPtr
;
1617 eventEndPtr
= bufferPtr
;
1620 #endif /* not defined XML_CONTEXT_BYTES */
1622 void *buff
= XML_GetBuffer(parser
, len
);
1624 return XML_STATUS_ERROR
;
1626 memcpy(buff
, s
, len
);
1627 return XML_ParseBuffer(parser
, len
, isFinal
);
1632 enum XML_Status XMLCALL
1633 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1636 enum XML_Status result
= XML_STATUS_OK
;
1638 switch (ps_parsing
) {
1640 errorCode
= XML_ERROR_SUSPENDED
;
1641 return XML_STATUS_ERROR
;
1643 errorCode
= XML_ERROR_FINISHED
;
1644 return XML_STATUS_ERROR
;
1645 case XML_INITIALIZED
:
1646 if (parentParser
== NULL
&& !startParsing(parser
)) {
1647 errorCode
= XML_ERROR_NO_MEMORY
;
1648 return XML_STATUS_ERROR
;
1651 ps_parsing
= XML_PARSING
;
1655 positionPtr
= start
;
1657 parseEndPtr
= bufferEnd
;
1658 parseEndByteIndex
+= len
;
1659 ps_finalBuffer
= (XML_Bool
)isFinal
;
1661 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1663 if (errorCode
!= XML_ERROR_NONE
) {
1664 eventEndPtr
= eventPtr
;
1665 processor
= errorProcessor
;
1666 return XML_STATUS_ERROR
;
1669 switch (ps_parsing
) {
1671 result
= XML_STATUS_SUSPENDED
;
1673 case XML_INITIALIZED
:
1676 ps_parsing
= XML_FINISHED
;
1679 default: ; /* should not happen */
1683 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1684 positionPtr
= bufferPtr
;
1689 XML_GetBuffer(XML_Parser parser
, int len
)
1691 switch (ps_parsing
) {
1693 errorCode
= XML_ERROR_SUSPENDED
;
1696 errorCode
= XML_ERROR_FINISHED
;
1701 if (len
> bufferLim
- bufferEnd
) {
1702 /* FIXME avoid integer overflow */
1703 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1704 #ifdef XML_CONTEXT_BYTES
1705 int keep
= (int)(bufferPtr
- buffer
);
1707 if (keep
> XML_CONTEXT_BYTES
)
1708 keep
= XML_CONTEXT_BYTES
;
1710 #endif /* defined XML_CONTEXT_BYTES */
1711 if (neededSize
<= bufferLim
- buffer
) {
1712 #ifdef XML_CONTEXT_BYTES
1713 if (keep
< bufferPtr
- buffer
) {
1714 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1715 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1716 bufferEnd
-= offset
;
1717 bufferPtr
-= offset
;
1720 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1721 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1723 #endif /* not defined XML_CONTEXT_BYTES */
1727 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1728 if (bufferSize
== 0)
1729 bufferSize
= INIT_BUFFER_SIZE
;
1732 } while (bufferSize
< neededSize
);
1733 newBuf
= (char *)MALLOC(bufferSize
);
1735 errorCode
= XML_ERROR_NO_MEMORY
;
1738 bufferLim
= newBuf
+ bufferSize
;
1739 #ifdef XML_CONTEXT_BYTES
1741 int keep
= (int)(bufferPtr
- buffer
);
1742 if (keep
> XML_CONTEXT_BYTES
)
1743 keep
= XML_CONTEXT_BYTES
;
1744 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1747 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1748 bufferPtr
= buffer
+ keep
;
1751 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1752 bufferPtr
= buffer
= newBuf
;
1756 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1759 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1760 bufferPtr
= buffer
= newBuf
;
1761 #endif /* not defined XML_CONTEXT_BYTES */
1763 eventPtr
= eventEndPtr
= NULL
;
1769 enum XML_Status XMLCALL
1770 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1772 switch (ps_parsing
) {
1775 errorCode
= XML_ERROR_SUSPENDED
;
1776 return XML_STATUS_ERROR
;
1778 ps_parsing
= XML_FINISHED
;
1781 errorCode
= XML_ERROR_FINISHED
;
1782 return XML_STATUS_ERROR
;
1786 if (isParamEntity
) {
1787 errorCode
= XML_ERROR_SUSPEND_PE
;
1788 return XML_STATUS_ERROR
;
1791 ps_parsing
= XML_SUSPENDED
;
1794 ps_parsing
= XML_FINISHED
;
1796 return XML_STATUS_OK
;
1799 enum XML_Status XMLCALL
1800 XML_ResumeParser(XML_Parser parser
)
1802 enum XML_Status result
= XML_STATUS_OK
;
1804 if (ps_parsing
!= XML_SUSPENDED
) {
1805 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1806 return XML_STATUS_ERROR
;
1808 ps_parsing
= XML_PARSING
;
1810 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1812 if (errorCode
!= XML_ERROR_NONE
) {
1813 eventEndPtr
= eventPtr
;
1814 processor
= errorProcessor
;
1815 return XML_STATUS_ERROR
;
1818 switch (ps_parsing
) {
1820 result
= XML_STATUS_SUSPENDED
;
1822 case XML_INITIALIZED
:
1824 if (ps_finalBuffer
) {
1825 ps_parsing
= XML_FINISHED
;
1832 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1833 positionPtr
= bufferPtr
;
1838 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1840 assert(status
!= NULL
);
1841 *status
= parser
->m_parsingStatus
;
1844 enum XML_Error XMLCALL
1845 XML_GetErrorCode(XML_Parser parser
)
1851 XML_GetCurrentByteIndex(XML_Parser parser
)
1854 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1859 XML_GetCurrentByteCount(XML_Parser parser
)
1861 if (eventEndPtr
&& eventPtr
)
1862 return (int)(eventEndPtr
- eventPtr
);
1866 const char * XMLCALL
1867 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1869 #ifdef XML_CONTEXT_BYTES
1870 if (eventPtr
&& buffer
) {
1871 *offset
= (int)(eventPtr
- buffer
);
1872 *size
= (int)(bufferEnd
- buffer
);
1875 #endif /* defined XML_CONTEXT_BYTES */
1880 XML_GetCurrentLineNumber(XML_Parser parser
)
1882 if (eventPtr
&& eventPtr
>= positionPtr
) {
1883 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1884 positionPtr
= eventPtr
;
1886 return position
.lineNumber
+ 1;
1890 XML_GetCurrentColumnNumber(XML_Parser parser
)
1892 if (eventPtr
&& eventPtr
>= positionPtr
) {
1893 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1894 positionPtr
= eventPtr
;
1896 return position
.columnNumber
;
1900 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1906 XML_MemMalloc(XML_Parser parser
, size_t size
)
1908 return MALLOC(size
);
1912 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1914 return REALLOC(ptr
, size
);
1918 XML_MemFree(XML_Parser parser
, void *ptr
)
1924 XML_DefaultCurrent(XML_Parser parser
)
1926 if (defaultHandler
) {
1927 if (openInternalEntities
)
1928 reportDefault(parser
,
1930 openInternalEntities
->internalEventPtr
,
1931 openInternalEntities
->internalEventEndPtr
);
1933 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1937 const XML_LChar
* XMLCALL
1938 XML_ErrorString(enum XML_Error code
)
1940 static const XML_LChar
* const message
[] = {
1942 XML_L("out of memory"),
1943 XML_L("syntax error"),
1944 XML_L("no element found"),
1945 XML_L("not well-formed (invalid token)"),
1946 XML_L("unclosed token"),
1947 XML_L("partial character"),
1948 XML_L("mismatched tag"),
1949 XML_L("duplicate attribute"),
1950 XML_L("junk after document element"),
1951 XML_L("illegal parameter entity reference"),
1952 XML_L("undefined entity"),
1953 XML_L("recursive entity reference"),
1954 XML_L("asynchronous entity"),
1955 XML_L("reference to invalid character number"),
1956 XML_L("reference to binary entity"),
1957 XML_L("reference to external entity in attribute"),
1958 XML_L("XML or text declaration not at start of entity"),
1959 XML_L("unknown encoding"),
1960 XML_L("encoding specified in XML declaration is incorrect"),
1961 XML_L("unclosed CDATA section"),
1962 XML_L("error in processing external entity reference"),
1963 XML_L("document is not standalone"),
1964 XML_L("unexpected parser state - please send a bug report"),
1965 XML_L("entity declared in parameter entity"),
1966 XML_L("requested feature requires XML_DTD support in Expat"),
1967 XML_L("cannot change setting once parsing has begun"),
1968 XML_L("unbound prefix"),
1969 XML_L("must not undeclare prefix"),
1970 XML_L("incomplete markup in parameter entity"),
1971 XML_L("XML declaration not well-formed"),
1972 XML_L("text declaration not well-formed"),
1973 XML_L("illegal character(s) in public id"),
1974 XML_L("parser suspended"),
1975 XML_L("parser not suspended"),
1976 XML_L("parsing aborted"),
1977 XML_L("parsing finished"),
1978 XML_L("cannot suspend in external parameter entity"),
1979 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1980 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1981 XML_L("prefix must not be bound to one of the reserved namespace names")
1983 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1984 return message
[code
];
1988 const XML_LChar
* XMLCALL
1989 XML_ExpatVersion(void) {
1991 /* V1 is used to string-ize the version number. However, it would
1992 string-ize the actual version macro *names* unless we get them
1993 substituted before being passed to V1. CPP is defined to expand
1994 a macro, then rescan for more expansions. Thus, we use V2 to expand
1995 the version macros, then CPP will expand the resulting V1() macro
1996 with the correct numerals. */
1997 /* ### I'm assuming cpp is portable in this respect... */
1999 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
2000 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
2002 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
2008 XML_Expat_Version XMLCALL
2009 XML_ExpatVersionInfo(void)
2011 XML_Expat_Version version
;
2013 version
.major
= XML_MAJOR_VERSION
;
2014 version
.minor
= XML_MINOR_VERSION
;
2015 version
.micro
= XML_MICRO_VERSION
;
2020 const XML_Feature
* XMLCALL
2021 XML_GetFeatureList(void)
2023 static const XML_Feature features
[] = {
2024 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
2026 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
2029 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
2031 #ifdef XML_UNICODE_WCHAR_T
2032 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
2035 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
2037 #ifdef XML_CONTEXT_BYTES
2038 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
2042 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
2045 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
2047 #ifdef XML_LARGE_SIZE
2048 {XML_FEATURE_LARGE_SIZE
, XML_L("XML_LARGE_SIZE"), 0},
2050 #ifdef XML_ATTR_INFO
2051 {XML_FEATURE_ATTR_INFO
, XML_L("XML_ATTR_INFO"), 0},
2053 {XML_FEATURE_END
, NULL
, 0}
2059 /* Initially tag->rawName always points into the parse buffer;
2060 for those TAG instances opened while the current parse buffer was
2061 processed, and not yet closed, we need to store tag->rawName in a more
2062 permanent location, since the parse buffer is about to be discarded.
2065 storeRawNames(XML_Parser parser
)
2067 TAG
*tag
= tagStack
;
2070 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
2071 char *rawNameBuf
= tag
->buf
+ nameLen
;
2072 /* Stop if already stored. Since tagStack is a stack, we can stop
2073 at the first entry that has already been copied; everything
2074 below it in the stack is already been accounted for in a
2075 previous call to this function.
2077 if (tag
->rawName
== rawNameBuf
)
2079 /* For re-use purposes we need to ensure that the
2080 size of tag->buf is a multiple of sizeof(XML_Char).
2082 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
2083 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
2084 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2087 /* if tag->name.str points to tag->buf (only when namespace
2088 processing is off) then we have to update it
2090 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
2091 tag
->name
.str
= (XML_Char
*)temp
;
2092 /* if tag->name.localPart is set (when namespace processing is on)
2093 then update it as well, since it will always point into tag->buf
2095 if (tag
->name
.localPart
)
2096 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
2097 (XML_Char
*)tag
->buf
);
2099 tag
->bufEnd
= temp
+ bufSize
;
2100 rawNameBuf
= temp
+ nameLen
;
2102 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2103 tag
->rawName
= rawNameBuf
;
2109 static enum XML_Error PTRCALL
2110 contentProcessor(XML_Parser parser
,
2113 const char **endPtr
)
2115 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2116 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2117 if (result
== XML_ERROR_NONE
) {
2118 if (!storeRawNames(parser
))
2119 return XML_ERROR_NO_MEMORY
;
2124 static enum XML_Error PTRCALL
2125 externalEntityInitProcessor(XML_Parser parser
,
2128 const char **endPtr
)
2130 enum XML_Error result
= initializeEncoding(parser
);
2131 if (result
!= XML_ERROR_NONE
)
2133 processor
= externalEntityInitProcessor2
;
2134 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2137 static enum XML_Error PTRCALL
2138 externalEntityInitProcessor2(XML_Parser parser
,
2141 const char **endPtr
)
2143 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2144 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2147 /* If we are at the end of the buffer, this would cause the next stage,
2148 i.e. externalEntityInitProcessor3, to pass control directly to
2149 doContent (by detecting XML_TOK_NONE) without processing any xml text
2150 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2152 if (next
== end
&& !ps_finalBuffer
) {
2154 return XML_ERROR_NONE
;
2158 case XML_TOK_PARTIAL
:
2159 if (!ps_finalBuffer
) {
2161 return XML_ERROR_NONE
;
2164 return XML_ERROR_UNCLOSED_TOKEN
;
2165 case XML_TOK_PARTIAL_CHAR
:
2166 if (!ps_finalBuffer
) {
2168 return XML_ERROR_NONE
;
2171 return XML_ERROR_PARTIAL_CHAR
;
2173 processor
= externalEntityInitProcessor3
;
2174 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2177 static enum XML_Error PTRCALL
2178 externalEntityInitProcessor3(XML_Parser parser
,
2181 const char **endPtr
)
2184 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2186 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2190 case XML_TOK_XML_DECL
:
2192 enum XML_Error result
;
2193 result
= processXmlDecl(parser
, 1, start
, next
);
2194 if (result
!= XML_ERROR_NONE
)
2196 switch (ps_parsing
) {
2199 return XML_ERROR_NONE
;
2201 return XML_ERROR_ABORTED
;
2207 case XML_TOK_PARTIAL
:
2208 if (!ps_finalBuffer
) {
2210 return XML_ERROR_NONE
;
2212 return XML_ERROR_UNCLOSED_TOKEN
;
2213 case XML_TOK_PARTIAL_CHAR
:
2214 if (!ps_finalBuffer
) {
2216 return XML_ERROR_NONE
;
2218 return XML_ERROR_PARTIAL_CHAR
;
2220 processor
= externalEntityContentProcessor
;
2222 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2225 static enum XML_Error PTRCALL
2226 externalEntityContentProcessor(XML_Parser parser
,
2229 const char **endPtr
)
2231 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2232 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2233 if (result
== XML_ERROR_NONE
) {
2234 if (!storeRawNames(parser
))
2235 return XML_ERROR_NO_MEMORY
;
2240 static enum XML_Error
2241 doContent(XML_Parser parser
,
2243 const ENCODING
*enc
,
2246 const char **nextPtr
,
2249 /* save one level of indirection */
2250 DTD
* const dtd
= _dtd
;
2252 const char **eventPP
;
2253 const char **eventEndPP
;
2254 if (enc
== encoding
) {
2255 eventPP
= &eventPtr
;
2256 eventEndPP
= &eventEndPtr
;
2259 eventPP
= &(openInternalEntities
->internalEventPtr
);
2260 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2265 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2266 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2269 case XML_TOK_TRAILING_CR
:
2272 return XML_ERROR_NONE
;
2275 if (characterDataHandler
) {
2277 characterDataHandler(handlerArg
, &c
, 1);
2279 else if (defaultHandler
)
2280 reportDefault(parser
, enc
, s
, end
);
2281 /* We are at the end of the final buffer, should we check for
2282 XML_SUSPENDED, XML_FINISHED?
2284 if (startTagLevel
== 0)
2285 return XML_ERROR_NO_ELEMENTS
;
2286 if (tagLevel
!= startTagLevel
)
2287 return XML_ERROR_ASYNC_ENTITY
;
2289 return XML_ERROR_NONE
;
2293 return XML_ERROR_NONE
;
2295 if (startTagLevel
> 0) {
2296 if (tagLevel
!= startTagLevel
)
2297 return XML_ERROR_ASYNC_ENTITY
;
2299 return XML_ERROR_NONE
;
2301 return XML_ERROR_NO_ELEMENTS
;
2302 case XML_TOK_INVALID
:
2304 return XML_ERROR_INVALID_TOKEN
;
2305 case XML_TOK_PARTIAL
:
2308 return XML_ERROR_NONE
;
2310 return XML_ERROR_UNCLOSED_TOKEN
;
2311 case XML_TOK_PARTIAL_CHAR
:
2314 return XML_ERROR_NONE
;
2316 return XML_ERROR_PARTIAL_CHAR
;
2317 case XML_TOK_ENTITY_REF
:
2319 const XML_Char
*name
;
2321 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2322 s
+ enc
->minBytesPerChar
,
2323 next
- enc
->minBytesPerChar
);
2325 if (characterDataHandler
)
2326 characterDataHandler(handlerArg
, &ch
, 1);
2327 else if (defaultHandler
)
2328 reportDefault(parser
, enc
, s
, next
);
2331 name
= poolStoreString(&dtd
->pool
, enc
,
2332 s
+ enc
->minBytesPerChar
,
2333 next
- enc
->minBytesPerChar
);
2335 return XML_ERROR_NO_MEMORY
;
2336 entity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
, 0);
2337 poolDiscard(&dtd
->pool
);
2338 /* First, determine if a check for an existing declaration is needed;
2339 if yes, check that the entity exists, and that it is internal,
2340 otherwise call the skipped entity or default handler.
2342 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2344 return XML_ERROR_UNDEFINED_ENTITY
;
2345 else if (!entity
->is_internal
)
2346 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2349 if (skippedEntityHandler
)
2350 skippedEntityHandler(handlerArg
, name
, 0);
2351 else if (defaultHandler
)
2352 reportDefault(parser
, enc
, s
, next
);
2356 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2357 if (entity
->notation
)
2358 return XML_ERROR_BINARY_ENTITY_REF
;
2359 if (entity
->textPtr
) {
2360 enum XML_Error result
;
2361 if (!defaultExpandInternalEntities
) {
2362 if (skippedEntityHandler
)
2363 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2364 else if (defaultHandler
)
2365 reportDefault(parser
, enc
, s
, next
);
2368 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2369 if (result
!= XML_ERROR_NONE
)
2372 else if (externalEntityRefHandler
) {
2373 const XML_Char
*context
;
2374 entity
->open
= XML_TRUE
;
2375 context
= getContext(parser
);
2376 entity
->open
= XML_FALSE
;
2378 return XML_ERROR_NO_MEMORY
;
2379 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2384 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2385 poolDiscard(&tempPool
);
2387 else if (defaultHandler
)
2388 reportDefault(parser
, enc
, s
, next
);
2391 case XML_TOK_START_TAG_NO_ATTS
:
2393 case XML_TOK_START_TAG_WITH_ATTS
:
2396 enum XML_Error result
;
2400 freeTagList
= freeTagList
->parent
;
2403 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2405 return XML_ERROR_NO_MEMORY
;
2406 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2409 return XML_ERROR_NO_MEMORY
;
2411 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2413 tag
->bindings
= NULL
;
2414 tag
->parent
= tagStack
;
2416 tag
->name
.localPart
= NULL
;
2417 tag
->name
.prefix
= NULL
;
2418 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2419 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2422 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2423 const char *fromPtr
= tag
->rawName
;
2424 toPtr
= (XML_Char
*)tag
->buf
;
2429 &fromPtr
, rawNameEnd
,
2430 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2431 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2432 if (fromPtr
== rawNameEnd
) {
2433 tag
->name
.strLen
= convLen
;
2436 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2438 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2440 return XML_ERROR_NO_MEMORY
;
2442 tag
->bufEnd
= temp
+ bufSize
;
2443 toPtr
= (XML_Char
*)temp
+ convLen
;
2447 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2448 *toPtr
= XML_T('\0');
2449 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2452 if (startElementHandler
)
2453 startElementHandler(handlerArg
, tag
->name
.str
,
2454 (const XML_Char
**)atts
);
2455 else if (defaultHandler
)
2456 reportDefault(parser
, enc
, s
, next
);
2457 poolClear(&tempPool
);
2460 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2462 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2464 const char *rawName
= s
+ enc
->minBytesPerChar
;
2465 enum XML_Error result
;
2466 BINDING
*bindings
= NULL
;
2467 XML_Bool noElmHandlers
= XML_TRUE
;
2469 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2470 rawName
+ XmlNameLength(enc
, rawName
));
2472 return XML_ERROR_NO_MEMORY
;
2473 poolFinish(&tempPool
);
2474 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2477 poolFinish(&tempPool
);
2478 if (startElementHandler
) {
2479 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2480 noElmHandlers
= XML_FALSE
;
2482 if (endElementHandler
) {
2483 if (startElementHandler
)
2484 *eventPP
= *eventEndPP
;
2485 endElementHandler(handlerArg
, name
.str
);
2486 noElmHandlers
= XML_FALSE
;
2488 if (noElmHandlers
&& defaultHandler
)
2489 reportDefault(parser
, enc
, s
, next
);
2490 poolClear(&tempPool
);
2492 BINDING
*b
= bindings
;
2493 if (endNamespaceDeclHandler
)
2494 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2495 bindings
= bindings
->nextTagBinding
;
2496 b
->nextTagBinding
= freeBindingList
;
2497 freeBindingList
= b
;
2498 b
->prefix
->binding
= b
->prevPrefixBinding
;
2502 return epilogProcessor(parser
, next
, end
, nextPtr
);
2504 case XML_TOK_END_TAG
:
2505 if (tagLevel
== startTagLevel
)
2506 return XML_ERROR_ASYNC_ENTITY
;
2509 const char *rawName
;
2510 TAG
*tag
= tagStack
;
2511 tagStack
= tag
->parent
;
2512 tag
->parent
= freeTagList
;
2514 rawName
= s
+ enc
->minBytesPerChar
*2;
2515 len
= XmlNameLength(enc
, rawName
);
2516 if (len
!= tag
->rawNameLength
2517 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2519 return XML_ERROR_TAG_MISMATCH
;
2522 if (endElementHandler
) {
2523 const XML_Char
*localPart
;
2524 const XML_Char
*prefix
;
2526 localPart
= tag
->name
.localPart
;
2527 if (ns
&& localPart
) {
2528 /* localPart and prefix may have been overwritten in
2529 tag->name.str, since this points to the binding->uri
2530 buffer which gets re-used; so we have to add them again
2532 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2533 /* don't need to check for space - already done in storeAtts() */
2534 while (*localPart
) *uri
++ = *localPart
++;
2535 prefix
= (XML_Char
*)tag
->name
.prefix
;
2536 if (ns_triplets
&& prefix
) {
2537 *uri
++ = namespaceSeparator
;
2538 while (*prefix
) *uri
++ = *prefix
++;
2542 endElementHandler(handlerArg
, tag
->name
.str
);
2544 else if (defaultHandler
)
2545 reportDefault(parser
, enc
, s
, next
);
2546 while (tag
->bindings
) {
2547 BINDING
*b
= tag
->bindings
;
2548 if (endNamespaceDeclHandler
)
2549 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2550 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2551 b
->nextTagBinding
= freeBindingList
;
2552 freeBindingList
= b
;
2553 b
->prefix
->binding
= b
->prevPrefixBinding
;
2556 return epilogProcessor(parser
, next
, end
, nextPtr
);
2559 case XML_TOK_CHAR_REF
:
2561 int n
= XmlCharRefNumber(enc
, s
);
2563 return XML_ERROR_BAD_CHAR_REF
;
2564 if (characterDataHandler
) {
2565 XML_Char buf
[XML_ENCODE_MAX
];
2566 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2568 else if (defaultHandler
)
2569 reportDefault(parser
, enc
, s
, next
);
2572 case XML_TOK_XML_DECL
:
2573 return XML_ERROR_MISPLACED_XML_PI
;
2574 case XML_TOK_DATA_NEWLINE
:
2575 if (characterDataHandler
) {
2577 characterDataHandler(handlerArg
, &c
, 1);
2579 else if (defaultHandler
)
2580 reportDefault(parser
, enc
, s
, next
);
2582 case XML_TOK_CDATA_SECT_OPEN
:
2584 enum XML_Error result
;
2585 if (startCdataSectionHandler
)
2586 startCdataSectionHandler(handlerArg
);
2588 /* Suppose you doing a transformation on a document that involves
2589 changing only the character data. You set up a defaultHandler
2590 and a characterDataHandler. The defaultHandler simply copies
2591 characters through. The characterDataHandler does the
2592 transformation and writes the characters out escaping them as
2593 necessary. This case will fail to work if we leave out the
2594 following two lines (because & and < inside CDATA sections will
2595 be incorrectly escaped).
2597 However, now we have a start/endCdataSectionHandler, so it seems
2598 easier to let the user deal with this.
2600 else if (characterDataHandler
)
2601 characterDataHandler(handlerArg
, dataBuf
, 0);
2603 else if (defaultHandler
)
2604 reportDefault(parser
, enc
, s
, next
);
2605 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2606 if (result
!= XML_ERROR_NONE
)
2609 processor
= cdataSectionProcessor
;
2614 case XML_TOK_TRAILING_RSQB
:
2617 return XML_ERROR_NONE
;
2619 if (characterDataHandler
) {
2620 if (MUST_CONVERT(enc
, s
)) {
2621 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2622 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2623 characterDataHandler(handlerArg
, dataBuf
,
2624 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2627 characterDataHandler(handlerArg
,
2629 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2631 else if (defaultHandler
)
2632 reportDefault(parser
, enc
, s
, end
);
2633 /* We are at the end of the final buffer, should we check for
2634 XML_SUSPENDED, XML_FINISHED?
2636 if (startTagLevel
== 0) {
2638 return XML_ERROR_NO_ELEMENTS
;
2640 if (tagLevel
!= startTagLevel
) {
2642 return XML_ERROR_ASYNC_ENTITY
;
2645 return XML_ERROR_NONE
;
2646 case XML_TOK_DATA_CHARS
:
2648 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
2649 if (charDataHandler
) {
2650 if (MUST_CONVERT(enc
, s
)) {
2652 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2653 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2655 charDataHandler(handlerArg
, dataBuf
,
2656 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2663 charDataHandler(handlerArg
,
2665 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2667 else if (defaultHandler
)
2668 reportDefault(parser
, enc
, s
, next
);
2672 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2673 return XML_ERROR_NO_MEMORY
;
2675 case XML_TOK_COMMENT
:
2676 if (!reportComment(parser
, enc
, s
, next
))
2677 return XML_ERROR_NO_MEMORY
;
2681 reportDefault(parser
, enc
, s
, next
);
2684 *eventPP
= s
= next
;
2685 switch (ps_parsing
) {
2688 return XML_ERROR_NONE
;
2690 return XML_ERROR_ABORTED
;
2697 /* Precondition: all arguments must be non-NULL;
2699 - normalize attributes
2700 - check attributes for well-formedness
2701 - generate namespace aware attribute names (URI, prefix)
2702 - build list of attributes for startElementHandler
2703 - default attributes
2704 - process namespace declarations (check and report them)
2705 - generate namespace aware element name (URI, prefix)
2707 static enum XML_Error
2708 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2709 const char *attStr
, TAG_NAME
*tagNamePtr
,
2710 BINDING
**bindingsPtr
)
2712 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2713 ELEMENT_TYPE
*elementType
;
2715 const XML_Char
**appAtts
; /* the attribute list for the application */
2723 const XML_Char
*localPart
;
2725 /* lookup the element type name */
2726 elementType
= (ELEMENT_TYPE
*)lookup(parser
, &dtd
->elementTypes
, tagNamePtr
->str
,0);
2728 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2730 return XML_ERROR_NO_MEMORY
;
2731 elementType
= (ELEMENT_TYPE
*)lookup(parser
, &dtd
->elementTypes
, name
,
2732 sizeof(ELEMENT_TYPE
));
2734 return XML_ERROR_NO_MEMORY
;
2735 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2736 return XML_ERROR_NO_MEMORY
;
2738 nDefaultAtts
= elementType
->nDefaultAtts
;
2740 /* get the attributes from the tokenizer */
2741 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2742 if (n
+ nDefaultAtts
> attsSize
) {
2743 int oldAttsSize
= attsSize
;
2745 #ifdef XML_ATTR_INFO
2746 XML_AttrInfo
*temp2
;
2748 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2749 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2751 return XML_ERROR_NO_MEMORY
;
2753 #ifdef XML_ATTR_INFO
2754 temp2
= (XML_AttrInfo
*)REALLOC((void *)attInfo
, attsSize
* sizeof(XML_AttrInfo
));
2756 return XML_ERROR_NO_MEMORY
;
2759 if (n
> oldAttsSize
)
2760 XmlGetAttributes(enc
, attStr
, n
, atts
);
2763 appAtts
= (const XML_Char
**)atts
;
2764 for (i
= 0; i
< n
; i
++) {
2765 ATTRIBUTE
*currAtt
= &atts
[i
];
2766 #ifdef XML_ATTR_INFO
2767 XML_AttrInfo
*currAttInfo
= &attInfo
[i
];
2769 /* add the name and value to the attribute list */
2770 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, currAtt
->name
,
2772 + XmlNameLength(enc
, currAtt
->name
));
2774 return XML_ERROR_NO_MEMORY
;
2775 #ifdef XML_ATTR_INFO
2776 currAttInfo
->nameStart
= parseEndByteIndex
- (parseEndPtr
- currAtt
->name
);
2777 currAttInfo
->nameEnd
= currAttInfo
->nameStart
+
2778 XmlNameLength(enc
, currAtt
->name
);
2779 currAttInfo
->valueStart
= parseEndByteIndex
-
2780 (parseEndPtr
- currAtt
->valuePtr
);
2781 currAttInfo
->valueEnd
= parseEndByteIndex
- (parseEndPtr
- currAtt
->valueEnd
);
2783 /* Detect duplicate attributes by their QNames. This does not work when
2784 namespace processing is turned on and different prefixes for the same
2785 namespace are used. For this case we have a check further down.
2787 if ((attId
->name
)[-1]) {
2788 if (enc
== encoding
)
2789 eventPtr
= atts
[i
].name
;
2790 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2792 (attId
->name
)[-1] = 1;
2793 appAtts
[attIndex
++] = attId
->name
;
2794 if (!atts
[i
].normalized
) {
2795 enum XML_Error result
;
2796 XML_Bool isCdata
= XML_TRUE
;
2798 /* figure out whether declared as other than CDATA */
2799 if (attId
->maybeTokenized
) {
2801 for (j
= 0; j
< nDefaultAtts
; j
++) {
2802 if (attId
== elementType
->defaultAtts
[j
].id
) {
2803 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2809 /* normalize the attribute value */
2810 result
= storeAttributeValue(parser
, enc
, isCdata
,
2811 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2815 appAtts
[attIndex
] = poolStart(&tempPool
);
2816 poolFinish(&tempPool
);
2819 /* the value did not need normalizing */
2820 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2822 if (appAtts
[attIndex
] == 0)
2823 return XML_ERROR_NO_MEMORY
;
2824 poolFinish(&tempPool
);
2826 /* handle prefixed attribute names */
2827 if (attId
->prefix
) {
2829 /* deal with namespace declarations here */
2830 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2831 appAtts
[attIndex
], bindingsPtr
);
2837 /* deal with other prefixed names later */
2840 (attId
->name
)[-1] = 2;
2847 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2848 nSpecifiedAtts
= attIndex
;
2849 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2850 for (i
= 0; i
< attIndex
; i
+= 2)
2851 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2859 /* do attribute defaulting */
2860 for (i
= 0; i
< nDefaultAtts
; i
++) {
2861 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2862 if (!(da
->id
->name
)[-1] && da
->value
) {
2863 if (da
->id
->prefix
) {
2864 if (da
->id
->xmlns
) {
2865 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2866 da
->value
, bindingsPtr
);
2871 (da
->id
->name
)[-1] = 2;
2873 appAtts
[attIndex
++] = da
->id
->name
;
2874 appAtts
[attIndex
++] = da
->value
;
2878 (da
->id
->name
)[-1] = 1;
2879 appAtts
[attIndex
++] = da
->id
->name
;
2880 appAtts
[attIndex
++] = da
->value
;
2884 appAtts
[attIndex
] = 0;
2886 /* expand prefixed attribute names, check for duplicates,
2887 and clear flags that say whether attributes were specified */
2890 int j
; /* hash table index */
2891 unsigned long version
= nsAttsVersion
;
2892 int nsAttsSize
= (int)1 << nsAttsPower
;
2893 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2894 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2896 /* hash table size must also be a power of 2 and >= 8 */
2897 while (nPrefixes
>> nsAttsPower
++);
2898 if (nsAttsPower
< 3)
2900 nsAttsSize
= (int)1 << nsAttsPower
;
2901 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2903 return XML_ERROR_NO_MEMORY
;
2905 version
= 0; /* force re-initialization of nsAtts hash table */
2907 /* using a version flag saves us from initializing nsAtts every time */
2908 if (!version
) { /* initialize version flags when version wraps around */
2909 version
= INIT_ATTS_VERSION
;
2910 for (j
= nsAttsSize
; j
!= 0; )
2911 nsAtts
[--j
].version
= version
;
2913 nsAttsVersion
= --version
;
2915 /* expand prefixed names and check for duplicates */
2916 for (; i
< attIndex
; i
+= 2) {
2917 const XML_Char
*s
= appAtts
[i
];
2918 if (s
[-1] == 2) { /* prefixed */
2921 unsigned long uriHash
= hash_secret_salt
;
2922 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2923 id
= (ATTRIBUTE_ID
*)lookup(parser
, &dtd
->attributeIds
, s
, 0);
2924 b
= id
->prefix
->binding
;
2926 return XML_ERROR_UNBOUND_PREFIX
;
2928 /* as we expand the name we also calculate its hash value */
2929 for (j
= 0; j
< b
->uriLen
; j
++) {
2930 const XML_Char c
= b
->uri
[j
];
2931 if (!poolAppendChar(&tempPool
, c
))
2932 return XML_ERROR_NO_MEMORY
;
2933 uriHash
= CHAR_HASH(uriHash
, c
);
2935 while (*s
++ != XML_T(ASCII_COLON
))
2937 do { /* copies null terminator */
2938 const XML_Char c
= *s
;
2939 if (!poolAppendChar(&tempPool
, *s
))
2940 return XML_ERROR_NO_MEMORY
;
2941 uriHash
= CHAR_HASH(uriHash
, c
);
2944 { /* Check hash table for duplicate of expanded name (uriName).
2945 Derived from code in lookup(parser, HASH_TABLE *table, ...).
2947 unsigned char step
= 0;
2948 unsigned long mask
= nsAttsSize
- 1;
2949 j
= uriHash
& mask
; /* index into hash table */
2950 while (nsAtts
[j
].version
== version
) {
2951 /* for speed we compare stored hash values first */
2952 if (uriHash
== nsAtts
[j
].hash
) {
2953 const XML_Char
*s1
= poolStart(&tempPool
);
2954 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2955 /* s1 is null terminated, but not s2 */
2956 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2958 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2961 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2962 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2966 if (ns_triplets
) { /* append namespace separator and prefix */
2967 tempPool
.ptr
[-1] = namespaceSeparator
;
2968 s
= b
->prefix
->name
;
2970 if (!poolAppendChar(&tempPool
, *s
))
2971 return XML_ERROR_NO_MEMORY
;
2975 /* store expanded name in attribute list */
2976 s
= poolStart(&tempPool
);
2977 poolFinish(&tempPool
);
2980 /* fill empty slot with new version, uriName and hash value */
2981 nsAtts
[j
].version
= version
;
2982 nsAtts
[j
].hash
= uriHash
;
2983 nsAtts
[j
].uriName
= s
;
2990 else /* not prefixed */
2991 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2994 /* clear flags for the remaining attributes */
2995 for (; i
< attIndex
; i
+= 2)
2996 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2997 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2998 binding
->attId
->name
[-1] = 0;
3001 return XML_ERROR_NONE
;
3003 /* expand the element type name */
3004 if (elementType
->prefix
) {
3005 binding
= elementType
->prefix
->binding
;
3007 return XML_ERROR_UNBOUND_PREFIX
;
3008 localPart
= tagNamePtr
->str
;
3009 while (*localPart
++ != XML_T(ASCII_COLON
))
3012 else if (dtd
->defaultPrefix
.binding
) {
3013 binding
= dtd
->defaultPrefix
.binding
;
3014 localPart
= tagNamePtr
->str
;
3017 return XML_ERROR_NONE
;
3019 if (ns_triplets
&& binding
->prefix
->name
) {
3020 for (; binding
->prefix
->name
[prefixLen
++];)
3021 ; /* prefixLen includes null terminator */
3023 tagNamePtr
->localPart
= localPart
;
3024 tagNamePtr
->uriLen
= binding
->uriLen
;
3025 tagNamePtr
->prefix
= binding
->prefix
->name
;
3026 tagNamePtr
->prefixLen
= prefixLen
;
3027 for (i
= 0; localPart
[i
++];)
3028 ; /* i includes null terminator */
3029 n
= i
+ binding
->uriLen
+ prefixLen
;
3030 if (n
> binding
->uriAlloc
) {
3032 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
3034 return XML_ERROR_NO_MEMORY
;
3035 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
3036 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
3037 for (p
= tagStack
; p
; p
= p
->parent
)
3038 if (p
->name
.str
== binding
->uri
)
3043 /* if namespaceSeparator != '\0' then uri includes it already */
3044 uri
= binding
->uri
+ binding
->uriLen
;
3045 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
3046 /* we always have a namespace separator between localPart and prefix */
3049 *uri
= namespaceSeparator
; /* replace null terminator */
3050 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
3052 tagNamePtr
->str
= binding
->uri
;
3053 return XML_ERROR_NONE
;
3056 /* addBinding() overwrites the value of prefix->binding without checking.
3057 Therefore one must keep track of the old value outside of addBinding().
3059 static enum XML_Error
3060 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
3061 const XML_Char
*uri
, BINDING
**bindingsPtr
)
3063 static const XML_Char xmlNamespace
[] = {
3064 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
3065 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
3066 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
,
3067 ASCII_SLASH
, ASCII_1
, ASCII_9
, ASCII_9
, ASCII_8
, ASCII_SLASH
,
3068 ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
, ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
,
3071 static const int xmlLen
=
3072 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
3073 static const XML_Char xmlnsNamespace
[] = {
3074 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
3075 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
3076 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_2
, ASCII_0
, ASCII_0
,
3077 ASCII_0
, ASCII_SLASH
, ASCII_x
, ASCII_m
, ASCII_l
, ASCII_n
, ASCII_s
,
3080 static const int xmlnsLen
=
3081 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
3083 XML_Bool mustBeXML
= XML_FALSE
;
3084 XML_Bool isXML
= XML_TRUE
;
3085 XML_Bool isXMLNS
= XML_TRUE
;
3090 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3091 if (*uri
== XML_T('\0') && prefix
->name
)
3092 return XML_ERROR_UNDECLARING_PREFIX
;
3095 && prefix
->name
[0] == XML_T(ASCII_x
)
3096 && prefix
->name
[1] == XML_T(ASCII_m
)
3097 && prefix
->name
[2] == XML_T(ASCII_l
)) {
3099 /* Not allowed to bind xmlns */
3100 if (prefix
->name
[3] == XML_T(ASCII_n
)
3101 && prefix
->name
[4] == XML_T(ASCII_s
)
3102 && prefix
->name
[5] == XML_T('\0'))
3103 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
3105 if (prefix
->name
[3] == XML_T('\0'))
3106 mustBeXML
= XML_TRUE
;
3109 for (len
= 0; uri
[len
]; len
++) {
3110 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
3113 if (!mustBeXML
&& isXMLNS
3114 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
3115 isXMLNS
= XML_FALSE
;
3117 isXML
= isXML
&& len
== xmlLen
;
3118 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
3120 if (mustBeXML
!= isXML
)
3121 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
3122 : XML_ERROR_RESERVED_NAMESPACE_URI
;
3125 return XML_ERROR_RESERVED_NAMESPACE_URI
;
3127 if (namespaceSeparator
)
3129 if (freeBindingList
) {
3130 b
= freeBindingList
;
3131 if (len
> b
->uriAlloc
) {
3132 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3133 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3135 return XML_ERROR_NO_MEMORY
;
3137 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3139 freeBindingList
= b
->nextTagBinding
;
3142 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3144 return XML_ERROR_NO_MEMORY
;
3145 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3148 return XML_ERROR_NO_MEMORY
;
3150 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3153 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3154 if (namespaceSeparator
)
3155 b
->uri
[len
- 1] = namespaceSeparator
;
3158 b
->prevPrefixBinding
= prefix
->binding
;
3159 /* NULL binding when default namespace undeclared */
3160 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3161 prefix
->binding
= NULL
;
3163 prefix
->binding
= b
;
3164 b
->nextTagBinding
= *bindingsPtr
;
3166 /* if attId == NULL then we are not starting a namespace scope */
3167 if (attId
&& startNamespaceDeclHandler
)
3168 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3169 prefix
->binding
? uri
: 0);
3170 return XML_ERROR_NONE
;
3173 /* The idea here is to avoid using stack for each CDATA section when
3174 the whole file is parsed with one call.
3176 static enum XML_Error PTRCALL
3177 cdataSectionProcessor(XML_Parser parser
,
3180 const char **endPtr
)
3182 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3183 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3184 if (result
!= XML_ERROR_NONE
)
3187 if (parentParser
) { /* we are parsing an external entity */
3188 processor
= externalEntityContentProcessor
;
3189 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3192 processor
= contentProcessor
;
3193 return contentProcessor(parser
, start
, end
, endPtr
);
3199 /* startPtr gets set to non-null if the section is closed, and to null if
3200 the section is not yet closed.
3202 static enum XML_Error
3203 doCdataSection(XML_Parser parser
,
3204 const ENCODING
*enc
,
3205 const char **startPtr
,
3207 const char **nextPtr
,
3210 const char *s
= *startPtr
;
3211 const char **eventPP
;
3212 const char **eventEndPP
;
3213 if (enc
== encoding
) {
3214 eventPP
= &eventPtr
;
3216 eventEndPP
= &eventEndPtr
;
3219 eventPP
= &(openInternalEntities
->internalEventPtr
);
3220 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3227 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3230 case XML_TOK_CDATA_SECT_CLOSE
:
3231 if (endCdataSectionHandler
)
3232 endCdataSectionHandler(handlerArg
);
3234 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3235 else if (characterDataHandler
)
3236 characterDataHandler(handlerArg
, dataBuf
, 0);
3238 else if (defaultHandler
)
3239 reportDefault(parser
, enc
, s
, next
);
3242 if (ps_parsing
== XML_FINISHED
)
3243 return XML_ERROR_ABORTED
;
3245 return XML_ERROR_NONE
;
3246 case XML_TOK_DATA_NEWLINE
:
3247 if (characterDataHandler
) {
3249 characterDataHandler(handlerArg
, &c
, 1);
3251 else if (defaultHandler
)
3252 reportDefault(parser
, enc
, s
, next
);
3254 case XML_TOK_DATA_CHARS
:
3256 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
3257 if (charDataHandler
) {
3258 if (MUST_CONVERT(enc
, s
)) {
3260 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3261 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3263 charDataHandler(handlerArg
, dataBuf
,
3264 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3271 charDataHandler(handlerArg
,
3273 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3275 else if (defaultHandler
)
3276 reportDefault(parser
, enc
, s
, next
);
3279 case XML_TOK_INVALID
:
3281 return XML_ERROR_INVALID_TOKEN
;
3282 case XML_TOK_PARTIAL_CHAR
:
3285 return XML_ERROR_NONE
;
3287 return XML_ERROR_PARTIAL_CHAR
;
3288 case XML_TOK_PARTIAL
:
3292 return XML_ERROR_NONE
;
3294 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3297 return XML_ERROR_UNEXPECTED_STATE
;
3300 *eventPP
= s
= next
;
3301 switch (ps_parsing
) {
3304 return XML_ERROR_NONE
;
3306 return XML_ERROR_ABORTED
;
3315 /* The idea here is to avoid using stack for each IGNORE section when
3316 the whole file is parsed with one call.
3318 static enum XML_Error PTRCALL
3319 ignoreSectionProcessor(XML_Parser parser
,
3322 const char **endPtr
)
3324 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3325 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3326 if (result
!= XML_ERROR_NONE
)
3329 processor
= prologProcessor
;
3330 return prologProcessor(parser
, start
, end
, endPtr
);
3335 /* startPtr gets set to non-null is the section is closed, and to null
3336 if the section is not yet closed.
3338 static enum XML_Error
3339 doIgnoreSection(XML_Parser parser
,
3340 const ENCODING
*enc
,
3341 const char **startPtr
,
3343 const char **nextPtr
,
3348 const char *s
= *startPtr
;
3349 const char **eventPP
;
3350 const char **eventEndPP
;
3351 if (enc
== encoding
) {
3352 eventPP
= &eventPtr
;
3354 eventEndPP
= &eventEndPtr
;
3357 eventPP
= &(openInternalEntities
->internalEventPtr
);
3358 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3362 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3365 case XML_TOK_IGNORE_SECT
:
3367 reportDefault(parser
, enc
, s
, next
);
3370 if (ps_parsing
== XML_FINISHED
)
3371 return XML_ERROR_ABORTED
;
3373 return XML_ERROR_NONE
;
3374 case XML_TOK_INVALID
:
3376 return XML_ERROR_INVALID_TOKEN
;
3377 case XML_TOK_PARTIAL_CHAR
:
3380 return XML_ERROR_NONE
;
3382 return XML_ERROR_PARTIAL_CHAR
;
3383 case XML_TOK_PARTIAL
:
3387 return XML_ERROR_NONE
;
3389 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3392 return XML_ERROR_UNEXPECTED_STATE
;
3397 #endif /* XML_DTD */
3399 static enum XML_Error
3400 initializeEncoding(XML_Parser parser
)
3404 char encodingBuf
[128];
3405 if (!protocolEncodingName
)
3409 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3410 if (i
== sizeof(encodingBuf
) - 1
3411 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3412 encodingBuf
[0] = '\0';
3415 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3417 encodingBuf
[i
] = '\0';
3421 s
= protocolEncodingName
;
3423 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3424 return XML_ERROR_NONE
;
3425 return handleUnknownEncoding(parser
, protocolEncodingName
);
3428 static enum XML_Error
3429 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3430 const char *s
, const char *next
)
3432 const char *encodingName
= NULL
;
3433 const XML_Char
*storedEncName
= NULL
;
3434 const ENCODING
*newEncoding
= NULL
;
3435 const char *version
= NULL
;
3436 const char *versionend
;
3437 const XML_Char
*storedversion
= NULL
;
3438 int standalone
= -1;
3441 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3451 if (isGeneralTextEntity
)
3452 return XML_ERROR_TEXT_DECL
;
3454 return XML_ERROR_XML_DECL
;
3456 if (!isGeneralTextEntity
&& standalone
== 1) {
3457 _dtd
->standalone
= XML_TRUE
;
3459 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3460 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3461 #endif /* XML_DTD */
3463 if (xmlDeclHandler
) {
3464 if (encodingName
!= NULL
) {
3465 storedEncName
= poolStoreString(&temp2Pool
,
3469 + XmlNameLength(encoding
, encodingName
));
3471 return XML_ERROR_NO_MEMORY
;
3472 poolFinish(&temp2Pool
);
3475 storedversion
= poolStoreString(&temp2Pool
,
3478 versionend
- encoding
->minBytesPerChar
);
3480 return XML_ERROR_NO_MEMORY
;
3482 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3484 else if (defaultHandler
)
3485 reportDefault(parser
, encoding
, s
, next
);
3486 if (protocolEncodingName
== NULL
) {
3488 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3489 eventPtr
= encodingName
;
3490 return XML_ERROR_INCORRECT_ENCODING
;
3492 encoding
= newEncoding
;
3494 else if (encodingName
) {
3495 enum XML_Error result
;
3496 if (!storedEncName
) {
3497 storedEncName
= poolStoreString(
3498 &temp2Pool
, encoding
, encodingName
,
3499 encodingName
+ XmlNameLength(encoding
, encodingName
));
3501 return XML_ERROR_NO_MEMORY
;
3503 result
= handleUnknownEncoding(parser
, storedEncName
);
3504 poolClear(&temp2Pool
);
3505 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3506 eventPtr
= encodingName
;
3511 if (storedEncName
|| storedversion
)
3512 poolClear(&temp2Pool
);
3514 return XML_ERROR_NONE
;
3517 static enum XML_Error
3518 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3520 if (unknownEncodingHandler
) {
3523 for (i
= 0; i
< 256; i
++)
3525 info
.convert
= NULL
;
3527 info
.release
= NULL
;
3528 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3531 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3532 if (!unknownEncodingMem
) {
3534 info
.release(info
.data
);
3535 return XML_ERROR_NO_MEMORY
;
3538 ? XmlInitUnknownEncodingNS
3539 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3544 unknownEncodingData
= info
.data
;
3545 unknownEncodingRelease
= info
.release
;
3547 return XML_ERROR_NONE
;
3550 if (info
.release
!= NULL
)
3551 info
.release(info
.data
);
3553 return XML_ERROR_UNKNOWN_ENCODING
;
3556 static enum XML_Error PTRCALL
3557 prologInitProcessor(XML_Parser parser
,
3560 const char **nextPtr
)
3562 enum XML_Error result
= initializeEncoding(parser
);
3563 if (result
!= XML_ERROR_NONE
)
3565 processor
= prologProcessor
;
3566 return prologProcessor(parser
, s
, end
, nextPtr
);
3571 static enum XML_Error PTRCALL
3572 externalParEntInitProcessor(XML_Parser parser
,
3575 const char **nextPtr
)
3577 enum XML_Error result
= initializeEncoding(parser
);
3578 if (result
!= XML_ERROR_NONE
)
3581 /* we know now that XML_Parse(Buffer) has been called,
3582 so we consider the external parameter entity read */
3583 _dtd
->paramEntityRead
= XML_TRUE
;
3585 if (prologState
.inEntityValue
) {
3586 processor
= entityValueInitProcessor
;
3587 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3590 processor
= externalParEntProcessor
;
3591 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3595 static enum XML_Error PTRCALL
3596 entityValueInitProcessor(XML_Parser parser
,
3599 const char **nextPtr
)
3602 const char *start
= s
;
3603 const char *next
= start
;
3607 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3610 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3612 return XML_ERROR_NONE
;
3615 case XML_TOK_INVALID
:
3616 return XML_ERROR_INVALID_TOKEN
;
3617 case XML_TOK_PARTIAL
:
3618 return XML_ERROR_UNCLOSED_TOKEN
;
3619 case XML_TOK_PARTIAL_CHAR
:
3620 return XML_ERROR_PARTIAL_CHAR
;
3621 case XML_TOK_NONE
: /* start == end */
3625 /* found end of entity value - can store it now */
3626 return storeEntityValue(parser
, encoding
, s
, end
);
3628 else if (tok
== XML_TOK_XML_DECL
) {
3629 enum XML_Error result
;
3630 result
= processXmlDecl(parser
, 0, start
, next
);
3631 if (result
!= XML_ERROR_NONE
)
3633 switch (ps_parsing
) {
3636 return XML_ERROR_NONE
;
3638 return XML_ERROR_ABORTED
;
3642 /* stop scanning for text declaration - we found one */
3643 processor
= entityValueProcessor
;
3644 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3646 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3647 return XML_TOK_NONE on the next call, which would then cause the
3648 function to exit with *nextPtr set to s - that is what we want for other
3649 tokens, but not for the BOM - we would rather like to skip it;
3650 then, when this routine is entered the next time, XmlPrologTok will
3651 return XML_TOK_INVALID, since the BOM is still in the buffer
3653 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3655 return XML_ERROR_NONE
;
3662 static enum XML_Error PTRCALL
3663 externalParEntProcessor(XML_Parser parser
,
3666 const char **nextPtr
)
3668 const char *next
= s
;
3671 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3673 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3675 return XML_ERROR_NONE
;
3678 case XML_TOK_INVALID
:
3679 return XML_ERROR_INVALID_TOKEN
;
3680 case XML_TOK_PARTIAL
:
3681 return XML_ERROR_UNCLOSED_TOKEN
;
3682 case XML_TOK_PARTIAL_CHAR
:
3683 return XML_ERROR_PARTIAL_CHAR
;
3684 case XML_TOK_NONE
: /* start == end */
3689 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3690 However, when parsing an external subset, doProlog will not accept a BOM
3691 as valid, and report a syntax error, so we have to skip the BOM
3693 else if (tok
== XML_TOK_BOM
) {
3695 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3698 processor
= prologProcessor
;
3699 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3700 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3703 static enum XML_Error PTRCALL
3704 entityValueProcessor(XML_Parser parser
,
3707 const char **nextPtr
)
3709 const char *start
= s
;
3710 const char *next
= s
;
3711 const ENCODING
*enc
= encoding
;
3715 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3717 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3719 return XML_ERROR_NONE
;
3722 case XML_TOK_INVALID
:
3723 return XML_ERROR_INVALID_TOKEN
;
3724 case XML_TOK_PARTIAL
:
3725 return XML_ERROR_UNCLOSED_TOKEN
;
3726 case XML_TOK_PARTIAL_CHAR
:
3727 return XML_ERROR_PARTIAL_CHAR
;
3728 case XML_TOK_NONE
: /* start == end */
3732 /* found end of entity value - can store it now */
3733 return storeEntityValue(parser
, enc
, s
, end
);
3739 #endif /* XML_DTD */
3741 static enum XML_Error PTRCALL
3742 prologProcessor(XML_Parser parser
,
3745 const char **nextPtr
)
3747 const char *next
= s
;
3748 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3749 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3750 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3753 static enum XML_Error
3754 doProlog(XML_Parser parser
,
3755 const ENCODING
*enc
,
3760 const char **nextPtr
,
3764 static const XML_Char externalSubsetName
[] = { ASCII_HASH
, '\0' };
3765 #endif /* XML_DTD */
3766 static const XML_Char atypeCDATA
[] =
3767 { ASCII_C
, ASCII_D
, ASCII_A
, ASCII_T
, ASCII_A
, '\0' };
3768 static const XML_Char atypeID
[] = { ASCII_I
, ASCII_D
, '\0' };
3769 static const XML_Char atypeIDREF
[] =
3770 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, '\0' };
3771 static const XML_Char atypeIDREFS
[] =
3772 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, ASCII_S
, '\0' };
3773 static const XML_Char atypeENTITY
[] =
3774 { ASCII_E
, ASCII_N
, ASCII_T
, ASCII_I
, ASCII_T
, ASCII_Y
, '\0' };
3775 static const XML_Char atypeENTITIES
[] = { ASCII_E
, ASCII_N
,
3776 ASCII_T
, ASCII_I
, ASCII_T
, ASCII_I
, ASCII_E
, ASCII_S
, '\0' };
3777 static const XML_Char atypeNMTOKEN
[] = {
3778 ASCII_N
, ASCII_M
, ASCII_T
, ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, '\0' };
3779 static const XML_Char atypeNMTOKENS
[] = { ASCII_N
, ASCII_M
, ASCII_T
,
3780 ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, ASCII_S
, '\0' };
3781 static const XML_Char notationPrefix
[] = { ASCII_N
, ASCII_O
, ASCII_T
,
3782 ASCII_A
, ASCII_T
, ASCII_I
, ASCII_O
, ASCII_N
, ASCII_LPAREN
, '\0' };
3783 static const XML_Char enumValueSep
[] = { ASCII_PIPE
, '\0' };
3784 static const XML_Char enumValueStart
[] = { ASCII_LPAREN
, '\0' };
3786 /* save one level of indirection */
3787 DTD
* const dtd
= _dtd
;
3789 const char **eventPP
;
3790 const char **eventEndPP
;
3791 enum XML_Content_Quant quant
;
3793 if (enc
== encoding
) {
3794 eventPP
= &eventPtr
;
3795 eventEndPP
= &eventEndPtr
;
3798 eventPP
= &(openInternalEntities
->internalEventPtr
);
3799 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3804 XML_Bool handleDefault
= XML_TRUE
;
3808 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3810 return XML_ERROR_NONE
;
3813 case XML_TOK_INVALID
:
3815 return XML_ERROR_INVALID_TOKEN
;
3816 case XML_TOK_PARTIAL
:
3817 return XML_ERROR_UNCLOSED_TOKEN
;
3818 case XML_TOK_PARTIAL_CHAR
:
3819 return XML_ERROR_PARTIAL_CHAR
;
3820 case -XML_TOK_PROLOG_S
:
3825 /* for internal PE NOT referenced between declarations */
3826 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3828 return XML_ERROR_NONE
;
3830 /* WFC: PE Between Declarations - must check that PE contains
3831 complete markup, not only for external PEs, but also for
3832 internal PEs if the reference occurs between declarations.
3834 if (isParamEntity
|| enc
!= encoding
) {
3835 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3837 return XML_ERROR_INCOMPLETE_PE
;
3839 return XML_ERROR_NONE
;
3841 #endif /* XML_DTD */
3842 return XML_ERROR_NO_ELEMENTS
;
3849 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3851 case XML_ROLE_XML_DECL
:
3853 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3854 if (result
!= XML_ERROR_NONE
)
3857 handleDefault
= XML_FALSE
;
3860 case XML_ROLE_DOCTYPE_NAME
:
3861 if (startDoctypeDeclHandler
) {
3862 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3864 return XML_ERROR_NO_MEMORY
;
3865 poolFinish(&tempPool
);
3866 doctypePubid
= NULL
;
3867 handleDefault
= XML_FALSE
;
3869 doctypeSysid
= NULL
; /* always initialize to NULL */
3871 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3872 if (startDoctypeDeclHandler
) {
3873 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3876 poolClear(&tempPool
);
3877 handleDefault
= XML_FALSE
;
3881 case XML_ROLE_TEXT_DECL
:
3883 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3884 if (result
!= XML_ERROR_NONE
)
3887 handleDefault
= XML_FALSE
;
3890 #endif /* XML_DTD */
3891 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3893 useForeignDTD
= XML_FALSE
;
3894 declEntity
= (ENTITY
*)lookup(parser
,
3895 &dtd
->paramEntities
,
3899 return XML_ERROR_NO_MEMORY
;
3900 #endif /* XML_DTD */
3901 dtd
->hasParamEntityRefs
= XML_TRUE
;
3902 if (startDoctypeDeclHandler
) {
3904 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3905 return XML_ERROR_PUBLICID
;
3906 pubId
= poolStoreString(&tempPool
, enc
,
3907 s
+ enc
->minBytesPerChar
,
3908 next
- enc
->minBytesPerChar
);
3910 return XML_ERROR_NO_MEMORY
;
3911 normalizePublicId(pubId
);
3912 poolFinish(&tempPool
);
3913 doctypePubid
= pubId
;
3914 handleDefault
= XML_FALSE
;
3915 goto alreadyChecked
;
3918 case XML_ROLE_ENTITY_PUBLIC_ID
:
3919 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3920 return XML_ERROR_PUBLICID
;
3922 if (dtd
->keepProcessing
&& declEntity
) {
3923 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3925 s
+ enc
->minBytesPerChar
,
3926 next
- enc
->minBytesPerChar
);
3928 return XML_ERROR_NO_MEMORY
;
3929 normalizePublicId(tem
);
3930 declEntity
->publicId
= tem
;
3931 poolFinish(&dtd
->pool
);
3932 if (entityDeclHandler
)
3933 handleDefault
= XML_FALSE
;
3936 case XML_ROLE_DOCTYPE_CLOSE
:
3938 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3939 doctypeSysid
, doctypePubid
, 0);
3940 poolClear(&tempPool
);
3941 handleDefault
= XML_FALSE
;
3943 /* doctypeSysid will be non-NULL in the case of a previous
3944 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3945 was not set, indicating an external subset
3948 if (doctypeSysid
|| useForeignDTD
) {
3949 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3950 dtd
->hasParamEntityRefs
= XML_TRUE
;
3951 if (paramEntityParsing
&& externalEntityRefHandler
) {
3952 ENTITY
*entity
= (ENTITY
*)lookup(parser
,
3953 &dtd
->paramEntities
,
3957 return XML_ERROR_NO_MEMORY
;
3959 entity
->base
= curBase
;
3960 dtd
->paramEntityRead
= XML_FALSE
;
3961 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3966 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3967 if (dtd
->paramEntityRead
) {
3968 if (!dtd
->standalone
&&
3969 notStandaloneHandler
&&
3970 !notStandaloneHandler(handlerArg
))
3971 return XML_ERROR_NOT_STANDALONE
;
3973 /* if we didn't read the foreign DTD then this means that there
3974 is no external subset and we must reset dtd->hasParamEntityRefs
3976 else if (!doctypeSysid
)
3977 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3978 /* end of DTD - no need to update dtd->keepProcessing */
3980 useForeignDTD
= XML_FALSE
;
3982 #endif /* XML_DTD */
3983 if (endDoctypeDeclHandler
) {
3984 endDoctypeDeclHandler(handlerArg
);
3985 handleDefault
= XML_FALSE
;
3988 case XML_ROLE_INSTANCE_START
:
3990 /* if there is no DOCTYPE declaration then now is the
3991 last chance to read the foreign DTD
3993 if (useForeignDTD
) {
3994 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3995 dtd
->hasParamEntityRefs
= XML_TRUE
;
3996 if (paramEntityParsing
&& externalEntityRefHandler
) {
3997 ENTITY
*entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
,
4001 return XML_ERROR_NO_MEMORY
;
4002 entity
->base
= curBase
;
4003 dtd
->paramEntityRead
= XML_FALSE
;
4004 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4009 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4010 if (dtd
->paramEntityRead
) {
4011 if (!dtd
->standalone
&&
4012 notStandaloneHandler
&&
4013 !notStandaloneHandler(handlerArg
))
4014 return XML_ERROR_NOT_STANDALONE
;
4016 /* if we didn't read the foreign DTD then this means that there
4017 is no external subset and we must reset dtd->hasParamEntityRefs
4020 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
4021 /* end of DTD - no need to update dtd->keepProcessing */
4024 #endif /* XML_DTD */
4025 processor
= contentProcessor
;
4026 return contentProcessor(parser
, s
, end
, nextPtr
);
4027 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
4028 declElementType
= getElementType(parser
, enc
, s
, next
);
4029 if (!declElementType
)
4030 return XML_ERROR_NO_MEMORY
;
4031 goto checkAttListDeclHandler
;
4032 case XML_ROLE_ATTRIBUTE_NAME
:
4033 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
4034 if (!declAttributeId
)
4035 return XML_ERROR_NO_MEMORY
;
4036 declAttributeIsCdata
= XML_FALSE
;
4037 declAttributeType
= NULL
;
4038 declAttributeIsId
= XML_FALSE
;
4039 goto checkAttListDeclHandler
;
4040 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
4041 declAttributeIsCdata
= XML_TRUE
;
4042 declAttributeType
= atypeCDATA
;
4043 goto checkAttListDeclHandler
;
4044 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
4045 declAttributeIsId
= XML_TRUE
;
4046 declAttributeType
= atypeID
;
4047 goto checkAttListDeclHandler
;
4048 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
4049 declAttributeType
= atypeIDREF
;
4050 goto checkAttListDeclHandler
;
4051 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
4052 declAttributeType
= atypeIDREFS
;
4053 goto checkAttListDeclHandler
;
4054 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
4055 declAttributeType
= atypeENTITY
;
4056 goto checkAttListDeclHandler
;
4057 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
4058 declAttributeType
= atypeENTITIES
;
4059 goto checkAttListDeclHandler
;
4060 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
4061 declAttributeType
= atypeNMTOKEN
;
4062 goto checkAttListDeclHandler
;
4063 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
4064 declAttributeType
= atypeNMTOKENS
;
4065 checkAttListDeclHandler
:
4066 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4067 handleDefault
= XML_FALSE
;
4069 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
4070 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
4071 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
4072 const XML_Char
*prefix
;
4073 if (declAttributeType
) {
4074 prefix
= enumValueSep
;
4077 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4081 if (!poolAppendString(&tempPool
, prefix
))
4082 return XML_ERROR_NO_MEMORY
;
4083 if (!poolAppend(&tempPool
, enc
, s
, next
))
4084 return XML_ERROR_NO_MEMORY
;
4085 declAttributeType
= tempPool
.start
;
4086 handleDefault
= XML_FALSE
;
4089 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
4090 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
4091 if (dtd
->keepProcessing
) {
4092 if (!defineAttribute(declElementType
, declAttributeId
,
4093 declAttributeIsCdata
, declAttributeIsId
,
4095 return XML_ERROR_NO_MEMORY
;
4096 if (attlistDeclHandler
&& declAttributeType
) {
4097 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4098 || (*declAttributeType
== XML_T(ASCII_N
)
4099 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4100 /* Enumerated or Notation type */
4101 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4102 || !poolAppendChar(&tempPool
, XML_T('\0')))
4103 return XML_ERROR_NO_MEMORY
;
4104 declAttributeType
= tempPool
.start
;
4105 poolFinish(&tempPool
);
4108 attlistDeclHandler(handlerArg
, declElementType
->name
,
4109 declAttributeId
->name
, declAttributeType
,
4110 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
4111 poolClear(&tempPool
);
4112 handleDefault
= XML_FALSE
;
4116 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
4117 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
4118 if (dtd
->keepProcessing
) {
4119 const XML_Char
*attVal
;
4120 enum XML_Error result
=
4121 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
4122 s
+ enc
->minBytesPerChar
,
4123 next
- enc
->minBytesPerChar
,
4127 attVal
= poolStart(&dtd
->pool
);
4128 poolFinish(&dtd
->pool
);
4129 /* ID attributes aren't allowed to have a default */
4130 if (!defineAttribute(declElementType
, declAttributeId
,
4131 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
4132 return XML_ERROR_NO_MEMORY
;
4133 if (attlistDeclHandler
&& declAttributeType
) {
4134 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4135 || (*declAttributeType
== XML_T(ASCII_N
)
4136 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4137 /* Enumerated or Notation type */
4138 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4139 || !poolAppendChar(&tempPool
, XML_T('\0')))
4140 return XML_ERROR_NO_MEMORY
;
4141 declAttributeType
= tempPool
.start
;
4142 poolFinish(&tempPool
);
4145 attlistDeclHandler(handlerArg
, declElementType
->name
,
4146 declAttributeId
->name
, declAttributeType
,
4148 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4149 poolClear(&tempPool
);
4150 handleDefault
= XML_FALSE
;
4154 case XML_ROLE_ENTITY_VALUE
:
4155 if (dtd
->keepProcessing
) {
4156 enum XML_Error result
= storeEntityValue(parser
, enc
,
4157 s
+ enc
->minBytesPerChar
,
4158 next
- enc
->minBytesPerChar
);
4160 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4161 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4162 poolFinish(&dtd
->entityValuePool
);
4163 if (entityDeclHandler
) {
4165 entityDeclHandler(handlerArg
,
4167 declEntity
->is_param
,
4168 declEntity
->textPtr
,
4169 declEntity
->textLen
,
4171 handleDefault
= XML_FALSE
;
4175 poolDiscard(&dtd
->entityValuePool
);
4176 if (result
!= XML_ERROR_NONE
)
4180 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4182 useForeignDTD
= XML_FALSE
;
4183 #endif /* XML_DTD */
4184 dtd
->hasParamEntityRefs
= XML_TRUE
;
4185 if (startDoctypeDeclHandler
) {
4186 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4187 s
+ enc
->minBytesPerChar
,
4188 next
- enc
->minBytesPerChar
);
4189 if (doctypeSysid
== NULL
)
4190 return XML_ERROR_NO_MEMORY
;
4191 poolFinish(&tempPool
);
4192 handleDefault
= XML_FALSE
;
4196 /* use externalSubsetName to make doctypeSysid non-NULL
4197 for the case where no startDoctypeDeclHandler is set */
4198 doctypeSysid
= externalSubsetName
;
4199 #endif /* XML_DTD */
4200 if (!dtd
->standalone
4202 && !paramEntityParsing
4203 #endif /* XML_DTD */
4204 && notStandaloneHandler
4205 && !notStandaloneHandler(handlerArg
))
4206 return XML_ERROR_NOT_STANDALONE
;
4211 declEntity
= (ENTITY
*)lookup(parser
,
4212 &dtd
->paramEntities
,
4216 return XML_ERROR_NO_MEMORY
;
4217 declEntity
->publicId
= NULL
;
4220 #endif /* XML_DTD */
4221 case XML_ROLE_ENTITY_SYSTEM_ID
:
4222 if (dtd
->keepProcessing
&& declEntity
) {
4223 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4224 s
+ enc
->minBytesPerChar
,
4225 next
- enc
->minBytesPerChar
);
4226 if (!declEntity
->systemId
)
4227 return XML_ERROR_NO_MEMORY
;
4228 declEntity
->base
= curBase
;
4229 poolFinish(&dtd
->pool
);
4230 if (entityDeclHandler
)
4231 handleDefault
= XML_FALSE
;
4234 case XML_ROLE_ENTITY_COMPLETE
:
4235 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4237 entityDeclHandler(handlerArg
,
4239 declEntity
->is_param
,
4242 declEntity
->systemId
,
4243 declEntity
->publicId
,
4245 handleDefault
= XML_FALSE
;
4248 case XML_ROLE_ENTITY_NOTATION_NAME
:
4249 if (dtd
->keepProcessing
&& declEntity
) {
4250 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4251 if (!declEntity
->notation
)
4252 return XML_ERROR_NO_MEMORY
;
4253 poolFinish(&dtd
->pool
);
4254 if (unparsedEntityDeclHandler
) {
4256 unparsedEntityDeclHandler(handlerArg
,
4259 declEntity
->systemId
,
4260 declEntity
->publicId
,
4261 declEntity
->notation
);
4262 handleDefault
= XML_FALSE
;
4264 else if (entityDeclHandler
) {
4266 entityDeclHandler(handlerArg
,
4270 declEntity
->systemId
,
4271 declEntity
->publicId
,
4272 declEntity
->notation
);
4273 handleDefault
= XML_FALSE
;
4277 case XML_ROLE_GENERAL_ENTITY_NAME
:
4279 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4283 if (dtd
->keepProcessing
) {
4284 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4286 return XML_ERROR_NO_MEMORY
;
4287 declEntity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
,
4290 return XML_ERROR_NO_MEMORY
;
4291 if (declEntity
->name
!= name
) {
4292 poolDiscard(&dtd
->pool
);
4296 poolFinish(&dtd
->pool
);
4297 declEntity
->publicId
= NULL
;
4298 declEntity
->is_param
= XML_FALSE
;
4299 /* if we have a parent parser or are reading an internal parameter
4300 entity, then the entity declaration is not considered "internal"
4302 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4303 if (entityDeclHandler
)
4304 handleDefault
= XML_FALSE
;
4308 poolDiscard(&dtd
->pool
);
4313 case XML_ROLE_PARAM_ENTITY_NAME
:
4315 if (dtd
->keepProcessing
) {
4316 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4318 return XML_ERROR_NO_MEMORY
;
4319 declEntity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
,
4320 name
, sizeof(ENTITY
));
4322 return XML_ERROR_NO_MEMORY
;
4323 if (declEntity
->name
!= name
) {
4324 poolDiscard(&dtd
->pool
);
4328 poolFinish(&dtd
->pool
);
4329 declEntity
->publicId
= NULL
;
4330 declEntity
->is_param
= XML_TRUE
;
4331 /* if we have a parent parser or are reading an internal parameter
4332 entity, then the entity declaration is not considered "internal"
4334 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4335 if (entityDeclHandler
)
4336 handleDefault
= XML_FALSE
;
4340 poolDiscard(&dtd
->pool
);
4343 #else /* not XML_DTD */
4345 #endif /* XML_DTD */
4347 case XML_ROLE_NOTATION_NAME
:
4348 declNotationPublicId
= NULL
;
4349 declNotationName
= NULL
;
4350 if (notationDeclHandler
) {
4351 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4352 if (!declNotationName
)
4353 return XML_ERROR_NO_MEMORY
;
4354 poolFinish(&tempPool
);
4355 handleDefault
= XML_FALSE
;
4358 case XML_ROLE_NOTATION_PUBLIC_ID
:
4359 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4360 return XML_ERROR_PUBLICID
;
4361 if (declNotationName
) { /* means notationDeclHandler != NULL */
4362 XML_Char
*tem
= poolStoreString(&tempPool
,
4364 s
+ enc
->minBytesPerChar
,
4365 next
- enc
->minBytesPerChar
);
4367 return XML_ERROR_NO_MEMORY
;
4368 normalizePublicId(tem
);
4369 declNotationPublicId
= tem
;
4370 poolFinish(&tempPool
);
4371 handleDefault
= XML_FALSE
;
4374 case XML_ROLE_NOTATION_SYSTEM_ID
:
4375 if (declNotationName
&& notationDeclHandler
) {
4376 const XML_Char
*systemId
4377 = poolStoreString(&tempPool
, enc
,
4378 s
+ enc
->minBytesPerChar
,
4379 next
- enc
->minBytesPerChar
);
4381 return XML_ERROR_NO_MEMORY
;
4383 notationDeclHandler(handlerArg
,
4387 declNotationPublicId
);
4388 handleDefault
= XML_FALSE
;
4390 poolClear(&tempPool
);
4392 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4393 if (declNotationPublicId
&& notationDeclHandler
) {
4395 notationDeclHandler(handlerArg
,
4399 declNotationPublicId
);
4400 handleDefault
= XML_FALSE
;
4402 poolClear(&tempPool
);
4404 case XML_ROLE_ERROR
:
4406 case XML_TOK_PARAM_ENTITY_REF
:
4407 /* PE references in internal subset are
4408 not allowed within declarations. */
4409 return XML_ERROR_PARAM_ENTITY_REF
;
4410 case XML_TOK_XML_DECL
:
4411 return XML_ERROR_MISPLACED_XML_PI
;
4413 return XML_ERROR_SYNTAX
;
4416 case XML_ROLE_IGNORE_SECT
:
4418 enum XML_Error result
;
4420 reportDefault(parser
, enc
, s
, next
);
4421 handleDefault
= XML_FALSE
;
4422 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4423 if (result
!= XML_ERROR_NONE
)
4426 processor
= ignoreSectionProcessor
;
4431 #endif /* XML_DTD */
4432 case XML_ROLE_GROUP_OPEN
:
4433 if (prologState
.level
>= groupSize
) {
4435 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4437 return XML_ERROR_NO_MEMORY
;
4438 groupConnector
= temp
;
4439 if (dtd
->scaffIndex
) {
4440 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4441 groupSize
* sizeof(int));
4443 return XML_ERROR_NO_MEMORY
;
4444 dtd
->scaffIndex
= temp
;
4448 groupConnector
= (char *)MALLOC(groupSize
= 32);
4449 if (!groupConnector
)
4450 return XML_ERROR_NO_MEMORY
;
4453 groupConnector
[prologState
.level
] = 0;
4454 if (dtd
->in_eldecl
) {
4455 int myindex
= nextScaffoldPart(parser
);
4457 return XML_ERROR_NO_MEMORY
;
4458 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4460 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4461 if (elementDeclHandler
)
4462 handleDefault
= XML_FALSE
;
4465 case XML_ROLE_GROUP_SEQUENCE
:
4466 if (groupConnector
[prologState
.level
] == ASCII_PIPE
)
4467 return XML_ERROR_SYNTAX
;
4468 groupConnector
[prologState
.level
] = ASCII_COMMA
;
4469 if (dtd
->in_eldecl
&& elementDeclHandler
)
4470 handleDefault
= XML_FALSE
;
4472 case XML_ROLE_GROUP_CHOICE
:
4473 if (groupConnector
[prologState
.level
] == ASCII_COMMA
)
4474 return XML_ERROR_SYNTAX
;
4476 && !groupConnector
[prologState
.level
]
4477 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4480 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4482 if (elementDeclHandler
)
4483 handleDefault
= XML_FALSE
;
4485 groupConnector
[prologState
.level
] = ASCII_PIPE
;
4487 case XML_ROLE_PARAM_ENTITY_REF
:
4489 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4490 dtd
->hasParamEntityRefs
= XML_TRUE
;
4491 if (!paramEntityParsing
)
4492 dtd
->keepProcessing
= dtd
->standalone
;
4494 const XML_Char
*name
;
4496 name
= poolStoreString(&dtd
->pool
, enc
,
4497 s
+ enc
->minBytesPerChar
,
4498 next
- enc
->minBytesPerChar
);
4500 return XML_ERROR_NO_MEMORY
;
4501 entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
, name
, 0);
4502 poolDiscard(&dtd
->pool
);
4503 /* first, determine if a check for an existing declaration is needed;
4504 if yes, check that the entity exists, and that it is internal,
4505 otherwise call the skipped entity handler
4507 if (prologState
.documentEntity
&&
4509 ? !openInternalEntities
4510 : !dtd
->hasParamEntityRefs
)) {
4512 return XML_ERROR_UNDEFINED_ENTITY
;
4513 else if (!entity
->is_internal
)
4514 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4517 dtd
->keepProcessing
= dtd
->standalone
;
4518 /* cannot report skipped entities in declarations */
4519 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4520 skippedEntityHandler(handlerArg
, name
, 1);
4521 handleDefault
= XML_FALSE
;
4526 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4527 if (entity
->textPtr
) {
4528 enum XML_Error result
;
4529 XML_Bool betweenDecl
=
4530 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4531 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4532 if (result
!= XML_ERROR_NONE
)
4534 handleDefault
= XML_FALSE
;
4537 if (externalEntityRefHandler
) {
4538 dtd
->paramEntityRead
= XML_FALSE
;
4539 entity
->open
= XML_TRUE
;
4540 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4544 entity
->publicId
)) {
4545 entity
->open
= XML_FALSE
;
4546 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4548 entity
->open
= XML_FALSE
;
4549 handleDefault
= XML_FALSE
;
4550 if (!dtd
->paramEntityRead
) {
4551 dtd
->keepProcessing
= dtd
->standalone
;
4556 dtd
->keepProcessing
= dtd
->standalone
;
4560 #endif /* XML_DTD */
4561 if (!dtd
->standalone
&&
4562 notStandaloneHandler
&&
4563 !notStandaloneHandler(handlerArg
))
4564 return XML_ERROR_NOT_STANDALONE
;
4567 /* Element declaration stuff */
4569 case XML_ROLE_ELEMENT_NAME
:
4570 if (elementDeclHandler
) {
4571 declElementType
= getElementType(parser
, enc
, s
, next
);
4572 if (!declElementType
)
4573 return XML_ERROR_NO_MEMORY
;
4574 dtd
->scaffLevel
= 0;
4575 dtd
->scaffCount
= 0;
4576 dtd
->in_eldecl
= XML_TRUE
;
4577 handleDefault
= XML_FALSE
;
4581 case XML_ROLE_CONTENT_ANY
:
4582 case XML_ROLE_CONTENT_EMPTY
:
4583 if (dtd
->in_eldecl
) {
4584 if (elementDeclHandler
) {
4585 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4587 return XML_ERROR_NO_MEMORY
;
4588 content
->quant
= XML_CQUANT_NONE
;
4589 content
->name
= NULL
;
4590 content
->numchildren
= 0;
4591 content
->children
= NULL
;
4592 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4596 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4597 handleDefault
= XML_FALSE
;
4599 dtd
->in_eldecl
= XML_FALSE
;
4603 case XML_ROLE_CONTENT_PCDATA
:
4604 if (dtd
->in_eldecl
) {
4605 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4607 if (elementDeclHandler
)
4608 handleDefault
= XML_FALSE
;
4612 case XML_ROLE_CONTENT_ELEMENT
:
4613 quant
= XML_CQUANT_NONE
;
4614 goto elementContent
;
4615 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4616 quant
= XML_CQUANT_OPT
;
4617 goto elementContent
;
4618 case XML_ROLE_CONTENT_ELEMENT_REP
:
4619 quant
= XML_CQUANT_REP
;
4620 goto elementContent
;
4621 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4622 quant
= XML_CQUANT_PLUS
;
4624 if (dtd
->in_eldecl
) {
4626 const XML_Char
*name
;
4628 const char *nxt
= (quant
== XML_CQUANT_NONE
4630 : next
- enc
->minBytesPerChar
);
4631 int myindex
= nextScaffoldPart(parser
);
4633 return XML_ERROR_NO_MEMORY
;
4634 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4635 dtd
->scaffold
[myindex
].quant
= quant
;
4636 el
= getElementType(parser
, enc
, s
, nxt
);
4638 return XML_ERROR_NO_MEMORY
;
4640 dtd
->scaffold
[myindex
].name
= name
;
4642 for (; name
[nameLen
++]; )
4644 dtd
->contentStringLen
+= nameLen
;
4645 if (elementDeclHandler
)
4646 handleDefault
= XML_FALSE
;
4650 case XML_ROLE_GROUP_CLOSE
:
4651 quant
= XML_CQUANT_NONE
;
4653 case XML_ROLE_GROUP_CLOSE_OPT
:
4654 quant
= XML_CQUANT_OPT
;
4656 case XML_ROLE_GROUP_CLOSE_REP
:
4657 quant
= XML_CQUANT_REP
;
4659 case XML_ROLE_GROUP_CLOSE_PLUS
:
4660 quant
= XML_CQUANT_PLUS
;
4662 if (dtd
->in_eldecl
) {
4663 if (elementDeclHandler
)
4664 handleDefault
= XML_FALSE
;
4666 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4667 if (dtd
->scaffLevel
== 0) {
4668 if (!handleDefault
) {
4669 XML_Content
*model
= build_model(parser
);
4671 return XML_ERROR_NO_MEMORY
;
4673 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4675 dtd
->in_eldecl
= XML_FALSE
;
4676 dtd
->contentStringLen
= 0;
4680 /* End element declaration stuff */
4683 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4684 return XML_ERROR_NO_MEMORY
;
4685 handleDefault
= XML_FALSE
;
4687 case XML_ROLE_COMMENT
:
4688 if (!reportComment(parser
, enc
, s
, next
))
4689 return XML_ERROR_NO_MEMORY
;
4690 handleDefault
= XML_FALSE
;
4695 handleDefault
= XML_FALSE
;
4699 case XML_ROLE_DOCTYPE_NONE
:
4700 if (startDoctypeDeclHandler
)
4701 handleDefault
= XML_FALSE
;
4703 case XML_ROLE_ENTITY_NONE
:
4704 if (dtd
->keepProcessing
&& entityDeclHandler
)
4705 handleDefault
= XML_FALSE
;
4707 case XML_ROLE_NOTATION_NONE
:
4708 if (notationDeclHandler
)
4709 handleDefault
= XML_FALSE
;
4711 case XML_ROLE_ATTLIST_NONE
:
4712 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4713 handleDefault
= XML_FALSE
;
4715 case XML_ROLE_ELEMENT_NONE
:
4716 if (elementDeclHandler
)
4717 handleDefault
= XML_FALSE
;
4719 } /* end of big switch */
4721 if (handleDefault
&& defaultHandler
)
4722 reportDefault(parser
, enc
, s
, next
);
4724 switch (ps_parsing
) {
4727 return XML_ERROR_NONE
;
4729 return XML_ERROR_ABORTED
;
4732 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4738 static enum XML_Error PTRCALL
4739 epilogProcessor(XML_Parser parser
,
4742 const char **nextPtr
)
4744 processor
= epilogProcessor
;
4747 const char *next
= NULL
;
4748 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4751 /* report partial linebreak - it might be the last token */
4752 case -XML_TOK_PROLOG_S
:
4753 if (defaultHandler
) {
4754 reportDefault(parser
, encoding
, s
, next
);
4755 if (ps_parsing
== XML_FINISHED
)
4756 return XML_ERROR_ABORTED
;
4759 return XML_ERROR_NONE
;
4762 return XML_ERROR_NONE
;
4763 case XML_TOK_PROLOG_S
:
4765 reportDefault(parser
, encoding
, s
, next
);
4768 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4769 return XML_ERROR_NO_MEMORY
;
4771 case XML_TOK_COMMENT
:
4772 if (!reportComment(parser
, encoding
, s
, next
))
4773 return XML_ERROR_NO_MEMORY
;
4775 case XML_TOK_INVALID
:
4777 return XML_ERROR_INVALID_TOKEN
;
4778 case XML_TOK_PARTIAL
:
4779 if (!ps_finalBuffer
) {
4781 return XML_ERROR_NONE
;
4783 return XML_ERROR_UNCLOSED_TOKEN
;
4784 case XML_TOK_PARTIAL_CHAR
:
4785 if (!ps_finalBuffer
) {
4787 return XML_ERROR_NONE
;
4789 return XML_ERROR_PARTIAL_CHAR
;
4791 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4793 eventPtr
= s
= next
;
4794 switch (ps_parsing
) {
4797 return XML_ERROR_NONE
;
4799 return XML_ERROR_ABORTED
;
4805 static enum XML_Error
4806 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4807 XML_Bool betweenDecl
)
4809 const char *textStart
, *textEnd
;
4811 enum XML_Error result
;
4812 OPEN_INTERNAL_ENTITY
*openEntity
;
4814 if (freeInternalEntities
) {
4815 openEntity
= freeInternalEntities
;
4816 freeInternalEntities
= openEntity
->next
;
4819 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4821 return XML_ERROR_NO_MEMORY
;
4823 entity
->open
= XML_TRUE
;
4824 entity
->processed
= 0;
4825 openEntity
->next
= openInternalEntities
;
4826 openInternalEntities
= openEntity
;
4827 openEntity
->entity
= entity
;
4828 openEntity
->startTagLevel
= tagLevel
;
4829 openEntity
->betweenDecl
= betweenDecl
;
4830 openEntity
->internalEventPtr
= NULL
;
4831 openEntity
->internalEventEndPtr
= NULL
;
4832 textStart
= (char *)entity
->textPtr
;
4833 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4836 if (entity
->is_param
) {
4837 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4838 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4839 next
, &next
, XML_FALSE
);
4842 #endif /* XML_DTD */
4843 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4844 textEnd
, &next
, XML_FALSE
);
4846 if (result
== XML_ERROR_NONE
) {
4847 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4848 entity
->processed
= (int)(next
- textStart
);
4849 processor
= internalEntityProcessor
;
4852 entity
->open
= XML_FALSE
;
4853 openInternalEntities
= openEntity
->next
;
4854 /* put openEntity back in list of free instances */
4855 openEntity
->next
= freeInternalEntities
;
4856 freeInternalEntities
= openEntity
;
4862 static enum XML_Error PTRCALL
4863 internalEntityProcessor(XML_Parser parser
,
4866 const char **nextPtr
)
4869 const char *textStart
, *textEnd
;
4871 enum XML_Error result
;
4872 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4874 return XML_ERROR_UNEXPECTED_STATE
;
4876 entity
= openEntity
->entity
;
4877 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4878 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4881 if (entity
->is_param
) {
4882 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4883 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4884 next
, &next
, XML_FALSE
);
4887 #endif /* XML_DTD */
4888 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4889 textStart
, textEnd
, &next
, XML_FALSE
);
4891 if (result
!= XML_ERROR_NONE
)
4893 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4894 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4898 entity
->open
= XML_FALSE
;
4899 openInternalEntities
= openEntity
->next
;
4900 /* put openEntity back in list of free instances */
4901 openEntity
->next
= freeInternalEntities
;
4902 freeInternalEntities
= openEntity
;
4906 if (entity
->is_param
) {
4908 processor
= prologProcessor
;
4909 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4910 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4911 (XML_Bool
)!ps_finalBuffer
);
4914 #endif /* XML_DTD */
4916 processor
= contentProcessor
;
4917 /* see externalEntityContentProcessor vs contentProcessor */
4918 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4919 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4923 static enum XML_Error PTRCALL
4924 errorProcessor(XML_Parser parser
,
4927 const char **nextPtr
)
4932 static enum XML_Error
4933 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4934 const char *ptr
, const char *end
,
4937 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4941 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4943 if (!poolAppendChar(pool
, XML_T('\0')))
4944 return XML_ERROR_NO_MEMORY
;
4945 return XML_ERROR_NONE
;
4948 static enum XML_Error
4949 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4950 const char *ptr
, const char *end
,
4953 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4956 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4959 return XML_ERROR_NONE
;
4960 case XML_TOK_INVALID
:
4961 if (enc
== encoding
)
4963 return XML_ERROR_INVALID_TOKEN
;
4964 case XML_TOK_PARTIAL
:
4965 if (enc
== encoding
)
4967 return XML_ERROR_INVALID_TOKEN
;
4968 case XML_TOK_CHAR_REF
:
4970 XML_Char buf
[XML_ENCODE_MAX
];
4972 int n
= XmlCharRefNumber(enc
, ptr
);
4974 if (enc
== encoding
)
4976 return XML_ERROR_BAD_CHAR_REF
;
4979 && n
== 0x20 /* space */
4980 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4982 n
= XmlEncode(n
, (ICHAR
*)buf
);
4984 if (enc
== encoding
)
4986 return XML_ERROR_BAD_CHAR_REF
;
4988 for (i
= 0; i
< n
; i
++) {
4989 if (!poolAppendChar(pool
, buf
[i
]))
4990 return XML_ERROR_NO_MEMORY
;
4994 case XML_TOK_DATA_CHARS
:
4995 if (!poolAppend(pool
, enc
, ptr
, next
))
4996 return XML_ERROR_NO_MEMORY
;
4998 case XML_TOK_TRAILING_CR
:
4999 next
= ptr
+ enc
->minBytesPerChar
;
5001 case XML_TOK_ATTRIBUTE_VALUE_S
:
5002 case XML_TOK_DATA_NEWLINE
:
5003 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
5005 if (!poolAppendChar(pool
, 0x20))
5006 return XML_ERROR_NO_MEMORY
;
5008 case XML_TOK_ENTITY_REF
:
5010 const XML_Char
*name
;
5012 char checkEntityDecl
;
5013 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
5014 ptr
+ enc
->minBytesPerChar
,
5015 next
- enc
->minBytesPerChar
);
5017 if (!poolAppendChar(pool
, ch
))
5018 return XML_ERROR_NO_MEMORY
;
5021 name
= poolStoreString(&temp2Pool
, enc
,
5022 ptr
+ enc
->minBytesPerChar
,
5023 next
- enc
->minBytesPerChar
);
5025 return XML_ERROR_NO_MEMORY
;
5026 entity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
, 0);
5027 poolDiscard(&temp2Pool
);
5028 /* First, determine if a check for an existing declaration is needed;
5029 if yes, check that the entity exists, and that it is internal.
5031 if (pool
== &dtd
->pool
) /* are we called from prolog? */
5034 prologState
.documentEntity
&&
5035 #endif /* XML_DTD */
5037 ? !openInternalEntities
5038 : !dtd
->hasParamEntityRefs
);
5039 else /* if (pool == &tempPool): we are called from content */
5040 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
5041 if (checkEntityDecl
) {
5043 return XML_ERROR_UNDEFINED_ENTITY
;
5044 else if (!entity
->is_internal
)
5045 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
5048 /* Cannot report skipped entity here - see comments on
5049 skippedEntityHandler.
5050 if (skippedEntityHandler)
5051 skippedEntityHandler(handlerArg, name, 0);
5053 /* Cannot call the default handler because this would be
5054 out of sync with the call to the startElementHandler.
5055 if ((pool == &tempPool) && defaultHandler)
5056 reportDefault(parser, enc, ptr, next);
5061 if (enc
== encoding
)
5063 return XML_ERROR_RECURSIVE_ENTITY_REF
;
5065 if (entity
->notation
) {
5066 if (enc
== encoding
)
5068 return XML_ERROR_BINARY_ENTITY_REF
;
5070 if (!entity
->textPtr
) {
5071 if (enc
== encoding
)
5073 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
5076 enum XML_Error result
;
5077 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
5078 entity
->open
= XML_TRUE
;
5079 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
5080 (char *)entity
->textPtr
,
5081 (char *)textEnd
, pool
);
5082 entity
->open
= XML_FALSE
;
5089 if (enc
== encoding
)
5091 return XML_ERROR_UNEXPECTED_STATE
;
5098 static enum XML_Error
5099 storeEntityValue(XML_Parser parser
,
5100 const ENCODING
*enc
,
5101 const char *entityTextPtr
,
5102 const char *entityTextEnd
)
5104 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5105 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
5106 enum XML_Error result
= XML_ERROR_NONE
;
5108 int oldInEntityValue
= prologState
.inEntityValue
;
5109 prologState
.inEntityValue
= 1;
5110 #endif /* XML_DTD */
5111 /* never return Null for the value argument in EntityDeclHandler,
5112 since this would indicate an external entity; therefore we
5113 have to make sure that entityValuePool.start is not null */
5114 if (!pool
->blocks
) {
5115 if (!poolGrow(pool
))
5116 return XML_ERROR_NO_MEMORY
;
5121 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
5123 case XML_TOK_PARAM_ENTITY_REF
:
5125 if (isParamEntity
|| enc
!= encoding
) {
5126 const XML_Char
*name
;
5128 name
= poolStoreString(&tempPool
, enc
,
5129 entityTextPtr
+ enc
->minBytesPerChar
,
5130 next
- enc
->minBytesPerChar
);
5132 result
= XML_ERROR_NO_MEMORY
;
5133 goto endEntityValue
;
5135 entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
, name
, 0);
5136 poolDiscard(&tempPool
);
5138 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5139 /* cannot report skipped entity here - see comments on
5140 skippedEntityHandler
5141 if (skippedEntityHandler)
5142 skippedEntityHandler(handlerArg, name, 0);
5144 dtd
->keepProcessing
= dtd
->standalone
;
5145 goto endEntityValue
;
5148 if (enc
== encoding
)
5149 eventPtr
= entityTextPtr
;
5150 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5151 goto endEntityValue
;
5153 if (entity
->systemId
) {
5154 if (externalEntityRefHandler
) {
5155 dtd
->paramEntityRead
= XML_FALSE
;
5156 entity
->open
= XML_TRUE
;
5157 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5161 entity
->publicId
)) {
5162 entity
->open
= XML_FALSE
;
5163 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5164 goto endEntityValue
;
5166 entity
->open
= XML_FALSE
;
5167 if (!dtd
->paramEntityRead
)
5168 dtd
->keepProcessing
= dtd
->standalone
;
5171 dtd
->keepProcessing
= dtd
->standalone
;
5174 entity
->open
= XML_TRUE
;
5175 result
= storeEntityValue(parser
,
5177 (char *)entity
->textPtr
,
5178 (char *)(entity
->textPtr
5179 + entity
->textLen
));
5180 entity
->open
= XML_FALSE
;
5182 goto endEntityValue
;
5186 #endif /* XML_DTD */
5187 /* In the internal subset, PE references are not legal
5188 within markup declarations, e.g entity values in this case. */
5189 eventPtr
= entityTextPtr
;
5190 result
= XML_ERROR_PARAM_ENTITY_REF
;
5191 goto endEntityValue
;
5193 result
= XML_ERROR_NONE
;
5194 goto endEntityValue
;
5195 case XML_TOK_ENTITY_REF
:
5196 case XML_TOK_DATA_CHARS
:
5197 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5198 result
= XML_ERROR_NO_MEMORY
;
5199 goto endEntityValue
;
5202 case XML_TOK_TRAILING_CR
:
5203 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5205 case XML_TOK_DATA_NEWLINE
:
5206 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5207 result
= XML_ERROR_NO_MEMORY
;
5208 goto endEntityValue
;
5210 *(pool
->ptr
)++ = 0xA;
5212 case XML_TOK_CHAR_REF
:
5214 XML_Char buf
[XML_ENCODE_MAX
];
5216 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5218 if (enc
== encoding
)
5219 eventPtr
= entityTextPtr
;
5220 result
= XML_ERROR_BAD_CHAR_REF
;
5221 goto endEntityValue
;
5223 n
= XmlEncode(n
, (ICHAR
*)buf
);
5225 if (enc
== encoding
)
5226 eventPtr
= entityTextPtr
;
5227 result
= XML_ERROR_BAD_CHAR_REF
;
5228 goto endEntityValue
;
5230 for (i
= 0; i
< n
; i
++) {
5231 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5232 result
= XML_ERROR_NO_MEMORY
;
5233 goto endEntityValue
;
5235 *(pool
->ptr
)++ = buf
[i
];
5239 case XML_TOK_PARTIAL
:
5240 if (enc
== encoding
)
5241 eventPtr
= entityTextPtr
;
5242 result
= XML_ERROR_INVALID_TOKEN
;
5243 goto endEntityValue
;
5244 case XML_TOK_INVALID
:
5245 if (enc
== encoding
)
5247 result
= XML_ERROR_INVALID_TOKEN
;
5248 goto endEntityValue
;
5250 if (enc
== encoding
)
5251 eventPtr
= entityTextPtr
;
5252 result
= XML_ERROR_UNEXPECTED_STATE
;
5253 goto endEntityValue
;
5255 entityTextPtr
= next
;
5259 prologState
.inEntityValue
= oldInEntityValue
;
5260 #endif /* XML_DTD */
5264 static void FASTCALL
5265 normalizeLines(XML_Char
*s
)
5269 if (*s
== XML_T('\0'))
5288 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5289 const char *start
, const char *end
)
5291 const XML_Char
*target
;
5294 if (!processingInstructionHandler
) {
5296 reportDefault(parser
, enc
, start
, end
);
5299 start
+= enc
->minBytesPerChar
* 2;
5300 tem
= start
+ XmlNameLength(enc
, start
);
5301 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5304 poolFinish(&tempPool
);
5305 data
= poolStoreString(&tempPool
, enc
,
5307 end
- enc
->minBytesPerChar
*2);
5310 normalizeLines(data
);
5311 processingInstructionHandler(handlerArg
, target
, data
);
5312 poolClear(&tempPool
);
5317 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5318 const char *start
, const char *end
)
5321 if (!commentHandler
) {
5323 reportDefault(parser
, enc
, start
, end
);
5326 data
= poolStoreString(&tempPool
,
5328 start
+ enc
->minBytesPerChar
* 4,
5329 end
- enc
->minBytesPerChar
* 3);
5332 normalizeLines(data
);
5333 commentHandler(handlerArg
, data
);
5334 poolClear(&tempPool
);
5339 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5340 const char *s
, const char *end
)
5342 if (MUST_CONVERT(enc
, s
)) {
5343 const char **eventPP
;
5344 const char **eventEndPP
;
5345 if (enc
== encoding
) {
5346 eventPP
= &eventPtr
;
5347 eventEndPP
= &eventEndPtr
;
5350 eventPP
= &(openInternalEntities
->internalEventPtr
);
5351 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5354 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5355 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5357 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5362 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5367 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5368 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5370 DEFAULT_ATTRIBUTE
*att
;
5371 if (value
|| isId
) {
5372 /* The handling of default attributes gets messed up if we have
5373 a default which duplicates a non-default. */
5375 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5376 if (attId
== type
->defaultAtts
[i
].id
)
5378 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5379 type
->idAtt
= attId
;
5381 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5382 if (type
->allocDefaultAtts
== 0) {
5383 type
->allocDefaultAtts
= 8;
5384 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5385 * sizeof(DEFAULT_ATTRIBUTE
));
5386 if (!type
->defaultAtts
)
5390 DEFAULT_ATTRIBUTE
*temp
;
5391 int count
= type
->allocDefaultAtts
* 2;
5392 temp
= (DEFAULT_ATTRIBUTE
*)
5393 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5396 type
->allocDefaultAtts
= count
;
5397 type
->defaultAtts
= temp
;
5400 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5403 att
->isCdata
= isCdata
;
5405 attId
->maybeTokenized
= XML_TRUE
;
5406 type
->nDefaultAtts
+= 1;
5411 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5413 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5414 const XML_Char
*name
;
5415 for (name
= elementType
->name
; *name
; name
++) {
5416 if (*name
== XML_T(ASCII_COLON
)) {
5419 for (s
= elementType
->name
; s
!= name
; s
++) {
5420 if (!poolAppendChar(&dtd
->pool
, *s
))
5423 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5425 prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&dtd
->pool
),
5429 if (prefix
->name
== poolStart(&dtd
->pool
))
5430 poolFinish(&dtd
->pool
);
5432 poolDiscard(&dtd
->pool
);
5433 elementType
->prefix
= prefix
;
5440 static ATTRIBUTE_ID
*
5441 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5442 const char *start
, const char *end
)
5444 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5446 const XML_Char
*name
;
5447 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5449 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5452 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5454 id
= (ATTRIBUTE_ID
*)lookup(parser
, &dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5457 if (id
->name
!= name
)
5458 poolDiscard(&dtd
->pool
);
5460 poolFinish(&dtd
->pool
);
5463 else if (name
[0] == XML_T(ASCII_x
)
5464 && name
[1] == XML_T(ASCII_m
)
5465 && name
[2] == XML_T(ASCII_l
)
5466 && name
[3] == XML_T(ASCII_n
)
5467 && name
[4] == XML_T(ASCII_s
)
5468 && (name
[5] == XML_T('\0') || name
[5] == XML_T(ASCII_COLON
))) {
5469 if (name
[5] == XML_T('\0'))
5470 id
->prefix
= &dtd
->defaultPrefix
;
5472 id
->prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5473 id
->xmlns
= XML_TRUE
;
5477 for (i
= 0; name
[i
]; i
++) {
5478 /* attributes without prefix are *not* in the default namespace */
5479 if (name
[i
] == XML_T(ASCII_COLON
)) {
5481 for (j
= 0; j
< i
; j
++) {
5482 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5485 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5487 id
->prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&dtd
->pool
),
5489 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5490 poolFinish(&dtd
->pool
);
5492 poolDiscard(&dtd
->pool
);
5501 #define CONTEXT_SEP XML_T(ASCII_FF)
5503 static const XML_Char
*
5504 getContext(XML_Parser parser
)
5506 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5507 HASH_TABLE_ITER iter
;
5508 XML_Bool needSep
= XML_FALSE
;
5510 if (dtd
->defaultPrefix
.binding
) {
5513 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5515 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5516 if (namespaceSeparator
)
5518 for (i
= 0; i
< len
; i
++)
5519 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5524 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5529 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5532 if (!prefix
->binding
)
5534 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5536 for (s
= prefix
->name
; *s
; s
++)
5537 if (!poolAppendChar(&tempPool
, *s
))
5539 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5541 len
= prefix
->binding
->uriLen
;
5542 if (namespaceSeparator
)
5544 for (i
= 0; i
< len
; i
++)
5545 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5551 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5554 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5559 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5561 for (s
= e
->name
; *s
; s
++)
5562 if (!poolAppendChar(&tempPool
, *s
))
5567 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5569 return tempPool
.start
;
5573 setContext(XML_Parser parser
, const XML_Char
*context
)
5575 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5576 const XML_Char
*s
= context
;
5578 while (*context
!= XML_T('\0')) {
5579 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5581 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5583 e
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, poolStart(&tempPool
), 0);
5586 if (*s
!= XML_T('\0'))
5589 poolDiscard(&tempPool
);
5591 else if (*s
== XML_T(ASCII_EQUALS
)) {
5593 if (poolLength(&tempPool
) == 0)
5594 prefix
= &dtd
->defaultPrefix
;
5596 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5598 prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&tempPool
),
5602 if (prefix
->name
== poolStart(&tempPool
)) {
5603 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5607 poolDiscard(&tempPool
);
5609 for (context
= s
+ 1;
5610 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5612 if (!poolAppendChar(&tempPool
, *context
))
5614 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5616 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5617 &inheritedBindings
) != XML_ERROR_NONE
)
5619 poolDiscard(&tempPool
);
5620 if (*context
!= XML_T('\0'))
5625 if (!poolAppendChar(&tempPool
, *s
))
5633 static void FASTCALL
5634 normalizePublicId(XML_Char
*publicId
)
5636 XML_Char
*p
= publicId
;
5638 for (s
= publicId
; *s
; s
++) {
5643 if (p
!= publicId
&& p
[-1] != 0x20)
5650 if (p
!= publicId
&& p
[-1] == 0x20)
5656 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5658 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5661 poolInit(&(p
->pool
), ms
);
5662 poolInit(&(p
->entityValuePool
), ms
);
5663 hashTableInit(&(p
->generalEntities
), ms
);
5664 hashTableInit(&(p
->elementTypes
), ms
);
5665 hashTableInit(&(p
->attributeIds
), ms
);
5666 hashTableInit(&(p
->prefixes
), ms
);
5668 p
->paramEntityRead
= XML_FALSE
;
5669 hashTableInit(&(p
->paramEntities
), ms
);
5670 #endif /* XML_DTD */
5671 p
->defaultPrefix
.name
= NULL
;
5672 p
->defaultPrefix
.binding
= NULL
;
5674 p
->in_eldecl
= XML_FALSE
;
5675 p
->scaffIndex
= NULL
;
5680 p
->contentStringLen
= 0;
5682 p
->keepProcessing
= XML_TRUE
;
5683 p
->hasParamEntityRefs
= XML_FALSE
;
5684 p
->standalone
= XML_FALSE
;
5689 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5691 HASH_TABLE_ITER iter
;
5692 hashTableIterInit(&iter
, &(p
->elementTypes
));
5694 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5697 if (e
->allocDefaultAtts
!= 0)
5698 ms
->free_fcn(e
->defaultAtts
);
5700 hashTableClear(&(p
->generalEntities
));
5702 p
->paramEntityRead
= XML_FALSE
;
5703 hashTableClear(&(p
->paramEntities
));
5704 #endif /* XML_DTD */
5705 hashTableClear(&(p
->elementTypes
));
5706 hashTableClear(&(p
->attributeIds
));
5707 hashTableClear(&(p
->prefixes
));
5708 poolClear(&(p
->pool
));
5709 poolClear(&(p
->entityValuePool
));
5710 p
->defaultPrefix
.name
= NULL
;
5711 p
->defaultPrefix
.binding
= NULL
;
5713 p
->in_eldecl
= XML_FALSE
;
5715 ms
->free_fcn(p
->scaffIndex
);
5716 p
->scaffIndex
= NULL
;
5717 ms
->free_fcn(p
->scaffold
);
5723 p
->contentStringLen
= 0;
5725 p
->keepProcessing
= XML_TRUE
;
5726 p
->hasParamEntityRefs
= XML_FALSE
;
5727 p
->standalone
= XML_FALSE
;
5731 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5733 HASH_TABLE_ITER iter
;
5734 hashTableIterInit(&iter
, &(p
->elementTypes
));
5736 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5739 if (e
->allocDefaultAtts
!= 0)
5740 ms
->free_fcn(e
->defaultAtts
);
5742 hashTableDestroy(&(p
->generalEntities
));
5744 hashTableDestroy(&(p
->paramEntities
));
5745 #endif /* XML_DTD */
5746 hashTableDestroy(&(p
->elementTypes
));
5747 hashTableDestroy(&(p
->attributeIds
));
5748 hashTableDestroy(&(p
->prefixes
));
5749 poolDestroy(&(p
->pool
));
5750 poolDestroy(&(p
->entityValuePool
));
5752 ms
->free_fcn(p
->scaffIndex
);
5753 ms
->free_fcn(p
->scaffold
);
5758 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5759 The new DTD has already been initialized.
5762 dtdCopy(XML_Parser oldParser
, DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5764 HASH_TABLE_ITER iter
;
5766 /* Copy the prefix table. */
5768 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5770 const XML_Char
*name
;
5771 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5774 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5777 if (!lookup(oldParser
, &(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5781 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5783 /* Copy the attribute id table. */
5787 const XML_Char
*name
;
5788 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5792 /* Remember to allocate the scratch byte before the name. */
5793 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5795 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5799 newA
= (ATTRIBUTE_ID
*)lookup(oldParser
, &(newDtd
->attributeIds
), name
,
5800 sizeof(ATTRIBUTE_ID
));
5803 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5805 newA
->xmlns
= oldA
->xmlns
;
5806 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5807 newA
->prefix
= &newDtd
->defaultPrefix
;
5809 newA
->prefix
= (PREFIX
*)lookup(oldParser
, &(newDtd
->prefixes
),
5810 oldA
->prefix
->name
, 0);
5814 /* Copy the element type table. */
5816 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5821 const XML_Char
*name
;
5822 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5825 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5828 newE
= (ELEMENT_TYPE
*)lookup(oldParser
, &(newDtd
->elementTypes
), name
,
5829 sizeof(ELEMENT_TYPE
));
5832 if (oldE
->nDefaultAtts
) {
5833 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5834 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5835 if (!newE
->defaultAtts
) {
5841 newE
->idAtt
= (ATTRIBUTE_ID
*)
5842 lookup(oldParser
, &(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5843 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5845 newE
->prefix
= (PREFIX
*)lookup(oldParser
, &(newDtd
->prefixes
),
5846 oldE
->prefix
->name
, 0);
5847 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5848 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5849 lookup(oldParser
, &(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5850 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5851 if (oldE
->defaultAtts
[i
].value
) {
5852 newE
->defaultAtts
[i
].value
5853 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5854 if (!newE
->defaultAtts
[i
].value
)
5858 newE
->defaultAtts
[i
].value
= NULL
;
5862 /* Copy the entity tables. */
5863 if (!copyEntityTable(oldParser
,
5864 &(newDtd
->generalEntities
),
5866 &(oldDtd
->generalEntities
)))
5870 if (!copyEntityTable(oldParser
,
5871 &(newDtd
->paramEntities
),
5873 &(oldDtd
->paramEntities
)))
5875 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5876 #endif /* XML_DTD */
5878 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5879 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5880 newDtd
->standalone
= oldDtd
->standalone
;
5882 /* Don't want deep copying for scaffolding */
5883 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5884 newDtd
->scaffold
= oldDtd
->scaffold
;
5885 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5886 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5887 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5888 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5894 copyEntityTable(XML_Parser oldParser
,
5895 HASH_TABLE
*newTable
,
5896 STRING_POOL
*newPool
,
5897 const HASH_TABLE
*oldTable
)
5899 HASH_TABLE_ITER iter
;
5900 const XML_Char
*cachedOldBase
= NULL
;
5901 const XML_Char
*cachedNewBase
= NULL
;
5903 hashTableIterInit(&iter
, oldTable
);
5907 const XML_Char
*name
;
5908 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5911 name
= poolCopyString(newPool
, oldE
->name
);
5914 newE
= (ENTITY
*)lookup(oldParser
, newTable
, name
, sizeof(ENTITY
));
5917 if (oldE
->systemId
) {
5918 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5921 newE
->systemId
= tem
;
5923 if (oldE
->base
== cachedOldBase
)
5924 newE
->base
= cachedNewBase
;
5926 cachedOldBase
= oldE
->base
;
5927 tem
= poolCopyString(newPool
, cachedOldBase
);
5930 cachedNewBase
= newE
->base
= tem
;
5933 if (oldE
->publicId
) {
5934 tem
= poolCopyString(newPool
, oldE
->publicId
);
5937 newE
->publicId
= tem
;
5941 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5945 newE
->textPtr
= tem
;
5946 newE
->textLen
= oldE
->textLen
;
5948 if (oldE
->notation
) {
5949 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5952 newE
->notation
= tem
;
5954 newE
->is_param
= oldE
->is_param
;
5955 newE
->is_internal
= oldE
->is_internal
;
5960 #define INIT_POWER 6
5962 static XML_Bool FASTCALL
5963 keyeq(KEY s1
, KEY s2
)
5965 for (; *s1
== *s2
; s1
++, s2
++)
5971 static unsigned long FASTCALL
5972 hash(XML_Parser parser
, KEY s
)
5974 unsigned long h
= hash_secret_salt
;
5976 h
= CHAR_HASH(h
, *s
++);
5981 lookup(XML_Parser parser
, HASH_TABLE
*table
, KEY name
, size_t createSize
)
5984 if (table
->size
== 0) {
5988 table
->power
= INIT_POWER
;
5989 /* table->size is a power of 2 */
5990 table
->size
= (size_t)1 << INIT_POWER
;
5991 tsize
= table
->size
* sizeof(NAMED
*);
5992 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5997 memset(table
->v
, 0, tsize
);
5998 i
= hash(parser
, name
) & ((unsigned long)table
->size
- 1);
6001 unsigned long h
= hash(parser
, name
);
6002 unsigned long mask
= (unsigned long)table
->size
- 1;
6003 unsigned char step
= 0;
6005 while (table
->v
[i
]) {
6006 if (keyeq(name
, table
->v
[i
]->name
))
6009 step
= PROBE_STEP(h
, mask
, table
->power
);
6010 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
6015 /* check for overflow (table is half full) */
6016 if (table
->used
>> (table
->power
- 1)) {
6017 unsigned char newPower
= table
->power
+ 1;
6018 size_t newSize
= (size_t)1 << newPower
;
6019 unsigned long newMask
= (unsigned long)newSize
- 1;
6020 size_t tsize
= newSize
* sizeof(NAMED
*);
6021 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
6024 memset(newV
, 0, tsize
);
6025 for (i
= 0; i
< table
->size
; i
++)
6027 unsigned long newHash
= hash(parser
, table
->v
[i
]->name
);
6028 size_t j
= newHash
& newMask
;
6032 step
= PROBE_STEP(newHash
, newMask
, newPower
);
6033 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
6035 newV
[j
] = table
->v
[i
];
6037 table
->mem
->free_fcn(table
->v
);
6039 table
->power
= newPower
;
6040 table
->size
= newSize
;
6043 while (table
->v
[i
]) {
6045 step
= PROBE_STEP(h
, newMask
, newPower
);
6046 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
6050 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
6053 memset(table
->v
[i
], 0, createSize
);
6054 table
->v
[i
]->name
= name
;
6059 static void FASTCALL
6060 hashTableClear(HASH_TABLE
*table
)
6063 for (i
= 0; i
< table
->size
; i
++) {
6064 table
->mem
->free_fcn(table
->v
[i
]);
6070 static void FASTCALL
6071 hashTableDestroy(HASH_TABLE
*table
)
6074 for (i
= 0; i
< table
->size
; i
++)
6075 table
->mem
->free_fcn(table
->v
[i
]);
6076 table
->mem
->free_fcn(table
->v
);
6079 static void FASTCALL
6080 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
6089 static void FASTCALL
6090 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
6093 iter
->end
= iter
->p
+ table
->size
;
6096 static NAMED
* FASTCALL
6097 hashTableIterNext(HASH_TABLE_ITER
*iter
)
6099 while (iter
->p
!= iter
->end
) {
6100 NAMED
*tem
= *(iter
->p
)++;
6107 static void FASTCALL
6108 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
6110 pool
->blocks
= NULL
;
6111 pool
->freeBlocks
= NULL
;
6118 static void FASTCALL
6119 poolClear(STRING_POOL
*pool
)
6121 if (!pool
->freeBlocks
)
6122 pool
->freeBlocks
= pool
->blocks
;
6124 BLOCK
*p
= pool
->blocks
;
6126 BLOCK
*tem
= p
->next
;
6127 p
->next
= pool
->freeBlocks
;
6128 pool
->freeBlocks
= p
;
6132 pool
->blocks
= NULL
;
6138 static void FASTCALL
6139 poolDestroy(STRING_POOL
*pool
)
6141 BLOCK
*p
= pool
->blocks
;
6143 BLOCK
*tem
= p
->next
;
6144 pool
->mem
->free_fcn(p
);
6147 p
= pool
->freeBlocks
;
6149 BLOCK
*tem
= p
->next
;
6150 pool
->mem
->free_fcn(p
);
6156 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6157 const char *ptr
, const char *end
)
6159 if (!pool
->ptr
&& !poolGrow(pool
))
6162 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6165 if (!poolGrow(pool
))
6171 static const XML_Char
* FASTCALL
6172 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6175 if (!poolAppendChar(pool
, *s
))
6183 static const XML_Char
*
6184 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6186 if (!pool
->ptr
&& !poolGrow(pool
))
6188 for (; n
> 0; --n
, s
++) {
6189 if (!poolAppendChar(pool
, *s
))
6197 static const XML_Char
* FASTCALL
6198 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6201 if (!poolAppendChar(pool
, *s
))
6209 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6210 const char *ptr
, const char *end
)
6212 if (!poolAppend(pool
, enc
, ptr
, end
))
6214 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6220 static XML_Bool FASTCALL
6221 poolGrow(STRING_POOL
*pool
)
6223 if (pool
->freeBlocks
) {
6224 if (pool
->start
== 0) {
6225 pool
->blocks
= pool
->freeBlocks
;
6226 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6227 pool
->blocks
->next
= NULL
;
6228 pool
->start
= pool
->blocks
->s
;
6229 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6230 pool
->ptr
= pool
->start
;
6233 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6234 BLOCK
*tem
= pool
->freeBlocks
->next
;
6235 pool
->freeBlocks
->next
= pool
->blocks
;
6236 pool
->blocks
= pool
->freeBlocks
;
6237 pool
->freeBlocks
= tem
;
6238 memcpy(pool
->blocks
->s
, pool
->start
,
6239 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6240 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6241 pool
->start
= pool
->blocks
->s
;
6242 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6246 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6247 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6248 BLOCK
*temp
= (BLOCK
*)
6249 pool
->mem
->realloc_fcn(pool
->blocks
,
6251 + blockSize
* sizeof(XML_Char
)));
6254 pool
->blocks
= temp
;
6255 pool
->blocks
->size
= blockSize
;
6256 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6257 pool
->start
= pool
->blocks
->s
;
6258 pool
->end
= pool
->start
+ blockSize
;
6262 int blockSize
= (int)(pool
->end
- pool
->start
);
6263 if (blockSize
< INIT_BLOCK_SIZE
)
6264 blockSize
= INIT_BLOCK_SIZE
;
6267 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6268 + blockSize
* sizeof(XML_Char
));
6271 tem
->size
= blockSize
;
6272 tem
->next
= pool
->blocks
;
6274 if (pool
->ptr
!= pool
->start
)
6275 memcpy(tem
->s
, pool
->start
,
6276 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6277 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6278 pool
->start
= tem
->s
;
6279 pool
->end
= tem
->s
+ blockSize
;
6285 nextScaffoldPart(XML_Parser parser
)
6287 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6288 CONTENT_SCAFFOLD
* me
;
6291 if (!dtd
->scaffIndex
) {
6292 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6293 if (!dtd
->scaffIndex
)
6295 dtd
->scaffIndex
[0] = 0;
6298 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6299 CONTENT_SCAFFOLD
*temp
;
6300 if (dtd
->scaffold
) {
6301 temp
= (CONTENT_SCAFFOLD
*)
6302 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6305 dtd
->scaffSize
*= 2;
6308 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6309 * sizeof(CONTENT_SCAFFOLD
));
6312 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6314 dtd
->scaffold
= temp
;
6316 next
= dtd
->scaffCount
++;
6317 me
= &dtd
->scaffold
[next
];
6318 if (dtd
->scaffLevel
) {
6319 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6320 if (parent
->lastchild
) {
6321 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6323 if (!parent
->childcnt
)
6324 parent
->firstchild
= next
;
6325 parent
->lastchild
= next
;
6328 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6333 build_node(XML_Parser parser
,
6336 XML_Content
**contpos
,
6339 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6340 dest
->type
= dtd
->scaffold
[src_node
].type
;
6341 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6342 if (dest
->type
== XML_CTYPE_NAME
) {
6343 const XML_Char
*src
;
6344 dest
->name
= *strpos
;
6345 src
= dtd
->scaffold
[src_node
].name
;
6347 *(*strpos
)++ = *src
;
6352 dest
->numchildren
= 0;
6353 dest
->children
= NULL
;
6358 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6359 dest
->children
= *contpos
;
6360 *contpos
+= dest
->numchildren
;
6361 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6362 i
< dest
->numchildren
;
6363 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6364 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6370 static XML_Content
*
6371 build_model (XML_Parser parser
)
6373 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6377 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6378 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6380 ret
= (XML_Content
*)MALLOC(allocsize
);
6384 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6387 build_node(parser
, 0, ret
, &cpos
, &str
);
6391 static ELEMENT_TYPE
*
6392 getElementType(XML_Parser parser
,
6393 const ENCODING
*enc
,
6397 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6398 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6403 ret
= (ELEMENT_TYPE
*) lookup(parser
, &dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6406 if (ret
->name
!= name
)
6407 poolDiscard(&dtd
->pool
);
6409 poolFinish(&dtd
->pool
);
6410 if (!setElementTypePrefix(parser
, ret
))