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