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