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