1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
6 #include <string.h> /* memset(), memcpy() */
8 #include <limits.h> /* UINT_MAX */
9 #include <time.h> /* time() */
11 #define XML_BUILDING_EXPAT 1
13 #ifdef COMPILED_FROM_DSP
14 #include "winconfig.h"
15 #elif defined(MACOS_CLASSIC)
16 #include "macconfig.h"
17 #elif defined(__amigaos__)
18 #include "amigaconfig.h"
19 #elif defined(__AROS__)
20 #include "arosconfig.h"
22 #define assert(x) ASSERT(x)
23 #elif defined(__WATCOMC__)
24 #include "watcomconfig.h"
25 #elif defined(HAVE_EXPAT_CONFIG_H)
26 #include <expat_config.h>
27 #endif /* ndef COMPILED_FROM_DSP */
33 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
34 #define XmlConvert XmlUtf16Convert
35 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
36 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
37 #define XmlEncode XmlUtf16Encode
38 /* Using pointer subtraction to convert to integer type. */
39 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
40 typedef unsigned short ICHAR
;
42 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
43 #define XmlConvert XmlUtf8Convert
44 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
45 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
46 #define XmlEncode XmlUtf8Encode
47 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
54 #define XmlInitEncodingNS XmlInitEncoding
55 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
56 #undef XmlGetInternalEncodingNS
57 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
58 #define XmlParseXmlDeclNS XmlParseXmlDecl
64 #ifdef XML_UNICODE_WCHAR_T
65 #define XML_T(x) (const wchar_t)x
66 #define XML_L(x) L ## x
68 #define XML_T(x) (const unsigned short)x
79 /* Round up n to be a multiple of sz, where sz is a power of 2. */
80 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
82 /* Handle the case where memmove() doesn't exist. */
85 #define memmove(d,s,l) bcopy((s),(d),(l))
87 #error memmove does not exist on this platform, nor is a substitute available
88 #endif /* HAVE_BCOPY */
89 #endif /* HAVE_MEMMOVE */
95 typedef const XML_Char
*KEY
;
106 const XML_Memory_Handling_Suite
*mem
;
109 /* Basic character hash algorithm, taken from Python's string hash:
110 h = h * 1000003 ^ character, the constant being a prime number.
114 #define CHAR_HASH(h, c) \
115 (((h) * 0xF4243) ^ (unsigned short)(c))
117 #define CHAR_HASH(h, c) \
118 (((h) * 0xF4243) ^ (unsigned char)(c))
121 /* For probing (after a collision) we need a step size relative prime
122 to the hash table size, which is a power of 2. We use double-hashing,
123 since we can calculate a second hash value cheaply by taking those bits
124 of the first hash value that were discarded (masked out) when the table
125 index was calculated: index = hash & mask, where mask = table->size - 1.
126 We limit the maximum step size to table->size / 4 (mask >> 2) and make
127 it odd, since odd numbers are always relative prime to a power of 2.
129 #define SECOND_HASH(hash, mask, power) \
130 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
131 #define PROBE_STEP(hash, mask, power) \
132 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
139 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
140 #define INIT_DATA_BUF_SIZE 1024
141 #define INIT_ATTS_SIZE 16
142 #define INIT_ATTS_VERSION 0xFFFFFFFF
143 #define INIT_BLOCK_SIZE 1024
144 #define INIT_BUFFER_SIZE 1024
146 #define EXPAND_SPARE 24
148 typedef struct binding
{
149 struct prefix
*prefix
;
150 struct binding
*nextTagBinding
;
151 struct binding
*prevPrefixBinding
;
152 const struct attribute_id
*attId
;
158 typedef struct prefix
{
159 const XML_Char
*name
;
165 const XML_Char
*localPart
;
166 const XML_Char
*prefix
;
172 /* TAG represents an open element.
173 The name of the element is stored in both the document and API
174 encodings. The memory buffer 'buf' is a separately-allocated
175 memory area which stores the name. During the XML_Parse()/
176 XMLParseBuffer() when the element is open, the memory for the 'raw'
177 version of the name (in the document encoding) is shared with the
178 document buffer. If the element is open across calls to
179 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
180 contain the 'raw' name as well.
182 A parser re-uses these structures, maintaining a list of allocated
183 TAG objects in a free list.
186 struct tag
*parent
; /* parent of this element */
187 const char *rawName
; /* tagName in the original encoding */
189 TAG_NAME name
; /* tagName in the API encoding */
190 char *buf
; /* buffer for name components */
191 char *bufEnd
; /* end of the buffer */
196 const XML_Char
*name
;
197 const XML_Char
*textPtr
;
198 int textLen
; /* length in XML_Chars */
199 int processed
; /* # of processed bytes - when suspended */
200 const XML_Char
*systemId
;
201 const XML_Char
*base
;
202 const XML_Char
*publicId
;
203 const XML_Char
*notation
;
206 XML_Bool is_internal
; /* true if declared in internal subset outside PE */
210 enum XML_Content_Type type
;
211 enum XML_Content_Quant quant
;
212 const XML_Char
* name
;
219 #define INIT_SCAFFOLD_ELEMENTS 32
221 typedef struct block
{
233 const XML_Memory_Handling_Suite
*mem
;
236 /* The XML_Char before the name is used to determine whether
237 an attribute has been specified. */
238 typedef struct attribute_id
{
241 XML_Bool maybeTokenized
;
246 const ATTRIBUTE_ID
*id
;
248 const XML_Char
*value
;
252 unsigned long version
;
254 const XML_Char
*uriName
;
258 const XML_Char
*name
;
260 const ATTRIBUTE_ID
*idAtt
;
262 int allocDefaultAtts
;
263 DEFAULT_ATTRIBUTE
*defaultAtts
;
267 HASH_TABLE generalEntities
;
268 HASH_TABLE elementTypes
;
269 HASH_TABLE attributeIds
;
272 STRING_POOL entityValuePool
;
273 /* false once a parameter entity reference has been skipped */
274 XML_Bool keepProcessing
;
275 /* true once an internal or external PE reference has been encountered;
276 this includes the reference to an external subset */
277 XML_Bool hasParamEntityRefs
;
280 /* indicates if external PE has been read */
281 XML_Bool paramEntityRead
;
282 HASH_TABLE paramEntities
;
284 PREFIX defaultPrefix
;
285 /* === scaffolding for building content model === */
287 CONTENT_SCAFFOLD
*scaffold
;
288 unsigned contentStringLen
;
295 typedef struct open_internal_entity
{
296 const char *internalEventPtr
;
297 const char *internalEventEndPtr
;
298 struct open_internal_entity
*next
;
301 XML_Bool betweenDecl
; /* WFC: PE Between Declarations */
302 } OPEN_INTERNAL_ENTITY
;
304 typedef enum XML_Error PTRCALL
Processor(XML_Parser parser
,
307 const char **endPtr
);
309 static Processor prologProcessor
;
310 static Processor prologInitProcessor
;
311 static Processor contentProcessor
;
312 static Processor cdataSectionProcessor
;
314 static Processor ignoreSectionProcessor
;
315 static Processor externalParEntProcessor
;
316 static Processor externalParEntInitProcessor
;
317 static Processor entityValueProcessor
;
318 static Processor entityValueInitProcessor
;
320 static Processor epilogProcessor
;
321 static Processor errorProcessor
;
322 static Processor externalEntityInitProcessor
;
323 static Processor externalEntityInitProcessor2
;
324 static Processor externalEntityInitProcessor3
;
325 static Processor externalEntityContentProcessor
;
326 static Processor internalEntityProcessor
;
328 static enum XML_Error
329 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
);
330 static enum XML_Error
331 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
332 const char *s
, const char *next
);
333 static enum XML_Error
334 initializeEncoding(XML_Parser parser
);
335 static enum XML_Error
336 doProlog(XML_Parser parser
, const ENCODING
*enc
, const char *s
,
337 const char *end
, int tok
, const char *next
, const char **nextPtr
,
339 static enum XML_Error
340 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
341 XML_Bool betweenDecl
);
342 static enum XML_Error
343 doContent(XML_Parser parser
, int startTagLevel
, const ENCODING
*enc
,
344 const char *start
, const char *end
, const char **endPtr
,
346 static enum XML_Error
347 doCdataSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
348 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
350 static enum XML_Error
351 doIgnoreSection(XML_Parser parser
, const ENCODING
*, const char **startPtr
,
352 const char *end
, const char **nextPtr
, XML_Bool haveMore
);
355 static enum XML_Error
356 storeAtts(XML_Parser parser
, const ENCODING
*, const char *s
,
357 TAG_NAME
*tagNamePtr
, BINDING
**bindingsPtr
);
358 static enum XML_Error
359 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
360 const XML_Char
*uri
, BINDING
**bindingsPtr
);
362 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*, XML_Bool isCdata
,
363 XML_Bool isId
, const XML_Char
*dfltValue
, XML_Parser parser
);
364 static enum XML_Error
365 storeAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
366 const char *, const char *, STRING_POOL
*);
367 static enum XML_Error
368 appendAttributeValue(XML_Parser parser
, const ENCODING
*, XML_Bool isCdata
,
369 const char *, const char *, STRING_POOL
*);
370 static ATTRIBUTE_ID
*
371 getAttributeId(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
374 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*);
375 static enum XML_Error
376 storeEntityValue(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
379 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
380 const char *start
, const char *end
);
382 reportComment(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
385 reportDefault(XML_Parser parser
, const ENCODING
*enc
, const char *start
,
388 static const XML_Char
* getContext(XML_Parser parser
);
390 setContext(XML_Parser parser
, const XML_Char
*context
);
392 static void FASTCALL
normalizePublicId(XML_Char
*s
);
394 static DTD
* dtdCreate(const XML_Memory_Handling_Suite
*ms
);
395 /* do not call if parentParser != NULL */
396 static void dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
);
398 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
);
400 dtdCopy(XML_Parser oldParser
,
401 DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
);
403 copyEntityTable(XML_Parser oldParser
,
404 HASH_TABLE
*, STRING_POOL
*, const HASH_TABLE
*);
406 lookup(XML_Parser parser
, HASH_TABLE
*table
, KEY name
, size_t createSize
);
408 hashTableInit(HASH_TABLE
*, const XML_Memory_Handling_Suite
*ms
);
409 static void FASTCALL
hashTableClear(HASH_TABLE
*);
410 static void FASTCALL
hashTableDestroy(HASH_TABLE
*);
412 hashTableIterInit(HASH_TABLE_ITER
*, const HASH_TABLE
*);
413 static NAMED
* FASTCALL
hashTableIterNext(HASH_TABLE_ITER
*);
416 poolInit(STRING_POOL
*, const XML_Memory_Handling_Suite
*ms
);
417 static void FASTCALL
poolClear(STRING_POOL
*);
418 static void FASTCALL
poolDestroy(STRING_POOL
*);
420 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
421 const char *ptr
, const char *end
);
423 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
424 const char *ptr
, const char *end
);
425 static XML_Bool FASTCALL
poolGrow(STRING_POOL
*pool
);
426 static const XML_Char
* FASTCALL
427 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
);
428 static const XML_Char
*
429 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
);
430 static const XML_Char
* FASTCALL
431 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
);
433 static int FASTCALL
nextScaffoldPart(XML_Parser parser
);
434 static XML_Content
* build_model(XML_Parser parser
);
435 static ELEMENT_TYPE
*
436 getElementType(XML_Parser parser
, const ENCODING
*enc
,
437 const char *ptr
, const char *end
);
439 static unsigned long generate_hash_secret_salt(void);
440 static XML_Bool
startParsing(XML_Parser parser
);
443 parserCreate(const XML_Char
*encodingName
,
444 const XML_Memory_Handling_Suite
*memsuite
,
445 const XML_Char
*nameSep
,
449 parserInit(XML_Parser parser
, const XML_Char
*encodingName
);
451 #define poolStart(pool) ((pool)->start)
452 #define poolEnd(pool) ((pool)->ptr)
453 #define poolLength(pool) ((pool)->ptr - (pool)->start)
454 #define poolChop(pool) ((void)--(pool->ptr))
455 #define poolLastChar(pool) (((pool)->ptr)[-1])
456 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
457 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
458 #define poolAppendChar(pool, c) \
459 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
461 : ((*((pool)->ptr)++ = c), 1))
463 struct XML_ParserStruct
{
464 /* The first member must be userData so that the XML_GetUserData
469 const XML_Memory_Handling_Suite m_mem
;
470 /* first character to be parsed */
471 const char *m_bufferPtr
;
472 /* past last character to be parsed */
474 /* allocated end of buffer */
475 const char *m_bufferLim
;
476 XML_Index m_parseEndByteIndex
;
477 const char *m_parseEndPtr
;
479 XML_Char
*m_dataBufEnd
;
480 XML_StartElementHandler m_startElementHandler
;
481 XML_EndElementHandler m_endElementHandler
;
482 XML_CharacterDataHandler m_characterDataHandler
;
483 XML_ProcessingInstructionHandler m_processingInstructionHandler
;
484 XML_CommentHandler m_commentHandler
;
485 XML_StartCdataSectionHandler m_startCdataSectionHandler
;
486 XML_EndCdataSectionHandler m_endCdataSectionHandler
;
487 XML_DefaultHandler m_defaultHandler
;
488 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler
;
489 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler
;
490 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler
;
491 XML_NotationDeclHandler m_notationDeclHandler
;
492 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler
;
493 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler
;
494 XML_NotStandaloneHandler m_notStandaloneHandler
;
495 XML_ExternalEntityRefHandler m_externalEntityRefHandler
;
496 XML_Parser m_externalEntityRefHandlerArg
;
497 XML_SkippedEntityHandler m_skippedEntityHandler
;
498 XML_UnknownEncodingHandler m_unknownEncodingHandler
;
499 XML_ElementDeclHandler m_elementDeclHandler
;
500 XML_AttlistDeclHandler m_attlistDeclHandler
;
501 XML_EntityDeclHandler m_entityDeclHandler
;
502 XML_XmlDeclHandler m_xmlDeclHandler
;
503 const ENCODING
*m_encoding
;
504 INIT_ENCODING m_initEncoding
;
505 const ENCODING
*m_internalEncoding
;
506 const XML_Char
*m_protocolEncodingName
;
508 XML_Bool m_ns_triplets
;
509 void *m_unknownEncodingMem
;
510 void *m_unknownEncodingData
;
511 void *m_unknownEncodingHandlerData
;
512 void (XMLCALL
*m_unknownEncodingRelease
)(void *);
513 PROLOG_STATE m_prologState
;
514 Processor
*m_processor
;
515 enum XML_Error m_errorCode
;
516 const char *m_eventPtr
;
517 const char *m_eventEndPtr
;
518 const char *m_positionPtr
;
519 OPEN_INTERNAL_ENTITY
*m_openInternalEntities
;
520 OPEN_INTERNAL_ENTITY
*m_freeInternalEntities
;
521 XML_Bool m_defaultExpandInternalEntities
;
523 ENTITY
*m_declEntity
;
524 const XML_Char
*m_doctypeName
;
525 const XML_Char
*m_doctypeSysid
;
526 const XML_Char
*m_doctypePubid
;
527 const XML_Char
*m_declAttributeType
;
528 const XML_Char
*m_declNotationName
;
529 const XML_Char
*m_declNotationPublicId
;
530 ELEMENT_TYPE
*m_declElementType
;
531 ATTRIBUTE_ID
*m_declAttributeId
;
532 XML_Bool m_declAttributeIsCdata
;
533 XML_Bool m_declAttributeIsId
;
535 const XML_Char
*m_curBase
;
538 BINDING
*m_inheritedBindings
;
539 BINDING
*m_freeBindingList
;
541 int m_nSpecifiedAtts
;
545 unsigned long m_nsAttsVersion
;
546 unsigned char m_nsAttsPower
;
548 XML_AttrInfo
*m_attInfo
;
551 STRING_POOL m_tempPool
;
552 STRING_POOL m_temp2Pool
;
553 char *m_groupConnector
;
554 unsigned int m_groupSize
;
555 XML_Char m_namespaceSeparator
;
556 XML_Parser m_parentParser
;
557 XML_ParsingStatus m_parsingStatus
;
559 XML_Bool m_isParamEntity
;
560 XML_Bool m_useForeignDTD
;
561 enum XML_ParamEntityParsing m_paramEntityParsing
;
563 unsigned long m_hash_secret_salt
;
566 #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
567 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
568 #define FREE(p) (parser->m_mem.free_fcn((p)))
570 #define userData (parser->m_userData)
571 #define handlerArg (parser->m_handlerArg)
572 #define startElementHandler (parser->m_startElementHandler)
573 #define endElementHandler (parser->m_endElementHandler)
574 #define characterDataHandler (parser->m_characterDataHandler)
575 #define processingInstructionHandler \
576 (parser->m_processingInstructionHandler)
577 #define commentHandler (parser->m_commentHandler)
578 #define startCdataSectionHandler \
579 (parser->m_startCdataSectionHandler)
580 #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
581 #define defaultHandler (parser->m_defaultHandler)
582 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
583 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
584 #define unparsedEntityDeclHandler \
585 (parser->m_unparsedEntityDeclHandler)
586 #define notationDeclHandler (parser->m_notationDeclHandler)
587 #define startNamespaceDeclHandler \
588 (parser->m_startNamespaceDeclHandler)
589 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
590 #define notStandaloneHandler (parser->m_notStandaloneHandler)
591 #define externalEntityRefHandler \
592 (parser->m_externalEntityRefHandler)
593 #define externalEntityRefHandlerArg \
594 (parser->m_externalEntityRefHandlerArg)
595 #define internalEntityRefHandler \
596 (parser->m_internalEntityRefHandler)
597 #define skippedEntityHandler (parser->m_skippedEntityHandler)
598 #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
599 #define elementDeclHandler (parser->m_elementDeclHandler)
600 #define attlistDeclHandler (parser->m_attlistDeclHandler)
601 #define entityDeclHandler (parser->m_entityDeclHandler)
602 #define xmlDeclHandler (parser->m_xmlDeclHandler)
603 #define encoding (parser->m_encoding)
604 #define initEncoding (parser->m_initEncoding)
605 #define internalEncoding (parser->m_internalEncoding)
606 #define unknownEncodingMem (parser->m_unknownEncodingMem)
607 #define unknownEncodingData (parser->m_unknownEncodingData)
608 #define unknownEncodingHandlerData \
609 (parser->m_unknownEncodingHandlerData)
610 #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
611 #define protocolEncodingName (parser->m_protocolEncodingName)
612 #define ns (parser->m_ns)
613 #define ns_triplets (parser->m_ns_triplets)
614 #define prologState (parser->m_prologState)
615 #define processor (parser->m_processor)
616 #define errorCode (parser->m_errorCode)
617 #define eventPtr (parser->m_eventPtr)
618 #define eventEndPtr (parser->m_eventEndPtr)
619 #define positionPtr (parser->m_positionPtr)
620 #define position (parser->m_position)
621 #define openInternalEntities (parser->m_openInternalEntities)
622 #define freeInternalEntities (parser->m_freeInternalEntities)
623 #define defaultExpandInternalEntities \
624 (parser->m_defaultExpandInternalEntities)
625 #define tagLevel (parser->m_tagLevel)
626 #define buffer (parser->m_buffer)
627 #define bufferPtr (parser->m_bufferPtr)
628 #define bufferEnd (parser->m_bufferEnd)
629 #define parseEndByteIndex (parser->m_parseEndByteIndex)
630 #define parseEndPtr (parser->m_parseEndPtr)
631 #define bufferLim (parser->m_bufferLim)
632 #define dataBuf (parser->m_dataBuf)
633 #define dataBufEnd (parser->m_dataBufEnd)
634 #define _dtd (parser->m_dtd)
635 #define curBase (parser->m_curBase)
636 #define declEntity (parser->m_declEntity)
637 #define doctypeName (parser->m_doctypeName)
638 #define doctypeSysid (parser->m_doctypeSysid)
639 #define doctypePubid (parser->m_doctypePubid)
640 #define declAttributeType (parser->m_declAttributeType)
641 #define declNotationName (parser->m_declNotationName)
642 #define declNotationPublicId (parser->m_declNotationPublicId)
643 #define declElementType (parser->m_declElementType)
644 #define declAttributeId (parser->m_declAttributeId)
645 #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
646 #define declAttributeIsId (parser->m_declAttributeIsId)
647 #define freeTagList (parser->m_freeTagList)
648 #define freeBindingList (parser->m_freeBindingList)
649 #define inheritedBindings (parser->m_inheritedBindings)
650 #define tagStack (parser->m_tagStack)
651 #define atts (parser->m_atts)
652 #define attsSize (parser->m_attsSize)
653 #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
654 #define idAttIndex (parser->m_idAttIndex)
655 #define nsAtts (parser->m_nsAtts)
656 #define nsAttsVersion (parser->m_nsAttsVersion)
657 #define nsAttsPower (parser->m_nsAttsPower)
658 #define attInfo (parser->m_attInfo)
659 #define tempPool (parser->m_tempPool)
660 #define temp2Pool (parser->m_temp2Pool)
661 #define groupConnector (parser->m_groupConnector)
662 #define groupSize (parser->m_groupSize)
663 #define namespaceSeparator (parser->m_namespaceSeparator)
664 #define parentParser (parser->m_parentParser)
665 #define ps_parsing (parser->m_parsingStatus.parsing)
666 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
668 #define isParamEntity (parser->m_isParamEntity)
669 #define useForeignDTD (parser->m_useForeignDTD)
670 #define paramEntityParsing (parser->m_paramEntityParsing)
672 #define hash_secret_salt (parser->m_hash_secret_salt)
675 XML_ParserCreate(const XML_Char
*encodingName
)
677 return XML_ParserCreate_MM(encodingName
, NULL
, NULL
);
681 XML_ParserCreateNS(const XML_Char
*encodingName
, XML_Char nsSep
)
685 return XML_ParserCreate_MM(encodingName
, NULL
, tmp
);
688 static const XML_Char implicitContext
[] = {
689 ASCII_x
, ASCII_m
, ASCII_l
, ASCII_EQUALS
, ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
,
690 ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
, ASCII_w
, ASCII_w
, ASCII_w
,
691 ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
, ASCII_o
, ASCII_r
, ASCII_g
,
692 ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
, ASCII_SLASH
, ASCII_1
, ASCII_9
,
693 ASCII_9
, ASCII_8
, ASCII_SLASH
, ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
,
694 ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
, ASCII_e
, '\0'
698 generate_hash_secret_salt(void)
700 unsigned int seed
= time(NULL
) % UINT_MAX
;
705 static XML_Bool
/* only valid for root parser */
706 startParsing(XML_Parser parser
)
708 /* hash functions must be initialized before setContext() is called */
709 if (hash_secret_salt
== 0)
710 hash_secret_salt
= generate_hash_secret_salt();
712 /* implicit context only set for root parser, since child
713 parsers (i.e. external entity parsers) will inherit it
715 return setContext(parser
, implicitContext
);
721 XML_ParserCreate_MM(const XML_Char
*encodingName
,
722 const XML_Memory_Handling_Suite
*memsuite
,
723 const XML_Char
*nameSep
)
725 return parserCreate(encodingName
, memsuite
, nameSep
, NULL
);
729 parserCreate(const XML_Char
*encodingName
,
730 const XML_Memory_Handling_Suite
*memsuite
,
731 const XML_Char
*nameSep
,
737 XML_Memory_Handling_Suite
*mtemp
;
738 parser
= (XML_Parser
)
739 memsuite
->malloc_fcn(sizeof(struct XML_ParserStruct
));
740 if (parser
!= NULL
) {
741 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
742 mtemp
->malloc_fcn
= memsuite
->malloc_fcn
;
743 mtemp
->realloc_fcn
= memsuite
->realloc_fcn
;
744 mtemp
->free_fcn
= memsuite
->free_fcn
;
748 XML_Memory_Handling_Suite
*mtemp
;
749 parser
= (XML_Parser
)malloc(sizeof(struct XML_ParserStruct
));
750 if (parser
!= NULL
) {
751 mtemp
= (XML_Memory_Handling_Suite
*)&(parser
->m_mem
);
752 mtemp
->malloc_fcn
= malloc
;
753 mtemp
->realloc_fcn
= realloc
;
754 mtemp
->free_fcn
= free
;
764 attsSize
= INIT_ATTS_SIZE
;
765 atts
= (ATTRIBUTE
*)MALLOC(attsSize
* sizeof(ATTRIBUTE
));
771 attInfo
= (XML_AttrInfo
*)MALLOC(attsSize
* sizeof(XML_AttrInfo
));
772 if (attInfo
== NULL
) {
778 dataBuf
= (XML_Char
*)MALLOC(INIT_DATA_BUF_SIZE
* sizeof(XML_Char
));
779 if (dataBuf
== NULL
) {
787 dataBufEnd
= dataBuf
+ INIT_DATA_BUF_SIZE
;
792 _dtd
= dtdCreate(&parser
->m_mem
);
804 freeBindingList
= NULL
;
806 freeInternalEntities
= NULL
;
809 groupConnector
= NULL
;
811 unknownEncodingHandler
= NULL
;
812 unknownEncodingHandlerData
= NULL
;
814 namespaceSeparator
= ASCII_EXCL
;
816 ns_triplets
= XML_FALSE
;
822 poolInit(&tempPool
, &(parser
->m_mem
));
823 poolInit(&temp2Pool
, &(parser
->m_mem
));
824 parserInit(parser
, encodingName
);
826 if (encodingName
&& !protocolEncodingName
) {
827 XML_ParserFree(parser
);
833 internalEncoding
= XmlGetInternalEncodingNS();
834 namespaceSeparator
= *nameSep
;
837 internalEncoding
= XmlGetInternalEncoding();
844 parserInit(XML_Parser parser
, const XML_Char
*encodingName
)
846 processor
= prologInitProcessor
;
847 XmlPrologStateInit(&prologState
);
848 protocolEncodingName
= (encodingName
!= NULL
849 ? poolCopyString(&tempPool
, encodingName
)
852 XmlInitEncoding(&initEncoding
, &encoding
, 0);
855 startElementHandler
= NULL
;
856 endElementHandler
= NULL
;
857 characterDataHandler
= NULL
;
858 processingInstructionHandler
= NULL
;
859 commentHandler
= NULL
;
860 startCdataSectionHandler
= NULL
;
861 endCdataSectionHandler
= NULL
;
862 defaultHandler
= NULL
;
863 startDoctypeDeclHandler
= NULL
;
864 endDoctypeDeclHandler
= NULL
;
865 unparsedEntityDeclHandler
= NULL
;
866 notationDeclHandler
= NULL
;
867 startNamespaceDeclHandler
= NULL
;
868 endNamespaceDeclHandler
= NULL
;
869 notStandaloneHandler
= NULL
;
870 externalEntityRefHandler
= NULL
;
871 externalEntityRefHandlerArg
= parser
;
872 skippedEntityHandler
= NULL
;
873 elementDeclHandler
= NULL
;
874 attlistDeclHandler
= NULL
;
875 entityDeclHandler
= NULL
;
876 xmlDeclHandler
= NULL
;
879 parseEndByteIndex
= 0;
881 declElementType
= NULL
;
882 declAttributeId
= NULL
;
887 declAttributeType
= NULL
;
888 declNotationName
= NULL
;
889 declNotationPublicId
= NULL
;
890 declAttributeIsCdata
= XML_FALSE
;
891 declAttributeIsId
= XML_FALSE
;
892 memset(&position
, 0, sizeof(POSITION
));
893 errorCode
= XML_ERROR_NONE
;
897 openInternalEntities
= NULL
;
898 defaultExpandInternalEntities
= XML_TRUE
;
901 inheritedBindings
= NULL
;
903 unknownEncodingMem
= NULL
;
904 unknownEncodingRelease
= NULL
;
905 unknownEncodingData
= NULL
;
907 ps_parsing
= XML_INITIALIZED
;
909 isParamEntity
= XML_FALSE
;
910 useForeignDTD
= XML_FALSE
;
911 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
913 hash_secret_salt
= 0;
916 /* moves list of bindings to freeBindingList */
918 moveToFreeBindingList(XML_Parser parser
, BINDING
*bindings
)
921 BINDING
*b
= bindings
;
922 bindings
= bindings
->nextTagBinding
;
923 b
->nextTagBinding
= freeBindingList
;
929 XML_ParserReset(XML_Parser parser
, const XML_Char
*encodingName
)
932 OPEN_INTERNAL_ENTITY
*openEntityList
;
935 /* move tagStack to freeTagList */
940 tag
->parent
= freeTagList
;
941 moveToFreeBindingList(parser
, tag
->bindings
);
942 tag
->bindings
= NULL
;
945 /* move openInternalEntities to freeInternalEntities */
946 openEntityList
= openInternalEntities
;
947 while (openEntityList
) {
948 OPEN_INTERNAL_ENTITY
*openEntity
= openEntityList
;
949 openEntityList
= openEntity
->next
;
950 openEntity
->next
= freeInternalEntities
;
951 freeInternalEntities
= openEntity
;
953 moveToFreeBindingList(parser
, inheritedBindings
);
954 FREE(unknownEncodingMem
);
955 if (unknownEncodingRelease
)
956 unknownEncodingRelease(unknownEncodingData
);
957 poolClear(&tempPool
);
958 poolClear(&temp2Pool
);
959 parserInit(parser
, encodingName
);
960 dtdReset(_dtd
, &parser
->m_mem
);
964 enum XML_Status XMLCALL
965 XML_SetEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
967 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
968 XXX There's no way for the caller to determine which of the
969 XXX possible error cases caused the XML_STATUS_ERROR return.
971 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
972 return XML_STATUS_ERROR
;
973 if (encodingName
== NULL
)
974 protocolEncodingName
= NULL
;
976 protocolEncodingName
= poolCopyString(&tempPool
, encodingName
);
977 if (!protocolEncodingName
)
978 return XML_STATUS_ERROR
;
980 return XML_STATUS_OK
;
984 XML_ExternalEntityParserCreate(XML_Parser oldParser
,
985 const XML_Char
*context
,
986 const XML_Char
*encodingName
)
988 XML_Parser parser
= oldParser
;
991 XML_StartElementHandler oldStartElementHandler
= startElementHandler
;
992 XML_EndElementHandler oldEndElementHandler
= endElementHandler
;
993 XML_CharacterDataHandler oldCharacterDataHandler
= characterDataHandler
;
994 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
995 = processingInstructionHandler
;
996 XML_CommentHandler oldCommentHandler
= commentHandler
;
997 XML_StartCdataSectionHandler oldStartCdataSectionHandler
998 = startCdataSectionHandler
;
999 XML_EndCdataSectionHandler oldEndCdataSectionHandler
1000 = endCdataSectionHandler
;
1001 XML_DefaultHandler oldDefaultHandler
= defaultHandler
;
1002 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
1003 = unparsedEntityDeclHandler
;
1004 XML_NotationDeclHandler oldNotationDeclHandler
= notationDeclHandler
;
1005 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
1006 = startNamespaceDeclHandler
;
1007 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
1008 = endNamespaceDeclHandler
;
1009 XML_NotStandaloneHandler oldNotStandaloneHandler
= notStandaloneHandler
;
1010 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
1011 = externalEntityRefHandler
;
1012 XML_SkippedEntityHandler oldSkippedEntityHandler
= skippedEntityHandler
;
1013 XML_UnknownEncodingHandler oldUnknownEncodingHandler
1014 = unknownEncodingHandler
;
1015 XML_ElementDeclHandler oldElementDeclHandler
= elementDeclHandler
;
1016 XML_AttlistDeclHandler oldAttlistDeclHandler
= attlistDeclHandler
;
1017 XML_EntityDeclHandler oldEntityDeclHandler
= entityDeclHandler
;
1018 XML_XmlDeclHandler oldXmlDeclHandler
= xmlDeclHandler
;
1019 ELEMENT_TYPE
* oldDeclElementType
= declElementType
;
1021 void *oldUserData
= userData
;
1022 void *oldHandlerArg
= handlerArg
;
1023 XML_Bool oldDefaultExpandInternalEntities
= defaultExpandInternalEntities
;
1024 XML_Parser oldExternalEntityRefHandlerArg
= externalEntityRefHandlerArg
;
1026 enum XML_ParamEntityParsing oldParamEntityParsing
= paramEntityParsing
;
1027 int oldInEntityValue
= prologState
.inEntityValue
;
1029 XML_Bool oldns_triplets
= ns_triplets
;
1030 /* Note that the new parser shares the same hash secret as the old
1031 parser, so that dtdCopy and copyEntityTable can lookup values
1032 from hash tables associated with either parser without us having
1033 to worry which hash secrets each table has.
1035 unsigned long oldhash_secret_salt
= hash_secret_salt
;
1040 #endif /* XML_DTD */
1042 /* Note that the magical uses of the pre-processor to make field
1043 access look more like C++ require that `parser' be overwritten
1044 here. This makes this function more painful to follow than it
1049 *tmp
= namespaceSeparator
;
1050 parser
= parserCreate(encodingName
, &parser
->m_mem
, tmp
, newDtd
);
1053 parser
= parserCreate(encodingName
, &parser
->m_mem
, NULL
, newDtd
);
1059 startElementHandler
= oldStartElementHandler
;
1060 endElementHandler
= oldEndElementHandler
;
1061 characterDataHandler
= oldCharacterDataHandler
;
1062 processingInstructionHandler
= oldProcessingInstructionHandler
;
1063 commentHandler
= oldCommentHandler
;
1064 startCdataSectionHandler
= oldStartCdataSectionHandler
;
1065 endCdataSectionHandler
= oldEndCdataSectionHandler
;
1066 defaultHandler
= oldDefaultHandler
;
1067 unparsedEntityDeclHandler
= oldUnparsedEntityDeclHandler
;
1068 notationDeclHandler
= oldNotationDeclHandler
;
1069 startNamespaceDeclHandler
= oldStartNamespaceDeclHandler
;
1070 endNamespaceDeclHandler
= oldEndNamespaceDeclHandler
;
1071 notStandaloneHandler
= oldNotStandaloneHandler
;
1072 externalEntityRefHandler
= oldExternalEntityRefHandler
;
1073 skippedEntityHandler
= oldSkippedEntityHandler
;
1074 unknownEncodingHandler
= oldUnknownEncodingHandler
;
1075 elementDeclHandler
= oldElementDeclHandler
;
1076 attlistDeclHandler
= oldAttlistDeclHandler
;
1077 entityDeclHandler
= oldEntityDeclHandler
;
1078 xmlDeclHandler
= oldXmlDeclHandler
;
1079 declElementType
= oldDeclElementType
;
1080 userData
= oldUserData
;
1081 if (oldUserData
== oldHandlerArg
)
1082 handlerArg
= userData
;
1084 handlerArg
= parser
;
1085 if (oldExternalEntityRefHandlerArg
!= oldParser
)
1086 externalEntityRefHandlerArg
= oldExternalEntityRefHandlerArg
;
1087 defaultExpandInternalEntities
= oldDefaultExpandInternalEntities
;
1088 ns_triplets
= oldns_triplets
;
1089 hash_secret_salt
= oldhash_secret_salt
;
1090 parentParser
= oldParser
;
1092 paramEntityParsing
= oldParamEntityParsing
;
1093 prologState
.inEntityValue
= oldInEntityValue
;
1095 #endif /* XML_DTD */
1096 if (!dtdCopy(oldParser
, _dtd
, oldDtd
, &parser
->m_mem
)
1097 || !setContext(parser
, context
)) {
1098 XML_ParserFree(parser
);
1101 processor
= externalEntityInitProcessor
;
1105 /* The DTD instance referenced by _dtd is shared between the document's
1106 root parser and external PE parsers, therefore one does not need to
1107 call setContext. In addition, one also *must* not call setContext,
1108 because this would overwrite existing prefix->binding pointers in
1109 _dtd with ones that get destroyed with the external PE parser.
1110 This would leave those prefixes with dangling pointers.
1112 isParamEntity
= XML_TRUE
;
1113 XmlPrologStateInitExternalEntity(&prologState
);
1114 processor
= externalParEntInitProcessor
;
1116 #endif /* XML_DTD */
1120 static void FASTCALL
1121 destroyBindings(BINDING
*bindings
, XML_Parser parser
)
1124 BINDING
*b
= bindings
;
1127 bindings
= b
->nextTagBinding
;
1134 XML_ParserFree(XML_Parser parser
)
1137 OPEN_INTERNAL_ENTITY
*entityList
;
1140 /* free tagStack and freeTagList */
1144 if (tagList
== NULL
) {
1145 if (freeTagList
== NULL
)
1147 tagList
= freeTagList
;
1151 tagList
= tagList
->parent
;
1153 destroyBindings(p
->bindings
, parser
);
1156 /* free openInternalEntities and freeInternalEntities */
1157 entityList
= openInternalEntities
;
1159 OPEN_INTERNAL_ENTITY
*openEntity
;
1160 if (entityList
== NULL
) {
1161 if (freeInternalEntities
== NULL
)
1163 entityList
= freeInternalEntities
;
1164 freeInternalEntities
= NULL
;
1166 openEntity
= entityList
;
1167 entityList
= entityList
->next
;
1171 destroyBindings(freeBindingList
, parser
);
1172 destroyBindings(inheritedBindings
, parser
);
1173 poolDestroy(&tempPool
);
1174 poolDestroy(&temp2Pool
);
1176 /* external parameter entity parsers share the DTD structure
1177 parser->m_dtd with the root parser, so we must not destroy it
1179 if (!isParamEntity
&& _dtd
)
1182 #endif /* XML_DTD */
1183 dtdDestroy(_dtd
, (XML_Bool
)!parentParser
, &parser
->m_mem
);
1185 #ifdef XML_ATTR_INFO
1186 FREE((void *)attInfo
);
1188 FREE(groupConnector
);
1192 FREE(unknownEncodingMem
);
1193 if (unknownEncodingRelease
)
1194 unknownEncodingRelease(unknownEncodingData
);
1199 XML_UseParserAsHandlerArg(XML_Parser parser
)
1201 handlerArg
= parser
;
1204 enum XML_Error XMLCALL
1205 XML_UseForeignDTD(XML_Parser parser
, XML_Bool useDTD
)
1208 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1209 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1210 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
;
1211 useForeignDTD
= useDTD
;
1212 return XML_ERROR_NONE
;
1214 return XML_ERROR_FEATURE_REQUIRES_XML_DTD
;
1219 XML_SetReturnNSTriplet(XML_Parser parser
, int do_nst
)
1221 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1222 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1224 ns_triplets
= do_nst
? XML_TRUE
: XML_FALSE
;
1228 XML_SetUserData(XML_Parser parser
, void *p
)
1230 if (handlerArg
== userData
)
1231 handlerArg
= userData
= p
;
1236 enum XML_Status XMLCALL
1237 XML_SetBase(XML_Parser parser
, const XML_Char
*p
)
1240 p
= poolCopyString(&_dtd
->pool
, p
);
1242 return XML_STATUS_ERROR
;
1247 return XML_STATUS_OK
;
1250 const XML_Char
* XMLCALL
1251 XML_GetBase(XML_Parser parser
)
1257 XML_GetSpecifiedAttributeCount(XML_Parser parser
)
1259 return nSpecifiedAtts
;
1263 XML_GetIdAttributeIndex(XML_Parser parser
)
1268 #ifdef XML_ATTR_INFO
1269 const XML_AttrInfo
* XMLCALL
1270 XML_GetAttributeInfo(XML_Parser parser
)
1277 XML_SetElementHandler(XML_Parser parser
,
1278 XML_StartElementHandler start
,
1279 XML_EndElementHandler end
)
1281 startElementHandler
= start
;
1282 endElementHandler
= end
;
1286 XML_SetStartElementHandler(XML_Parser parser
,
1287 XML_StartElementHandler start
) {
1288 startElementHandler
= start
;
1292 XML_SetEndElementHandler(XML_Parser parser
,
1293 XML_EndElementHandler end
) {
1294 endElementHandler
= end
;
1298 XML_SetCharacterDataHandler(XML_Parser parser
,
1299 XML_CharacterDataHandler handler
)
1301 characterDataHandler
= handler
;
1305 XML_SetProcessingInstructionHandler(XML_Parser parser
,
1306 XML_ProcessingInstructionHandler handler
)
1308 processingInstructionHandler
= handler
;
1312 XML_SetCommentHandler(XML_Parser parser
,
1313 XML_CommentHandler handler
)
1315 commentHandler
= handler
;
1319 XML_SetCdataSectionHandler(XML_Parser parser
,
1320 XML_StartCdataSectionHandler start
,
1321 XML_EndCdataSectionHandler end
)
1323 startCdataSectionHandler
= start
;
1324 endCdataSectionHandler
= end
;
1328 XML_SetStartCdataSectionHandler(XML_Parser parser
,
1329 XML_StartCdataSectionHandler start
) {
1330 startCdataSectionHandler
= start
;
1334 XML_SetEndCdataSectionHandler(XML_Parser parser
,
1335 XML_EndCdataSectionHandler end
) {
1336 endCdataSectionHandler
= end
;
1340 XML_SetDefaultHandler(XML_Parser parser
,
1341 XML_DefaultHandler handler
)
1343 defaultHandler
= handler
;
1344 defaultExpandInternalEntities
= XML_FALSE
;
1348 XML_SetDefaultHandlerExpand(XML_Parser parser
,
1349 XML_DefaultHandler handler
)
1351 defaultHandler
= handler
;
1352 defaultExpandInternalEntities
= XML_TRUE
;
1356 XML_SetDoctypeDeclHandler(XML_Parser parser
,
1357 XML_StartDoctypeDeclHandler start
,
1358 XML_EndDoctypeDeclHandler end
)
1360 startDoctypeDeclHandler
= start
;
1361 endDoctypeDeclHandler
= end
;
1365 XML_SetStartDoctypeDeclHandler(XML_Parser parser
,
1366 XML_StartDoctypeDeclHandler start
) {
1367 startDoctypeDeclHandler
= start
;
1371 XML_SetEndDoctypeDeclHandler(XML_Parser parser
,
1372 XML_EndDoctypeDeclHandler end
) {
1373 endDoctypeDeclHandler
= end
;
1377 XML_SetUnparsedEntityDeclHandler(XML_Parser parser
,
1378 XML_UnparsedEntityDeclHandler handler
)
1380 unparsedEntityDeclHandler
= handler
;
1384 XML_SetNotationDeclHandler(XML_Parser parser
,
1385 XML_NotationDeclHandler handler
)
1387 notationDeclHandler
= handler
;
1391 XML_SetNamespaceDeclHandler(XML_Parser parser
,
1392 XML_StartNamespaceDeclHandler start
,
1393 XML_EndNamespaceDeclHandler end
)
1395 startNamespaceDeclHandler
= start
;
1396 endNamespaceDeclHandler
= end
;
1400 XML_SetStartNamespaceDeclHandler(XML_Parser parser
,
1401 XML_StartNamespaceDeclHandler start
) {
1402 startNamespaceDeclHandler
= start
;
1406 XML_SetEndNamespaceDeclHandler(XML_Parser parser
,
1407 XML_EndNamespaceDeclHandler end
) {
1408 endNamespaceDeclHandler
= end
;
1412 XML_SetNotStandaloneHandler(XML_Parser parser
,
1413 XML_NotStandaloneHandler handler
)
1415 notStandaloneHandler
= handler
;
1419 XML_SetExternalEntityRefHandler(XML_Parser parser
,
1420 XML_ExternalEntityRefHandler handler
)
1422 externalEntityRefHandler
= handler
;
1426 XML_SetExternalEntityRefHandlerArg(XML_Parser parser
, void *arg
)
1429 externalEntityRefHandlerArg
= (XML_Parser
)arg
;
1431 externalEntityRefHandlerArg
= parser
;
1435 XML_SetSkippedEntityHandler(XML_Parser parser
,
1436 XML_SkippedEntityHandler handler
)
1438 skippedEntityHandler
= handler
;
1442 XML_SetUnknownEncodingHandler(XML_Parser parser
,
1443 XML_UnknownEncodingHandler handler
,
1446 unknownEncodingHandler
= handler
;
1447 unknownEncodingHandlerData
= data
;
1451 XML_SetElementDeclHandler(XML_Parser parser
,
1452 XML_ElementDeclHandler eldecl
)
1454 elementDeclHandler
= eldecl
;
1458 XML_SetAttlistDeclHandler(XML_Parser parser
,
1459 XML_AttlistDeclHandler attdecl
)
1461 attlistDeclHandler
= attdecl
;
1465 XML_SetEntityDeclHandler(XML_Parser parser
,
1466 XML_EntityDeclHandler handler
)
1468 entityDeclHandler
= handler
;
1472 XML_SetXmlDeclHandler(XML_Parser parser
,
1473 XML_XmlDeclHandler handler
) {
1474 xmlDeclHandler
= handler
;
1478 XML_SetParamEntityParsing(XML_Parser parser
,
1479 enum XML_ParamEntityParsing peParsing
)
1481 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1482 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1485 paramEntityParsing
= peParsing
;
1488 return peParsing
== XML_PARAM_ENTITY_PARSING_NEVER
;
1493 XML_SetHashSalt(XML_Parser parser
,
1494 unsigned long hash_salt
)
1496 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1497 if (ps_parsing
== XML_PARSING
|| ps_parsing
== XML_SUSPENDED
)
1499 hash_secret_salt
= hash_salt
;
1503 enum XML_Status XMLCALL
1504 XML_Parse(XML_Parser parser
, const char *s
, int len
, int isFinal
)
1506 switch (ps_parsing
) {
1508 errorCode
= XML_ERROR_SUSPENDED
;
1509 return XML_STATUS_ERROR
;
1511 errorCode
= XML_ERROR_FINISHED
;
1512 return XML_STATUS_ERROR
;
1513 case XML_INITIALIZED
:
1514 if (parentParser
== NULL
&& !startParsing(parser
)) {
1515 errorCode
= XML_ERROR_NO_MEMORY
;
1516 return XML_STATUS_ERROR
;
1519 ps_parsing
= XML_PARSING
;
1523 ps_finalBuffer
= (XML_Bool
)isFinal
;
1525 return XML_STATUS_OK
;
1526 positionPtr
= bufferPtr
;
1527 parseEndPtr
= bufferEnd
;
1529 /* If data are left over from last buffer, and we now know that these
1530 data are the final chunk of input, then we have to check them again
1531 to detect errors based on that fact.
1533 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1535 if (errorCode
== XML_ERROR_NONE
) {
1536 switch (ps_parsing
) {
1538 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1539 positionPtr
= bufferPtr
;
1540 return XML_STATUS_SUSPENDED
;
1541 case XML_INITIALIZED
:
1543 ps_parsing
= XML_FINISHED
;
1546 return XML_STATUS_OK
;
1549 eventEndPtr
= eventPtr
;
1550 processor
= errorProcessor
;
1551 return XML_STATUS_ERROR
;
1553 #ifndef XML_CONTEXT_BYTES
1554 else if (bufferPtr
== bufferEnd
) {
1557 enum XML_Error result
;
1558 parseEndByteIndex
+= len
;
1560 ps_finalBuffer
= (XML_Bool
)isFinal
;
1562 errorCode
= processor(parser
, s
, parseEndPtr
= s
+ len
, &end
);
1564 if (errorCode
!= XML_ERROR_NONE
) {
1565 eventEndPtr
= eventPtr
;
1566 processor
= errorProcessor
;
1567 return XML_STATUS_ERROR
;
1570 switch (ps_parsing
) {
1572 result
= XML_STATUS_SUSPENDED
;
1574 case XML_INITIALIZED
:
1577 ps_parsing
= XML_FINISHED
;
1578 return XML_STATUS_OK
;
1582 result
= XML_STATUS_OK
;
1586 XmlUpdatePosition(encoding
, positionPtr
, end
, &position
);
1587 nLeftOver
= s
+ len
- end
;
1589 if (buffer
== NULL
|| nLeftOver
> bufferLim
- buffer
) {
1590 /* FIXME avoid integer overflow */
1592 temp
= (buffer
== NULL
1593 ? (char *)MALLOC(len
* 2)
1594 : (char *)REALLOC(buffer
, len
* 2));
1596 errorCode
= XML_ERROR_NO_MEMORY
;
1597 eventPtr
= eventEndPtr
= NULL
;
1598 processor
= errorProcessor
;
1599 return XML_STATUS_ERROR
;
1602 bufferLim
= buffer
+ len
* 2;
1604 memcpy(buffer
, end
, nLeftOver
);
1607 bufferEnd
= buffer
+ nLeftOver
;
1608 positionPtr
= bufferPtr
;
1609 parseEndPtr
= bufferEnd
;
1610 eventPtr
= bufferPtr
;
1611 eventEndPtr
= bufferPtr
;
1614 #endif /* not defined XML_CONTEXT_BYTES */
1616 void *buff
= XML_GetBuffer(parser
, len
);
1618 return XML_STATUS_ERROR
;
1620 memcpy(buff
, s
, len
);
1621 return XML_ParseBuffer(parser
, len
, isFinal
);
1626 enum XML_Status XMLCALL
1627 XML_ParseBuffer(XML_Parser parser
, int len
, int isFinal
)
1630 enum XML_Status result
= XML_STATUS_OK
;
1632 switch (ps_parsing
) {
1634 errorCode
= XML_ERROR_SUSPENDED
;
1635 return XML_STATUS_ERROR
;
1637 errorCode
= XML_ERROR_FINISHED
;
1638 return XML_STATUS_ERROR
;
1639 case XML_INITIALIZED
:
1640 if (parentParser
== NULL
&& !startParsing(parser
)) {
1641 errorCode
= XML_ERROR_NO_MEMORY
;
1642 return XML_STATUS_ERROR
;
1645 ps_parsing
= XML_PARSING
;
1649 positionPtr
= start
;
1651 parseEndPtr
= bufferEnd
;
1652 parseEndByteIndex
+= len
;
1653 ps_finalBuffer
= (XML_Bool
)isFinal
;
1655 errorCode
= processor(parser
, start
, parseEndPtr
, &bufferPtr
);
1657 if (errorCode
!= XML_ERROR_NONE
) {
1658 eventEndPtr
= eventPtr
;
1659 processor
= errorProcessor
;
1660 return XML_STATUS_ERROR
;
1663 switch (ps_parsing
) {
1665 result
= XML_STATUS_SUSPENDED
;
1667 case XML_INITIALIZED
:
1670 ps_parsing
= XML_FINISHED
;
1673 default: ; /* should not happen */
1677 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1678 positionPtr
= bufferPtr
;
1683 XML_GetBuffer(XML_Parser parser
, int len
)
1685 switch (ps_parsing
) {
1687 errorCode
= XML_ERROR_SUSPENDED
;
1690 errorCode
= XML_ERROR_FINISHED
;
1695 if (len
> bufferLim
- bufferEnd
) {
1696 /* FIXME avoid integer overflow */
1697 int neededSize
= len
+ (int)(bufferEnd
- bufferPtr
);
1698 #ifdef XML_CONTEXT_BYTES
1699 int keep
= (int)(bufferPtr
- buffer
);
1701 if (keep
> XML_CONTEXT_BYTES
)
1702 keep
= XML_CONTEXT_BYTES
;
1704 #endif /* defined XML_CONTEXT_BYTES */
1705 if (neededSize
<= bufferLim
- buffer
) {
1706 #ifdef XML_CONTEXT_BYTES
1707 if (keep
< bufferPtr
- buffer
) {
1708 int offset
= (int)(bufferPtr
- buffer
) - keep
;
1709 memmove(buffer
, &buffer
[offset
], bufferEnd
- bufferPtr
+ keep
);
1710 bufferEnd
-= offset
;
1711 bufferPtr
-= offset
;
1714 memmove(buffer
, bufferPtr
, bufferEnd
- bufferPtr
);
1715 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
);
1717 #endif /* not defined XML_CONTEXT_BYTES */
1721 int bufferSize
= (int)(bufferLim
- bufferPtr
);
1722 if (bufferSize
== 0)
1723 bufferSize
= INIT_BUFFER_SIZE
;
1726 } while (bufferSize
< neededSize
);
1727 newBuf
= (char *)MALLOC(bufferSize
);
1729 errorCode
= XML_ERROR_NO_MEMORY
;
1732 bufferLim
= newBuf
+ bufferSize
;
1733 #ifdef XML_CONTEXT_BYTES
1735 int keep
= (int)(bufferPtr
- buffer
);
1736 if (keep
> XML_CONTEXT_BYTES
)
1737 keep
= XML_CONTEXT_BYTES
;
1738 memcpy(newBuf
, &bufferPtr
[-keep
], bufferEnd
- bufferPtr
+ keep
);
1741 bufferEnd
= buffer
+ (bufferEnd
- bufferPtr
) + keep
;
1742 bufferPtr
= buffer
+ keep
;
1745 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1746 bufferPtr
= buffer
= newBuf
;
1750 memcpy(newBuf
, bufferPtr
, bufferEnd
- bufferPtr
);
1753 bufferEnd
= newBuf
+ (bufferEnd
- bufferPtr
);
1754 bufferPtr
= buffer
= newBuf
;
1755 #endif /* not defined XML_CONTEXT_BYTES */
1757 eventPtr
= eventEndPtr
= NULL
;
1763 enum XML_Status XMLCALL
1764 XML_StopParser(XML_Parser parser
, XML_Bool resumable
)
1766 switch (ps_parsing
) {
1769 errorCode
= XML_ERROR_SUSPENDED
;
1770 return XML_STATUS_ERROR
;
1772 ps_parsing
= XML_FINISHED
;
1775 errorCode
= XML_ERROR_FINISHED
;
1776 return XML_STATUS_ERROR
;
1780 if (isParamEntity
) {
1781 errorCode
= XML_ERROR_SUSPEND_PE
;
1782 return XML_STATUS_ERROR
;
1785 ps_parsing
= XML_SUSPENDED
;
1788 ps_parsing
= XML_FINISHED
;
1790 return XML_STATUS_OK
;
1793 enum XML_Status XMLCALL
1794 XML_ResumeParser(XML_Parser parser
)
1796 enum XML_Status result
= XML_STATUS_OK
;
1798 if (ps_parsing
!= XML_SUSPENDED
) {
1799 errorCode
= XML_ERROR_NOT_SUSPENDED
;
1800 return XML_STATUS_ERROR
;
1802 ps_parsing
= XML_PARSING
;
1804 errorCode
= processor(parser
, bufferPtr
, parseEndPtr
, &bufferPtr
);
1806 if (errorCode
!= XML_ERROR_NONE
) {
1807 eventEndPtr
= eventPtr
;
1808 processor
= errorProcessor
;
1809 return XML_STATUS_ERROR
;
1812 switch (ps_parsing
) {
1814 result
= XML_STATUS_SUSPENDED
;
1816 case XML_INITIALIZED
:
1818 if (ps_finalBuffer
) {
1819 ps_parsing
= XML_FINISHED
;
1826 XmlUpdatePosition(encoding
, positionPtr
, bufferPtr
, &position
);
1827 positionPtr
= bufferPtr
;
1832 XML_GetParsingStatus(XML_Parser parser
, XML_ParsingStatus
*status
)
1834 assert(status
!= NULL
);
1835 *status
= parser
->m_parsingStatus
;
1838 enum XML_Error XMLCALL
1839 XML_GetErrorCode(XML_Parser parser
)
1845 XML_GetCurrentByteIndex(XML_Parser parser
)
1848 return parseEndByteIndex
- (parseEndPtr
- eventPtr
);
1853 XML_GetCurrentByteCount(XML_Parser parser
)
1855 if (eventEndPtr
&& eventPtr
)
1856 return (int)(eventEndPtr
- eventPtr
);
1860 const char * XMLCALL
1861 XML_GetInputContext(XML_Parser parser
, int *offset
, int *size
)
1863 #ifdef XML_CONTEXT_BYTES
1864 if (eventPtr
&& buffer
) {
1865 *offset
= (int)(eventPtr
- buffer
);
1866 *size
= (int)(bufferEnd
- buffer
);
1869 #endif /* defined XML_CONTEXT_BYTES */
1874 XML_GetCurrentLineNumber(XML_Parser parser
)
1876 if (eventPtr
&& eventPtr
>= positionPtr
) {
1877 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1878 positionPtr
= eventPtr
;
1880 return position
.lineNumber
+ 1;
1884 XML_GetCurrentColumnNumber(XML_Parser parser
)
1886 if (eventPtr
&& eventPtr
>= positionPtr
) {
1887 XmlUpdatePosition(encoding
, positionPtr
, eventPtr
, &position
);
1888 positionPtr
= eventPtr
;
1890 return position
.columnNumber
;
1894 XML_FreeContentModel(XML_Parser parser
, XML_Content
*model
)
1900 XML_MemMalloc(XML_Parser parser
, size_t size
)
1902 return MALLOC(size
);
1906 XML_MemRealloc(XML_Parser parser
, void *ptr
, size_t size
)
1908 return REALLOC(ptr
, size
);
1912 XML_MemFree(XML_Parser parser
, void *ptr
)
1918 XML_DefaultCurrent(XML_Parser parser
)
1920 if (defaultHandler
) {
1921 if (openInternalEntities
)
1922 reportDefault(parser
,
1924 openInternalEntities
->internalEventPtr
,
1925 openInternalEntities
->internalEventEndPtr
);
1927 reportDefault(parser
, encoding
, eventPtr
, eventEndPtr
);
1931 const XML_LChar
* XMLCALL
1932 XML_ErrorString(enum XML_Error code
)
1934 static const XML_LChar
* const message
[] = {
1936 XML_L("out of memory"),
1937 XML_L("syntax error"),
1938 XML_L("no element found"),
1939 XML_L("not well-formed (invalid token)"),
1940 XML_L("unclosed token"),
1941 XML_L("partial character"),
1942 XML_L("mismatched tag"),
1943 XML_L("duplicate attribute"),
1944 XML_L("junk after document element"),
1945 XML_L("illegal parameter entity reference"),
1946 XML_L("undefined entity"),
1947 XML_L("recursive entity reference"),
1948 XML_L("asynchronous entity"),
1949 XML_L("reference to invalid character number"),
1950 XML_L("reference to binary entity"),
1951 XML_L("reference to external entity in attribute"),
1952 XML_L("XML or text declaration not at start of entity"),
1953 XML_L("unknown encoding"),
1954 XML_L("encoding specified in XML declaration is incorrect"),
1955 XML_L("unclosed CDATA section"),
1956 XML_L("error in processing external entity reference"),
1957 XML_L("document is not standalone"),
1958 XML_L("unexpected parser state - please send a bug report"),
1959 XML_L("entity declared in parameter entity"),
1960 XML_L("requested feature requires XML_DTD support in Expat"),
1961 XML_L("cannot change setting once parsing has begun"),
1962 XML_L("unbound prefix"),
1963 XML_L("must not undeclare prefix"),
1964 XML_L("incomplete markup in parameter entity"),
1965 XML_L("XML declaration not well-formed"),
1966 XML_L("text declaration not well-formed"),
1967 XML_L("illegal character(s) in public id"),
1968 XML_L("parser suspended"),
1969 XML_L("parser not suspended"),
1970 XML_L("parsing aborted"),
1971 XML_L("parsing finished"),
1972 XML_L("cannot suspend in external parameter entity"),
1973 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1974 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1975 XML_L("prefix must not be bound to one of the reserved namespace names")
1977 if (code
> 0 && code
< sizeof(message
)/sizeof(message
[0]))
1978 return message
[code
];
1982 const XML_LChar
* XMLCALL
1983 XML_ExpatVersion(void) {
1985 /* V1 is used to string-ize the version number. However, it would
1986 string-ize the actual version macro *names* unless we get them
1987 substituted before being passed to V1. CPP is defined to expand
1988 a macro, then rescan for more expansions. Thus, we use V2 to expand
1989 the version macros, then CPP will expand the resulting V1() macro
1990 with the correct numerals. */
1991 /* ### I'm assuming cpp is portable in this respect... */
1993 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1994 #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1996 return V2(XML_MAJOR_VERSION
, XML_MINOR_VERSION
, XML_MICRO_VERSION
);
2002 XML_Expat_Version XMLCALL
2003 XML_ExpatVersionInfo(void)
2005 XML_Expat_Version version
;
2007 version
.major
= XML_MAJOR_VERSION
;
2008 version
.minor
= XML_MINOR_VERSION
;
2009 version
.micro
= XML_MICRO_VERSION
;
2014 const XML_Feature
* XMLCALL
2015 XML_GetFeatureList(void)
2017 static const XML_Feature features
[] = {
2018 {XML_FEATURE_SIZEOF_XML_CHAR
, XML_L("sizeof(XML_Char)"),
2020 {XML_FEATURE_SIZEOF_XML_LCHAR
, XML_L("sizeof(XML_LChar)"),
2023 {XML_FEATURE_UNICODE
, XML_L("XML_UNICODE"), 0},
2025 #ifdef XML_UNICODE_WCHAR_T
2026 {XML_FEATURE_UNICODE_WCHAR_T
, XML_L("XML_UNICODE_WCHAR_T"), 0},
2029 {XML_FEATURE_DTD
, XML_L("XML_DTD"), 0},
2031 #ifdef XML_CONTEXT_BYTES
2032 {XML_FEATURE_CONTEXT_BYTES
, XML_L("XML_CONTEXT_BYTES"),
2036 {XML_FEATURE_MIN_SIZE
, XML_L("XML_MIN_SIZE"), 0},
2039 {XML_FEATURE_NS
, XML_L("XML_NS"), 0},
2041 #ifdef XML_LARGE_SIZE
2042 {XML_FEATURE_LARGE_SIZE
, XML_L("XML_LARGE_SIZE"), 0},
2044 #ifdef XML_ATTR_INFO
2045 {XML_FEATURE_ATTR_INFO
, XML_L("XML_ATTR_INFO"), 0},
2047 {XML_FEATURE_END
, NULL
, 0}
2053 /* Initially tag->rawName always points into the parse buffer;
2054 for those TAG instances opened while the current parse buffer was
2055 processed, and not yet closed, we need to store tag->rawName in a more
2056 permanent location, since the parse buffer is about to be discarded.
2059 storeRawNames(XML_Parser parser
)
2061 TAG
*tag
= tagStack
;
2064 int nameLen
= sizeof(XML_Char
) * (tag
->name
.strLen
+ 1);
2065 char *rawNameBuf
= tag
->buf
+ nameLen
;
2066 /* Stop if already stored. Since tagStack is a stack, we can stop
2067 at the first entry that has already been copied; everything
2068 below it in the stack is already been accounted for in a
2069 previous call to this function.
2071 if (tag
->rawName
== rawNameBuf
)
2073 /* For re-use purposes we need to ensure that the
2074 size of tag->buf is a multiple of sizeof(XML_Char).
2076 bufSize
= nameLen
+ ROUND_UP(tag
->rawNameLength
, sizeof(XML_Char
));
2077 if (bufSize
> tag
->bufEnd
- tag
->buf
) {
2078 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2081 /* if tag->name.str points to tag->buf (only when namespace
2082 processing is off) then we have to update it
2084 if (tag
->name
.str
== (XML_Char
*)tag
->buf
)
2085 tag
->name
.str
= (XML_Char
*)temp
;
2086 /* if tag->name.localPart is set (when namespace processing is on)
2087 then update it as well, since it will always point into tag->buf
2089 if (tag
->name
.localPart
)
2090 tag
->name
.localPart
= (XML_Char
*)temp
+ (tag
->name
.localPart
-
2091 (XML_Char
*)tag
->buf
);
2093 tag
->bufEnd
= temp
+ bufSize
;
2094 rawNameBuf
= temp
+ nameLen
;
2096 memcpy(rawNameBuf
, tag
->rawName
, tag
->rawNameLength
);
2097 tag
->rawName
= rawNameBuf
;
2103 static enum XML_Error PTRCALL
2104 contentProcessor(XML_Parser parser
,
2107 const char **endPtr
)
2109 enum XML_Error result
= doContent(parser
, 0, encoding
, start
, end
,
2110 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2111 if (result
== XML_ERROR_NONE
) {
2112 if (!storeRawNames(parser
))
2113 return XML_ERROR_NO_MEMORY
;
2118 static enum XML_Error PTRCALL
2119 externalEntityInitProcessor(XML_Parser parser
,
2122 const char **endPtr
)
2124 enum XML_Error result
= initializeEncoding(parser
);
2125 if (result
!= XML_ERROR_NONE
)
2127 processor
= externalEntityInitProcessor2
;
2128 return externalEntityInitProcessor2(parser
, start
, end
, endPtr
);
2131 static enum XML_Error PTRCALL
2132 externalEntityInitProcessor2(XML_Parser parser
,
2135 const char **endPtr
)
2137 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2138 int tok
= XmlContentTok(encoding
, start
, end
, &next
);
2141 /* If we are at the end of the buffer, this would cause the next stage,
2142 i.e. externalEntityInitProcessor3, to pass control directly to
2143 doContent (by detecting XML_TOK_NONE) without processing any xml text
2144 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2146 if (next
== end
&& !ps_finalBuffer
) {
2148 return XML_ERROR_NONE
;
2152 case XML_TOK_PARTIAL
:
2153 if (!ps_finalBuffer
) {
2155 return XML_ERROR_NONE
;
2158 return XML_ERROR_UNCLOSED_TOKEN
;
2159 case XML_TOK_PARTIAL_CHAR
:
2160 if (!ps_finalBuffer
) {
2162 return XML_ERROR_NONE
;
2165 return XML_ERROR_PARTIAL_CHAR
;
2167 processor
= externalEntityInitProcessor3
;
2168 return externalEntityInitProcessor3(parser
, start
, end
, endPtr
);
2171 static enum XML_Error PTRCALL
2172 externalEntityInitProcessor3(XML_Parser parser
,
2175 const char **endPtr
)
2178 const char *next
= start
; /* XmlContentTok doesn't always set the last arg */
2180 tok
= XmlContentTok(encoding
, start
, end
, &next
);
2184 case XML_TOK_XML_DECL
:
2186 enum XML_Error result
;
2187 result
= processXmlDecl(parser
, 1, start
, next
);
2188 if (result
!= XML_ERROR_NONE
)
2190 switch (ps_parsing
) {
2193 return XML_ERROR_NONE
;
2195 return XML_ERROR_ABORTED
;
2201 case XML_TOK_PARTIAL
:
2202 if (!ps_finalBuffer
) {
2204 return XML_ERROR_NONE
;
2206 return XML_ERROR_UNCLOSED_TOKEN
;
2207 case XML_TOK_PARTIAL_CHAR
:
2208 if (!ps_finalBuffer
) {
2210 return XML_ERROR_NONE
;
2212 return XML_ERROR_PARTIAL_CHAR
;
2214 processor
= externalEntityContentProcessor
;
2216 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
2219 static enum XML_Error PTRCALL
2220 externalEntityContentProcessor(XML_Parser parser
,
2223 const char **endPtr
)
2225 enum XML_Error result
= doContent(parser
, 1, encoding
, start
, end
,
2226 endPtr
, (XML_Bool
)!ps_finalBuffer
);
2227 if (result
== XML_ERROR_NONE
) {
2228 if (!storeRawNames(parser
))
2229 return XML_ERROR_NO_MEMORY
;
2234 static enum XML_Error
2235 doContent(XML_Parser parser
,
2237 const ENCODING
*enc
,
2240 const char **nextPtr
,
2243 /* save one level of indirection */
2244 DTD
* const dtd
= _dtd
;
2246 const char **eventPP
;
2247 const char **eventEndPP
;
2248 if (enc
== encoding
) {
2249 eventPP
= &eventPtr
;
2250 eventEndPP
= &eventEndPtr
;
2253 eventPP
= &(openInternalEntities
->internalEventPtr
);
2254 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
2259 const char *next
= s
; /* XmlContentTok doesn't always set the last arg */
2260 int tok
= XmlContentTok(enc
, s
, end
, &next
);
2263 case XML_TOK_TRAILING_CR
:
2266 return XML_ERROR_NONE
;
2269 if (characterDataHandler
) {
2271 characterDataHandler(handlerArg
, &c
, 1);
2273 else if (defaultHandler
)
2274 reportDefault(parser
, enc
, s
, end
);
2275 /* We are at the end of the final buffer, should we check for
2276 XML_SUSPENDED, XML_FINISHED?
2278 if (startTagLevel
== 0)
2279 return XML_ERROR_NO_ELEMENTS
;
2280 if (tagLevel
!= startTagLevel
)
2281 return XML_ERROR_ASYNC_ENTITY
;
2283 return XML_ERROR_NONE
;
2287 return XML_ERROR_NONE
;
2289 if (startTagLevel
> 0) {
2290 if (tagLevel
!= startTagLevel
)
2291 return XML_ERROR_ASYNC_ENTITY
;
2293 return XML_ERROR_NONE
;
2295 return XML_ERROR_NO_ELEMENTS
;
2296 case XML_TOK_INVALID
:
2298 return XML_ERROR_INVALID_TOKEN
;
2299 case XML_TOK_PARTIAL
:
2302 return XML_ERROR_NONE
;
2304 return XML_ERROR_UNCLOSED_TOKEN
;
2305 case XML_TOK_PARTIAL_CHAR
:
2308 return XML_ERROR_NONE
;
2310 return XML_ERROR_PARTIAL_CHAR
;
2311 case XML_TOK_ENTITY_REF
:
2313 const XML_Char
*name
;
2315 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
2316 s
+ enc
->minBytesPerChar
,
2317 next
- enc
->minBytesPerChar
);
2319 if (characterDataHandler
)
2320 characterDataHandler(handlerArg
, &ch
, 1);
2321 else if (defaultHandler
)
2322 reportDefault(parser
, enc
, s
, next
);
2325 name
= poolStoreString(&dtd
->pool
, enc
,
2326 s
+ enc
->minBytesPerChar
,
2327 next
- enc
->minBytesPerChar
);
2329 return XML_ERROR_NO_MEMORY
;
2330 entity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
, 0);
2331 poolDiscard(&dtd
->pool
);
2332 /* First, determine if a check for an existing declaration is needed;
2333 if yes, check that the entity exists, and that it is internal,
2334 otherwise call the skipped entity or default handler.
2336 if (!dtd
->hasParamEntityRefs
|| dtd
->standalone
) {
2338 return XML_ERROR_UNDEFINED_ENTITY
;
2339 else if (!entity
->is_internal
)
2340 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
2343 if (skippedEntityHandler
)
2344 skippedEntityHandler(handlerArg
, name
, 0);
2345 else if (defaultHandler
)
2346 reportDefault(parser
, enc
, s
, next
);
2350 return XML_ERROR_RECURSIVE_ENTITY_REF
;
2351 if (entity
->notation
)
2352 return XML_ERROR_BINARY_ENTITY_REF
;
2353 if (entity
->textPtr
) {
2354 enum XML_Error result
;
2355 if (!defaultExpandInternalEntities
) {
2356 if (skippedEntityHandler
)
2357 skippedEntityHandler(handlerArg
, entity
->name
, 0);
2358 else if (defaultHandler
)
2359 reportDefault(parser
, enc
, s
, next
);
2362 result
= processInternalEntity(parser
, entity
, XML_FALSE
);
2363 if (result
!= XML_ERROR_NONE
)
2366 else if (externalEntityRefHandler
) {
2367 const XML_Char
*context
;
2368 entity
->open
= XML_TRUE
;
2369 context
= getContext(parser
);
2370 entity
->open
= XML_FALSE
;
2372 return XML_ERROR_NO_MEMORY
;
2373 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
2378 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
2379 poolDiscard(&tempPool
);
2381 else if (defaultHandler
)
2382 reportDefault(parser
, enc
, s
, next
);
2385 case XML_TOK_START_TAG_NO_ATTS
:
2387 case XML_TOK_START_TAG_WITH_ATTS
:
2390 enum XML_Error result
;
2394 freeTagList
= freeTagList
->parent
;
2397 tag
= (TAG
*)MALLOC(sizeof(TAG
));
2399 return XML_ERROR_NO_MEMORY
;
2400 tag
->buf
= (char *)MALLOC(INIT_TAG_BUF_SIZE
);
2403 return XML_ERROR_NO_MEMORY
;
2405 tag
->bufEnd
= tag
->buf
+ INIT_TAG_BUF_SIZE
;
2407 tag
->bindings
= NULL
;
2408 tag
->parent
= tagStack
;
2410 tag
->name
.localPart
= NULL
;
2411 tag
->name
.prefix
= NULL
;
2412 tag
->rawName
= s
+ enc
->minBytesPerChar
;
2413 tag
->rawNameLength
= XmlNameLength(enc
, tag
->rawName
);
2416 const char *rawNameEnd
= tag
->rawName
+ tag
->rawNameLength
;
2417 const char *fromPtr
= tag
->rawName
;
2418 toPtr
= (XML_Char
*)tag
->buf
;
2423 &fromPtr
, rawNameEnd
,
2424 (ICHAR
**)&toPtr
, (ICHAR
*)tag
->bufEnd
- 1);
2425 convLen
= (int)(toPtr
- (XML_Char
*)tag
->buf
);
2426 if (fromPtr
== rawNameEnd
) {
2427 tag
->name
.strLen
= convLen
;
2430 bufSize
= (int)(tag
->bufEnd
- tag
->buf
) << 1;
2432 char *temp
= (char *)REALLOC(tag
->buf
, bufSize
);
2434 return XML_ERROR_NO_MEMORY
;
2436 tag
->bufEnd
= temp
+ bufSize
;
2437 toPtr
= (XML_Char
*)temp
+ convLen
;
2441 tag
->name
.str
= (XML_Char
*)tag
->buf
;
2442 *toPtr
= XML_T('\0');
2443 result
= storeAtts(parser
, enc
, s
, &(tag
->name
), &(tag
->bindings
));
2446 if (startElementHandler
)
2447 startElementHandler(handlerArg
, tag
->name
.str
,
2448 (const XML_Char
**)atts
);
2449 else if (defaultHandler
)
2450 reportDefault(parser
, enc
, s
, next
);
2451 poolClear(&tempPool
);
2454 case XML_TOK_EMPTY_ELEMENT_NO_ATTS
:
2456 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS
:
2458 const char *rawName
= s
+ enc
->minBytesPerChar
;
2459 enum XML_Error result
;
2460 BINDING
*bindings
= NULL
;
2461 XML_Bool noElmHandlers
= XML_TRUE
;
2463 name
.str
= poolStoreString(&tempPool
, enc
, rawName
,
2464 rawName
+ XmlNameLength(enc
, rawName
));
2466 return XML_ERROR_NO_MEMORY
;
2467 poolFinish(&tempPool
);
2468 result
= storeAtts(parser
, enc
, s
, &name
, &bindings
);
2471 poolFinish(&tempPool
);
2472 if (startElementHandler
) {
2473 startElementHandler(handlerArg
, name
.str
, (const XML_Char
**)atts
);
2474 noElmHandlers
= XML_FALSE
;
2476 if (endElementHandler
) {
2477 if (startElementHandler
)
2478 *eventPP
= *eventEndPP
;
2479 endElementHandler(handlerArg
, name
.str
);
2480 noElmHandlers
= XML_FALSE
;
2482 if (noElmHandlers
&& defaultHandler
)
2483 reportDefault(parser
, enc
, s
, next
);
2484 poolClear(&tempPool
);
2486 BINDING
*b
= bindings
;
2487 if (endNamespaceDeclHandler
)
2488 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2489 bindings
= bindings
->nextTagBinding
;
2490 b
->nextTagBinding
= freeBindingList
;
2491 freeBindingList
= b
;
2492 b
->prefix
->binding
= b
->prevPrefixBinding
;
2496 return epilogProcessor(parser
, next
, end
, nextPtr
);
2498 case XML_TOK_END_TAG
:
2499 if (tagLevel
== startTagLevel
)
2500 return XML_ERROR_ASYNC_ENTITY
;
2503 const char *rawName
;
2504 TAG
*tag
= tagStack
;
2505 tagStack
= tag
->parent
;
2506 tag
->parent
= freeTagList
;
2508 rawName
= s
+ enc
->minBytesPerChar
*2;
2509 len
= XmlNameLength(enc
, rawName
);
2510 if (len
!= tag
->rawNameLength
2511 || memcmp(tag
->rawName
, rawName
, len
) != 0) {
2513 return XML_ERROR_TAG_MISMATCH
;
2516 if (endElementHandler
) {
2517 const XML_Char
*localPart
;
2518 const XML_Char
*prefix
;
2520 localPart
= tag
->name
.localPart
;
2521 if (ns
&& localPart
) {
2522 /* localPart and prefix may have been overwritten in
2523 tag->name.str, since this points to the binding->uri
2524 buffer which gets re-used; so we have to add them again
2526 uri
= (XML_Char
*)tag
->name
.str
+ tag
->name
.uriLen
;
2527 /* don't need to check for space - already done in storeAtts() */
2528 while (*localPart
) *uri
++ = *localPart
++;
2529 prefix
= (XML_Char
*)tag
->name
.prefix
;
2530 if (ns_triplets
&& prefix
) {
2531 *uri
++ = namespaceSeparator
;
2532 while (*prefix
) *uri
++ = *prefix
++;
2536 endElementHandler(handlerArg
, tag
->name
.str
);
2538 else if (defaultHandler
)
2539 reportDefault(parser
, enc
, s
, next
);
2540 while (tag
->bindings
) {
2541 BINDING
*b
= tag
->bindings
;
2542 if (endNamespaceDeclHandler
)
2543 endNamespaceDeclHandler(handlerArg
, b
->prefix
->name
);
2544 tag
->bindings
= tag
->bindings
->nextTagBinding
;
2545 b
->nextTagBinding
= freeBindingList
;
2546 freeBindingList
= b
;
2547 b
->prefix
->binding
= b
->prevPrefixBinding
;
2550 return epilogProcessor(parser
, next
, end
, nextPtr
);
2553 case XML_TOK_CHAR_REF
:
2555 int n
= XmlCharRefNumber(enc
, s
);
2557 return XML_ERROR_BAD_CHAR_REF
;
2558 if (characterDataHandler
) {
2559 XML_Char buf
[XML_ENCODE_MAX
];
2560 characterDataHandler(handlerArg
, buf
, XmlEncode(n
, (ICHAR
*)buf
));
2562 else if (defaultHandler
)
2563 reportDefault(parser
, enc
, s
, next
);
2566 case XML_TOK_XML_DECL
:
2567 return XML_ERROR_MISPLACED_XML_PI
;
2568 case XML_TOK_DATA_NEWLINE
:
2569 if (characterDataHandler
) {
2571 characterDataHandler(handlerArg
, &c
, 1);
2573 else if (defaultHandler
)
2574 reportDefault(parser
, enc
, s
, next
);
2576 case XML_TOK_CDATA_SECT_OPEN
:
2578 enum XML_Error result
;
2579 if (startCdataSectionHandler
)
2580 startCdataSectionHandler(handlerArg
);
2582 /* Suppose you doing a transformation on a document that involves
2583 changing only the character data. You set up a defaultHandler
2584 and a characterDataHandler. The defaultHandler simply copies
2585 characters through. The characterDataHandler does the
2586 transformation and writes the characters out escaping them as
2587 necessary. This case will fail to work if we leave out the
2588 following two lines (because & and < inside CDATA sections will
2589 be incorrectly escaped).
2591 However, now we have a start/endCdataSectionHandler, so it seems
2592 easier to let the user deal with this.
2594 else if (characterDataHandler
)
2595 characterDataHandler(handlerArg
, dataBuf
, 0);
2597 else if (defaultHandler
)
2598 reportDefault(parser
, enc
, s
, next
);
2599 result
= doCdataSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
2600 if (result
!= XML_ERROR_NONE
)
2603 processor
= cdataSectionProcessor
;
2608 case XML_TOK_TRAILING_RSQB
:
2611 return XML_ERROR_NONE
;
2613 if (characterDataHandler
) {
2614 if (MUST_CONVERT(enc
, s
)) {
2615 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2616 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2617 characterDataHandler(handlerArg
, dataBuf
,
2618 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2621 characterDataHandler(handlerArg
,
2623 (int)((XML_Char
*)end
- (XML_Char
*)s
));
2625 else if (defaultHandler
)
2626 reportDefault(parser
, enc
, s
, end
);
2627 /* We are at the end of the final buffer, should we check for
2628 XML_SUSPENDED, XML_FINISHED?
2630 if (startTagLevel
== 0) {
2632 return XML_ERROR_NO_ELEMENTS
;
2634 if (tagLevel
!= startTagLevel
) {
2636 return XML_ERROR_ASYNC_ENTITY
;
2639 return XML_ERROR_NONE
;
2640 case XML_TOK_DATA_CHARS
:
2642 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
2643 if (charDataHandler
) {
2644 if (MUST_CONVERT(enc
, s
)) {
2646 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
2647 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
2649 charDataHandler(handlerArg
, dataBuf
,
2650 (int)(dataPtr
- (ICHAR
*)dataBuf
));
2657 charDataHandler(handlerArg
,
2659 (int)((XML_Char
*)next
- (XML_Char
*)s
));
2661 else if (defaultHandler
)
2662 reportDefault(parser
, enc
, s
, next
);
2666 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
2667 return XML_ERROR_NO_MEMORY
;
2669 case XML_TOK_COMMENT
:
2670 if (!reportComment(parser
, enc
, s
, next
))
2671 return XML_ERROR_NO_MEMORY
;
2675 reportDefault(parser
, enc
, s
, next
);
2678 *eventPP
= s
= next
;
2679 switch (ps_parsing
) {
2682 return XML_ERROR_NONE
;
2684 return XML_ERROR_ABORTED
;
2691 /* Precondition: all arguments must be non-NULL;
2693 - normalize attributes
2694 - check attributes for well-formedness
2695 - generate namespace aware attribute names (URI, prefix)
2696 - build list of attributes for startElementHandler
2697 - default attributes
2698 - process namespace declarations (check and report them)
2699 - generate namespace aware element name (URI, prefix)
2701 static enum XML_Error
2702 storeAtts(XML_Parser parser
, const ENCODING
*enc
,
2703 const char *attStr
, TAG_NAME
*tagNamePtr
,
2704 BINDING
**bindingsPtr
)
2706 DTD
* const dtd
= _dtd
; /* save one level of indirection */
2707 ELEMENT_TYPE
*elementType
;
2709 const XML_Char
**appAtts
; /* the attribute list for the application */
2717 const XML_Char
*localPart
;
2719 /* lookup the element type name */
2720 elementType
= (ELEMENT_TYPE
*)lookup(parser
, &dtd
->elementTypes
, tagNamePtr
->str
,0);
2722 const XML_Char
*name
= poolCopyString(&dtd
->pool
, tagNamePtr
->str
);
2724 return XML_ERROR_NO_MEMORY
;
2725 elementType
= (ELEMENT_TYPE
*)lookup(parser
, &dtd
->elementTypes
, name
,
2726 sizeof(ELEMENT_TYPE
));
2728 return XML_ERROR_NO_MEMORY
;
2729 if (ns
&& !setElementTypePrefix(parser
, elementType
))
2730 return XML_ERROR_NO_MEMORY
;
2732 nDefaultAtts
= elementType
->nDefaultAtts
;
2734 /* get the attributes from the tokenizer */
2735 n
= XmlGetAttributes(enc
, attStr
, attsSize
, atts
);
2736 if (n
+ nDefaultAtts
> attsSize
) {
2737 int oldAttsSize
= attsSize
;
2739 #ifdef XML_ATTR_INFO
2740 XML_AttrInfo
*temp2
;
2742 attsSize
= n
+ nDefaultAtts
+ INIT_ATTS_SIZE
;
2743 temp
= (ATTRIBUTE
*)REALLOC((void *)atts
, attsSize
* sizeof(ATTRIBUTE
));
2745 return XML_ERROR_NO_MEMORY
;
2747 #ifdef XML_ATTR_INFO
2748 temp2
= (XML_AttrInfo
*)REALLOC((void *)attInfo
, attsSize
* sizeof(XML_AttrInfo
));
2750 return XML_ERROR_NO_MEMORY
;
2753 if (n
> oldAttsSize
)
2754 XmlGetAttributes(enc
, attStr
, n
, atts
);
2757 appAtts
= (const XML_Char
**)atts
;
2758 for (i
= 0; i
< n
; i
++) {
2759 ATTRIBUTE
*currAtt
= &atts
[i
];
2760 #ifdef XML_ATTR_INFO
2761 XML_AttrInfo
*currAttInfo
= &attInfo
[i
];
2763 /* add the name and value to the attribute list */
2764 ATTRIBUTE_ID
*attId
= getAttributeId(parser
, enc
, currAtt
->name
,
2766 + XmlNameLength(enc
, currAtt
->name
));
2768 return XML_ERROR_NO_MEMORY
;
2769 #ifdef XML_ATTR_INFO
2770 currAttInfo
->nameStart
= parseEndByteIndex
- (parseEndPtr
- currAtt
->name
);
2771 currAttInfo
->nameEnd
= currAttInfo
->nameStart
+
2772 XmlNameLength(enc
, currAtt
->name
);
2773 currAttInfo
->valueStart
= parseEndByteIndex
-
2774 (parseEndPtr
- currAtt
->valuePtr
);
2775 currAttInfo
->valueEnd
= parseEndByteIndex
- (parseEndPtr
- currAtt
->valueEnd
);
2777 /* Detect duplicate attributes by their QNames. This does not work when
2778 namespace processing is turned on and different prefixes for the same
2779 namespace are used. For this case we have a check further down.
2781 if ((attId
->name
)[-1]) {
2782 if (enc
== encoding
)
2783 eventPtr
= atts
[i
].name
;
2784 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2786 (attId
->name
)[-1] = 1;
2787 appAtts
[attIndex
++] = attId
->name
;
2788 if (!atts
[i
].normalized
) {
2789 enum XML_Error result
;
2790 XML_Bool isCdata
= XML_TRUE
;
2792 /* figure out whether declared as other than CDATA */
2793 if (attId
->maybeTokenized
) {
2795 for (j
= 0; j
< nDefaultAtts
; j
++) {
2796 if (attId
== elementType
->defaultAtts
[j
].id
) {
2797 isCdata
= elementType
->defaultAtts
[j
].isCdata
;
2803 /* normalize the attribute value */
2804 result
= storeAttributeValue(parser
, enc
, isCdata
,
2805 atts
[i
].valuePtr
, atts
[i
].valueEnd
,
2809 appAtts
[attIndex
] = poolStart(&tempPool
);
2810 poolFinish(&tempPool
);
2813 /* the value did not need normalizing */
2814 appAtts
[attIndex
] = poolStoreString(&tempPool
, enc
, atts
[i
].valuePtr
,
2816 if (appAtts
[attIndex
] == 0)
2817 return XML_ERROR_NO_MEMORY
;
2818 poolFinish(&tempPool
);
2820 /* handle prefixed attribute names */
2821 if (attId
->prefix
) {
2823 /* deal with namespace declarations here */
2824 enum XML_Error result
= addBinding(parser
, attId
->prefix
, attId
,
2825 appAtts
[attIndex
], bindingsPtr
);
2831 /* deal with other prefixed names later */
2834 (attId
->name
)[-1] = 2;
2841 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2842 nSpecifiedAtts
= attIndex
;
2843 if (elementType
->idAtt
&& (elementType
->idAtt
->name
)[-1]) {
2844 for (i
= 0; i
< attIndex
; i
+= 2)
2845 if (appAtts
[i
] == elementType
->idAtt
->name
) {
2853 /* do attribute defaulting */
2854 for (i
= 0; i
< nDefaultAtts
; i
++) {
2855 const DEFAULT_ATTRIBUTE
*da
= elementType
->defaultAtts
+ i
;
2856 if (!(da
->id
->name
)[-1] && da
->value
) {
2857 if (da
->id
->prefix
) {
2858 if (da
->id
->xmlns
) {
2859 enum XML_Error result
= addBinding(parser
, da
->id
->prefix
, da
->id
,
2860 da
->value
, bindingsPtr
);
2865 (da
->id
->name
)[-1] = 2;
2867 appAtts
[attIndex
++] = da
->id
->name
;
2868 appAtts
[attIndex
++] = da
->value
;
2872 (da
->id
->name
)[-1] = 1;
2873 appAtts
[attIndex
++] = da
->id
->name
;
2874 appAtts
[attIndex
++] = da
->value
;
2878 appAtts
[attIndex
] = 0;
2880 /* expand prefixed attribute names, check for duplicates,
2881 and clear flags that say whether attributes were specified */
2884 int j
; /* hash table index */
2885 unsigned long version
= nsAttsVersion
;
2886 int nsAttsSize
= (int)1 << nsAttsPower
;
2887 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2888 if ((nPrefixes
<< 1) >> nsAttsPower
) { /* true for nsAttsPower = 0 */
2890 /* hash table size must also be a power of 2 and >= 8 */
2891 while (nPrefixes
>> nsAttsPower
++);
2892 if (nsAttsPower
< 3)
2894 nsAttsSize
= (int)1 << nsAttsPower
;
2895 temp
= (NS_ATT
*)REALLOC(nsAtts
, nsAttsSize
* sizeof(NS_ATT
));
2897 return XML_ERROR_NO_MEMORY
;
2899 version
= 0; /* force re-initialization of nsAtts hash table */
2901 /* using a version flag saves us from initializing nsAtts every time */
2902 if (!version
) { /* initialize version flags when version wraps around */
2903 version
= INIT_ATTS_VERSION
;
2904 for (j
= nsAttsSize
; j
!= 0; )
2905 nsAtts
[--j
].version
= version
;
2907 nsAttsVersion
= --version
;
2909 /* expand prefixed names and check for duplicates */
2910 for (; i
< attIndex
; i
+= 2) {
2911 const XML_Char
*s
= appAtts
[i
];
2912 if (s
[-1] == 2) { /* prefixed */
2915 unsigned long uriHash
= hash_secret_salt
;
2916 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2917 id
= (ATTRIBUTE_ID
*)lookup(parser
, &dtd
->attributeIds
, s
, 0);
2918 b
= id
->prefix
->binding
;
2920 return XML_ERROR_UNBOUND_PREFIX
;
2922 /* as we expand the name we also calculate its hash value */
2923 for (j
= 0; j
< b
->uriLen
; j
++) {
2924 const XML_Char c
= b
->uri
[j
];
2925 if (!poolAppendChar(&tempPool
, c
))
2926 return XML_ERROR_NO_MEMORY
;
2927 uriHash
= CHAR_HASH(uriHash
, c
);
2929 while (*s
++ != XML_T(ASCII_COLON
))
2931 do { /* copies null terminator */
2932 const XML_Char c
= *s
;
2933 if (!poolAppendChar(&tempPool
, *s
))
2934 return XML_ERROR_NO_MEMORY
;
2935 uriHash
= CHAR_HASH(uriHash
, c
);
2938 { /* Check hash table for duplicate of expanded name (uriName).
2939 Derived from code in lookup(parser, HASH_TABLE *table, ...).
2941 unsigned char step
= 0;
2942 unsigned long mask
= nsAttsSize
- 1;
2943 j
= uriHash
& mask
; /* index into hash table */
2944 while (nsAtts
[j
].version
== version
) {
2945 /* for speed we compare stored hash values first */
2946 if (uriHash
== nsAtts
[j
].hash
) {
2947 const XML_Char
*s1
= poolStart(&tempPool
);
2948 const XML_Char
*s2
= nsAtts
[j
].uriName
;
2949 /* s1 is null terminated, but not s2 */
2950 for (; *s1
== *s2
&& *s1
!= 0; s1
++, s2
++);
2952 return XML_ERROR_DUPLICATE_ATTRIBUTE
;
2955 step
= PROBE_STEP(uriHash
, mask
, nsAttsPower
);
2956 j
< step
? (j
+= nsAttsSize
- step
) : (j
-= step
);
2960 if (ns_triplets
) { /* append namespace separator and prefix */
2961 tempPool
.ptr
[-1] = namespaceSeparator
;
2962 s
= b
->prefix
->name
;
2964 if (!poolAppendChar(&tempPool
, *s
))
2965 return XML_ERROR_NO_MEMORY
;
2969 /* store expanded name in attribute list */
2970 s
= poolStart(&tempPool
);
2971 poolFinish(&tempPool
);
2974 /* fill empty slot with new version, uriName and hash value */
2975 nsAtts
[j
].version
= version
;
2976 nsAtts
[j
].hash
= uriHash
;
2977 nsAtts
[j
].uriName
= s
;
2984 else /* not prefixed */
2985 ((XML_Char
*)s
)[-1] = 0; /* clear flag */
2988 /* clear flags for the remaining attributes */
2989 for (; i
< attIndex
; i
+= 2)
2990 ((XML_Char
*)(appAtts
[i
]))[-1] = 0;
2991 for (binding
= *bindingsPtr
; binding
; binding
= binding
->nextTagBinding
)
2992 binding
->attId
->name
[-1] = 0;
2995 return XML_ERROR_NONE
;
2997 /* expand the element type name */
2998 if (elementType
->prefix
) {
2999 binding
= elementType
->prefix
->binding
;
3001 return XML_ERROR_UNBOUND_PREFIX
;
3002 localPart
= tagNamePtr
->str
;
3003 while (*localPart
++ != XML_T(ASCII_COLON
))
3006 else if (dtd
->defaultPrefix
.binding
) {
3007 binding
= dtd
->defaultPrefix
.binding
;
3008 localPart
= tagNamePtr
->str
;
3011 return XML_ERROR_NONE
;
3013 if (ns_triplets
&& binding
->prefix
->name
) {
3014 for (; binding
->prefix
->name
[prefixLen
++];)
3015 ; /* prefixLen includes null terminator */
3017 tagNamePtr
->localPart
= localPart
;
3018 tagNamePtr
->uriLen
= binding
->uriLen
;
3019 tagNamePtr
->prefix
= binding
->prefix
->name
;
3020 tagNamePtr
->prefixLen
= prefixLen
;
3021 for (i
= 0; localPart
[i
++];)
3022 ; /* i includes null terminator */
3023 n
= i
+ binding
->uriLen
+ prefixLen
;
3024 if (n
> binding
->uriAlloc
) {
3026 uri
= (XML_Char
*)MALLOC((n
+ EXPAND_SPARE
) * sizeof(XML_Char
));
3028 return XML_ERROR_NO_MEMORY
;
3029 binding
->uriAlloc
= n
+ EXPAND_SPARE
;
3030 memcpy(uri
, binding
->uri
, binding
->uriLen
* sizeof(XML_Char
));
3031 for (p
= tagStack
; p
; p
= p
->parent
)
3032 if (p
->name
.str
== binding
->uri
)
3037 /* if namespaceSeparator != '\0' then uri includes it already */
3038 uri
= binding
->uri
+ binding
->uriLen
;
3039 memcpy(uri
, localPart
, i
* sizeof(XML_Char
));
3040 /* we always have a namespace separator between localPart and prefix */
3043 *uri
= namespaceSeparator
; /* replace null terminator */
3044 memcpy(uri
+ 1, binding
->prefix
->name
, prefixLen
* sizeof(XML_Char
));
3046 tagNamePtr
->str
= binding
->uri
;
3047 return XML_ERROR_NONE
;
3050 /* addBinding() overwrites the value of prefix->binding without checking.
3051 Therefore one must keep track of the old value outside of addBinding().
3053 static enum XML_Error
3054 addBinding(XML_Parser parser
, PREFIX
*prefix
, const ATTRIBUTE_ID
*attId
,
3055 const XML_Char
*uri
, BINDING
**bindingsPtr
)
3057 static const XML_Char xmlNamespace
[] = {
3058 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
3059 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
3060 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_X
, ASCII_M
, ASCII_L
,
3061 ASCII_SLASH
, ASCII_1
, ASCII_9
, ASCII_9
, ASCII_8
, ASCII_SLASH
,
3062 ASCII_n
, ASCII_a
, ASCII_m
, ASCII_e
, ASCII_s
, ASCII_p
, ASCII_a
, ASCII_c
,
3065 static const int xmlLen
=
3066 (int)sizeof(xmlNamespace
)/sizeof(XML_Char
) - 1;
3067 static const XML_Char xmlnsNamespace
[] = {
3068 ASCII_h
, ASCII_t
, ASCII_t
, ASCII_p
, ASCII_COLON
, ASCII_SLASH
, ASCII_SLASH
,
3069 ASCII_w
, ASCII_w
, ASCII_w
, ASCII_PERIOD
, ASCII_w
, ASCII_3
, ASCII_PERIOD
,
3070 ASCII_o
, ASCII_r
, ASCII_g
, ASCII_SLASH
, ASCII_2
, ASCII_0
, ASCII_0
,
3071 ASCII_0
, ASCII_SLASH
, ASCII_x
, ASCII_m
, ASCII_l
, ASCII_n
, ASCII_s
,
3074 static const int xmlnsLen
=
3075 (int)sizeof(xmlnsNamespace
)/sizeof(XML_Char
) - 1;
3077 XML_Bool mustBeXML
= XML_FALSE
;
3078 XML_Bool isXML
= XML_TRUE
;
3079 XML_Bool isXMLNS
= XML_TRUE
;
3084 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3085 if (*uri
== XML_T('\0') && prefix
->name
)
3086 return XML_ERROR_UNDECLARING_PREFIX
;
3089 && prefix
->name
[0] == XML_T(ASCII_x
)
3090 && prefix
->name
[1] == XML_T(ASCII_m
)
3091 && prefix
->name
[2] == XML_T(ASCII_l
)) {
3093 /* Not allowed to bind xmlns */
3094 if (prefix
->name
[3] == XML_T(ASCII_n
)
3095 && prefix
->name
[4] == XML_T(ASCII_s
)
3096 && prefix
->name
[5] == XML_T('\0'))
3097 return XML_ERROR_RESERVED_PREFIX_XMLNS
;
3099 if (prefix
->name
[3] == XML_T('\0'))
3100 mustBeXML
= XML_TRUE
;
3103 for (len
= 0; uri
[len
]; len
++) {
3104 if (isXML
&& (len
> xmlLen
|| uri
[len
] != xmlNamespace
[len
]))
3107 if (!mustBeXML
&& isXMLNS
3108 && (len
> xmlnsLen
|| uri
[len
] != xmlnsNamespace
[len
]))
3109 isXMLNS
= XML_FALSE
;
3111 isXML
= isXML
&& len
== xmlLen
;
3112 isXMLNS
= isXMLNS
&& len
== xmlnsLen
;
3114 if (mustBeXML
!= isXML
)
3115 return mustBeXML
? XML_ERROR_RESERVED_PREFIX_XML
3116 : XML_ERROR_RESERVED_NAMESPACE_URI
;
3119 return XML_ERROR_RESERVED_NAMESPACE_URI
;
3121 if (namespaceSeparator
)
3123 if (freeBindingList
) {
3124 b
= freeBindingList
;
3125 if (len
> b
->uriAlloc
) {
3126 XML_Char
*temp
= (XML_Char
*)REALLOC(b
->uri
,
3127 sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3129 return XML_ERROR_NO_MEMORY
;
3131 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3133 freeBindingList
= b
->nextTagBinding
;
3136 b
= (BINDING
*)MALLOC(sizeof(BINDING
));
3138 return XML_ERROR_NO_MEMORY
;
3139 b
->uri
= (XML_Char
*)MALLOC(sizeof(XML_Char
) * (len
+ EXPAND_SPARE
));
3142 return XML_ERROR_NO_MEMORY
;
3144 b
->uriAlloc
= len
+ EXPAND_SPARE
;
3147 memcpy(b
->uri
, uri
, len
* sizeof(XML_Char
));
3148 if (namespaceSeparator
)
3149 b
->uri
[len
- 1] = namespaceSeparator
;
3152 b
->prevPrefixBinding
= prefix
->binding
;
3153 /* NULL binding when default namespace undeclared */
3154 if (*uri
== XML_T('\0') && prefix
== &_dtd
->defaultPrefix
)
3155 prefix
->binding
= NULL
;
3157 prefix
->binding
= b
;
3158 b
->nextTagBinding
= *bindingsPtr
;
3160 /* if attId == NULL then we are not starting a namespace scope */
3161 if (attId
&& startNamespaceDeclHandler
)
3162 startNamespaceDeclHandler(handlerArg
, prefix
->name
,
3163 prefix
->binding
? uri
: 0);
3164 return XML_ERROR_NONE
;
3167 /* The idea here is to avoid using stack for each CDATA section when
3168 the whole file is parsed with one call.
3170 static enum XML_Error PTRCALL
3171 cdataSectionProcessor(XML_Parser parser
,
3174 const char **endPtr
)
3176 enum XML_Error result
= doCdataSection(parser
, encoding
, &start
, end
,
3177 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3178 if (result
!= XML_ERROR_NONE
)
3181 if (parentParser
) { /* we are parsing an external entity */
3182 processor
= externalEntityContentProcessor
;
3183 return externalEntityContentProcessor(parser
, start
, end
, endPtr
);
3186 processor
= contentProcessor
;
3187 return contentProcessor(parser
, start
, end
, endPtr
);
3193 /* startPtr gets set to non-null if the section is closed, and to null if
3194 the section is not yet closed.
3196 static enum XML_Error
3197 doCdataSection(XML_Parser parser
,
3198 const ENCODING
*enc
,
3199 const char **startPtr
,
3201 const char **nextPtr
,
3204 const char *s
= *startPtr
;
3205 const char **eventPP
;
3206 const char **eventEndPP
;
3207 if (enc
== encoding
) {
3208 eventPP
= &eventPtr
;
3210 eventEndPP
= &eventEndPtr
;
3213 eventPP
= &(openInternalEntities
->internalEventPtr
);
3214 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3221 int tok
= XmlCdataSectionTok(enc
, s
, end
, &next
);
3224 case XML_TOK_CDATA_SECT_CLOSE
:
3225 if (endCdataSectionHandler
)
3226 endCdataSectionHandler(handlerArg
);
3228 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3229 else if (characterDataHandler
)
3230 characterDataHandler(handlerArg
, dataBuf
, 0);
3232 else if (defaultHandler
)
3233 reportDefault(parser
, enc
, s
, next
);
3236 if (ps_parsing
== XML_FINISHED
)
3237 return XML_ERROR_ABORTED
;
3239 return XML_ERROR_NONE
;
3240 case XML_TOK_DATA_NEWLINE
:
3241 if (characterDataHandler
) {
3243 characterDataHandler(handlerArg
, &c
, 1);
3245 else if (defaultHandler
)
3246 reportDefault(parser
, enc
, s
, next
);
3248 case XML_TOK_DATA_CHARS
:
3250 XML_CharacterDataHandler charDataHandler
= characterDataHandler
;
3251 if (charDataHandler
) {
3252 if (MUST_CONVERT(enc
, s
)) {
3254 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
3255 XmlConvert(enc
, &s
, next
, &dataPtr
, (ICHAR
*)dataBufEnd
);
3257 charDataHandler(handlerArg
, dataBuf
,
3258 (int)(dataPtr
- (ICHAR
*)dataBuf
));
3265 charDataHandler(handlerArg
,
3267 (int)((XML_Char
*)next
- (XML_Char
*)s
));
3269 else if (defaultHandler
)
3270 reportDefault(parser
, enc
, s
, next
);
3273 case XML_TOK_INVALID
:
3275 return XML_ERROR_INVALID_TOKEN
;
3276 case XML_TOK_PARTIAL_CHAR
:
3279 return XML_ERROR_NONE
;
3281 return XML_ERROR_PARTIAL_CHAR
;
3282 case XML_TOK_PARTIAL
:
3286 return XML_ERROR_NONE
;
3288 return XML_ERROR_UNCLOSED_CDATA_SECTION
;
3291 return XML_ERROR_UNEXPECTED_STATE
;
3294 *eventPP
= s
= next
;
3295 switch (ps_parsing
) {
3298 return XML_ERROR_NONE
;
3300 return XML_ERROR_ABORTED
;
3309 /* The idea here is to avoid using stack for each IGNORE section when
3310 the whole file is parsed with one call.
3312 static enum XML_Error PTRCALL
3313 ignoreSectionProcessor(XML_Parser parser
,
3316 const char **endPtr
)
3318 enum XML_Error result
= doIgnoreSection(parser
, encoding
, &start
, end
,
3319 endPtr
, (XML_Bool
)!ps_finalBuffer
);
3320 if (result
!= XML_ERROR_NONE
)
3323 processor
= prologProcessor
;
3324 return prologProcessor(parser
, start
, end
, endPtr
);
3329 /* startPtr gets set to non-null is the section is closed, and to null
3330 if the section is not yet closed.
3332 static enum XML_Error
3333 doIgnoreSection(XML_Parser parser
,
3334 const ENCODING
*enc
,
3335 const char **startPtr
,
3337 const char **nextPtr
,
3342 const char *s
= *startPtr
;
3343 const char **eventPP
;
3344 const char **eventEndPP
;
3345 if (enc
== encoding
) {
3346 eventPP
= &eventPtr
;
3348 eventEndPP
= &eventEndPtr
;
3351 eventPP
= &(openInternalEntities
->internalEventPtr
);
3352 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3356 tok
= XmlIgnoreSectionTok(enc
, s
, end
, &next
);
3359 case XML_TOK_IGNORE_SECT
:
3361 reportDefault(parser
, enc
, s
, next
);
3364 if (ps_parsing
== XML_FINISHED
)
3365 return XML_ERROR_ABORTED
;
3367 return XML_ERROR_NONE
;
3368 case XML_TOK_INVALID
:
3370 return XML_ERROR_INVALID_TOKEN
;
3371 case XML_TOK_PARTIAL_CHAR
:
3374 return XML_ERROR_NONE
;
3376 return XML_ERROR_PARTIAL_CHAR
;
3377 case XML_TOK_PARTIAL
:
3381 return XML_ERROR_NONE
;
3383 return XML_ERROR_SYNTAX
; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3386 return XML_ERROR_UNEXPECTED_STATE
;
3391 #endif /* XML_DTD */
3393 static enum XML_Error
3394 initializeEncoding(XML_Parser parser
)
3398 char encodingBuf
[128];
3399 if (!protocolEncodingName
)
3403 for (i
= 0; protocolEncodingName
[i
]; i
++) {
3404 if (i
== sizeof(encodingBuf
) - 1
3405 || (protocolEncodingName
[i
] & ~0x7f) != 0) {
3406 encodingBuf
[0] = '\0';
3409 encodingBuf
[i
] = (char)protocolEncodingName
[i
];
3411 encodingBuf
[i
] = '\0';
3415 s
= protocolEncodingName
;
3417 if ((ns
? XmlInitEncodingNS
: XmlInitEncoding
)(&initEncoding
, &encoding
, s
))
3418 return XML_ERROR_NONE
;
3419 return handleUnknownEncoding(parser
, protocolEncodingName
);
3422 static enum XML_Error
3423 processXmlDecl(XML_Parser parser
, int isGeneralTextEntity
,
3424 const char *s
, const char *next
)
3426 const char *encodingName
= NULL
;
3427 const XML_Char
*storedEncName
= NULL
;
3428 const ENCODING
*newEncoding
= NULL
;
3429 const char *version
= NULL
;
3430 const char *versionend
;
3431 const XML_Char
*storedversion
= NULL
;
3432 int standalone
= -1;
3435 : XmlParseXmlDecl
)(isGeneralTextEntity
,
3445 if (isGeneralTextEntity
)
3446 return XML_ERROR_TEXT_DECL
;
3448 return XML_ERROR_XML_DECL
;
3450 if (!isGeneralTextEntity
&& standalone
== 1) {
3451 _dtd
->standalone
= XML_TRUE
;
3453 if (paramEntityParsing
== XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE
)
3454 paramEntityParsing
= XML_PARAM_ENTITY_PARSING_NEVER
;
3455 #endif /* XML_DTD */
3457 if (xmlDeclHandler
) {
3458 if (encodingName
!= NULL
) {
3459 storedEncName
= poolStoreString(&temp2Pool
,
3463 + XmlNameLength(encoding
, encodingName
));
3465 return XML_ERROR_NO_MEMORY
;
3466 poolFinish(&temp2Pool
);
3469 storedversion
= poolStoreString(&temp2Pool
,
3472 versionend
- encoding
->minBytesPerChar
);
3474 return XML_ERROR_NO_MEMORY
;
3476 xmlDeclHandler(handlerArg
, storedversion
, storedEncName
, standalone
);
3478 else if (defaultHandler
)
3479 reportDefault(parser
, encoding
, s
, next
);
3480 if (protocolEncodingName
== NULL
) {
3482 if (newEncoding
->minBytesPerChar
!= encoding
->minBytesPerChar
) {
3483 eventPtr
= encodingName
;
3484 return XML_ERROR_INCORRECT_ENCODING
;
3486 encoding
= newEncoding
;
3488 else if (encodingName
) {
3489 enum XML_Error result
;
3490 if (!storedEncName
) {
3491 storedEncName
= poolStoreString(
3492 &temp2Pool
, encoding
, encodingName
,
3493 encodingName
+ XmlNameLength(encoding
, encodingName
));
3495 return XML_ERROR_NO_MEMORY
;
3497 result
= handleUnknownEncoding(parser
, storedEncName
);
3498 poolClear(&temp2Pool
);
3499 if (result
== XML_ERROR_UNKNOWN_ENCODING
)
3500 eventPtr
= encodingName
;
3505 if (storedEncName
|| storedversion
)
3506 poolClear(&temp2Pool
);
3508 return XML_ERROR_NONE
;
3511 static enum XML_Error
3512 handleUnknownEncoding(XML_Parser parser
, const XML_Char
*encodingName
)
3514 if (unknownEncodingHandler
) {
3517 for (i
= 0; i
< 256; i
++)
3519 info
.convert
= NULL
;
3521 info
.release
= NULL
;
3522 if (unknownEncodingHandler(unknownEncodingHandlerData
, encodingName
,
3525 unknownEncodingMem
= MALLOC(XmlSizeOfUnknownEncoding());
3526 if (!unknownEncodingMem
) {
3528 info
.release(info
.data
);
3529 return XML_ERROR_NO_MEMORY
;
3532 ? XmlInitUnknownEncodingNS
3533 : XmlInitUnknownEncoding
)(unknownEncodingMem
,
3538 unknownEncodingData
= info
.data
;
3539 unknownEncodingRelease
= info
.release
;
3541 return XML_ERROR_NONE
;
3544 if (info
.release
!= NULL
)
3545 info
.release(info
.data
);
3547 return XML_ERROR_UNKNOWN_ENCODING
;
3550 static enum XML_Error PTRCALL
3551 prologInitProcessor(XML_Parser parser
,
3554 const char **nextPtr
)
3556 enum XML_Error result
= initializeEncoding(parser
);
3557 if (result
!= XML_ERROR_NONE
)
3559 processor
= prologProcessor
;
3560 return prologProcessor(parser
, s
, end
, nextPtr
);
3565 static enum XML_Error PTRCALL
3566 externalParEntInitProcessor(XML_Parser parser
,
3569 const char **nextPtr
)
3571 enum XML_Error result
= initializeEncoding(parser
);
3572 if (result
!= XML_ERROR_NONE
)
3575 /* we know now that XML_Parse(Buffer) has been called,
3576 so we consider the external parameter entity read */
3577 _dtd
->paramEntityRead
= XML_TRUE
;
3579 if (prologState
.inEntityValue
) {
3580 processor
= entityValueInitProcessor
;
3581 return entityValueInitProcessor(parser
, s
, end
, nextPtr
);
3584 processor
= externalParEntProcessor
;
3585 return externalParEntProcessor(parser
, s
, end
, nextPtr
);
3589 static enum XML_Error PTRCALL
3590 entityValueInitProcessor(XML_Parser parser
,
3593 const char **nextPtr
)
3596 const char *start
= s
;
3597 const char *next
= start
;
3601 tok
= XmlPrologTok(encoding
, start
, end
, &next
);
3604 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3606 return XML_ERROR_NONE
;
3609 case XML_TOK_INVALID
:
3610 return XML_ERROR_INVALID_TOKEN
;
3611 case XML_TOK_PARTIAL
:
3612 return XML_ERROR_UNCLOSED_TOKEN
;
3613 case XML_TOK_PARTIAL_CHAR
:
3614 return XML_ERROR_PARTIAL_CHAR
;
3615 case XML_TOK_NONE
: /* start == end */
3619 /* found end of entity value - can store it now */
3620 return storeEntityValue(parser
, encoding
, s
, end
);
3622 else if (tok
== XML_TOK_XML_DECL
) {
3623 enum XML_Error result
;
3624 result
= processXmlDecl(parser
, 0, start
, next
);
3625 if (result
!= XML_ERROR_NONE
)
3627 switch (ps_parsing
) {
3630 return XML_ERROR_NONE
;
3632 return XML_ERROR_ABORTED
;
3636 /* stop scanning for text declaration - we found one */
3637 processor
= entityValueProcessor
;
3638 return entityValueProcessor(parser
, next
, end
, nextPtr
);
3640 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3641 return XML_TOK_NONE on the next call, which would then cause the
3642 function to exit with *nextPtr set to s - that is what we want for other
3643 tokens, but not for the BOM - we would rather like to skip it;
3644 then, when this routine is entered the next time, XmlPrologTok will
3645 return XML_TOK_INVALID, since the BOM is still in the buffer
3647 else if (tok
== XML_TOK_BOM
&& next
== end
&& !ps_finalBuffer
) {
3649 return XML_ERROR_NONE
;
3656 static enum XML_Error PTRCALL
3657 externalParEntProcessor(XML_Parser parser
,
3660 const char **nextPtr
)
3662 const char *next
= s
;
3665 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3667 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3669 return XML_ERROR_NONE
;
3672 case XML_TOK_INVALID
:
3673 return XML_ERROR_INVALID_TOKEN
;
3674 case XML_TOK_PARTIAL
:
3675 return XML_ERROR_UNCLOSED_TOKEN
;
3676 case XML_TOK_PARTIAL_CHAR
:
3677 return XML_ERROR_PARTIAL_CHAR
;
3678 case XML_TOK_NONE
: /* start == end */
3683 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3684 However, when parsing an external subset, doProlog will not accept a BOM
3685 as valid, and report a syntax error, so we have to skip the BOM
3687 else if (tok
== XML_TOK_BOM
) {
3689 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3692 processor
= prologProcessor
;
3693 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3694 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3697 static enum XML_Error PTRCALL
3698 entityValueProcessor(XML_Parser parser
,
3701 const char **nextPtr
)
3703 const char *start
= s
;
3704 const char *next
= s
;
3705 const ENCODING
*enc
= encoding
;
3709 tok
= XmlPrologTok(enc
, start
, end
, &next
);
3711 if (!ps_finalBuffer
&& tok
!= XML_TOK_INVALID
) {
3713 return XML_ERROR_NONE
;
3716 case XML_TOK_INVALID
:
3717 return XML_ERROR_INVALID_TOKEN
;
3718 case XML_TOK_PARTIAL
:
3719 return XML_ERROR_UNCLOSED_TOKEN
;
3720 case XML_TOK_PARTIAL_CHAR
:
3721 return XML_ERROR_PARTIAL_CHAR
;
3722 case XML_TOK_NONE
: /* start == end */
3726 /* found end of entity value - can store it now */
3727 return storeEntityValue(parser
, enc
, s
, end
);
3733 #endif /* XML_DTD */
3735 static enum XML_Error PTRCALL
3736 prologProcessor(XML_Parser parser
,
3739 const char **nextPtr
)
3741 const char *next
= s
;
3742 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
3743 return doProlog(parser
, encoding
, s
, end
, tok
, next
,
3744 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
3747 static enum XML_Error
3748 doProlog(XML_Parser parser
,
3749 const ENCODING
*enc
,
3754 const char **nextPtr
,
3758 static const XML_Char externalSubsetName
[] = { ASCII_HASH
, '\0' };
3759 #endif /* XML_DTD */
3760 static const XML_Char atypeCDATA
[] =
3761 { ASCII_C
, ASCII_D
, ASCII_A
, ASCII_T
, ASCII_A
, '\0' };
3762 static const XML_Char atypeID
[] = { ASCII_I
, ASCII_D
, '\0' };
3763 static const XML_Char atypeIDREF
[] =
3764 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, '\0' };
3765 static const XML_Char atypeIDREFS
[] =
3766 { ASCII_I
, ASCII_D
, ASCII_R
, ASCII_E
, ASCII_F
, ASCII_S
, '\0' };
3767 static const XML_Char atypeENTITY
[] =
3768 { ASCII_E
, ASCII_N
, ASCII_T
, ASCII_I
, ASCII_T
, ASCII_Y
, '\0' };
3769 static const XML_Char atypeENTITIES
[] = { ASCII_E
, ASCII_N
,
3770 ASCII_T
, ASCII_I
, ASCII_T
, ASCII_I
, ASCII_E
, ASCII_S
, '\0' };
3771 static const XML_Char atypeNMTOKEN
[] = {
3772 ASCII_N
, ASCII_M
, ASCII_T
, ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, '\0' };
3773 static const XML_Char atypeNMTOKENS
[] = { ASCII_N
, ASCII_M
, ASCII_T
,
3774 ASCII_O
, ASCII_K
, ASCII_E
, ASCII_N
, ASCII_S
, '\0' };
3775 static const XML_Char notationPrefix
[] = { ASCII_N
, ASCII_O
, ASCII_T
,
3776 ASCII_A
, ASCII_T
, ASCII_I
, ASCII_O
, ASCII_N
, ASCII_LPAREN
, '\0' };
3777 static const XML_Char enumValueSep
[] = { ASCII_PIPE
, '\0' };
3778 static const XML_Char enumValueStart
[] = { ASCII_LPAREN
, '\0' };
3780 /* save one level of indirection */
3781 DTD
* const dtd
= _dtd
;
3783 const char **eventPP
;
3784 const char **eventEndPP
;
3785 enum XML_Content_Quant quant
;
3787 if (enc
== encoding
) {
3788 eventPP
= &eventPtr
;
3789 eventEndPP
= &eventEndPtr
;
3792 eventPP
= &(openInternalEntities
->internalEventPtr
);
3793 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
3798 XML_Bool handleDefault
= XML_TRUE
;
3802 if (haveMore
&& tok
!= XML_TOK_INVALID
) {
3804 return XML_ERROR_NONE
;
3807 case XML_TOK_INVALID
:
3809 return XML_ERROR_INVALID_TOKEN
;
3810 case XML_TOK_PARTIAL
:
3811 return XML_ERROR_UNCLOSED_TOKEN
;
3812 case XML_TOK_PARTIAL_CHAR
:
3813 return XML_ERROR_PARTIAL_CHAR
;
3814 case -XML_TOK_PROLOG_S
:
3819 /* for internal PE NOT referenced between declarations */
3820 if (enc
!= encoding
&& !openInternalEntities
->betweenDecl
) {
3822 return XML_ERROR_NONE
;
3824 /* WFC: PE Between Declarations - must check that PE contains
3825 complete markup, not only for external PEs, but also for
3826 internal PEs if the reference occurs between declarations.
3828 if (isParamEntity
|| enc
!= encoding
) {
3829 if (XmlTokenRole(&prologState
, XML_TOK_NONE
, end
, end
, enc
)
3831 return XML_ERROR_INCOMPLETE_PE
;
3833 return XML_ERROR_NONE
;
3835 #endif /* XML_DTD */
3836 return XML_ERROR_NO_ELEMENTS
;
3843 role
= XmlTokenRole(&prologState
, tok
, s
, next
, enc
);
3845 case XML_ROLE_XML_DECL
:
3847 enum XML_Error result
= processXmlDecl(parser
, 0, s
, next
);
3848 if (result
!= XML_ERROR_NONE
)
3851 handleDefault
= XML_FALSE
;
3854 case XML_ROLE_DOCTYPE_NAME
:
3855 if (startDoctypeDeclHandler
) {
3856 doctypeName
= poolStoreString(&tempPool
, enc
, s
, next
);
3858 return XML_ERROR_NO_MEMORY
;
3859 poolFinish(&tempPool
);
3860 doctypePubid
= NULL
;
3861 handleDefault
= XML_FALSE
;
3863 doctypeSysid
= NULL
; /* always initialize to NULL */
3865 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET
:
3866 if (startDoctypeDeclHandler
) {
3867 startDoctypeDeclHandler(handlerArg
, doctypeName
, doctypeSysid
,
3870 poolClear(&tempPool
);
3871 handleDefault
= XML_FALSE
;
3875 case XML_ROLE_TEXT_DECL
:
3877 enum XML_Error result
= processXmlDecl(parser
, 1, s
, next
);
3878 if (result
!= XML_ERROR_NONE
)
3881 handleDefault
= XML_FALSE
;
3884 #endif /* XML_DTD */
3885 case XML_ROLE_DOCTYPE_PUBLIC_ID
:
3887 useForeignDTD
= XML_FALSE
;
3888 declEntity
= (ENTITY
*)lookup(parser
,
3889 &dtd
->paramEntities
,
3893 return XML_ERROR_NO_MEMORY
;
3894 #endif /* XML_DTD */
3895 dtd
->hasParamEntityRefs
= XML_TRUE
;
3896 if (startDoctypeDeclHandler
) {
3898 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3899 return XML_ERROR_PUBLICID
;
3900 pubId
= poolStoreString(&tempPool
, enc
,
3901 s
+ enc
->minBytesPerChar
,
3902 next
- enc
->minBytesPerChar
);
3904 return XML_ERROR_NO_MEMORY
;
3905 normalizePublicId(pubId
);
3906 poolFinish(&tempPool
);
3907 doctypePubid
= pubId
;
3908 handleDefault
= XML_FALSE
;
3909 goto alreadyChecked
;
3912 case XML_ROLE_ENTITY_PUBLIC_ID
:
3913 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
3914 return XML_ERROR_PUBLICID
;
3916 if (dtd
->keepProcessing
&& declEntity
) {
3917 XML_Char
*tem
= poolStoreString(&dtd
->pool
,
3919 s
+ enc
->minBytesPerChar
,
3920 next
- enc
->minBytesPerChar
);
3922 return XML_ERROR_NO_MEMORY
;
3923 normalizePublicId(tem
);
3924 declEntity
->publicId
= tem
;
3925 poolFinish(&dtd
->pool
);
3926 if (entityDeclHandler
)
3927 handleDefault
= XML_FALSE
;
3930 case XML_ROLE_DOCTYPE_CLOSE
:
3932 startDoctypeDeclHandler(handlerArg
, doctypeName
,
3933 doctypeSysid
, doctypePubid
, 0);
3934 poolClear(&tempPool
);
3935 handleDefault
= XML_FALSE
;
3937 /* doctypeSysid will be non-NULL in the case of a previous
3938 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3939 was not set, indicating an external subset
3942 if (doctypeSysid
|| useForeignDTD
) {
3943 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3944 dtd
->hasParamEntityRefs
= XML_TRUE
;
3945 if (paramEntityParsing
&& externalEntityRefHandler
) {
3946 ENTITY
*entity
= (ENTITY
*)lookup(parser
,
3947 &dtd
->paramEntities
,
3951 return XML_ERROR_NO_MEMORY
;
3953 entity
->base
= curBase
;
3954 dtd
->paramEntityRead
= XML_FALSE
;
3955 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
3960 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
3961 if (dtd
->paramEntityRead
) {
3962 if (!dtd
->standalone
&&
3963 notStandaloneHandler
&&
3964 !notStandaloneHandler(handlerArg
))
3965 return XML_ERROR_NOT_STANDALONE
;
3967 /* if we didn't read the foreign DTD then this means that there
3968 is no external subset and we must reset dtd->hasParamEntityRefs
3970 else if (!doctypeSysid
)
3971 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
3972 /* end of DTD - no need to update dtd->keepProcessing */
3974 useForeignDTD
= XML_FALSE
;
3976 #endif /* XML_DTD */
3977 if (endDoctypeDeclHandler
) {
3978 endDoctypeDeclHandler(handlerArg
);
3979 handleDefault
= XML_FALSE
;
3982 case XML_ROLE_INSTANCE_START
:
3984 /* if there is no DOCTYPE declaration then now is the
3985 last chance to read the foreign DTD
3987 if (useForeignDTD
) {
3988 XML_Bool hadParamEntityRefs
= dtd
->hasParamEntityRefs
;
3989 dtd
->hasParamEntityRefs
= XML_TRUE
;
3990 if (paramEntityParsing
&& externalEntityRefHandler
) {
3991 ENTITY
*entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
,
3995 return XML_ERROR_NO_MEMORY
;
3996 entity
->base
= curBase
;
3997 dtd
->paramEntityRead
= XML_FALSE
;
3998 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4003 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4004 if (dtd
->paramEntityRead
) {
4005 if (!dtd
->standalone
&&
4006 notStandaloneHandler
&&
4007 !notStandaloneHandler(handlerArg
))
4008 return XML_ERROR_NOT_STANDALONE
;
4010 /* if we didn't read the foreign DTD then this means that there
4011 is no external subset and we must reset dtd->hasParamEntityRefs
4014 dtd
->hasParamEntityRefs
= hadParamEntityRefs
;
4015 /* end of DTD - no need to update dtd->keepProcessing */
4018 #endif /* XML_DTD */
4019 processor
= contentProcessor
;
4020 return contentProcessor(parser
, s
, end
, nextPtr
);
4021 case XML_ROLE_ATTLIST_ELEMENT_NAME
:
4022 declElementType
= getElementType(parser
, enc
, s
, next
);
4023 if (!declElementType
)
4024 return XML_ERROR_NO_MEMORY
;
4025 goto checkAttListDeclHandler
;
4026 case XML_ROLE_ATTRIBUTE_NAME
:
4027 declAttributeId
= getAttributeId(parser
, enc
, s
, next
);
4028 if (!declAttributeId
)
4029 return XML_ERROR_NO_MEMORY
;
4030 declAttributeIsCdata
= XML_FALSE
;
4031 declAttributeType
= NULL
;
4032 declAttributeIsId
= XML_FALSE
;
4033 goto checkAttListDeclHandler
;
4034 case XML_ROLE_ATTRIBUTE_TYPE_CDATA
:
4035 declAttributeIsCdata
= XML_TRUE
;
4036 declAttributeType
= atypeCDATA
;
4037 goto checkAttListDeclHandler
;
4038 case XML_ROLE_ATTRIBUTE_TYPE_ID
:
4039 declAttributeIsId
= XML_TRUE
;
4040 declAttributeType
= atypeID
;
4041 goto checkAttListDeclHandler
;
4042 case XML_ROLE_ATTRIBUTE_TYPE_IDREF
:
4043 declAttributeType
= atypeIDREF
;
4044 goto checkAttListDeclHandler
;
4045 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS
:
4046 declAttributeType
= atypeIDREFS
;
4047 goto checkAttListDeclHandler
;
4048 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY
:
4049 declAttributeType
= atypeENTITY
;
4050 goto checkAttListDeclHandler
;
4051 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES
:
4052 declAttributeType
= atypeENTITIES
;
4053 goto checkAttListDeclHandler
;
4054 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN
:
4055 declAttributeType
= atypeNMTOKEN
;
4056 goto checkAttListDeclHandler
;
4057 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS
:
4058 declAttributeType
= atypeNMTOKENS
;
4059 checkAttListDeclHandler
:
4060 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4061 handleDefault
= XML_FALSE
;
4063 case XML_ROLE_ATTRIBUTE_ENUM_VALUE
:
4064 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE
:
4065 if (dtd
->keepProcessing
&& attlistDeclHandler
) {
4066 const XML_Char
*prefix
;
4067 if (declAttributeType
) {
4068 prefix
= enumValueSep
;
4071 prefix
= (role
== XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4075 if (!poolAppendString(&tempPool
, prefix
))
4076 return XML_ERROR_NO_MEMORY
;
4077 if (!poolAppend(&tempPool
, enc
, s
, next
))
4078 return XML_ERROR_NO_MEMORY
;
4079 declAttributeType
= tempPool
.start
;
4080 handleDefault
= XML_FALSE
;
4083 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE
:
4084 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
:
4085 if (dtd
->keepProcessing
) {
4086 if (!defineAttribute(declElementType
, declAttributeId
,
4087 declAttributeIsCdata
, declAttributeIsId
,
4089 return XML_ERROR_NO_MEMORY
;
4090 if (attlistDeclHandler
&& declAttributeType
) {
4091 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4092 || (*declAttributeType
== XML_T(ASCII_N
)
4093 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4094 /* Enumerated or Notation type */
4095 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4096 || !poolAppendChar(&tempPool
, XML_T('\0')))
4097 return XML_ERROR_NO_MEMORY
;
4098 declAttributeType
= tempPool
.start
;
4099 poolFinish(&tempPool
);
4102 attlistDeclHandler(handlerArg
, declElementType
->name
,
4103 declAttributeId
->name
, declAttributeType
,
4104 0, role
== XML_ROLE_REQUIRED_ATTRIBUTE_VALUE
);
4105 poolClear(&tempPool
);
4106 handleDefault
= XML_FALSE
;
4110 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE
:
4111 case XML_ROLE_FIXED_ATTRIBUTE_VALUE
:
4112 if (dtd
->keepProcessing
) {
4113 const XML_Char
*attVal
;
4114 enum XML_Error result
=
4115 storeAttributeValue(parser
, enc
, declAttributeIsCdata
,
4116 s
+ enc
->minBytesPerChar
,
4117 next
- enc
->minBytesPerChar
,
4121 attVal
= poolStart(&dtd
->pool
);
4122 poolFinish(&dtd
->pool
);
4123 /* ID attributes aren't allowed to have a default */
4124 if (!defineAttribute(declElementType
, declAttributeId
,
4125 declAttributeIsCdata
, XML_FALSE
, attVal
, parser
))
4126 return XML_ERROR_NO_MEMORY
;
4127 if (attlistDeclHandler
&& declAttributeType
) {
4128 if (*declAttributeType
== XML_T(ASCII_LPAREN
)
4129 || (*declAttributeType
== XML_T(ASCII_N
)
4130 && declAttributeType
[1] == XML_T(ASCII_O
))) {
4131 /* Enumerated or Notation type */
4132 if (!poolAppendChar(&tempPool
, XML_T(ASCII_RPAREN
))
4133 || !poolAppendChar(&tempPool
, XML_T('\0')))
4134 return XML_ERROR_NO_MEMORY
;
4135 declAttributeType
= tempPool
.start
;
4136 poolFinish(&tempPool
);
4139 attlistDeclHandler(handlerArg
, declElementType
->name
,
4140 declAttributeId
->name
, declAttributeType
,
4142 role
== XML_ROLE_FIXED_ATTRIBUTE_VALUE
);
4143 poolClear(&tempPool
);
4144 handleDefault
= XML_FALSE
;
4148 case XML_ROLE_ENTITY_VALUE
:
4149 if (dtd
->keepProcessing
) {
4150 enum XML_Error result
= storeEntityValue(parser
, enc
,
4151 s
+ enc
->minBytesPerChar
,
4152 next
- enc
->minBytesPerChar
);
4154 declEntity
->textPtr
= poolStart(&dtd
->entityValuePool
);
4155 declEntity
->textLen
= (int)(poolLength(&dtd
->entityValuePool
));
4156 poolFinish(&dtd
->entityValuePool
);
4157 if (entityDeclHandler
) {
4159 entityDeclHandler(handlerArg
,
4161 declEntity
->is_param
,
4162 declEntity
->textPtr
,
4163 declEntity
->textLen
,
4165 handleDefault
= XML_FALSE
;
4169 poolDiscard(&dtd
->entityValuePool
);
4170 if (result
!= XML_ERROR_NONE
)
4174 case XML_ROLE_DOCTYPE_SYSTEM_ID
:
4176 useForeignDTD
= XML_FALSE
;
4177 #endif /* XML_DTD */
4178 dtd
->hasParamEntityRefs
= XML_TRUE
;
4179 if (startDoctypeDeclHandler
) {
4180 doctypeSysid
= poolStoreString(&tempPool
, enc
,
4181 s
+ enc
->minBytesPerChar
,
4182 next
- enc
->minBytesPerChar
);
4183 if (doctypeSysid
== NULL
)
4184 return XML_ERROR_NO_MEMORY
;
4185 poolFinish(&tempPool
);
4186 handleDefault
= XML_FALSE
;
4190 /* use externalSubsetName to make doctypeSysid non-NULL
4191 for the case where no startDoctypeDeclHandler is set */
4192 doctypeSysid
= externalSubsetName
;
4193 #endif /* XML_DTD */
4194 if (!dtd
->standalone
4196 && !paramEntityParsing
4197 #endif /* XML_DTD */
4198 && notStandaloneHandler
4199 && !notStandaloneHandler(handlerArg
))
4200 return XML_ERROR_NOT_STANDALONE
;
4205 declEntity
= (ENTITY
*)lookup(parser
,
4206 &dtd
->paramEntities
,
4210 return XML_ERROR_NO_MEMORY
;
4211 declEntity
->publicId
= NULL
;
4214 #endif /* XML_DTD */
4215 case XML_ROLE_ENTITY_SYSTEM_ID
:
4216 if (dtd
->keepProcessing
&& declEntity
) {
4217 declEntity
->systemId
= poolStoreString(&dtd
->pool
, enc
,
4218 s
+ enc
->minBytesPerChar
,
4219 next
- enc
->minBytesPerChar
);
4220 if (!declEntity
->systemId
)
4221 return XML_ERROR_NO_MEMORY
;
4222 declEntity
->base
= curBase
;
4223 poolFinish(&dtd
->pool
);
4224 if (entityDeclHandler
)
4225 handleDefault
= XML_FALSE
;
4228 case XML_ROLE_ENTITY_COMPLETE
:
4229 if (dtd
->keepProcessing
&& declEntity
&& entityDeclHandler
) {
4231 entityDeclHandler(handlerArg
,
4233 declEntity
->is_param
,
4236 declEntity
->systemId
,
4237 declEntity
->publicId
,
4239 handleDefault
= XML_FALSE
;
4242 case XML_ROLE_ENTITY_NOTATION_NAME
:
4243 if (dtd
->keepProcessing
&& declEntity
) {
4244 declEntity
->notation
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4245 if (!declEntity
->notation
)
4246 return XML_ERROR_NO_MEMORY
;
4247 poolFinish(&dtd
->pool
);
4248 if (unparsedEntityDeclHandler
) {
4250 unparsedEntityDeclHandler(handlerArg
,
4253 declEntity
->systemId
,
4254 declEntity
->publicId
,
4255 declEntity
->notation
);
4256 handleDefault
= XML_FALSE
;
4258 else if (entityDeclHandler
) {
4260 entityDeclHandler(handlerArg
,
4264 declEntity
->systemId
,
4265 declEntity
->publicId
,
4266 declEntity
->notation
);
4267 handleDefault
= XML_FALSE
;
4271 case XML_ROLE_GENERAL_ENTITY_NAME
:
4273 if (XmlPredefinedEntityName(enc
, s
, next
)) {
4277 if (dtd
->keepProcessing
) {
4278 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4280 return XML_ERROR_NO_MEMORY
;
4281 declEntity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
,
4284 return XML_ERROR_NO_MEMORY
;
4285 if (declEntity
->name
!= name
) {
4286 poolDiscard(&dtd
->pool
);
4290 poolFinish(&dtd
->pool
);
4291 declEntity
->publicId
= NULL
;
4292 declEntity
->is_param
= XML_FALSE
;
4293 /* if we have a parent parser or are reading an internal parameter
4294 entity, then the entity declaration is not considered "internal"
4296 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4297 if (entityDeclHandler
)
4298 handleDefault
= XML_FALSE
;
4302 poolDiscard(&dtd
->pool
);
4307 case XML_ROLE_PARAM_ENTITY_NAME
:
4309 if (dtd
->keepProcessing
) {
4310 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, s
, next
);
4312 return XML_ERROR_NO_MEMORY
;
4313 declEntity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
,
4314 name
, sizeof(ENTITY
));
4316 return XML_ERROR_NO_MEMORY
;
4317 if (declEntity
->name
!= name
) {
4318 poolDiscard(&dtd
->pool
);
4322 poolFinish(&dtd
->pool
);
4323 declEntity
->publicId
= NULL
;
4324 declEntity
->is_param
= XML_TRUE
;
4325 /* if we have a parent parser or are reading an internal parameter
4326 entity, then the entity declaration is not considered "internal"
4328 declEntity
->is_internal
= !(parentParser
|| openInternalEntities
);
4329 if (entityDeclHandler
)
4330 handleDefault
= XML_FALSE
;
4334 poolDiscard(&dtd
->pool
);
4337 #else /* not XML_DTD */
4339 #endif /* XML_DTD */
4341 case XML_ROLE_NOTATION_NAME
:
4342 declNotationPublicId
= NULL
;
4343 declNotationName
= NULL
;
4344 if (notationDeclHandler
) {
4345 declNotationName
= poolStoreString(&tempPool
, enc
, s
, next
);
4346 if (!declNotationName
)
4347 return XML_ERROR_NO_MEMORY
;
4348 poolFinish(&tempPool
);
4349 handleDefault
= XML_FALSE
;
4352 case XML_ROLE_NOTATION_PUBLIC_ID
:
4353 if (!XmlIsPublicId(enc
, s
, next
, eventPP
))
4354 return XML_ERROR_PUBLICID
;
4355 if (declNotationName
) { /* means notationDeclHandler != NULL */
4356 XML_Char
*tem
= poolStoreString(&tempPool
,
4358 s
+ enc
->minBytesPerChar
,
4359 next
- enc
->minBytesPerChar
);
4361 return XML_ERROR_NO_MEMORY
;
4362 normalizePublicId(tem
);
4363 declNotationPublicId
= tem
;
4364 poolFinish(&tempPool
);
4365 handleDefault
= XML_FALSE
;
4368 case XML_ROLE_NOTATION_SYSTEM_ID
:
4369 if (declNotationName
&& notationDeclHandler
) {
4370 const XML_Char
*systemId
4371 = poolStoreString(&tempPool
, enc
,
4372 s
+ enc
->minBytesPerChar
,
4373 next
- enc
->minBytesPerChar
);
4375 return XML_ERROR_NO_MEMORY
;
4377 notationDeclHandler(handlerArg
,
4381 declNotationPublicId
);
4382 handleDefault
= XML_FALSE
;
4384 poolClear(&tempPool
);
4386 case XML_ROLE_NOTATION_NO_SYSTEM_ID
:
4387 if (declNotationPublicId
&& notationDeclHandler
) {
4389 notationDeclHandler(handlerArg
,
4393 declNotationPublicId
);
4394 handleDefault
= XML_FALSE
;
4396 poolClear(&tempPool
);
4398 case XML_ROLE_ERROR
:
4400 case XML_TOK_PARAM_ENTITY_REF
:
4401 /* PE references in internal subset are
4402 not allowed within declarations. */
4403 return XML_ERROR_PARAM_ENTITY_REF
;
4404 case XML_TOK_XML_DECL
:
4405 return XML_ERROR_MISPLACED_XML_PI
;
4407 return XML_ERROR_SYNTAX
;
4410 case XML_ROLE_IGNORE_SECT
:
4412 enum XML_Error result
;
4414 reportDefault(parser
, enc
, s
, next
);
4415 handleDefault
= XML_FALSE
;
4416 result
= doIgnoreSection(parser
, enc
, &next
, end
, nextPtr
, haveMore
);
4417 if (result
!= XML_ERROR_NONE
)
4420 processor
= ignoreSectionProcessor
;
4425 #endif /* XML_DTD */
4426 case XML_ROLE_GROUP_OPEN
:
4427 if (prologState
.level
>= groupSize
) {
4429 char *temp
= (char *)REALLOC(groupConnector
, groupSize
*= 2);
4431 return XML_ERROR_NO_MEMORY
;
4432 groupConnector
= temp
;
4433 if (dtd
->scaffIndex
) {
4434 int *temp
= (int *)REALLOC(dtd
->scaffIndex
,
4435 groupSize
* sizeof(int));
4437 return XML_ERROR_NO_MEMORY
;
4438 dtd
->scaffIndex
= temp
;
4442 groupConnector
= (char *)MALLOC(groupSize
= 32);
4443 if (!groupConnector
)
4444 return XML_ERROR_NO_MEMORY
;
4447 groupConnector
[prologState
.level
] = 0;
4448 if (dtd
->in_eldecl
) {
4449 int myindex
= nextScaffoldPart(parser
);
4451 return XML_ERROR_NO_MEMORY
;
4452 dtd
->scaffIndex
[dtd
->scaffLevel
] = myindex
;
4454 dtd
->scaffold
[myindex
].type
= XML_CTYPE_SEQ
;
4455 if (elementDeclHandler
)
4456 handleDefault
= XML_FALSE
;
4459 case XML_ROLE_GROUP_SEQUENCE
:
4460 if (groupConnector
[prologState
.level
] == ASCII_PIPE
)
4461 return XML_ERROR_SYNTAX
;
4462 groupConnector
[prologState
.level
] = ASCII_COMMA
;
4463 if (dtd
->in_eldecl
&& elementDeclHandler
)
4464 handleDefault
= XML_FALSE
;
4466 case XML_ROLE_GROUP_CHOICE
:
4467 if (groupConnector
[prologState
.level
] == ASCII_COMMA
)
4468 return XML_ERROR_SYNTAX
;
4470 && !groupConnector
[prologState
.level
]
4471 && (dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4474 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4476 if (elementDeclHandler
)
4477 handleDefault
= XML_FALSE
;
4479 groupConnector
[prologState
.level
] = ASCII_PIPE
;
4481 case XML_ROLE_PARAM_ENTITY_REF
:
4483 case XML_ROLE_INNER_PARAM_ENTITY_REF
:
4484 dtd
->hasParamEntityRefs
= XML_TRUE
;
4485 if (!paramEntityParsing
)
4486 dtd
->keepProcessing
= dtd
->standalone
;
4488 const XML_Char
*name
;
4490 name
= poolStoreString(&dtd
->pool
, enc
,
4491 s
+ enc
->minBytesPerChar
,
4492 next
- enc
->minBytesPerChar
);
4494 return XML_ERROR_NO_MEMORY
;
4495 entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
, name
, 0);
4496 poolDiscard(&dtd
->pool
);
4497 /* first, determine if a check for an existing declaration is needed;
4498 if yes, check that the entity exists, and that it is internal,
4499 otherwise call the skipped entity handler
4501 if (prologState
.documentEntity
&&
4503 ? !openInternalEntities
4504 : !dtd
->hasParamEntityRefs
)) {
4506 return XML_ERROR_UNDEFINED_ENTITY
;
4507 else if (!entity
->is_internal
)
4508 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
4511 dtd
->keepProcessing
= dtd
->standalone
;
4512 /* cannot report skipped entities in declarations */
4513 if ((role
== XML_ROLE_PARAM_ENTITY_REF
) && skippedEntityHandler
) {
4514 skippedEntityHandler(handlerArg
, name
, 1);
4515 handleDefault
= XML_FALSE
;
4520 return XML_ERROR_RECURSIVE_ENTITY_REF
;
4521 if (entity
->textPtr
) {
4522 enum XML_Error result
;
4523 XML_Bool betweenDecl
=
4524 (role
== XML_ROLE_PARAM_ENTITY_REF
? XML_TRUE
: XML_FALSE
);
4525 result
= processInternalEntity(parser
, entity
, betweenDecl
);
4526 if (result
!= XML_ERROR_NONE
)
4528 handleDefault
= XML_FALSE
;
4531 if (externalEntityRefHandler
) {
4532 dtd
->paramEntityRead
= XML_FALSE
;
4533 entity
->open
= XML_TRUE
;
4534 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
4538 entity
->publicId
)) {
4539 entity
->open
= XML_FALSE
;
4540 return XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
4542 entity
->open
= XML_FALSE
;
4543 handleDefault
= XML_FALSE
;
4544 if (!dtd
->paramEntityRead
) {
4545 dtd
->keepProcessing
= dtd
->standalone
;
4550 dtd
->keepProcessing
= dtd
->standalone
;
4554 #endif /* XML_DTD */
4555 if (!dtd
->standalone
&&
4556 notStandaloneHandler
&&
4557 !notStandaloneHandler(handlerArg
))
4558 return XML_ERROR_NOT_STANDALONE
;
4561 /* Element declaration stuff */
4563 case XML_ROLE_ELEMENT_NAME
:
4564 if (elementDeclHandler
) {
4565 declElementType
= getElementType(parser
, enc
, s
, next
);
4566 if (!declElementType
)
4567 return XML_ERROR_NO_MEMORY
;
4568 dtd
->scaffLevel
= 0;
4569 dtd
->scaffCount
= 0;
4570 dtd
->in_eldecl
= XML_TRUE
;
4571 handleDefault
= XML_FALSE
;
4575 case XML_ROLE_CONTENT_ANY
:
4576 case XML_ROLE_CONTENT_EMPTY
:
4577 if (dtd
->in_eldecl
) {
4578 if (elementDeclHandler
) {
4579 XML_Content
* content
= (XML_Content
*) MALLOC(sizeof(XML_Content
));
4581 return XML_ERROR_NO_MEMORY
;
4582 content
->quant
= XML_CQUANT_NONE
;
4583 content
->name
= NULL
;
4584 content
->numchildren
= 0;
4585 content
->children
= NULL
;
4586 content
->type
= ((role
== XML_ROLE_CONTENT_ANY
) ?
4590 elementDeclHandler(handlerArg
, declElementType
->name
, content
);
4591 handleDefault
= XML_FALSE
;
4593 dtd
->in_eldecl
= XML_FALSE
;
4597 case XML_ROLE_CONTENT_PCDATA
:
4598 if (dtd
->in_eldecl
) {
4599 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
- 1]].type
4601 if (elementDeclHandler
)
4602 handleDefault
= XML_FALSE
;
4606 case XML_ROLE_CONTENT_ELEMENT
:
4607 quant
= XML_CQUANT_NONE
;
4608 goto elementContent
;
4609 case XML_ROLE_CONTENT_ELEMENT_OPT
:
4610 quant
= XML_CQUANT_OPT
;
4611 goto elementContent
;
4612 case XML_ROLE_CONTENT_ELEMENT_REP
:
4613 quant
= XML_CQUANT_REP
;
4614 goto elementContent
;
4615 case XML_ROLE_CONTENT_ELEMENT_PLUS
:
4616 quant
= XML_CQUANT_PLUS
;
4618 if (dtd
->in_eldecl
) {
4620 const XML_Char
*name
;
4622 const char *nxt
= (quant
== XML_CQUANT_NONE
4624 : next
- enc
->minBytesPerChar
);
4625 int myindex
= nextScaffoldPart(parser
);
4627 return XML_ERROR_NO_MEMORY
;
4628 dtd
->scaffold
[myindex
].type
= XML_CTYPE_NAME
;
4629 dtd
->scaffold
[myindex
].quant
= quant
;
4630 el
= getElementType(parser
, enc
, s
, nxt
);
4632 return XML_ERROR_NO_MEMORY
;
4634 dtd
->scaffold
[myindex
].name
= name
;
4636 for (; name
[nameLen
++]; );
4637 dtd
->contentStringLen
+= nameLen
;
4638 if (elementDeclHandler
)
4639 handleDefault
= XML_FALSE
;
4643 case XML_ROLE_GROUP_CLOSE
:
4644 quant
= XML_CQUANT_NONE
;
4646 case XML_ROLE_GROUP_CLOSE_OPT
:
4647 quant
= XML_CQUANT_OPT
;
4649 case XML_ROLE_GROUP_CLOSE_REP
:
4650 quant
= XML_CQUANT_REP
;
4652 case XML_ROLE_GROUP_CLOSE_PLUS
:
4653 quant
= XML_CQUANT_PLUS
;
4655 if (dtd
->in_eldecl
) {
4656 if (elementDeclHandler
)
4657 handleDefault
= XML_FALSE
;
4659 dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
]].quant
= quant
;
4660 if (dtd
->scaffLevel
== 0) {
4661 if (!handleDefault
) {
4662 XML_Content
*model
= build_model(parser
);
4664 return XML_ERROR_NO_MEMORY
;
4666 elementDeclHandler(handlerArg
, declElementType
->name
, model
);
4668 dtd
->in_eldecl
= XML_FALSE
;
4669 dtd
->contentStringLen
= 0;
4673 /* End element declaration stuff */
4676 if (!reportProcessingInstruction(parser
, enc
, s
, next
))
4677 return XML_ERROR_NO_MEMORY
;
4678 handleDefault
= XML_FALSE
;
4680 case XML_ROLE_COMMENT
:
4681 if (!reportComment(parser
, enc
, s
, next
))
4682 return XML_ERROR_NO_MEMORY
;
4683 handleDefault
= XML_FALSE
;
4688 handleDefault
= XML_FALSE
;
4692 case XML_ROLE_DOCTYPE_NONE
:
4693 if (startDoctypeDeclHandler
)
4694 handleDefault
= XML_FALSE
;
4696 case XML_ROLE_ENTITY_NONE
:
4697 if (dtd
->keepProcessing
&& entityDeclHandler
)
4698 handleDefault
= XML_FALSE
;
4700 case XML_ROLE_NOTATION_NONE
:
4701 if (notationDeclHandler
)
4702 handleDefault
= XML_FALSE
;
4704 case XML_ROLE_ATTLIST_NONE
:
4705 if (dtd
->keepProcessing
&& attlistDeclHandler
)
4706 handleDefault
= XML_FALSE
;
4708 case XML_ROLE_ELEMENT_NONE
:
4709 if (elementDeclHandler
)
4710 handleDefault
= XML_FALSE
;
4712 } /* end of big switch */
4714 if (handleDefault
&& defaultHandler
)
4715 reportDefault(parser
, enc
, s
, next
);
4717 switch (ps_parsing
) {
4720 return XML_ERROR_NONE
;
4722 return XML_ERROR_ABORTED
;
4725 tok
= XmlPrologTok(enc
, s
, end
, &next
);
4731 static enum XML_Error PTRCALL
4732 epilogProcessor(XML_Parser parser
,
4735 const char **nextPtr
)
4737 processor
= epilogProcessor
;
4740 const char *next
= NULL
;
4741 int tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4744 /* report partial linebreak - it might be the last token */
4745 case -XML_TOK_PROLOG_S
:
4746 if (defaultHandler
) {
4747 reportDefault(parser
, encoding
, s
, next
);
4748 if (ps_parsing
== XML_FINISHED
)
4749 return XML_ERROR_ABORTED
;
4752 return XML_ERROR_NONE
;
4755 return XML_ERROR_NONE
;
4756 case XML_TOK_PROLOG_S
:
4758 reportDefault(parser
, encoding
, s
, next
);
4761 if (!reportProcessingInstruction(parser
, encoding
, s
, next
))
4762 return XML_ERROR_NO_MEMORY
;
4764 case XML_TOK_COMMENT
:
4765 if (!reportComment(parser
, encoding
, s
, next
))
4766 return XML_ERROR_NO_MEMORY
;
4768 case XML_TOK_INVALID
:
4770 return XML_ERROR_INVALID_TOKEN
;
4771 case XML_TOK_PARTIAL
:
4772 if (!ps_finalBuffer
) {
4774 return XML_ERROR_NONE
;
4776 return XML_ERROR_UNCLOSED_TOKEN
;
4777 case XML_TOK_PARTIAL_CHAR
:
4778 if (!ps_finalBuffer
) {
4780 return XML_ERROR_NONE
;
4782 return XML_ERROR_PARTIAL_CHAR
;
4784 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT
;
4786 eventPtr
= s
= next
;
4787 switch (ps_parsing
) {
4790 return XML_ERROR_NONE
;
4792 return XML_ERROR_ABORTED
;
4798 static enum XML_Error
4799 processInternalEntity(XML_Parser parser
, ENTITY
*entity
,
4800 XML_Bool betweenDecl
)
4802 const char *textStart
, *textEnd
;
4804 enum XML_Error result
;
4805 OPEN_INTERNAL_ENTITY
*openEntity
;
4807 if (freeInternalEntities
) {
4808 openEntity
= freeInternalEntities
;
4809 freeInternalEntities
= openEntity
->next
;
4812 openEntity
= (OPEN_INTERNAL_ENTITY
*)MALLOC(sizeof(OPEN_INTERNAL_ENTITY
));
4814 return XML_ERROR_NO_MEMORY
;
4816 entity
->open
= XML_TRUE
;
4817 entity
->processed
= 0;
4818 openEntity
->next
= openInternalEntities
;
4819 openInternalEntities
= openEntity
;
4820 openEntity
->entity
= entity
;
4821 openEntity
->startTagLevel
= tagLevel
;
4822 openEntity
->betweenDecl
= betweenDecl
;
4823 openEntity
->internalEventPtr
= NULL
;
4824 openEntity
->internalEventEndPtr
= NULL
;
4825 textStart
= (char *)entity
->textPtr
;
4826 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4829 if (entity
->is_param
) {
4830 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4831 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4832 next
, &next
, XML_FALSE
);
4835 #endif /* XML_DTD */
4836 result
= doContent(parser
, tagLevel
, internalEncoding
, textStart
,
4837 textEnd
, &next
, XML_FALSE
);
4839 if (result
== XML_ERROR_NONE
) {
4840 if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4841 entity
->processed
= (int)(next
- textStart
);
4842 processor
= internalEntityProcessor
;
4845 entity
->open
= XML_FALSE
;
4846 openInternalEntities
= openEntity
->next
;
4847 /* put openEntity back in list of free instances */
4848 openEntity
->next
= freeInternalEntities
;
4849 freeInternalEntities
= openEntity
;
4855 static enum XML_Error PTRCALL
4856 internalEntityProcessor(XML_Parser parser
,
4859 const char **nextPtr
)
4862 const char *textStart
, *textEnd
;
4864 enum XML_Error result
;
4865 OPEN_INTERNAL_ENTITY
*openEntity
= openInternalEntities
;
4867 return XML_ERROR_UNEXPECTED_STATE
;
4869 entity
= openEntity
->entity
;
4870 textStart
= ((char *)entity
->textPtr
) + entity
->processed
;
4871 textEnd
= (char *)(entity
->textPtr
+ entity
->textLen
);
4874 if (entity
->is_param
) {
4875 int tok
= XmlPrologTok(internalEncoding
, textStart
, textEnd
, &next
);
4876 result
= doProlog(parser
, internalEncoding
, textStart
, textEnd
, tok
,
4877 next
, &next
, XML_FALSE
);
4880 #endif /* XML_DTD */
4881 result
= doContent(parser
, openEntity
->startTagLevel
, internalEncoding
,
4882 textStart
, textEnd
, &next
, XML_FALSE
);
4884 if (result
!= XML_ERROR_NONE
)
4886 else if (textEnd
!= next
&& ps_parsing
== XML_SUSPENDED
) {
4887 entity
->processed
= (int)(next
- (char *)entity
->textPtr
);
4891 entity
->open
= XML_FALSE
;
4892 openInternalEntities
= openEntity
->next
;
4893 /* put openEntity back in list of free instances */
4894 openEntity
->next
= freeInternalEntities
;
4895 freeInternalEntities
= openEntity
;
4899 if (entity
->is_param
) {
4901 processor
= prologProcessor
;
4902 tok
= XmlPrologTok(encoding
, s
, end
, &next
);
4903 return doProlog(parser
, encoding
, s
, end
, tok
, next
, nextPtr
,
4904 (XML_Bool
)!ps_finalBuffer
);
4907 #endif /* XML_DTD */
4909 processor
= contentProcessor
;
4910 /* see externalEntityContentProcessor vs contentProcessor */
4911 return doContent(parser
, parentParser
? 1 : 0, encoding
, s
, end
,
4912 nextPtr
, (XML_Bool
)!ps_finalBuffer
);
4916 static enum XML_Error PTRCALL
4917 errorProcessor(XML_Parser parser
,
4920 const char **nextPtr
)
4925 static enum XML_Error
4926 storeAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4927 const char *ptr
, const char *end
,
4930 enum XML_Error result
= appendAttributeValue(parser
, enc
, isCdata
, ptr
,
4934 if (!isCdata
&& poolLength(pool
) && poolLastChar(pool
) == 0x20)
4936 if (!poolAppendChar(pool
, XML_T('\0')))
4937 return XML_ERROR_NO_MEMORY
;
4938 return XML_ERROR_NONE
;
4941 static enum XML_Error
4942 appendAttributeValue(XML_Parser parser
, const ENCODING
*enc
, XML_Bool isCdata
,
4943 const char *ptr
, const char *end
,
4946 DTD
* const dtd
= _dtd
; /* save one level of indirection */
4949 int tok
= XmlAttributeValueTok(enc
, ptr
, end
, &next
);
4952 return XML_ERROR_NONE
;
4953 case XML_TOK_INVALID
:
4954 if (enc
== encoding
)
4956 return XML_ERROR_INVALID_TOKEN
;
4957 case XML_TOK_PARTIAL
:
4958 if (enc
== encoding
)
4960 return XML_ERROR_INVALID_TOKEN
;
4961 case XML_TOK_CHAR_REF
:
4963 XML_Char buf
[XML_ENCODE_MAX
];
4965 int n
= XmlCharRefNumber(enc
, ptr
);
4967 if (enc
== encoding
)
4969 return XML_ERROR_BAD_CHAR_REF
;
4972 && n
== 0x20 /* space */
4973 && (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4975 n
= XmlEncode(n
, (ICHAR
*)buf
);
4977 if (enc
== encoding
)
4979 return XML_ERROR_BAD_CHAR_REF
;
4981 for (i
= 0; i
< n
; i
++) {
4982 if (!poolAppendChar(pool
, buf
[i
]))
4983 return XML_ERROR_NO_MEMORY
;
4987 case XML_TOK_DATA_CHARS
:
4988 if (!poolAppend(pool
, enc
, ptr
, next
))
4989 return XML_ERROR_NO_MEMORY
;
4991 case XML_TOK_TRAILING_CR
:
4992 next
= ptr
+ enc
->minBytesPerChar
;
4994 case XML_TOK_ATTRIBUTE_VALUE_S
:
4995 case XML_TOK_DATA_NEWLINE
:
4996 if (!isCdata
&& (poolLength(pool
) == 0 || poolLastChar(pool
) == 0x20))
4998 if (!poolAppendChar(pool
, 0x20))
4999 return XML_ERROR_NO_MEMORY
;
5001 case XML_TOK_ENTITY_REF
:
5003 const XML_Char
*name
;
5005 char checkEntityDecl
;
5006 XML_Char ch
= (XML_Char
) XmlPredefinedEntityName(enc
,
5007 ptr
+ enc
->minBytesPerChar
,
5008 next
- enc
->minBytesPerChar
);
5010 if (!poolAppendChar(pool
, ch
))
5011 return XML_ERROR_NO_MEMORY
;
5014 name
= poolStoreString(&temp2Pool
, enc
,
5015 ptr
+ enc
->minBytesPerChar
,
5016 next
- enc
->minBytesPerChar
);
5018 return XML_ERROR_NO_MEMORY
;
5019 entity
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, name
, 0);
5020 poolDiscard(&temp2Pool
);
5021 /* First, determine if a check for an existing declaration is needed;
5022 if yes, check that the entity exists, and that it is internal.
5024 if (pool
== &dtd
->pool
) /* are we called from prolog? */
5027 prologState
.documentEntity
&&
5028 #endif /* XML_DTD */
5030 ? !openInternalEntities
5031 : !dtd
->hasParamEntityRefs
);
5032 else /* if (pool == &tempPool): we are called from content */
5033 checkEntityDecl
= !dtd
->hasParamEntityRefs
|| dtd
->standalone
;
5034 if (checkEntityDecl
) {
5036 return XML_ERROR_UNDEFINED_ENTITY
;
5037 else if (!entity
->is_internal
)
5038 return XML_ERROR_ENTITY_DECLARED_IN_PE
;
5041 /* Cannot report skipped entity here - see comments on
5042 skippedEntityHandler.
5043 if (skippedEntityHandler)
5044 skippedEntityHandler(handlerArg, name, 0);
5046 /* Cannot call the default handler because this would be
5047 out of sync with the call to the startElementHandler.
5048 if ((pool == &tempPool) && defaultHandler)
5049 reportDefault(parser, enc, ptr, next);
5054 if (enc
== encoding
)
5056 return XML_ERROR_RECURSIVE_ENTITY_REF
;
5058 if (entity
->notation
) {
5059 if (enc
== encoding
)
5061 return XML_ERROR_BINARY_ENTITY_REF
;
5063 if (!entity
->textPtr
) {
5064 if (enc
== encoding
)
5066 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF
;
5069 enum XML_Error result
;
5070 const XML_Char
*textEnd
= entity
->textPtr
+ entity
->textLen
;
5071 entity
->open
= XML_TRUE
;
5072 result
= appendAttributeValue(parser
, internalEncoding
, isCdata
,
5073 (char *)entity
->textPtr
,
5074 (char *)textEnd
, pool
);
5075 entity
->open
= XML_FALSE
;
5082 if (enc
== encoding
)
5084 return XML_ERROR_UNEXPECTED_STATE
;
5091 static enum XML_Error
5092 storeEntityValue(XML_Parser parser
,
5093 const ENCODING
*enc
,
5094 const char *entityTextPtr
,
5095 const char *entityTextEnd
)
5097 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5098 STRING_POOL
*pool
= &(dtd
->entityValuePool
);
5099 enum XML_Error result
= XML_ERROR_NONE
;
5101 int oldInEntityValue
= prologState
.inEntityValue
;
5102 prologState
.inEntityValue
= 1;
5103 #endif /* XML_DTD */
5104 /* never return Null for the value argument in EntityDeclHandler,
5105 since this would indicate an external entity; therefore we
5106 have to make sure that entityValuePool.start is not null */
5107 if (!pool
->blocks
) {
5108 if (!poolGrow(pool
))
5109 return XML_ERROR_NO_MEMORY
;
5114 int tok
= XmlEntityValueTok(enc
, entityTextPtr
, entityTextEnd
, &next
);
5116 case XML_TOK_PARAM_ENTITY_REF
:
5118 if (isParamEntity
|| enc
!= encoding
) {
5119 const XML_Char
*name
;
5121 name
= poolStoreString(&tempPool
, enc
,
5122 entityTextPtr
+ enc
->minBytesPerChar
,
5123 next
- enc
->minBytesPerChar
);
5125 result
= XML_ERROR_NO_MEMORY
;
5126 goto endEntityValue
;
5128 entity
= (ENTITY
*)lookup(parser
, &dtd
->paramEntities
, name
, 0);
5129 poolDiscard(&tempPool
);
5131 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5132 /* cannot report skipped entity here - see comments on
5133 skippedEntityHandler
5134 if (skippedEntityHandler)
5135 skippedEntityHandler(handlerArg, name, 0);
5137 dtd
->keepProcessing
= dtd
->standalone
;
5138 goto endEntityValue
;
5141 if (enc
== encoding
)
5142 eventPtr
= entityTextPtr
;
5143 result
= XML_ERROR_RECURSIVE_ENTITY_REF
;
5144 goto endEntityValue
;
5146 if (entity
->systemId
) {
5147 if (externalEntityRefHandler
) {
5148 dtd
->paramEntityRead
= XML_FALSE
;
5149 entity
->open
= XML_TRUE
;
5150 if (!externalEntityRefHandler(externalEntityRefHandlerArg
,
5154 entity
->publicId
)) {
5155 entity
->open
= XML_FALSE
;
5156 result
= XML_ERROR_EXTERNAL_ENTITY_HANDLING
;
5157 goto endEntityValue
;
5159 entity
->open
= XML_FALSE
;
5160 if (!dtd
->paramEntityRead
)
5161 dtd
->keepProcessing
= dtd
->standalone
;
5164 dtd
->keepProcessing
= dtd
->standalone
;
5167 entity
->open
= XML_TRUE
;
5168 result
= storeEntityValue(parser
,
5170 (char *)entity
->textPtr
,
5171 (char *)(entity
->textPtr
5172 + entity
->textLen
));
5173 entity
->open
= XML_FALSE
;
5175 goto endEntityValue
;
5179 #endif /* XML_DTD */
5180 /* In the internal subset, PE references are not legal
5181 within markup declarations, e.g entity values in this case. */
5182 eventPtr
= entityTextPtr
;
5183 result
= XML_ERROR_PARAM_ENTITY_REF
;
5184 goto endEntityValue
;
5186 result
= XML_ERROR_NONE
;
5187 goto endEntityValue
;
5188 case XML_TOK_ENTITY_REF
:
5189 case XML_TOK_DATA_CHARS
:
5190 if (!poolAppend(pool
, enc
, entityTextPtr
, next
)) {
5191 result
= XML_ERROR_NO_MEMORY
;
5192 goto endEntityValue
;
5195 case XML_TOK_TRAILING_CR
:
5196 next
= entityTextPtr
+ enc
->minBytesPerChar
;
5198 case XML_TOK_DATA_NEWLINE
:
5199 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5200 result
= XML_ERROR_NO_MEMORY
;
5201 goto endEntityValue
;
5203 *(pool
->ptr
)++ = 0xA;
5205 case XML_TOK_CHAR_REF
:
5207 XML_Char buf
[XML_ENCODE_MAX
];
5209 int n
= XmlCharRefNumber(enc
, entityTextPtr
);
5211 if (enc
== encoding
)
5212 eventPtr
= entityTextPtr
;
5213 result
= XML_ERROR_BAD_CHAR_REF
;
5214 goto endEntityValue
;
5216 n
= XmlEncode(n
, (ICHAR
*)buf
);
5218 if (enc
== encoding
)
5219 eventPtr
= entityTextPtr
;
5220 result
= XML_ERROR_BAD_CHAR_REF
;
5221 goto endEntityValue
;
5223 for (i
= 0; i
< n
; i
++) {
5224 if (pool
->end
== pool
->ptr
&& !poolGrow(pool
)) {
5225 result
= XML_ERROR_NO_MEMORY
;
5226 goto endEntityValue
;
5228 *(pool
->ptr
)++ = buf
[i
];
5232 case XML_TOK_PARTIAL
:
5233 if (enc
== encoding
)
5234 eventPtr
= entityTextPtr
;
5235 result
= XML_ERROR_INVALID_TOKEN
;
5236 goto endEntityValue
;
5237 case XML_TOK_INVALID
:
5238 if (enc
== encoding
)
5240 result
= XML_ERROR_INVALID_TOKEN
;
5241 goto endEntityValue
;
5243 if (enc
== encoding
)
5244 eventPtr
= entityTextPtr
;
5245 result
= XML_ERROR_UNEXPECTED_STATE
;
5246 goto endEntityValue
;
5248 entityTextPtr
= next
;
5252 prologState
.inEntityValue
= oldInEntityValue
;
5253 #endif /* XML_DTD */
5257 static void FASTCALL
5258 normalizeLines(XML_Char
*s
)
5262 if (*s
== XML_T('\0'))
5281 reportProcessingInstruction(XML_Parser parser
, const ENCODING
*enc
,
5282 const char *start
, const char *end
)
5284 const XML_Char
*target
;
5287 if (!processingInstructionHandler
) {
5289 reportDefault(parser
, enc
, start
, end
);
5292 start
+= enc
->minBytesPerChar
* 2;
5293 tem
= start
+ XmlNameLength(enc
, start
);
5294 target
= poolStoreString(&tempPool
, enc
, start
, tem
);
5297 poolFinish(&tempPool
);
5298 data
= poolStoreString(&tempPool
, enc
,
5300 end
- enc
->minBytesPerChar
*2);
5303 normalizeLines(data
);
5304 processingInstructionHandler(handlerArg
, target
, data
);
5305 poolClear(&tempPool
);
5310 reportComment(XML_Parser parser
, const ENCODING
*enc
,
5311 const char *start
, const char *end
)
5314 if (!commentHandler
) {
5316 reportDefault(parser
, enc
, start
, end
);
5319 data
= poolStoreString(&tempPool
,
5321 start
+ enc
->minBytesPerChar
* 4,
5322 end
- enc
->minBytesPerChar
* 3);
5325 normalizeLines(data
);
5326 commentHandler(handlerArg
, data
);
5327 poolClear(&tempPool
);
5332 reportDefault(XML_Parser parser
, const ENCODING
*enc
,
5333 const char *s
, const char *end
)
5335 if (MUST_CONVERT(enc
, s
)) {
5336 const char **eventPP
;
5337 const char **eventEndPP
;
5338 if (enc
== encoding
) {
5339 eventPP
= &eventPtr
;
5340 eventEndPP
= &eventEndPtr
;
5343 eventPP
= &(openInternalEntities
->internalEventPtr
);
5344 eventEndPP
= &(openInternalEntities
->internalEventEndPtr
);
5347 ICHAR
*dataPtr
= (ICHAR
*)dataBuf
;
5348 XmlConvert(enc
, &s
, end
, &dataPtr
, (ICHAR
*)dataBufEnd
);
5350 defaultHandler(handlerArg
, dataBuf
, (int)(dataPtr
- (ICHAR
*)dataBuf
));
5355 defaultHandler(handlerArg
, (XML_Char
*)s
, (int)((XML_Char
*)end
- (XML_Char
*)s
));
5360 defineAttribute(ELEMENT_TYPE
*type
, ATTRIBUTE_ID
*attId
, XML_Bool isCdata
,
5361 XML_Bool isId
, const XML_Char
*value
, XML_Parser parser
)
5363 DEFAULT_ATTRIBUTE
*att
;
5364 if (value
|| isId
) {
5365 /* The handling of default attributes gets messed up if we have
5366 a default which duplicates a non-default. */
5368 for (i
= 0; i
< type
->nDefaultAtts
; i
++)
5369 if (attId
== type
->defaultAtts
[i
].id
)
5371 if (isId
&& !type
->idAtt
&& !attId
->xmlns
)
5372 type
->idAtt
= attId
;
5374 if (type
->nDefaultAtts
== type
->allocDefaultAtts
) {
5375 if (type
->allocDefaultAtts
== 0) {
5376 type
->allocDefaultAtts
= 8;
5377 type
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)MALLOC(type
->allocDefaultAtts
5378 * sizeof(DEFAULT_ATTRIBUTE
));
5379 if (!type
->defaultAtts
)
5383 DEFAULT_ATTRIBUTE
*temp
;
5384 int count
= type
->allocDefaultAtts
* 2;
5385 temp
= (DEFAULT_ATTRIBUTE
*)
5386 REALLOC(type
->defaultAtts
, (count
* sizeof(DEFAULT_ATTRIBUTE
)));
5389 type
->allocDefaultAtts
= count
;
5390 type
->defaultAtts
= temp
;
5393 att
= type
->defaultAtts
+ type
->nDefaultAtts
;
5396 att
->isCdata
= isCdata
;
5398 attId
->maybeTokenized
= XML_TRUE
;
5399 type
->nDefaultAtts
+= 1;
5404 setElementTypePrefix(XML_Parser parser
, ELEMENT_TYPE
*elementType
)
5406 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5407 const XML_Char
*name
;
5408 for (name
= elementType
->name
; *name
; name
++) {
5409 if (*name
== XML_T(ASCII_COLON
)) {
5412 for (s
= elementType
->name
; s
!= name
; s
++) {
5413 if (!poolAppendChar(&dtd
->pool
, *s
))
5416 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5418 prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&dtd
->pool
),
5422 if (prefix
->name
== poolStart(&dtd
->pool
))
5423 poolFinish(&dtd
->pool
);
5425 poolDiscard(&dtd
->pool
);
5426 elementType
->prefix
= prefix
;
5433 static ATTRIBUTE_ID
*
5434 getAttributeId(XML_Parser parser
, const ENCODING
*enc
,
5435 const char *start
, const char *end
)
5437 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5439 const XML_Char
*name
;
5440 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5442 name
= poolStoreString(&dtd
->pool
, enc
, start
, end
);
5445 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5447 id
= (ATTRIBUTE_ID
*)lookup(parser
, &dtd
->attributeIds
, name
, sizeof(ATTRIBUTE_ID
));
5450 if (id
->name
!= name
)
5451 poolDiscard(&dtd
->pool
);
5453 poolFinish(&dtd
->pool
);
5456 else if (name
[0] == XML_T(ASCII_x
)
5457 && name
[1] == XML_T(ASCII_m
)
5458 && name
[2] == XML_T(ASCII_l
)
5459 && name
[3] == XML_T(ASCII_n
)
5460 && name
[4] == XML_T(ASCII_s
)
5461 && (name
[5] == XML_T('\0') || name
[5] == XML_T(ASCII_COLON
))) {
5462 if (name
[5] == XML_T('\0'))
5463 id
->prefix
= &dtd
->defaultPrefix
;
5465 id
->prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, name
+ 6, sizeof(PREFIX
));
5466 id
->xmlns
= XML_TRUE
;
5470 for (i
= 0; name
[i
]; i
++) {
5471 /* attributes without prefix are *not* in the default namespace */
5472 if (name
[i
] == XML_T(ASCII_COLON
)) {
5474 for (j
= 0; j
< i
; j
++) {
5475 if (!poolAppendChar(&dtd
->pool
, name
[j
]))
5478 if (!poolAppendChar(&dtd
->pool
, XML_T('\0')))
5480 id
->prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&dtd
->pool
),
5482 if (id
->prefix
->name
== poolStart(&dtd
->pool
))
5483 poolFinish(&dtd
->pool
);
5485 poolDiscard(&dtd
->pool
);
5494 #define CONTEXT_SEP XML_T(ASCII_FF)
5496 static const XML_Char
*
5497 getContext(XML_Parser parser
)
5499 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5500 HASH_TABLE_ITER iter
;
5501 XML_Bool needSep
= XML_FALSE
;
5503 if (dtd
->defaultPrefix
.binding
) {
5506 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5508 len
= dtd
->defaultPrefix
.binding
->uriLen
;
5509 if (namespaceSeparator
)
5511 for (i
= 0; i
< len
; i
++)
5512 if (!poolAppendChar(&tempPool
, dtd
->defaultPrefix
.binding
->uri
[i
]))
5517 hashTableIterInit(&iter
, &(dtd
->prefixes
));
5522 PREFIX
*prefix
= (PREFIX
*)hashTableIterNext(&iter
);
5525 if (!prefix
->binding
)
5527 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5529 for (s
= prefix
->name
; *s
; s
++)
5530 if (!poolAppendChar(&tempPool
, *s
))
5532 if (!poolAppendChar(&tempPool
, XML_T(ASCII_EQUALS
)))
5534 len
= prefix
->binding
->uriLen
;
5535 if (namespaceSeparator
)
5537 for (i
= 0; i
< len
; i
++)
5538 if (!poolAppendChar(&tempPool
, prefix
->binding
->uri
[i
]))
5544 hashTableIterInit(&iter
, &(dtd
->generalEntities
));
5547 ENTITY
*e
= (ENTITY
*)hashTableIterNext(&iter
);
5552 if (needSep
&& !poolAppendChar(&tempPool
, CONTEXT_SEP
))
5554 for (s
= e
->name
; *s
; s
++)
5555 if (!poolAppendChar(&tempPool
, *s
))
5560 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5562 return tempPool
.start
;
5566 setContext(XML_Parser parser
, const XML_Char
*context
)
5568 DTD
* const dtd
= _dtd
; /* save one level of indirection */
5569 const XML_Char
*s
= context
;
5571 while (*context
!= XML_T('\0')) {
5572 if (*s
== CONTEXT_SEP
|| *s
== XML_T('\0')) {
5574 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5576 e
= (ENTITY
*)lookup(parser
, &dtd
->generalEntities
, poolStart(&tempPool
), 0);
5579 if (*s
!= XML_T('\0'))
5582 poolDiscard(&tempPool
);
5584 else if (*s
== XML_T(ASCII_EQUALS
)) {
5586 if (poolLength(&tempPool
) == 0)
5587 prefix
= &dtd
->defaultPrefix
;
5589 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5591 prefix
= (PREFIX
*)lookup(parser
, &dtd
->prefixes
, poolStart(&tempPool
),
5595 if (prefix
->name
== poolStart(&tempPool
)) {
5596 prefix
->name
= poolCopyString(&dtd
->pool
, prefix
->name
);
5600 poolDiscard(&tempPool
);
5602 for (context
= s
+ 1;
5603 *context
!= CONTEXT_SEP
&& *context
!= XML_T('\0');
5605 if (!poolAppendChar(&tempPool
, *context
))
5607 if (!poolAppendChar(&tempPool
, XML_T('\0')))
5609 if (addBinding(parser
, prefix
, NULL
, poolStart(&tempPool
),
5610 &inheritedBindings
) != XML_ERROR_NONE
)
5612 poolDiscard(&tempPool
);
5613 if (*context
!= XML_T('\0'))
5618 if (!poolAppendChar(&tempPool
, *s
))
5626 static void FASTCALL
5627 normalizePublicId(XML_Char
*publicId
)
5629 XML_Char
*p
= publicId
;
5631 for (s
= publicId
; *s
; s
++) {
5636 if (p
!= publicId
&& p
[-1] != 0x20)
5643 if (p
!= publicId
&& p
[-1] == 0x20)
5649 dtdCreate(const XML_Memory_Handling_Suite
*ms
)
5651 DTD
*p
= (DTD
*)ms
->malloc_fcn(sizeof(DTD
));
5654 poolInit(&(p
->pool
), ms
);
5655 poolInit(&(p
->entityValuePool
), ms
);
5656 hashTableInit(&(p
->generalEntities
), ms
);
5657 hashTableInit(&(p
->elementTypes
), ms
);
5658 hashTableInit(&(p
->attributeIds
), ms
);
5659 hashTableInit(&(p
->prefixes
), ms
);
5661 p
->paramEntityRead
= XML_FALSE
;
5662 hashTableInit(&(p
->paramEntities
), ms
);
5663 #endif /* XML_DTD */
5664 p
->defaultPrefix
.name
= NULL
;
5665 p
->defaultPrefix
.binding
= NULL
;
5667 p
->in_eldecl
= XML_FALSE
;
5668 p
->scaffIndex
= NULL
;
5673 p
->contentStringLen
= 0;
5675 p
->keepProcessing
= XML_TRUE
;
5676 p
->hasParamEntityRefs
= XML_FALSE
;
5677 p
->standalone
= XML_FALSE
;
5682 dtdReset(DTD
*p
, const XML_Memory_Handling_Suite
*ms
)
5684 HASH_TABLE_ITER iter
;
5685 hashTableIterInit(&iter
, &(p
->elementTypes
));
5687 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5690 if (e
->allocDefaultAtts
!= 0)
5691 ms
->free_fcn(e
->defaultAtts
);
5693 hashTableClear(&(p
->generalEntities
));
5695 p
->paramEntityRead
= XML_FALSE
;
5696 hashTableClear(&(p
->paramEntities
));
5697 #endif /* XML_DTD */
5698 hashTableClear(&(p
->elementTypes
));
5699 hashTableClear(&(p
->attributeIds
));
5700 hashTableClear(&(p
->prefixes
));
5701 poolClear(&(p
->pool
));
5702 poolClear(&(p
->entityValuePool
));
5703 p
->defaultPrefix
.name
= NULL
;
5704 p
->defaultPrefix
.binding
= NULL
;
5706 p
->in_eldecl
= XML_FALSE
;
5708 ms
->free_fcn(p
->scaffIndex
);
5709 p
->scaffIndex
= NULL
;
5710 ms
->free_fcn(p
->scaffold
);
5716 p
->contentStringLen
= 0;
5718 p
->keepProcessing
= XML_TRUE
;
5719 p
->hasParamEntityRefs
= XML_FALSE
;
5720 p
->standalone
= XML_FALSE
;
5724 dtdDestroy(DTD
*p
, XML_Bool isDocEntity
, const XML_Memory_Handling_Suite
*ms
)
5726 HASH_TABLE_ITER iter
;
5727 hashTableIterInit(&iter
, &(p
->elementTypes
));
5729 ELEMENT_TYPE
*e
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5732 if (e
->allocDefaultAtts
!= 0)
5733 ms
->free_fcn(e
->defaultAtts
);
5735 hashTableDestroy(&(p
->generalEntities
));
5737 hashTableDestroy(&(p
->paramEntities
));
5738 #endif /* XML_DTD */
5739 hashTableDestroy(&(p
->elementTypes
));
5740 hashTableDestroy(&(p
->attributeIds
));
5741 hashTableDestroy(&(p
->prefixes
));
5742 poolDestroy(&(p
->pool
));
5743 poolDestroy(&(p
->entityValuePool
));
5745 ms
->free_fcn(p
->scaffIndex
);
5746 ms
->free_fcn(p
->scaffold
);
5751 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5752 The new DTD has already been initialized.
5755 dtdCopy(XML_Parser oldParser
, DTD
*newDtd
, const DTD
*oldDtd
, const XML_Memory_Handling_Suite
*ms
)
5757 HASH_TABLE_ITER iter
;
5759 /* Copy the prefix table. */
5761 hashTableIterInit(&iter
, &(oldDtd
->prefixes
));
5763 const XML_Char
*name
;
5764 const PREFIX
*oldP
= (PREFIX
*)hashTableIterNext(&iter
);
5767 name
= poolCopyString(&(newDtd
->pool
), oldP
->name
);
5770 if (!lookup(oldParser
, &(newDtd
->prefixes
), name
, sizeof(PREFIX
)))
5774 hashTableIterInit(&iter
, &(oldDtd
->attributeIds
));
5776 /* Copy the attribute id table. */
5780 const XML_Char
*name
;
5781 const ATTRIBUTE_ID
*oldA
= (ATTRIBUTE_ID
*)hashTableIterNext(&iter
);
5785 /* Remember to allocate the scratch byte before the name. */
5786 if (!poolAppendChar(&(newDtd
->pool
), XML_T('\0')))
5788 name
= poolCopyString(&(newDtd
->pool
), oldA
->name
);
5792 newA
= (ATTRIBUTE_ID
*)lookup(oldParser
, &(newDtd
->attributeIds
), name
,
5793 sizeof(ATTRIBUTE_ID
));
5796 newA
->maybeTokenized
= oldA
->maybeTokenized
;
5798 newA
->xmlns
= oldA
->xmlns
;
5799 if (oldA
->prefix
== &oldDtd
->defaultPrefix
)
5800 newA
->prefix
= &newDtd
->defaultPrefix
;
5802 newA
->prefix
= (PREFIX
*)lookup(oldParser
, &(newDtd
->prefixes
),
5803 oldA
->prefix
->name
, 0);
5807 /* Copy the element type table. */
5809 hashTableIterInit(&iter
, &(oldDtd
->elementTypes
));
5814 const XML_Char
*name
;
5815 const ELEMENT_TYPE
*oldE
= (ELEMENT_TYPE
*)hashTableIterNext(&iter
);
5818 name
= poolCopyString(&(newDtd
->pool
), oldE
->name
);
5821 newE
= (ELEMENT_TYPE
*)lookup(oldParser
, &(newDtd
->elementTypes
), name
,
5822 sizeof(ELEMENT_TYPE
));
5825 if (oldE
->nDefaultAtts
) {
5826 newE
->defaultAtts
= (DEFAULT_ATTRIBUTE
*)
5827 ms
->malloc_fcn(oldE
->nDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE
));
5828 if (!newE
->defaultAtts
) {
5834 newE
->idAtt
= (ATTRIBUTE_ID
*)
5835 lookup(oldParser
, &(newDtd
->attributeIds
), oldE
->idAtt
->name
, 0);
5836 newE
->allocDefaultAtts
= newE
->nDefaultAtts
= oldE
->nDefaultAtts
;
5838 newE
->prefix
= (PREFIX
*)lookup(oldParser
, &(newDtd
->prefixes
),
5839 oldE
->prefix
->name
, 0);
5840 for (i
= 0; i
< newE
->nDefaultAtts
; i
++) {
5841 newE
->defaultAtts
[i
].id
= (ATTRIBUTE_ID
*)
5842 lookup(oldParser
, &(newDtd
->attributeIds
), oldE
->defaultAtts
[i
].id
->name
, 0);
5843 newE
->defaultAtts
[i
].isCdata
= oldE
->defaultAtts
[i
].isCdata
;
5844 if (oldE
->defaultAtts
[i
].value
) {
5845 newE
->defaultAtts
[i
].value
5846 = poolCopyString(&(newDtd
->pool
), oldE
->defaultAtts
[i
].value
);
5847 if (!newE
->defaultAtts
[i
].value
)
5851 newE
->defaultAtts
[i
].value
= NULL
;
5855 /* Copy the entity tables. */
5856 if (!copyEntityTable(oldParser
,
5857 &(newDtd
->generalEntities
),
5859 &(oldDtd
->generalEntities
)))
5863 if (!copyEntityTable(oldParser
,
5864 &(newDtd
->paramEntities
),
5866 &(oldDtd
->paramEntities
)))
5868 newDtd
->paramEntityRead
= oldDtd
->paramEntityRead
;
5869 #endif /* XML_DTD */
5871 newDtd
->keepProcessing
= oldDtd
->keepProcessing
;
5872 newDtd
->hasParamEntityRefs
= oldDtd
->hasParamEntityRefs
;
5873 newDtd
->standalone
= oldDtd
->standalone
;
5875 /* Don't want deep copying for scaffolding */
5876 newDtd
->in_eldecl
= oldDtd
->in_eldecl
;
5877 newDtd
->scaffold
= oldDtd
->scaffold
;
5878 newDtd
->contentStringLen
= oldDtd
->contentStringLen
;
5879 newDtd
->scaffSize
= oldDtd
->scaffSize
;
5880 newDtd
->scaffLevel
= oldDtd
->scaffLevel
;
5881 newDtd
->scaffIndex
= oldDtd
->scaffIndex
;
5887 copyEntityTable(XML_Parser oldParser
,
5888 HASH_TABLE
*newTable
,
5889 STRING_POOL
*newPool
,
5890 const HASH_TABLE
*oldTable
)
5892 HASH_TABLE_ITER iter
;
5893 const XML_Char
*cachedOldBase
= NULL
;
5894 const XML_Char
*cachedNewBase
= NULL
;
5896 hashTableIterInit(&iter
, oldTable
);
5900 const XML_Char
*name
;
5901 const ENTITY
*oldE
= (ENTITY
*)hashTableIterNext(&iter
);
5904 name
= poolCopyString(newPool
, oldE
->name
);
5907 newE
= (ENTITY
*)lookup(oldParser
, newTable
, name
, sizeof(ENTITY
));
5910 if (oldE
->systemId
) {
5911 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->systemId
);
5914 newE
->systemId
= tem
;
5916 if (oldE
->base
== cachedOldBase
)
5917 newE
->base
= cachedNewBase
;
5919 cachedOldBase
= oldE
->base
;
5920 tem
= poolCopyString(newPool
, cachedOldBase
);
5923 cachedNewBase
= newE
->base
= tem
;
5926 if (oldE
->publicId
) {
5927 tem
= poolCopyString(newPool
, oldE
->publicId
);
5930 newE
->publicId
= tem
;
5934 const XML_Char
*tem
= poolCopyStringN(newPool
, oldE
->textPtr
,
5938 newE
->textPtr
= tem
;
5939 newE
->textLen
= oldE
->textLen
;
5941 if (oldE
->notation
) {
5942 const XML_Char
*tem
= poolCopyString(newPool
, oldE
->notation
);
5945 newE
->notation
= tem
;
5947 newE
->is_param
= oldE
->is_param
;
5948 newE
->is_internal
= oldE
->is_internal
;
5953 #define INIT_POWER 6
5955 static XML_Bool FASTCALL
5956 keyeq(KEY s1
, KEY s2
)
5958 for (; *s1
== *s2
; s1
++, s2
++)
5964 static unsigned long FASTCALL
5965 hash(XML_Parser parser
, KEY s
)
5967 unsigned long h
= hash_secret_salt
;
5969 h
= CHAR_HASH(h
, *s
++);
5974 lookup(XML_Parser parser
, HASH_TABLE
*table
, KEY name
, size_t createSize
)
5977 if (table
->size
== 0) {
5981 table
->power
= INIT_POWER
;
5982 /* table->size is a power of 2 */
5983 table
->size
= (size_t)1 << INIT_POWER
;
5984 tsize
= table
->size
* sizeof(NAMED
*);
5985 table
->v
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
5990 memset(table
->v
, 0, tsize
);
5991 i
= hash(parser
, name
) & ((unsigned long)table
->size
- 1);
5994 unsigned long h
= hash(parser
, name
);
5995 unsigned long mask
= (unsigned long)table
->size
- 1;
5996 unsigned char step
= 0;
5998 while (table
->v
[i
]) {
5999 if (keyeq(name
, table
->v
[i
]->name
))
6002 step
= PROBE_STEP(h
, mask
, table
->power
);
6003 i
< step
? (i
+= table
->size
- step
) : (i
-= step
);
6008 /* check for overflow (table is half full) */
6009 if (table
->used
>> (table
->power
- 1)) {
6010 unsigned char newPower
= table
->power
+ 1;
6011 size_t newSize
= (size_t)1 << newPower
;
6012 unsigned long newMask
= (unsigned long)newSize
- 1;
6013 size_t tsize
= newSize
* sizeof(NAMED
*);
6014 NAMED
**newV
= (NAMED
**)table
->mem
->malloc_fcn(tsize
);
6017 memset(newV
, 0, tsize
);
6018 for (i
= 0; i
< table
->size
; i
++)
6020 unsigned long newHash
= hash(parser
, table
->v
[i
]->name
);
6021 size_t j
= newHash
& newMask
;
6025 step
= PROBE_STEP(newHash
, newMask
, newPower
);
6026 j
< step
? (j
+= newSize
- step
) : (j
-= step
);
6028 newV
[j
] = table
->v
[i
];
6030 table
->mem
->free_fcn(table
->v
);
6032 table
->power
= newPower
;
6033 table
->size
= newSize
;
6036 while (table
->v
[i
]) {
6038 step
= PROBE_STEP(h
, newMask
, newPower
);
6039 i
< step
? (i
+= newSize
- step
) : (i
-= step
);
6043 table
->v
[i
] = (NAMED
*)table
->mem
->malloc_fcn(createSize
);
6046 memset(table
->v
[i
], 0, createSize
);
6047 table
->v
[i
]->name
= name
;
6052 static void FASTCALL
6053 hashTableClear(HASH_TABLE
*table
)
6056 for (i
= 0; i
< table
->size
; i
++) {
6057 table
->mem
->free_fcn(table
->v
[i
]);
6063 static void FASTCALL
6064 hashTableDestroy(HASH_TABLE
*table
)
6067 for (i
= 0; i
< table
->size
; i
++)
6068 table
->mem
->free_fcn(table
->v
[i
]);
6069 table
->mem
->free_fcn(table
->v
);
6072 static void FASTCALL
6073 hashTableInit(HASH_TABLE
*p
, const XML_Memory_Handling_Suite
*ms
)
6082 static void FASTCALL
6083 hashTableIterInit(HASH_TABLE_ITER
*iter
, const HASH_TABLE
*table
)
6086 iter
->end
= iter
->p
+ table
->size
;
6089 static NAMED
* FASTCALL
6090 hashTableIterNext(HASH_TABLE_ITER
*iter
)
6092 while (iter
->p
!= iter
->end
) {
6093 NAMED
*tem
= *(iter
->p
)++;
6100 static void FASTCALL
6101 poolInit(STRING_POOL
*pool
, const XML_Memory_Handling_Suite
*ms
)
6103 pool
->blocks
= NULL
;
6104 pool
->freeBlocks
= NULL
;
6111 static void FASTCALL
6112 poolClear(STRING_POOL
*pool
)
6114 if (!pool
->freeBlocks
)
6115 pool
->freeBlocks
= pool
->blocks
;
6117 BLOCK
*p
= pool
->blocks
;
6119 BLOCK
*tem
= p
->next
;
6120 p
->next
= pool
->freeBlocks
;
6121 pool
->freeBlocks
= p
;
6125 pool
->blocks
= NULL
;
6131 static void FASTCALL
6132 poolDestroy(STRING_POOL
*pool
)
6134 BLOCK
*p
= pool
->blocks
;
6136 BLOCK
*tem
= p
->next
;
6137 pool
->mem
->free_fcn(p
);
6140 p
= pool
->freeBlocks
;
6142 BLOCK
*tem
= p
->next
;
6143 pool
->mem
->free_fcn(p
);
6149 poolAppend(STRING_POOL
*pool
, const ENCODING
*enc
,
6150 const char *ptr
, const char *end
)
6152 if (!pool
->ptr
&& !poolGrow(pool
))
6155 XmlConvert(enc
, &ptr
, end
, (ICHAR
**)&(pool
->ptr
), (ICHAR
*)pool
->end
);
6158 if (!poolGrow(pool
))
6164 static const XML_Char
* FASTCALL
6165 poolCopyString(STRING_POOL
*pool
, const XML_Char
*s
)
6168 if (!poolAppendChar(pool
, *s
))
6176 static const XML_Char
*
6177 poolCopyStringN(STRING_POOL
*pool
, const XML_Char
*s
, int n
)
6179 if (!pool
->ptr
&& !poolGrow(pool
))
6181 for (; n
> 0; --n
, s
++) {
6182 if (!poolAppendChar(pool
, *s
))
6190 static const XML_Char
* FASTCALL
6191 poolAppendString(STRING_POOL
*pool
, const XML_Char
*s
)
6194 if (!poolAppendChar(pool
, *s
))
6202 poolStoreString(STRING_POOL
*pool
, const ENCODING
*enc
,
6203 const char *ptr
, const char *end
)
6205 if (!poolAppend(pool
, enc
, ptr
, end
))
6207 if (pool
->ptr
== pool
->end
&& !poolGrow(pool
))
6213 static XML_Bool FASTCALL
6214 poolGrow(STRING_POOL
*pool
)
6216 if (pool
->freeBlocks
) {
6217 if (pool
->start
== 0) {
6218 pool
->blocks
= pool
->freeBlocks
;
6219 pool
->freeBlocks
= pool
->freeBlocks
->next
;
6220 pool
->blocks
->next
= NULL
;
6221 pool
->start
= pool
->blocks
->s
;
6222 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6223 pool
->ptr
= pool
->start
;
6226 if (pool
->end
- pool
->start
< pool
->freeBlocks
->size
) {
6227 BLOCK
*tem
= pool
->freeBlocks
->next
;
6228 pool
->freeBlocks
->next
= pool
->blocks
;
6229 pool
->blocks
= pool
->freeBlocks
;
6230 pool
->freeBlocks
= tem
;
6231 memcpy(pool
->blocks
->s
, pool
->start
,
6232 (pool
->end
- pool
->start
) * sizeof(XML_Char
));
6233 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6234 pool
->start
= pool
->blocks
->s
;
6235 pool
->end
= pool
->start
+ pool
->blocks
->size
;
6239 if (pool
->blocks
&& pool
->start
== pool
->blocks
->s
) {
6240 int blockSize
= (int)(pool
->end
- pool
->start
)*2;
6241 BLOCK
*temp
= (BLOCK
*)
6242 pool
->mem
->realloc_fcn(pool
->blocks
,
6244 + blockSize
* sizeof(XML_Char
)));
6247 pool
->blocks
= temp
;
6248 pool
->blocks
->size
= blockSize
;
6249 pool
->ptr
= pool
->blocks
->s
+ (pool
->ptr
- pool
->start
);
6250 pool
->start
= pool
->blocks
->s
;
6251 pool
->end
= pool
->start
+ blockSize
;
6255 int blockSize
= (int)(pool
->end
- pool
->start
);
6256 if (blockSize
< INIT_BLOCK_SIZE
)
6257 blockSize
= INIT_BLOCK_SIZE
;
6260 tem
= (BLOCK
*)pool
->mem
->malloc_fcn(offsetof(BLOCK
, s
)
6261 + blockSize
* sizeof(XML_Char
));
6264 tem
->size
= blockSize
;
6265 tem
->next
= pool
->blocks
;
6267 if (pool
->ptr
!= pool
->start
)
6268 memcpy(tem
->s
, pool
->start
,
6269 (pool
->ptr
- pool
->start
) * sizeof(XML_Char
));
6270 pool
->ptr
= tem
->s
+ (pool
->ptr
- pool
->start
);
6271 pool
->start
= tem
->s
;
6272 pool
->end
= tem
->s
+ blockSize
;
6278 nextScaffoldPart(XML_Parser parser
)
6280 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6281 CONTENT_SCAFFOLD
* me
;
6284 if (!dtd
->scaffIndex
) {
6285 dtd
->scaffIndex
= (int *)MALLOC(groupSize
* sizeof(int));
6286 if (!dtd
->scaffIndex
)
6288 dtd
->scaffIndex
[0] = 0;
6291 if (dtd
->scaffCount
>= dtd
->scaffSize
) {
6292 CONTENT_SCAFFOLD
*temp
;
6293 if (dtd
->scaffold
) {
6294 temp
= (CONTENT_SCAFFOLD
*)
6295 REALLOC(dtd
->scaffold
, dtd
->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD
));
6298 dtd
->scaffSize
*= 2;
6301 temp
= (CONTENT_SCAFFOLD
*)MALLOC(INIT_SCAFFOLD_ELEMENTS
6302 * sizeof(CONTENT_SCAFFOLD
));
6305 dtd
->scaffSize
= INIT_SCAFFOLD_ELEMENTS
;
6307 dtd
->scaffold
= temp
;
6309 next
= dtd
->scaffCount
++;
6310 me
= &dtd
->scaffold
[next
];
6311 if (dtd
->scaffLevel
) {
6312 CONTENT_SCAFFOLD
*parent
= &dtd
->scaffold
[dtd
->scaffIndex
[dtd
->scaffLevel
-1]];
6313 if (parent
->lastchild
) {
6314 dtd
->scaffold
[parent
->lastchild
].nextsib
= next
;
6316 if (!parent
->childcnt
)
6317 parent
->firstchild
= next
;
6318 parent
->lastchild
= next
;
6321 me
->firstchild
= me
->lastchild
= me
->childcnt
= me
->nextsib
= 0;
6326 build_node(XML_Parser parser
,
6329 XML_Content
**contpos
,
6332 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6333 dest
->type
= dtd
->scaffold
[src_node
].type
;
6334 dest
->quant
= dtd
->scaffold
[src_node
].quant
;
6335 if (dest
->type
== XML_CTYPE_NAME
) {
6336 const XML_Char
*src
;
6337 dest
->name
= *strpos
;
6338 src
= dtd
->scaffold
[src_node
].name
;
6340 *(*strpos
)++ = *src
;
6345 dest
->numchildren
= 0;
6346 dest
->children
= NULL
;
6351 dest
->numchildren
= dtd
->scaffold
[src_node
].childcnt
;
6352 dest
->children
= *contpos
;
6353 *contpos
+= dest
->numchildren
;
6354 for (i
= 0, cn
= dtd
->scaffold
[src_node
].firstchild
;
6355 i
< dest
->numchildren
;
6356 i
++, cn
= dtd
->scaffold
[cn
].nextsib
) {
6357 build_node(parser
, cn
, &(dest
->children
[i
]), contpos
, strpos
);
6363 static XML_Content
*
6364 build_model (XML_Parser parser
)
6366 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6370 int allocsize
= (dtd
->scaffCount
* sizeof(XML_Content
)
6371 + (dtd
->contentStringLen
* sizeof(XML_Char
)));
6373 ret
= (XML_Content
*)MALLOC(allocsize
);
6377 str
= (XML_Char
*) (&ret
[dtd
->scaffCount
]);
6380 build_node(parser
, 0, ret
, &cpos
, &str
);
6384 static ELEMENT_TYPE
*
6385 getElementType(XML_Parser parser
,
6386 const ENCODING
*enc
,
6390 DTD
* const dtd
= _dtd
; /* save one level of indirection */
6391 const XML_Char
*name
= poolStoreString(&dtd
->pool
, enc
, ptr
, end
);
6396 ret
= (ELEMENT_TYPE
*) lookup(parser
, &dtd
->elementTypes
, name
, sizeof(ELEMENT_TYPE
));
6399 if (ret
->name
!= name
)
6400 poolDiscard(&dtd
->pool
);
6402 poolFinish(&dtd
->pool
);
6403 if (!setElementTypePrefix(parser
, ret
))