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