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