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