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