1 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd 2 See the file COPYING for copying permission. 3 */ 4 5 #define XML_BUILDING_EXPAT 1 6 7 #ifdef COMPILED_FROM_DSP 8 #include "winconfig.h" 9 #elif defined(MACOS_CLASSIC) 10 #include "macconfig.h" 11 #elif defined(__amigaos__) 12 #include "amigaconfig.h" 13 #elif defined(__WATCOMC__) 14 #include "watcomconfig.h" 15 #elif defined(HAVE_EXPAT_CONFIG_H) 16 #include <expat_config.h> 17 #endif /* ndef COMPILED_FROM_DSP */ 18 19 #include <stddef.h> 20 #include <string.h> /* memset(), memcpy() */ 21 #include <assert.h> 22 #include <limits.h> /* UINT_MAX */ 23 #include <time.h> /* time() */ 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 #ifdef XML_CONTEXT_BYTES 1697 int keep; 1698 #endif 1699 int neededSize = len + (int)(bufferEnd - bufferPtr); 1700 if (neededSize < 0) { 1701 errorCode = XML_ERROR_NO_MEMORY; 1702 return NULL; 1703 } 1704 #ifdef XML_CONTEXT_BYTES 1705 keep = (int)(bufferPtr - buffer); 1706 1707 if (keep > XML_CONTEXT_BYTES) 1708 keep = XML_CONTEXT_BYTES; 1709 neededSize += keep; 1710 #endif /* defined XML_CONTEXT_BYTES */ 1711 if (neededSize <= bufferLim - buffer) { 1712 #ifdef XML_CONTEXT_BYTES 1713 if (keep < bufferPtr - buffer) { 1714 int offset = (int)(bufferPtr - buffer) - keep; 1715 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep); 1716 bufferEnd -= offset; 1717 bufferPtr -= offset; 1718 } 1719 #else 1720 memmove(buffer, bufferPtr, bufferEnd - bufferPtr); 1721 bufferEnd = buffer + (bufferEnd - bufferPtr); 1722 bufferPtr = buffer; 1723 #endif /* not defined XML_CONTEXT_BYTES */ 1724 } 1725 else { 1726 char *newBuf; 1727 int bufferSize = (int)(bufferLim - bufferPtr); 1728 if (bufferSize == 0) 1729 bufferSize = INIT_BUFFER_SIZE; 1730 do { 1731 bufferSize *= 2; 1732 } while (bufferSize < neededSize && bufferSize > 0); 1733 if (bufferSize <= 0) { 1734 errorCode = XML_ERROR_NO_MEMORY; 1735 return NULL; 1736 } 1737 newBuf = (char *)MALLOC(bufferSize); 1738 if (newBuf == 0) { 1739 errorCode = XML_ERROR_NO_MEMORY; 1740 return NULL; 1741 } 1742 bufferLim = newBuf + bufferSize; 1743 #ifdef XML_CONTEXT_BYTES 1744 if (bufferPtr) { 1745 int keep = (int)(bufferPtr - buffer); 1746 if (keep > XML_CONTEXT_BYTES) 1747 keep = XML_CONTEXT_BYTES; 1748 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep); 1749 FREE(buffer); 1750 buffer = newBuf; 1751 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep; 1752 bufferPtr = buffer + keep; 1753 } 1754 else { 1755 bufferEnd = newBuf + (bufferEnd - bufferPtr); 1756 bufferPtr = buffer = newBuf; 1757 } 1758 #else 1759 if (bufferPtr) { 1760 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); 1761 FREE(buffer); 1762 } 1763 bufferEnd = newBuf + (bufferEnd - bufferPtr); 1764 bufferPtr = buffer = newBuf; 1765 #endif /* not defined XML_CONTEXT_BYTES */ 1766 } 1767 eventPtr = eventEndPtr = NULL; 1768 positionPtr = NULL; 1769 } 1770 return bufferEnd; 1771 } 1772 1773 enum XML_Status XMLCALL 1774 XML_StopParser(XML_Parser parser, XML_Bool resumable) 1775 { 1776 switch (ps_parsing) { 1777 case XML_SUSPENDED: 1778 if (resumable) { 1779 errorCode = XML_ERROR_SUSPENDED; 1780 return XML_STATUS_ERROR; 1781 } 1782 ps_parsing = XML_FINISHED; 1783 break; 1784 case XML_FINISHED: 1785 errorCode = XML_ERROR_FINISHED; 1786 return XML_STATUS_ERROR; 1787 default: 1788 if (resumable) { 1789 #ifdef XML_DTD 1790 if (isParamEntity) { 1791 errorCode = XML_ERROR_SUSPEND_PE; 1792 return XML_STATUS_ERROR; 1793 } 1794 #endif 1795 ps_parsing = XML_SUSPENDED; 1796 } 1797 else 1798 ps_parsing = XML_FINISHED; 1799 } 1800 return XML_STATUS_OK; 1801 } 1802 1803 enum XML_Status XMLCALL 1804 XML_ResumeParser(XML_Parser parser) 1805 { 1806 enum XML_Status result = XML_STATUS_OK; 1807 1808 if (ps_parsing != XML_SUSPENDED) { 1809 errorCode = XML_ERROR_NOT_SUSPENDED; 1810 return XML_STATUS_ERROR; 1811 } 1812 ps_parsing = XML_PARSING; 1813 1814 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); 1815 1816 if (errorCode != XML_ERROR_NONE) { 1817 eventEndPtr = eventPtr; 1818 processor = errorProcessor; 1819 return XML_STATUS_ERROR; 1820 } 1821 else { 1822 switch (ps_parsing) { 1823 case XML_SUSPENDED: 1824 result = XML_STATUS_SUSPENDED; 1825 break; 1826 case XML_INITIALIZED: 1827 case XML_PARSING: 1828 if (ps_finalBuffer) { 1829 ps_parsing = XML_FINISHED; 1830 return result; 1831 } 1832 default: ; 1833 } 1834 } 1835 1836 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); 1837 positionPtr = bufferPtr; 1838 return result; 1839 } 1840 1841 void XMLCALL 1842 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) 1843 { 1844 assert(status != NULL); 1845 *status = parser->m_parsingStatus; 1846 } 1847 1848 enum XML_Error XMLCALL 1849 XML_GetErrorCode(XML_Parser parser) 1850 { 1851 return errorCode; 1852 } 1853 1854 XML_Index XMLCALL 1855 XML_GetCurrentByteIndex(XML_Parser parser) 1856 { 1857 if (eventPtr) 1858 return parseEndByteIndex - (parseEndPtr - eventPtr); 1859 return -1; 1860 } 1861 1862 int XMLCALL 1863 XML_GetCurrentByteCount(XML_Parser parser) 1864 { 1865 if (eventEndPtr && eventPtr) 1866 return (int)(eventEndPtr - eventPtr); 1867 return 0; 1868 } 1869 1870 const char * XMLCALL 1871 XML_GetInputContext(XML_Parser parser, int *offset, int *size) 1872 { 1873 #ifdef XML_CONTEXT_BYTES 1874 if (eventPtr && buffer) { 1875 *offset = (int)(eventPtr - buffer); 1876 *size = (int)(bufferEnd - buffer); 1877 return buffer; 1878 } 1879 #endif /* defined XML_CONTEXT_BYTES */ 1880 return (char *) 0; 1881 } 1882 1883 XML_Size XMLCALL 1884 XML_GetCurrentLineNumber(XML_Parser parser) 1885 { 1886 if (eventPtr && eventPtr >= positionPtr) { 1887 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); 1888 positionPtr = eventPtr; 1889 } 1890 return position.lineNumber + 1; 1891 } 1892 1893 XML_Size XMLCALL 1894 XML_GetCurrentColumnNumber(XML_Parser parser) 1895 { 1896 if (eventPtr && eventPtr >= positionPtr) { 1897 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); 1898 positionPtr = eventPtr; 1899 } 1900 return position.columnNumber; 1901 } 1902 1903 void XMLCALL 1904 XML_FreeContentModel(XML_Parser parser, XML_Content *model) 1905 { 1906 FREE(model); 1907 } 1908 1909 void * XMLCALL 1910 XML_MemMalloc(XML_Parser parser, size_t size) 1911 { 1912 return MALLOC(size); 1913 } 1914 1915 void * XMLCALL 1916 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) 1917 { 1918 return REALLOC(ptr, size); 1919 } 1920 1921 void XMLCALL 1922 XML_MemFree(XML_Parser parser, void *ptr) 1923 { 1924 FREE(ptr); 1925 } 1926 1927 void XMLCALL 1928 XML_DefaultCurrent(XML_Parser parser) 1929 { 1930 if (defaultHandler) { 1931 if (openInternalEntities) 1932 reportDefault(parser, 1933 internalEncoding, 1934 openInternalEntities->internalEventPtr, 1935 openInternalEntities->internalEventEndPtr); 1936 else 1937 reportDefault(parser, encoding, eventPtr, eventEndPtr); 1938 } 1939 } 1940 1941 const XML_LChar * XMLCALL 1942 XML_ErrorString(enum XML_Error code) 1943 { 1944 static const XML_LChar* const message[] = { 1945 0, 1946 XML_L("out of memory"), 1947 XML_L("syntax error"), 1948 XML_L("no element found"), 1949 XML_L("not well-formed (invalid token)"), 1950 XML_L("unclosed token"), 1951 XML_L("partial character"), 1952 XML_L("mismatched tag"), 1953 XML_L("duplicate attribute"), 1954 XML_L("junk after document element"), 1955 XML_L("illegal parameter entity reference"), 1956 XML_L("undefined entity"), 1957 XML_L("recursive entity reference"), 1958 XML_L("asynchronous entity"), 1959 XML_L("reference to invalid character number"), 1960 XML_L("reference to binary entity"), 1961 XML_L("reference to external entity in attribute"), 1962 XML_L("XML or text declaration not at start of entity"), 1963 XML_L("unknown encoding"), 1964 XML_L("encoding specified in XML declaration is incorrect"), 1965 XML_L("unclosed CDATA section"), 1966 XML_L("error in processing external entity reference"), 1967 XML_L("document is not standalone"), 1968 XML_L("unexpected parser state - please send a bug report"), 1969 XML_L("entity declared in parameter entity"), 1970 XML_L("requested feature requires XML_DTD support in Expat"), 1971 XML_L("cannot change setting once parsing has begun"), 1972 XML_L("unbound prefix"), 1973 XML_L("must not undeclare prefix"), 1974 XML_L("incomplete markup in parameter entity"), 1975 XML_L("XML declaration not well-formed"), 1976 XML_L("text declaration not well-formed"), 1977 XML_L("illegal character(s) in public id"), 1978 XML_L("parser suspended"), 1979 XML_L("parser not suspended"), 1980 XML_L("parsing aborted"), 1981 XML_L("parsing finished"), 1982 XML_L("cannot suspend in external parameter entity"), 1983 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"), 1984 XML_L("reserved prefix (xmlns) must not be declared or undeclared"), 1985 XML_L("prefix must not be bound to one of the reserved namespace names") 1986 }; 1987 if (code > 0 && code < sizeof(message)/sizeof(message[0])) 1988 return message[code]; 1989 return NULL; 1990 } 1991 1992 const XML_LChar * XMLCALL 1993 XML_ExpatVersion(void) { 1994 1995 /* V1 is used to string-ize the version number. However, it would 1996 string-ize the actual version macro *names* unless we get them 1997 substituted before being passed to V1. CPP is defined to expand 1998 a macro, then rescan for more expansions. Thus, we use V2 to expand 1999 the version macros, then CPP will expand the resulting V1() macro 2000 with the correct numerals. */ 2001 /* ### I'm assuming cpp is portable in this respect... */ 2002 2003 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) 2004 #define V2(a,b,c) XML_L("expat_")V1(a,b,c) 2005 2006 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); 2007 2008 #undef V1 2009 #undef V2 2010 } 2011 2012 XML_Expat_Version XMLCALL 2013 XML_ExpatVersionInfo(void) 2014 { 2015 XML_Expat_Version version; 2016 2017 version.major = XML_MAJOR_VERSION; 2018 version.minor = XML_MINOR_VERSION; 2019 version.micro = XML_MICRO_VERSION; 2020 2021 return version; 2022 } 2023 2024 const XML_Feature * XMLCALL 2025 XML_GetFeatureList(void) 2026 { 2027 static const XML_Feature features[] = { 2028 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 2029 sizeof(XML_Char)}, 2030 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 2031 sizeof(XML_LChar)}, 2032 #ifdef XML_UNICODE 2033 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, 2034 #endif 2035 #ifdef XML_UNICODE_WCHAR_T 2036 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, 2037 #endif 2038 #ifdef XML_DTD 2039 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, 2040 #endif 2041 #ifdef XML_CONTEXT_BYTES 2042 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), 2043 XML_CONTEXT_BYTES}, 2044 #endif 2045 #ifdef XML_MIN_SIZE 2046 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, 2047 #endif 2048 #ifdef XML_NS 2049 {XML_FEATURE_NS, XML_L("XML_NS"), 0}, 2050 #endif 2051 #ifdef XML_LARGE_SIZE 2052 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, 2053 #endif 2054 #ifdef XML_ATTR_INFO 2055 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, 2056 #endif 2057 {XML_FEATURE_END, NULL, 0} 2058 }; 2059 2060 return features; 2061 } 2062 2063 /* Initially tag->rawName always points into the parse buffer; 2064 for those TAG instances opened while the current parse buffer was 2065 processed, and not yet closed, we need to store tag->rawName in a more 2066 permanent location, since the parse buffer is about to be discarded. 2067 */ 2068 static XML_Bool 2069 storeRawNames(XML_Parser parser) 2070 { 2071 TAG *tag = tagStack; 2072 while (tag) { 2073 int bufSize; 2074 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); 2075 char *rawNameBuf = tag->buf + nameLen; 2076 /* Stop if already stored. Since tagStack is a stack, we can stop 2077 at the first entry that has already been copied; everything 2078 below it in the stack is already been accounted for in a 2079 previous call to this function. 2080 */ 2081 if (tag->rawName == rawNameBuf) 2082 break; 2083 /* For re-use purposes we need to ensure that the 2084 size of tag->buf is a multiple of sizeof(XML_Char). 2085 */ 2086 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); 2087 if (bufSize > tag->bufEnd - tag->buf) { 2088 char *temp = (char *)REALLOC(tag->buf, bufSize); 2089 if (temp == NULL) 2090 return XML_FALSE; 2091 /* if tag->name.str points to tag->buf (only when namespace 2092 processing is off) then we have to update it 2093 */ 2094 if (tag->name.str == (XML_Char *)tag->buf) 2095 tag->name.str = (XML_Char *)temp; 2096 /* if tag->name.localPart is set (when namespace processing is on) 2097 then update it as well, since it will always point into tag->buf 2098 */ 2099 if (tag->name.localPart) 2100 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - 2101 (XML_Char *)tag->buf); 2102 tag->buf = temp; 2103 tag->bufEnd = temp + bufSize; 2104 rawNameBuf = temp + nameLen; 2105 } 2106 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); 2107 tag->rawName = rawNameBuf; 2108 tag = tag->parent; 2109 } 2110 return XML_TRUE; 2111 } 2112 2113 static enum XML_Error PTRCALL 2114 contentProcessor(XML_Parser parser, 2115 const char *start, 2116 const char *end, 2117 const char **endPtr) 2118 { 2119 enum XML_Error result = doContent(parser, 0, encoding, start, end, 2120 endPtr, (XML_Bool)!ps_finalBuffer); 2121 if (result == XML_ERROR_NONE) { 2122 if (!storeRawNames(parser)) 2123 return XML_ERROR_NO_MEMORY; 2124 } 2125 return result; 2126 } 2127 2128 static enum XML_Error PTRCALL 2129 externalEntityInitProcessor(XML_Parser parser, 2130 const char *start, 2131 const char *end, 2132 const char **endPtr) 2133 { 2134 enum XML_Error result = initializeEncoding(parser); 2135 if (result != XML_ERROR_NONE) 2136 return result; 2137 processor = externalEntityInitProcessor2; 2138 return externalEntityInitProcessor2(parser, start, end, endPtr); 2139 } 2140 2141 static enum XML_Error PTRCALL 2142 externalEntityInitProcessor2(XML_Parser parser, 2143 const char *start, 2144 const char *end, 2145 const char **endPtr) 2146 { 2147 const char *next = start; /* XmlContentTok doesn't always set the last arg */ 2148 int tok = XmlContentTok(encoding, start, end, &next); 2149 switch (tok) { 2150 case XML_TOK_BOM: 2151 /* If we are at the end of the buffer, this would cause the next stage, 2152 i.e. externalEntityInitProcessor3, to pass control directly to 2153 doContent (by detecting XML_TOK_NONE) without processing any xml text 2154 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. 2155 */ 2156 if (next == end && !ps_finalBuffer) { 2157 *endPtr = next; 2158 return XML_ERROR_NONE; 2159 } 2160 start = next; 2161 break; 2162 case XML_TOK_PARTIAL: 2163 if (!ps_finalBuffer) { 2164 *endPtr = start; 2165 return XML_ERROR_NONE; 2166 } 2167 eventPtr = start; 2168 return XML_ERROR_UNCLOSED_TOKEN; 2169 case XML_TOK_PARTIAL_CHAR: 2170 if (!ps_finalBuffer) { 2171 *endPtr = start; 2172 return XML_ERROR_NONE; 2173 } 2174 eventPtr = start; 2175 return XML_ERROR_PARTIAL_CHAR; 2176 } 2177 processor = externalEntityInitProcessor3; 2178 return externalEntityInitProcessor3(parser, start, end, endPtr); 2179 } 2180 2181 static enum XML_Error PTRCALL 2182 externalEntityInitProcessor3(XML_Parser parser, 2183 const char *start, 2184 const char *end, 2185 const char **endPtr) 2186 { 2187 int tok; 2188 const char *next = start; /* XmlContentTok doesn't always set the last arg */ 2189 eventPtr = start; 2190 tok = XmlContentTok(encoding, start, end, &next); 2191 eventEndPtr = next; 2192 2193 switch (tok) { 2194 case XML_TOK_XML_DECL: 2195 { 2196 enum XML_Error result; 2197 result = processXmlDecl(parser, 1, start, next); 2198 if (result != XML_ERROR_NONE) 2199 return result; 2200 switch (ps_parsing) { 2201 case XML_SUSPENDED: 2202 *endPtr = next; 2203 return XML_ERROR_NONE; 2204 case XML_FINISHED: 2205 return XML_ERROR_ABORTED; 2206 default: 2207 start = next; 2208 } 2209 } 2210 break; 2211 case XML_TOK_PARTIAL: 2212 if (!ps_finalBuffer) { 2213 *endPtr = start; 2214 return XML_ERROR_NONE; 2215 } 2216 return XML_ERROR_UNCLOSED_TOKEN; 2217 case XML_TOK_PARTIAL_CHAR: 2218 if (!ps_finalBuffer) { 2219 *endPtr = start; 2220 return XML_ERROR_NONE; 2221 } 2222 return XML_ERROR_PARTIAL_CHAR; 2223 } 2224 processor = externalEntityContentProcessor; 2225 tagLevel = 1; 2226 return externalEntityContentProcessor(parser, start, end, endPtr); 2227 } 2228 2229 static enum XML_Error PTRCALL 2230 externalEntityContentProcessor(XML_Parser parser, 2231 const char *start, 2232 const char *end, 2233 const char **endPtr) 2234 { 2235 enum XML_Error result = doContent(parser, 1, encoding, start, end, 2236 endPtr, (XML_Bool)!ps_finalBuffer); 2237 if (result == XML_ERROR_NONE) { 2238 if (!storeRawNames(parser)) 2239 return XML_ERROR_NO_MEMORY; 2240 } 2241 return result; 2242 } 2243 2244 static enum XML_Error 2245 doContent(XML_Parser parser, 2246 int startTagLevel, 2247 const ENCODING *enc, 2248 const char *s, 2249 const char *end, 2250 const char **nextPtr, 2251 XML_Bool haveMore) 2252 { 2253 /* save one level of indirection */ 2254 DTD * const dtd = _dtd; 2255 2256 const char **eventPP; 2257 const char **eventEndPP; 2258 if (enc == encoding) { 2259 eventPP = &eventPtr; 2260 eventEndPP = &eventEndPtr; 2261 } 2262 else { 2263 eventPP = &(openInternalEntities->internalEventPtr); 2264 eventEndPP = &(openInternalEntities->internalEventEndPtr); 2265 } 2266 *eventPP = s; 2267 2268 for (;;) { 2269 const char *next = s; /* XmlContentTok doesn't always set the last arg */ 2270 int tok = XmlContentTok(enc, s, end, &next); 2271 *eventEndPP = next; 2272 switch (tok) { 2273 case XML_TOK_TRAILING_CR: 2274 if (haveMore) { 2275 *nextPtr = s; 2276 return XML_ERROR_NONE; 2277 } 2278 *eventEndPP = end; 2279 if (characterDataHandler) { 2280 XML_Char c = 0xA; 2281 characterDataHandler(handlerArg, &c, 1); 2282 } 2283 else if (defaultHandler) 2284 reportDefault(parser, enc, s, end); 2285 /* We are at the end of the final buffer, should we check for 2286 XML_SUSPENDED, XML_FINISHED? 2287 */ 2288 if (startTagLevel == 0) 2289 return XML_ERROR_NO_ELEMENTS; 2290 if (tagLevel != startTagLevel) 2291 return XML_ERROR_ASYNC_ENTITY; 2292 *nextPtr = end; 2293 return XML_ERROR_NONE; 2294 case XML_TOK_NONE: 2295 if (haveMore) { 2296 *nextPtr = s; 2297 return XML_ERROR_NONE; 2298 } 2299 if (startTagLevel > 0) { 2300 if (tagLevel != startTagLevel) 2301 return XML_ERROR_ASYNC_ENTITY; 2302 *nextPtr = s; 2303 return XML_ERROR_NONE; 2304 } 2305 return XML_ERROR_NO_ELEMENTS; 2306 case XML_TOK_INVALID: 2307 *eventPP = next; 2308 return XML_ERROR_INVALID_TOKEN; 2309 case XML_TOK_PARTIAL: 2310 if (haveMore) { 2311 *nextPtr = s; 2312 return XML_ERROR_NONE; 2313 } 2314 return XML_ERROR_UNCLOSED_TOKEN; 2315 case XML_TOK_PARTIAL_CHAR: 2316 if (haveMore) { 2317 *nextPtr = s; 2318 return XML_ERROR_NONE; 2319 } 2320 return XML_ERROR_PARTIAL_CHAR; 2321 case XML_TOK_ENTITY_REF: 2322 { 2323 const XML_Char *name; 2324 ENTITY *entity; 2325 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, 2326 s + enc->minBytesPerChar, 2327 next - enc->minBytesPerChar); 2328 if (ch) { 2329 if (characterDataHandler) 2330 characterDataHandler(handlerArg, &ch, 1); 2331 else if (defaultHandler) 2332 reportDefault(parser, enc, s, next); 2333 break; 2334 } 2335 name = poolStoreString(&dtd->pool, enc, 2336 s + enc->minBytesPerChar, 2337 next - enc->minBytesPerChar); 2338 if (!name) 2339 return XML_ERROR_NO_MEMORY; 2340 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); 2341 poolDiscard(&dtd->pool); 2342 /* First, determine if a check for an existing declaration is needed; 2343 if yes, check that the entity exists, and that it is internal, 2344 otherwise call the skipped entity or default handler. 2345 */ 2346 if (!dtd->hasParamEntityRefs || dtd->standalone) { 2347 if (!entity) 2348 return XML_ERROR_UNDEFINED_ENTITY; 2349 else if (!entity->is_internal) 2350 return XML_ERROR_ENTITY_DECLARED_IN_PE; 2351 } 2352 else if (!entity) { 2353 if (skippedEntityHandler) 2354 skippedEntityHandler(handlerArg, name, 0); 2355 else if (defaultHandler) 2356 reportDefault(parser, enc, s, next); 2357 break; 2358 } 2359 if (entity->open) 2360 return XML_ERROR_RECURSIVE_ENTITY_REF; 2361 if (entity->notation) 2362 return XML_ERROR_BINARY_ENTITY_REF; 2363 if (entity->textPtr) { 2364 enum XML_Error result; 2365 if (!defaultExpandInternalEntities) { 2366 if (skippedEntityHandler) 2367 skippedEntityHandler(handlerArg, entity->name, 0); 2368 else if (defaultHandler) 2369 reportDefault(parser, enc, s, next); 2370 break; 2371 } 2372 result = processInternalEntity(parser, entity, XML_FALSE); 2373 if (result != XML_ERROR_NONE) 2374 return result; 2375 } 2376 else if (externalEntityRefHandler) { 2377 const XML_Char *context; 2378 entity->open = XML_TRUE; 2379 context = getContext(parser); 2380 entity->open = XML_FALSE; 2381 if (!context) 2382 return XML_ERROR_NO_MEMORY; 2383 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 2384 context, 2385 entity->base, 2386 entity->systemId, 2387 entity->publicId)) 2388 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 2389 poolDiscard(&tempPool); 2390 } 2391 else if (defaultHandler) 2392 reportDefault(parser, enc, s, next); 2393 break; 2394 } 2395 case XML_TOK_START_TAG_NO_ATTS: 2396 /* fall through */ 2397 case XML_TOK_START_TAG_WITH_ATTS: 2398 { 2399 TAG *tag; 2400 enum XML_Error result; 2401 XML_Char *toPtr; 2402 if (freeTagList) { 2403 tag = freeTagList; 2404 freeTagList = freeTagList->parent; 2405 } 2406 else { 2407 tag = (TAG *)MALLOC(sizeof(TAG)); 2408 if (!tag) 2409 return XML_ERROR_NO_MEMORY; 2410 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE); 2411 if (!tag->buf) { 2412 FREE(tag); 2413 return XML_ERROR_NO_MEMORY; 2414 } 2415 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; 2416 } 2417 tag->bindings = NULL; 2418 tag->parent = tagStack; 2419 tagStack = tag; 2420 tag->name.localPart = NULL; 2421 tag->name.prefix = NULL; 2422 tag->rawName = s + enc->minBytesPerChar; 2423 tag->rawNameLength = XmlNameLength(enc, tag->rawName); 2424 ++tagLevel; 2425 { 2426 const char *rawNameEnd = tag->rawName + tag->rawNameLength; 2427 const char *fromPtr = tag->rawName; 2428 toPtr = (XML_Char *)tag->buf; 2429 for (;;) { 2430 int bufSize; 2431 int convLen; 2432 XmlConvert(enc, 2433 &fromPtr, rawNameEnd, 2434 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); 2435 convLen = (int)(toPtr - (XML_Char *)tag->buf); 2436 if (fromPtr == rawNameEnd) { 2437 tag->name.strLen = convLen; 2438 break; 2439 } 2440 bufSize = (int)(tag->bufEnd - tag->buf) << 1; 2441 { 2442 char *temp = (char *)REALLOC(tag->buf, bufSize); 2443 if (temp == NULL) 2444 return XML_ERROR_NO_MEMORY; 2445 tag->buf = temp; 2446 tag->bufEnd = temp + bufSize; 2447 toPtr = (XML_Char *)temp + convLen; 2448 } 2449 } 2450 } 2451 tag->name.str = (XML_Char *)tag->buf; 2452 *toPtr = XML_T('\0'); 2453 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); 2454 if (result) 2455 return result; 2456 if (startElementHandler) 2457 startElementHandler(handlerArg, tag->name.str, 2458 (const XML_Char **)atts); 2459 else if (defaultHandler) 2460 reportDefault(parser, enc, s, next); 2461 poolClear(&tempPool); 2462 break; 2463 } 2464 case XML_TOK_EMPTY_ELEMENT_NO_ATTS: 2465 /* fall through */ 2466 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: 2467 { 2468 const char *rawName = s + enc->minBytesPerChar; 2469 enum XML_Error result; 2470 BINDING *bindings = NULL; 2471 XML_Bool noElmHandlers = XML_TRUE; 2472 TAG_NAME name; 2473 name.str = poolStoreString(&tempPool, enc, rawName, 2474 rawName + XmlNameLength(enc, rawName)); 2475 if (!name.str) 2476 return XML_ERROR_NO_MEMORY; 2477 poolFinish(&tempPool); 2478 result = storeAtts(parser, enc, s, &name, &bindings); 2479 if (result) 2480 return result; 2481 poolFinish(&tempPool); 2482 if (startElementHandler) { 2483 startElementHandler(handlerArg, name.str, (const XML_Char **)atts); 2484 noElmHandlers = XML_FALSE; 2485 } 2486 if (endElementHandler) { 2487 if (startElementHandler) 2488 *eventPP = *eventEndPP; 2489 endElementHandler(handlerArg, name.str); 2490 noElmHandlers = XML_FALSE; 2491 } 2492 if (noElmHandlers && defaultHandler) 2493 reportDefault(parser, enc, s, next); 2494 poolClear(&tempPool); 2495 while (bindings) { 2496 BINDING *b = bindings; 2497 if (endNamespaceDeclHandler) 2498 endNamespaceDeclHandler(handlerArg, b->prefix->name); 2499 bindings = bindings->nextTagBinding; 2500 b->nextTagBinding = freeBindingList; 2501 freeBindingList = b; 2502 b->prefix->binding = b->prevPrefixBinding; 2503 } 2504 } 2505 if (tagLevel == 0) 2506 return epilogProcessor(parser, next, end, nextPtr); 2507 break; 2508 case XML_TOK_END_TAG: 2509 if (tagLevel == startTagLevel) 2510 return XML_ERROR_ASYNC_ENTITY; 2511 else { 2512 int len; 2513 const char *rawName; 2514 TAG *tag = tagStack; 2515 tagStack = tag->parent; 2516 tag->parent = freeTagList; 2517 freeTagList = tag; 2518 rawName = s + enc->minBytesPerChar*2; 2519 len = XmlNameLength(enc, rawName); 2520 if (len != tag->rawNameLength 2521 || memcmp(tag->rawName, rawName, len) != 0) { 2522 *eventPP = rawName; 2523 return XML_ERROR_TAG_MISMATCH; 2524 } 2525 --tagLevel; 2526 if (endElementHandler) { 2527 const XML_Char *localPart; 2528 const XML_Char *prefix; 2529 XML_Char *uri; 2530 localPart = tag->name.localPart; 2531 if (ns && localPart) { 2532 /* localPart and prefix may have been overwritten in 2533 tag->name.str, since this points to the binding->uri 2534 buffer which gets re-used; so we have to add them again 2535 */ 2536 uri = (XML_Char *)tag->name.str + tag->name.uriLen; 2537 /* don't need to check for space - already done in storeAtts() */ 2538 while (*localPart) *uri++ = *localPart++; 2539 prefix = (XML_Char *)tag->name.prefix; 2540 if (ns_triplets && prefix) { 2541 *uri++ = namespaceSeparator; 2542 while (*prefix) *uri++ = *prefix++; 2543 } 2544 *uri = XML_T('\0'); 2545 } 2546 endElementHandler(handlerArg, tag->name.str); 2547 } 2548 else if (defaultHandler) 2549 reportDefault(parser, enc, s, next); 2550 while (tag->bindings) { 2551 BINDING *b = tag->bindings; 2552 if (endNamespaceDeclHandler) 2553 endNamespaceDeclHandler(handlerArg, b->prefix->name); 2554 tag->bindings = tag->bindings->nextTagBinding; 2555 b->nextTagBinding = freeBindingList; 2556 freeBindingList = b; 2557 b->prefix->binding = b->prevPrefixBinding; 2558 } 2559 if (tagLevel == 0) 2560 return epilogProcessor(parser, next, end, nextPtr); 2561 } 2562 break; 2563 case XML_TOK_CHAR_REF: 2564 { 2565 int n = XmlCharRefNumber(enc, s); 2566 if (n < 0) 2567 return XML_ERROR_BAD_CHAR_REF; 2568 if (characterDataHandler) { 2569 XML_Char buf[XML_ENCODE_MAX]; 2570 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); 2571 } 2572 else if (defaultHandler) 2573 reportDefault(parser, enc, s, next); 2574 } 2575 break; 2576 case XML_TOK_XML_DECL: 2577 return XML_ERROR_MISPLACED_XML_PI; 2578 case XML_TOK_DATA_NEWLINE: 2579 if (characterDataHandler) { 2580 XML_Char c = 0xA; 2581 characterDataHandler(handlerArg, &c, 1); 2582 } 2583 else if (defaultHandler) 2584 reportDefault(parser, enc, s, next); 2585 break; 2586 case XML_TOK_CDATA_SECT_OPEN: 2587 { 2588 enum XML_Error result; 2589 if (startCdataSectionHandler) 2590 startCdataSectionHandler(handlerArg); 2591 #if 0 2592 /* Suppose you doing a transformation on a document that involves 2593 changing only the character data. You set up a defaultHandler 2594 and a characterDataHandler. The defaultHandler simply copies 2595 characters through. The characterDataHandler does the 2596 transformation and writes the characters out escaping them as 2597 necessary. This case will fail to work if we leave out the 2598 following two lines (because & and < inside CDATA sections will 2599 be incorrectly escaped). 2600 2601 However, now we have a start/endCdataSectionHandler, so it seems 2602 easier to let the user deal with this. 2603 */ 2604 else if (characterDataHandler) 2605 characterDataHandler(handlerArg, dataBuf, 0); 2606 #endif 2607 else if (defaultHandler) 2608 reportDefault(parser, enc, s, next); 2609 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); 2610 if (result != XML_ERROR_NONE) 2611 return result; 2612 else if (!next) { 2613 processor = cdataSectionProcessor; 2614 return result; 2615 } 2616 } 2617 break; 2618 case XML_TOK_TRAILING_RSQB: 2619 if (haveMore) { 2620 *nextPtr = s; 2621 return XML_ERROR_NONE; 2622 } 2623 if (characterDataHandler) { 2624 if (MUST_CONVERT(enc, s)) { 2625 ICHAR *dataPtr = (ICHAR *)dataBuf; 2626 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); 2627 characterDataHandler(handlerArg, dataBuf, 2628 (int)(dataPtr - (ICHAR *)dataBuf)); 2629 } 2630 else 2631 characterDataHandler(handlerArg, 2632 (XML_Char *)s, 2633 (int)((XML_Char *)end - (XML_Char *)s)); 2634 } 2635 else if (defaultHandler) 2636 reportDefault(parser, enc, s, end); 2637 /* We are at the end of the final buffer, should we check for 2638 XML_SUSPENDED, XML_FINISHED? 2639 */ 2640 if (startTagLevel == 0) { 2641 *eventPP = end; 2642 return XML_ERROR_NO_ELEMENTS; 2643 } 2644 if (tagLevel != startTagLevel) { 2645 *eventPP = end; 2646 return XML_ERROR_ASYNC_ENTITY; 2647 } 2648 *nextPtr = end; 2649 return XML_ERROR_NONE; 2650 case XML_TOK_DATA_CHARS: 2651 { 2652 XML_CharacterDataHandler charDataHandler = characterDataHandler; 2653 if (charDataHandler) { 2654 if (MUST_CONVERT(enc, s)) { 2655 for (;;) { 2656 ICHAR *dataPtr = (ICHAR *)dataBuf; 2657 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); 2658 *eventEndPP = s; 2659 charDataHandler(handlerArg, dataBuf, 2660 (int)(dataPtr - (ICHAR *)dataBuf)); 2661 if (s == next) 2662 break; 2663 *eventPP = s; 2664 } 2665 } 2666 else 2667 charDataHandler(handlerArg, 2668 (XML_Char *)s, 2669 (int)((XML_Char *)next - (XML_Char *)s)); 2670 } 2671 else if (defaultHandler) 2672 reportDefault(parser, enc, s, next); 2673 } 2674 break; 2675 case XML_TOK_PI: 2676 if (!reportProcessingInstruction(parser, enc, s, next)) 2677 return XML_ERROR_NO_MEMORY; 2678 break; 2679 case XML_TOK_COMMENT: 2680 if (!reportComment(parser, enc, s, next)) 2681 return XML_ERROR_NO_MEMORY; 2682 break; 2683 default: 2684 if (defaultHandler) 2685 reportDefault(parser, enc, s, next); 2686 break; 2687 } 2688 *eventPP = s = next; 2689 switch (ps_parsing) { 2690 case XML_SUSPENDED: 2691 *nextPtr = next; 2692 return XML_ERROR_NONE; 2693 case XML_FINISHED: 2694 return XML_ERROR_ABORTED; 2695 default: ; 2696 } 2697 } 2698 /* not reached */ 2699 } 2700 2701 /* Precondition: all arguments must be non-NULL; 2702 Purpose: 2703 - normalize attributes 2704 - check attributes for well-formedness 2705 - generate namespace aware attribute names (URI, prefix) 2706 - build list of attributes for startElementHandler 2707 - default attributes 2708 - process namespace declarations (check and report them) 2709 - generate namespace aware element name (URI, prefix) 2710 */ 2711 static enum XML_Error 2712 storeAtts(XML_Parser parser, const ENCODING *enc, 2713 const char *attStr, TAG_NAME *tagNamePtr, 2714 BINDING **bindingsPtr) 2715 { 2716 DTD * const dtd = _dtd; /* save one level of indirection */ 2717 ELEMENT_TYPE *elementType; 2718 int nDefaultAtts; 2719 const XML_Char **appAtts; /* the attribute list for the application */ 2720 int attIndex = 0; 2721 int prefixLen; 2722 int i; 2723 int n; 2724 XML_Char *uri; 2725 int nPrefixes = 0; 2726 BINDING *binding; 2727 const XML_Char *localPart; 2728 2729 /* lookup the element type name */ 2730 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0); 2731 if (!elementType) { 2732 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); 2733 if (!name) 2734 return XML_ERROR_NO_MEMORY; 2735 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, 2736 sizeof(ELEMENT_TYPE)); 2737 if (!elementType) 2738 return XML_ERROR_NO_MEMORY; 2739 if (ns && !setElementTypePrefix(parser, elementType)) 2740 return XML_ERROR_NO_MEMORY; 2741 } 2742 nDefaultAtts = elementType->nDefaultAtts; 2743 2744 /* get the attributes from the tokenizer */ 2745 n = XmlGetAttributes(enc, attStr, attsSize, atts); 2746 if (n + nDefaultAtts > attsSize) { 2747 int oldAttsSize = attsSize; 2748 ATTRIBUTE *temp; 2749 #ifdef XML_ATTR_INFO 2750 XML_AttrInfo *temp2; 2751 #endif 2752 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; 2753 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); 2754 if (temp == NULL) 2755 return XML_ERROR_NO_MEMORY; 2756 atts = temp; 2757 #ifdef XML_ATTR_INFO 2758 temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo)); 2759 if (temp2 == NULL) 2760 return XML_ERROR_NO_MEMORY; 2761 attInfo = temp2; 2762 #endif 2763 if (n > oldAttsSize) 2764 XmlGetAttributes(enc, attStr, n, atts); 2765 } 2766 2767 appAtts = (const XML_Char **)atts; 2768 for (i = 0; i < n; i++) { 2769 ATTRIBUTE *currAtt = &atts[i]; 2770 #ifdef XML_ATTR_INFO 2771 XML_AttrInfo *currAttInfo = &attInfo[i]; 2772 #endif 2773 /* add the name and value to the attribute list */ 2774 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name, 2775 currAtt->name 2776 + XmlNameLength(enc, currAtt->name)); 2777 if (!attId) 2778 return XML_ERROR_NO_MEMORY; 2779 #ifdef XML_ATTR_INFO 2780 currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name); 2781 currAttInfo->nameEnd = currAttInfo->nameStart + 2782 XmlNameLength(enc, currAtt->name); 2783 currAttInfo->valueStart = parseEndByteIndex - 2784 (parseEndPtr - currAtt->valuePtr); 2785 currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd); 2786 #endif 2787 /* Detect duplicate attributes by their QNames. This does not work when 2788 namespace processing is turned on and different prefixes for the same 2789 namespace are used. For this case we have a check further down. 2790 */ 2791 if ((attId->name)[-1]) { 2792 if (enc == encoding) 2793 eventPtr = atts[i].name; 2794 return XML_ERROR_DUPLICATE_ATTRIBUTE; 2795 } 2796 (attId->name)[-1] = 1; 2797 appAtts[attIndex++] = attId->name; 2798 if (!atts[i].normalized) { 2799 enum XML_Error result; 2800 XML_Bool isCdata = XML_TRUE; 2801 2802 /* figure out whether declared as other than CDATA */ 2803 if (attId->maybeTokenized) { 2804 int j; 2805 for (j = 0; j < nDefaultAtts; j++) { 2806 if (attId == elementType->defaultAtts[j].id) { 2807 isCdata = elementType->defaultAtts[j].isCdata; 2808 break; 2809 } 2810 } 2811 } 2812 2813 /* normalize the attribute value */ 2814 result = storeAttributeValue(parser, enc, isCdata, 2815 atts[i].valuePtr, atts[i].valueEnd, 2816 &tempPool); 2817 if (result) 2818 return result; 2819 appAtts[attIndex] = poolStart(&tempPool); 2820 poolFinish(&tempPool); 2821 } 2822 else { 2823 /* the value did not need normalizing */ 2824 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, 2825 atts[i].valueEnd); 2826 if (appAtts[attIndex] == 0) 2827 return XML_ERROR_NO_MEMORY; 2828 poolFinish(&tempPool); 2829 } 2830 /* handle prefixed attribute names */ 2831 if (attId->prefix) { 2832 if (attId->xmlns) { 2833 /* deal with namespace declarations here */ 2834 enum XML_Error result = addBinding(parser, attId->prefix, attId, 2835 appAtts[attIndex], bindingsPtr); 2836 if (result) 2837 return result; 2838 --attIndex; 2839 } 2840 else { 2841 /* deal with other prefixed names later */ 2842 attIndex++; 2843 nPrefixes++; 2844 (attId->name)[-1] = 2; 2845 } 2846 } 2847 else 2848 attIndex++; 2849 } 2850 2851 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ 2852 nSpecifiedAtts = attIndex; 2853 if (elementType->idAtt && (elementType->idAtt->name)[-1]) { 2854 for (i = 0; i < attIndex; i += 2) 2855 if (appAtts[i] == elementType->idAtt->name) { 2856 idAttIndex = i; 2857 break; 2858 } 2859 } 2860 else 2861 idAttIndex = -1; 2862 2863 /* do attribute defaulting */ 2864 for (i = 0; i < nDefaultAtts; i++) { 2865 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; 2866 if (!(da->id->name)[-1] && da->value) { 2867 if (da->id->prefix) { 2868 if (da->id->xmlns) { 2869 enum XML_Error result = addBinding(parser, da->id->prefix, da->id, 2870 da->value, bindingsPtr); 2871 if (result) 2872 return result; 2873 } 2874 else { 2875 (da->id->name)[-1] = 2; 2876 nPrefixes++; 2877 appAtts[attIndex++] = da->id->name; 2878 appAtts[attIndex++] = da->value; 2879 } 2880 } 2881 else { 2882 (da->id->name)[-1] = 1; 2883 appAtts[attIndex++] = da->id->name; 2884 appAtts[attIndex++] = da->value; 2885 } 2886 } 2887 } 2888 appAtts[attIndex] = 0; 2889 2890 /* expand prefixed attribute names, check for duplicates, 2891 and clear flags that say whether attributes were specified */ 2892 i = 0; 2893 if (nPrefixes) { 2894 int j; /* hash table index */ 2895 unsigned long version = nsAttsVersion; 2896 int nsAttsSize = (int)1 << nsAttsPower; 2897 /* size of hash table must be at least 2 * (# of prefixed attributes) */ 2898 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */ 2899 NS_ATT *temp; 2900 /* hash table size must also be a power of 2 and >= 8 */ 2901 while (nPrefixes >> nsAttsPower++); 2902 if (nsAttsPower < 3) 2903 nsAttsPower = 3; 2904 nsAttsSize = (int)1 << nsAttsPower; 2905 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT)); 2906 if (!temp) 2907 return XML_ERROR_NO_MEMORY; 2908 nsAtts = temp; 2909 version = 0; /* force re-initialization of nsAtts hash table */ 2910 } 2911 /* using a version flag saves us from initializing nsAtts every time */ 2912 if (!version) { /* initialize version flags when version wraps around */ 2913 version = INIT_ATTS_VERSION; 2914 for (j = nsAttsSize; j != 0; ) 2915 nsAtts[--j].version = version; 2916 } 2917 nsAttsVersion = --version; 2918 2919 /* expand prefixed names and check for duplicates */ 2920 for (; i < attIndex; i += 2) { 2921 const XML_Char *s = appAtts[i]; 2922 if (s[-1] == 2) { /* prefixed */ 2923 ATTRIBUTE_ID *id; 2924 const BINDING *b; 2925 unsigned long uriHash = hash_secret_salt; 2926 ((XML_Char *)s)[-1] = 0; /* clear flag */ 2927 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); 2928 if (!id || !id->prefix) 2929 return XML_ERROR_NO_MEMORY; 2930 b = id->prefix->binding; 2931 if (!b) 2932 return XML_ERROR_UNBOUND_PREFIX; 2933 2934 /* as we expand the name we also calculate its hash value */ 2935 for (j = 0; j < b->uriLen; j++) { 2936 const XML_Char c = b->uri[j]; 2937 if (!poolAppendChar(&tempPool, c)) 2938 return XML_ERROR_NO_MEMORY; 2939 uriHash = CHAR_HASH(uriHash, c); 2940 } 2941 while (*s++ != XML_T(ASCII_COLON)) 2942 ; 2943 do { /* copies null terminator */ 2944 const XML_Char c = *s; 2945 if (!poolAppendChar(&tempPool, *s)) 2946 return XML_ERROR_NO_MEMORY; 2947 uriHash = CHAR_HASH(uriHash, c); 2948 } while (*s++); 2949 2950 { /* Check hash table for duplicate of expanded name (uriName). 2951 Derived from code in lookup(parser, HASH_TABLE *table, ...). 2952 */ 2953 unsigned char step = 0; 2954 unsigned long mask = nsAttsSize - 1; 2955 j = uriHash & mask; /* index into hash table */ 2956 while (nsAtts[j].version == version) { 2957 /* for speed we compare stored hash values first */ 2958 if (uriHash == nsAtts[j].hash) { 2959 const XML_Char *s1 = poolStart(&tempPool); 2960 const XML_Char *s2 = nsAtts[j].uriName; 2961 /* s1 is null terminated, but not s2 */ 2962 for (; *s1 == *s2 && *s1 != 0; s1++, s2++); 2963 if (*s1 == 0) 2964 return XML_ERROR_DUPLICATE_ATTRIBUTE; 2965 } 2966 if (!step) 2967 step = PROBE_STEP(uriHash, mask, nsAttsPower); 2968 j < step ? (j += nsAttsSize - step) : (j -= step); 2969 } 2970 } 2971 2972 if (ns_triplets) { /* append namespace separator and prefix */ 2973 tempPool.ptr[-1] = namespaceSeparator; 2974 s = b->prefix->name; 2975 do { 2976 if (!poolAppendChar(&tempPool, *s)) 2977 return XML_ERROR_NO_MEMORY; 2978 } while (*s++); 2979 } 2980 2981 /* store expanded name in attribute list */ 2982 s = poolStart(&tempPool); 2983 poolFinish(&tempPool); 2984 appAtts[i] = s; 2985 2986 /* fill empty slot with new version, uriName and hash value */ 2987 nsAtts[j].version = version; 2988 nsAtts[j].hash = uriHash; 2989 nsAtts[j].uriName = s; 2990 2991 if (!--nPrefixes) { 2992 i += 2; 2993 break; 2994 } 2995 } 2996 else /* not prefixed */ 2997 ((XML_Char *)s)[-1] = 0; /* clear flag */ 2998 } 2999 } 3000 /* clear flags for the remaining attributes */ 3001 for (; i < attIndex; i += 2) 3002 ((XML_Char *)(appAtts[i]))[-1] = 0; 3003 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) 3004 binding->attId->name[-1] = 0; 3005 3006 if (!ns) 3007 return XML_ERROR_NONE; 3008 3009 /* expand the element type name */ 3010 if (elementType->prefix) { 3011 binding = elementType->prefix->binding; 3012 if (!binding) 3013 return XML_ERROR_UNBOUND_PREFIX; 3014 localPart = tagNamePtr->str; 3015 while (*localPart++ != XML_T(ASCII_COLON)) 3016 ; 3017 } 3018 else if (dtd->defaultPrefix.binding) { 3019 binding = dtd->defaultPrefix.binding; 3020 localPart = tagNamePtr->str; 3021 } 3022 else 3023 return XML_ERROR_NONE; 3024 prefixLen = 0; 3025 if (ns_triplets && binding->prefix->name) { 3026 for (; binding->prefix->name[prefixLen++];) 3027 ; /* prefixLen includes null terminator */ 3028 } 3029 tagNamePtr->localPart = localPart; 3030 tagNamePtr->uriLen = binding->uriLen; 3031 tagNamePtr->prefix = binding->prefix->name; 3032 tagNamePtr->prefixLen = prefixLen; 3033 for (i = 0; localPart[i++];) 3034 ; /* i includes null terminator */ 3035 n = i + binding->uriLen + prefixLen; 3036 if (n > binding->uriAlloc) { 3037 TAG *p; 3038 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char)); 3039 if (!uri) 3040 return XML_ERROR_NO_MEMORY; 3041 binding->uriAlloc = n + EXPAND_SPARE; 3042 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); 3043 for (p = tagStack; p; p = p->parent) 3044 if (p->name.str == binding->uri) 3045 p->name.str = uri; 3046 FREE(binding->uri); 3047 binding->uri = uri; 3048 } 3049 /* if namespaceSeparator != '\0' then uri includes it already */ 3050 uri = binding->uri + binding->uriLen; 3051 memcpy(uri, localPart, i * sizeof(XML_Char)); 3052 /* we always have a namespace separator between localPart and prefix */ 3053 if (prefixLen) { 3054 uri += i - 1; 3055 *uri = namespaceSeparator; /* replace null terminator */ 3056 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); 3057 } 3058 tagNamePtr->str = binding->uri; 3059 return XML_ERROR_NONE; 3060 } 3061 3062 /* addBinding() overwrites the value of prefix->binding without checking. 3063 Therefore one must keep track of the old value outside of addBinding(). 3064 */ 3065 static enum XML_Error 3066 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, 3067 const XML_Char *uri, BINDING **bindingsPtr) 3068 { 3069 static const XML_Char xmlNamespace[] = { 3070 ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, 3071 ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, 3072 ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, 3073 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, 3074 ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, 3075 ASCII_e, '\0' 3076 }; 3077 static const int xmlLen = 3078 (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1; 3079 static const XML_Char xmlnsNamespace[] = { 3080 ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, 3081 ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, 3082 ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, 3083 ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, 3084 ASCII_SLASH, '\0' 3085 }; 3086 static const int xmlnsLen = 3087 (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1; 3088 3089 XML_Bool mustBeXML = XML_FALSE; 3090 XML_Bool isXML = XML_TRUE; 3091 XML_Bool isXMLNS = XML_TRUE; 3092 3093 BINDING *b; 3094 int len; 3095 3096 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ 3097 if (*uri == XML_T('\0') && prefix->name) 3098 return XML_ERROR_UNDECLARING_PREFIX; 3099 3100 if (prefix->name 3101 && prefix->name[0] == XML_T(ASCII_x) 3102 && prefix->name[1] == XML_T(ASCII_m) 3103 && prefix->name[2] == XML_T(ASCII_l)) { 3104 3105 /* Not allowed to bind xmlns */ 3106 if (prefix->name[3] == XML_T(ASCII_n) 3107 && prefix->name[4] == XML_T(ASCII_s) 3108 && prefix->name[5] == XML_T('\0')) 3109 return XML_ERROR_RESERVED_PREFIX_XMLNS; 3110 3111 if (prefix->name[3] == XML_T('\0')) 3112 mustBeXML = XML_TRUE; 3113 } 3114 3115 for (len = 0; uri[len]; len++) { 3116 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) 3117 isXML = XML_FALSE; 3118 3119 if (!mustBeXML && isXMLNS 3120 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) 3121 isXMLNS = XML_FALSE; 3122 } 3123 isXML = isXML && len == xmlLen; 3124 isXMLNS = isXMLNS && len == xmlnsLen; 3125 3126 if (mustBeXML != isXML) 3127 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML 3128 : XML_ERROR_RESERVED_NAMESPACE_URI; 3129 3130 if (isXMLNS) 3131 return XML_ERROR_RESERVED_NAMESPACE_URI; 3132 3133 if (namespaceSeparator) 3134 len++; 3135 if (freeBindingList) { 3136 b = freeBindingList; 3137 if (len > b->uriAlloc) { 3138 XML_Char *temp = (XML_Char *)REALLOC(b->uri, 3139 sizeof(XML_Char) * (len + EXPAND_SPARE)); 3140 if (temp == NULL) 3141 return XML_ERROR_NO_MEMORY; 3142 b->uri = temp; 3143 b->uriAlloc = len + EXPAND_SPARE; 3144 } 3145 freeBindingList = b->nextTagBinding; 3146 } 3147 else { 3148 b = (BINDING *)MALLOC(sizeof(BINDING)); 3149 if (!b) 3150 return XML_ERROR_NO_MEMORY; 3151 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE)); 3152 if (!b->uri) { 3153 FREE(b); 3154 return XML_ERROR_NO_MEMORY; 3155 } 3156 b->uriAlloc = len + EXPAND_SPARE; 3157 } 3158 b->uriLen = len; 3159 memcpy(b->uri, uri, len * sizeof(XML_Char)); 3160 if (namespaceSeparator) 3161 b->uri[len - 1] = namespaceSeparator; 3162 b->prefix = prefix; 3163 b->attId = attId; 3164 b->prevPrefixBinding = prefix->binding; 3165 /* NULL binding when default namespace undeclared */ 3166 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix) 3167 prefix->binding = NULL; 3168 else 3169 prefix->binding = b; 3170 b->nextTagBinding = *bindingsPtr; 3171 *bindingsPtr = b; 3172 /* if attId == NULL then we are not starting a namespace scope */ 3173 if (attId && startNamespaceDeclHandler) 3174 startNamespaceDeclHandler(handlerArg, prefix->name, 3175 prefix->binding ? uri : 0); 3176 return XML_ERROR_NONE; 3177 } 3178 3179 /* The idea here is to avoid using stack for each CDATA section when 3180 the whole file is parsed with one call. 3181 */ 3182 static enum XML_Error PTRCALL 3183 cdataSectionProcessor(XML_Parser parser, 3184 const char *start, 3185 const char *end, 3186 const char **endPtr) 3187 { 3188 enum XML_Error result = doCdataSection(parser, encoding, &start, end, 3189 endPtr, (XML_Bool)!ps_finalBuffer); 3190 if (result != XML_ERROR_NONE) 3191 return result; 3192 if (start) { 3193 if (parentParser) { /* we are parsing an external entity */ 3194 processor = externalEntityContentProcessor; 3195 return externalEntityContentProcessor(parser, start, end, endPtr); 3196 } 3197 else { 3198 processor = contentProcessor; 3199 return contentProcessor(parser, start, end, endPtr); 3200 } 3201 } 3202 return result; 3203 } 3204 3205 /* startPtr gets set to non-null if the section is closed, and to null if 3206 the section is not yet closed. 3207 */ 3208 static enum XML_Error 3209 doCdataSection(XML_Parser parser, 3210 const ENCODING *enc, 3211 const char **startPtr, 3212 const char *end, 3213 const char **nextPtr, 3214 XML_Bool haveMore) 3215 { 3216 const char *s = *startPtr; 3217 const char **eventPP; 3218 const char **eventEndPP; 3219 if (enc == encoding) { 3220 eventPP = &eventPtr; 3221 *eventPP = s; 3222 eventEndPP = &eventEndPtr; 3223 } 3224 else { 3225 eventPP = &(openInternalEntities->internalEventPtr); 3226 eventEndPP = &(openInternalEntities->internalEventEndPtr); 3227 } 3228 *eventPP = s; 3229 *startPtr = NULL; 3230 3231 for (;;) { 3232 const char *next; 3233 int tok = XmlCdataSectionTok(enc, s, end, &next); 3234 *eventEndPP = next; 3235 switch (tok) { 3236 case XML_TOK_CDATA_SECT_CLOSE: 3237 if (endCdataSectionHandler) 3238 endCdataSectionHandler(handlerArg); 3239 #if 0 3240 /* see comment under XML_TOK_CDATA_SECT_OPEN */ 3241 else if (characterDataHandler) 3242 characterDataHandler(handlerArg, dataBuf, 0); 3243 #endif 3244 else if (defaultHandler) 3245 reportDefault(parser, enc, s, next); 3246 *startPtr = next; 3247 *nextPtr = next; 3248 if (ps_parsing == XML_FINISHED) 3249 return XML_ERROR_ABORTED; 3250 else 3251 return XML_ERROR_NONE; 3252 case XML_TOK_DATA_NEWLINE: 3253 if (characterDataHandler) { 3254 XML_Char c = 0xA; 3255 characterDataHandler(handlerArg, &c, 1); 3256 } 3257 else if (defaultHandler) 3258 reportDefault(parser, enc, s, next); 3259 break; 3260 case XML_TOK_DATA_CHARS: 3261 { 3262 XML_CharacterDataHandler charDataHandler = characterDataHandler; 3263 if (charDataHandler) { 3264 if (MUST_CONVERT(enc, s)) { 3265 for (;;) { 3266 ICHAR *dataPtr = (ICHAR *)dataBuf; 3267 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); 3268 *eventEndPP = next; 3269 charDataHandler(handlerArg, dataBuf, 3270 (int)(dataPtr - (ICHAR *)dataBuf)); 3271 if (s == next) 3272 break; 3273 *eventPP = s; 3274 } 3275 } 3276 else 3277 charDataHandler(handlerArg, 3278 (XML_Char *)s, 3279 (int)((XML_Char *)next - (XML_Char *)s)); 3280 } 3281 else if (defaultHandler) 3282 reportDefault(parser, enc, s, next); 3283 } 3284 break; 3285 case XML_TOK_INVALID: 3286 *eventPP = next; 3287 return XML_ERROR_INVALID_TOKEN; 3288 case XML_TOK_PARTIAL_CHAR: 3289 if (haveMore) { 3290 *nextPtr = s; 3291 return XML_ERROR_NONE; 3292 } 3293 return XML_ERROR_PARTIAL_CHAR; 3294 case XML_TOK_PARTIAL: 3295 case XML_TOK_NONE: 3296 if (haveMore) { 3297 *nextPtr = s; 3298 return XML_ERROR_NONE; 3299 } 3300 return XML_ERROR_UNCLOSED_CDATA_SECTION; 3301 default: 3302 *eventPP = next; 3303 return XML_ERROR_UNEXPECTED_STATE; 3304 } 3305 3306 *eventPP = s = next; 3307 switch (ps_parsing) { 3308 case XML_SUSPENDED: 3309 *nextPtr = next; 3310 return XML_ERROR_NONE; 3311 case XML_FINISHED: 3312 return XML_ERROR_ABORTED; 3313 default: ; 3314 } 3315 } 3316 /* not reached */ 3317 } 3318 3319 #ifdef XML_DTD 3320 3321 /* The idea here is to avoid using stack for each IGNORE section when 3322 the whole file is parsed with one call. 3323 */ 3324 static enum XML_Error PTRCALL 3325 ignoreSectionProcessor(XML_Parser parser, 3326 const char *start, 3327 const char *end, 3328 const char **endPtr) 3329 { 3330 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 3331 endPtr, (XML_Bool)!ps_finalBuffer); 3332 if (result != XML_ERROR_NONE) 3333 return result; 3334 if (start) { 3335 processor = prologProcessor; 3336 return prologProcessor(parser, start, end, endPtr); 3337 } 3338 return result; 3339 } 3340 3341 /* startPtr gets set to non-null is the section is closed, and to null 3342 if the section is not yet closed. 3343 */ 3344 static enum XML_Error 3345 doIgnoreSection(XML_Parser parser, 3346 const ENCODING *enc, 3347 const char **startPtr, 3348 const char *end, 3349 const char **nextPtr, 3350 XML_Bool haveMore) 3351 { 3352 const char *next; 3353 int tok; 3354 const char *s = *startPtr; 3355 const char **eventPP; 3356 const char **eventEndPP; 3357 if (enc == encoding) { 3358 eventPP = &eventPtr; 3359 *eventPP = s; 3360 eventEndPP = &eventEndPtr; 3361 } 3362 else { 3363 eventPP = &(openInternalEntities->internalEventPtr); 3364 eventEndPP = &(openInternalEntities->internalEventEndPtr); 3365 } 3366 *eventPP = s; 3367 *startPtr = NULL; 3368 tok = XmlIgnoreSectionTok(enc, s, end, &next); 3369 *eventEndPP = next; 3370 switch (tok) { 3371 case XML_TOK_IGNORE_SECT: 3372 if (defaultHandler) 3373 reportDefault(parser, enc, s, next); 3374 *startPtr = next; 3375 *nextPtr = next; 3376 if (ps_parsing == XML_FINISHED) 3377 return XML_ERROR_ABORTED; 3378 else 3379 return XML_ERROR_NONE; 3380 case XML_TOK_INVALID: 3381 *eventPP = next; 3382 return XML_ERROR_INVALID_TOKEN; 3383 case XML_TOK_PARTIAL_CHAR: 3384 if (haveMore) { 3385 *nextPtr = s; 3386 return XML_ERROR_NONE; 3387 } 3388 return XML_ERROR_PARTIAL_CHAR; 3389 case XML_TOK_PARTIAL: 3390 case XML_TOK_NONE: 3391 if (haveMore) { 3392 *nextPtr = s; 3393 return XML_ERROR_NONE; 3394 } 3395 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ 3396 default: 3397 *eventPP = next; 3398 return XML_ERROR_UNEXPECTED_STATE; 3399 } 3400 /* not reached */ 3401 } 3402 3403 #endif /* XML_DTD */ 3404 3405 static enum XML_Error 3406 initializeEncoding(XML_Parser parser) 3407 { 3408 const char *s; 3409 #ifdef XML_UNICODE 3410 char encodingBuf[128]; 3411 if (!protocolEncodingName) 3412 s = NULL; 3413 else { 3414 int i; 3415 for (i = 0; protocolEncodingName[i]; i++) { 3416 if (i == sizeof(encodingBuf) - 1 3417 || (protocolEncodingName[i] & ~0x7f) != 0) { 3418 encodingBuf[0] = '\0'; 3419 break; 3420 } 3421 encodingBuf[i] = (char)protocolEncodingName[i]; 3422 } 3423 encodingBuf[i] = '\0'; 3424 s = encodingBuf; 3425 } 3426 #else 3427 s = protocolEncodingName; 3428 #endif 3429 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) 3430 return XML_ERROR_NONE; 3431 return handleUnknownEncoding(parser, protocolEncodingName); 3432 } 3433 3434 static enum XML_Error 3435 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, 3436 const char *s, const char *next) 3437 { 3438 const char *encodingName = NULL; 3439 const XML_Char *storedEncName = NULL; 3440 const ENCODING *newEncoding = NULL; 3441 const char *version = NULL; 3442 const char *versionend; 3443 const XML_Char *storedversion = NULL; 3444 int standalone = -1; 3445 if (!(ns 3446 ? XmlParseXmlDeclNS 3447 : XmlParseXmlDecl)(isGeneralTextEntity, 3448 encoding, 3449 s, 3450 next, 3451 &eventPtr, 3452 &version, 3453 &versionend, 3454 &encodingName, 3455 &newEncoding, 3456 &standalone)) { 3457 if (isGeneralTextEntity) 3458 return XML_ERROR_TEXT_DECL; 3459 else 3460 return XML_ERROR_XML_DECL; 3461 } 3462 if (!isGeneralTextEntity && standalone == 1) { 3463 _dtd->standalone = XML_TRUE; 3464 #ifdef XML_DTD 3465 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) 3466 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 3467 #endif /* XML_DTD */ 3468 } 3469 if (xmlDeclHandler) { 3470 if (encodingName != NULL) { 3471 storedEncName = poolStoreString(&temp2Pool, 3472 encoding, 3473 encodingName, 3474 encodingName 3475 + XmlNameLength(encoding, encodingName)); 3476 if (!storedEncName) 3477 return XML_ERROR_NO_MEMORY; 3478 poolFinish(&temp2Pool); 3479 } 3480 if (version) { 3481 storedversion = poolStoreString(&temp2Pool, 3482 encoding, 3483 version, 3484 versionend - encoding->minBytesPerChar); 3485 if (!storedversion) 3486 return XML_ERROR_NO_MEMORY; 3487 } 3488 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); 3489 } 3490 else if (defaultHandler) 3491 reportDefault(parser, encoding, s, next); 3492 if (protocolEncodingName == NULL) { 3493 if (newEncoding) { 3494 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { 3495 eventPtr = encodingName; 3496 return XML_ERROR_INCORRECT_ENCODING; 3497 } 3498 encoding = newEncoding; 3499 } 3500 else if (encodingName) { 3501 enum XML_Error result; 3502 if (!storedEncName) { 3503 storedEncName = poolStoreString( 3504 &temp2Pool, encoding, encodingName, 3505 encodingName + XmlNameLength(encoding, encodingName)); 3506 if (!storedEncName) 3507 return XML_ERROR_NO_MEMORY; 3508 } 3509 result = handleUnknownEncoding(parser, storedEncName); 3510 poolClear(&temp2Pool); 3511 if (result == XML_ERROR_UNKNOWN_ENCODING) 3512 eventPtr = encodingName; 3513 return result; 3514 } 3515 } 3516 3517 if (storedEncName || storedversion) 3518 poolClear(&temp2Pool); 3519 3520 return XML_ERROR_NONE; 3521 } 3522 3523 static enum XML_Error 3524 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) 3525 { 3526 if (unknownEncodingHandler) { 3527 XML_Encoding info; 3528 int i; 3529 for (i = 0; i < 256; i++) 3530 info.map[i] = -1; 3531 info.convert = NULL; 3532 info.data = NULL; 3533 info.release = NULL; 3534 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, 3535 &info)) { 3536 ENCODING *enc; 3537 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding()); 3538 if (!unknownEncodingMem) { 3539 if (info.release) 3540 info.release(info.data); 3541 return XML_ERROR_NO_MEMORY; 3542 } 3543 enc = (ns 3544 ? XmlInitUnknownEncodingNS 3545 : XmlInitUnknownEncoding)(unknownEncodingMem, 3546 info.map, 3547 info.convert, 3548 info.data); 3549 if (enc) { 3550 unknownEncodingData = info.data; 3551 unknownEncodingRelease = info.release; 3552 encoding = enc; 3553 return XML_ERROR_NONE; 3554 } 3555 } 3556 if (info.release != NULL) 3557 info.release(info.data); 3558 } 3559 return XML_ERROR_UNKNOWN_ENCODING; 3560 } 3561 3562 static enum XML_Error PTRCALL 3563 prologInitProcessor(XML_Parser parser, 3564 const char *s, 3565 const char *end, 3566 const char **nextPtr) 3567 { 3568 enum XML_Error result = initializeEncoding(parser); 3569 if (result != XML_ERROR_NONE) 3570 return result; 3571 processor = prologProcessor; 3572 return prologProcessor(parser, s, end, nextPtr); 3573 } 3574 3575 #ifdef XML_DTD 3576 3577 static enum XML_Error PTRCALL 3578 externalParEntInitProcessor(XML_Parser parser, 3579 const char *s, 3580 const char *end, 3581 const char **nextPtr) 3582 { 3583 enum XML_Error result = initializeEncoding(parser); 3584 if (result != XML_ERROR_NONE) 3585 return result; 3586 3587 /* we know now that XML_Parse(Buffer) has been called, 3588 so we consider the external parameter entity read */ 3589 _dtd->paramEntityRead = XML_TRUE; 3590 3591 if (prologState.inEntityValue) { 3592 processor = entityValueInitProcessor; 3593 return entityValueInitProcessor(parser, s, end, nextPtr); 3594 } 3595 else { 3596 processor = externalParEntProcessor; 3597 return externalParEntProcessor(parser, s, end, nextPtr); 3598 } 3599 } 3600 3601 static enum XML_Error PTRCALL 3602 entityValueInitProcessor(XML_Parser parser, 3603 const char *s, 3604 const char *end, 3605 const char **nextPtr) 3606 { 3607 int tok; 3608 const char *start = s; 3609 const char *next = start; 3610 eventPtr = start; 3611 3612 for (;;) { 3613 tok = XmlPrologTok(encoding, start, end, &next); 3614 eventEndPtr = next; 3615 if (tok <= 0) { 3616 if (!ps_finalBuffer && tok != XML_TOK_INVALID) { 3617 *nextPtr = s; 3618 return XML_ERROR_NONE; 3619 } 3620 switch (tok) { 3621 case XML_TOK_INVALID: 3622 return XML_ERROR_INVALID_TOKEN; 3623 case XML_TOK_PARTIAL: 3624 return XML_ERROR_UNCLOSED_TOKEN; 3625 case XML_TOK_PARTIAL_CHAR: 3626 return XML_ERROR_PARTIAL_CHAR; 3627 case XML_TOK_NONE: /* start == end */ 3628 default: 3629 break; 3630 } 3631 /* found end of entity value - can store it now */ 3632 return storeEntityValue(parser, encoding, s, end); 3633 } 3634 else if (tok == XML_TOK_XML_DECL) { 3635 enum XML_Error result; 3636 result = processXmlDecl(parser, 0, start, next); 3637 if (result != XML_ERROR_NONE) 3638 return result; 3639 switch (ps_parsing) { 3640 case XML_SUSPENDED: 3641 *nextPtr = next; 3642 return XML_ERROR_NONE; 3643 case XML_FINISHED: 3644 return XML_ERROR_ABORTED; 3645 default: 3646 *nextPtr = next; 3647 } 3648 /* stop scanning for text declaration - we found one */ 3649 processor = entityValueProcessor; 3650 return entityValueProcessor(parser, next, end, nextPtr); 3651 } 3652 /* If we are at the end of the buffer, this would cause XmlPrologTok to 3653 return XML_TOK_NONE on the next call, which would then cause the 3654 function to exit with *nextPtr set to s - that is what we want for other 3655 tokens, but not for the BOM - we would rather like to skip it; 3656 then, when this routine is entered the next time, XmlPrologTok will 3657 return XML_TOK_INVALID, since the BOM is still in the buffer 3658 */ 3659 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) { 3660 *nextPtr = next; 3661 return XML_ERROR_NONE; 3662 } 3663 start = next; 3664 eventPtr = start; 3665 } 3666 } 3667 3668 static enum XML_Error PTRCALL 3669 externalParEntProcessor(XML_Parser parser, 3670 const char *s, 3671 const char *end, 3672 const char **nextPtr) 3673 { 3674 const char *next = s; 3675 int tok; 3676 3677 tok = XmlPrologTok(encoding, s, end, &next); 3678 if (tok <= 0) { 3679 if (!ps_finalBuffer && tok != XML_TOK_INVALID) { 3680 *nextPtr = s; 3681 return XML_ERROR_NONE; 3682 } 3683 switch (tok) { 3684 case XML_TOK_INVALID: 3685 return XML_ERROR_INVALID_TOKEN; 3686 case XML_TOK_PARTIAL: 3687 return XML_ERROR_UNCLOSED_TOKEN; 3688 case XML_TOK_PARTIAL_CHAR: 3689 return XML_ERROR_PARTIAL_CHAR; 3690 case XML_TOK_NONE: /* start == end */ 3691 default: 3692 break; 3693 } 3694 } 3695 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. 3696 However, when parsing an external subset, doProlog will not accept a BOM 3697 as valid, and report a syntax error, so we have to skip the BOM 3698 */ 3699 else if (tok == XML_TOK_BOM) { 3700 s = next; 3701 tok = XmlPrologTok(encoding, s, end, &next); 3702 } 3703 3704 processor = prologProcessor; 3705 return doProlog(parser, encoding, s, end, tok, next, 3706 nextPtr, (XML_Bool)!ps_finalBuffer); 3707 } 3708 3709 static enum XML_Error PTRCALL 3710 entityValueProcessor(XML_Parser parser, 3711 const char *s, 3712 const char *end, 3713 const char **nextPtr) 3714 { 3715 const char *start = s; 3716 const char *next = s; 3717 const ENCODING *enc = encoding; 3718 int tok; 3719 3720 for (;;) { 3721 tok = XmlPrologTok(enc, start, end, &next); 3722 if (tok <= 0) { 3723 if (!ps_finalBuffer && tok != XML_TOK_INVALID) { 3724 *nextPtr = s; 3725 return XML_ERROR_NONE; 3726 } 3727 switch (tok) { 3728 case XML_TOK_INVALID: 3729 return XML_ERROR_INVALID_TOKEN; 3730 case XML_TOK_PARTIAL: 3731 return XML_ERROR_UNCLOSED_TOKEN; 3732 case XML_TOK_PARTIAL_CHAR: 3733 return XML_ERROR_PARTIAL_CHAR; 3734 case XML_TOK_NONE: /* start == end */ 3735 default: 3736 break; 3737 } 3738 /* found end of entity value - can store it now */ 3739 return storeEntityValue(parser, enc, s, end); 3740 } 3741 start = next; 3742 } 3743 } 3744 3745 #endif /* XML_DTD */ 3746 3747 static enum XML_Error PTRCALL 3748 prologProcessor(XML_Parser parser, 3749 const char *s, 3750 const char *end, 3751 const char **nextPtr) 3752 { 3753 const char *next = s; 3754 int tok = XmlPrologTok(encoding, s, end, &next); 3755 return doProlog(parser, encoding, s, end, tok, next, 3756 nextPtr, (XML_Bool)!ps_finalBuffer); 3757 } 3758 3759 static enum XML_Error 3760 doProlog(XML_Parser parser, 3761 const ENCODING *enc, 3762 const char *s, 3763 const char *end, 3764 int tok, 3765 const char *next, 3766 const char **nextPtr, 3767 XML_Bool haveMore) 3768 { 3769 #ifdef XML_DTD 3770 static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' }; 3771 #endif /* XML_DTD */ 3772 static const XML_Char atypeCDATA[] = 3773 { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; 3774 static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' }; 3775 static const XML_Char atypeIDREF[] = 3776 { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; 3777 static const XML_Char atypeIDREFS[] = 3778 { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; 3779 static const XML_Char atypeENTITY[] = 3780 { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; 3781 static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N, 3782 ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' }; 3783 static const XML_Char atypeNMTOKEN[] = { 3784 ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; 3785 static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, 3786 ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' }; 3787 static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T, 3788 ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' }; 3789 static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' }; 3790 static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' }; 3791 3792 /* save one level of indirection */ 3793 DTD * const dtd = _dtd; 3794 3795 const char **eventPP; 3796 const char **eventEndPP; 3797 enum XML_Content_Quant quant; 3798 3799 if (enc == encoding) { 3800 eventPP = &eventPtr; 3801 eventEndPP = &eventEndPtr; 3802 } 3803 else { 3804 eventPP = &(openInternalEntities->internalEventPtr); 3805 eventEndPP = &(openInternalEntities->internalEventEndPtr); 3806 } 3807 3808 for (;;) { 3809 int role; 3810 XML_Bool handleDefault = XML_TRUE; 3811 *eventPP = s; 3812 *eventEndPP = next; 3813 if (tok <= 0) { 3814 if (haveMore && tok != XML_TOK_INVALID) { 3815 *nextPtr = s; 3816 return XML_ERROR_NONE; 3817 } 3818 switch (tok) { 3819 case XML_TOK_INVALID: 3820 *eventPP = next; 3821 return XML_ERROR_INVALID_TOKEN; 3822 case XML_TOK_PARTIAL: 3823 return XML_ERROR_UNCLOSED_TOKEN; 3824 case XML_TOK_PARTIAL_CHAR: 3825 return XML_ERROR_PARTIAL_CHAR; 3826 case -XML_TOK_PROLOG_S: 3827 tok = -tok; 3828 break; 3829 case XML_TOK_NONE: 3830 #ifdef XML_DTD 3831 /* for internal PE NOT referenced between declarations */ 3832 if (enc != encoding && !openInternalEntities->betweenDecl) { 3833 *nextPtr = s; 3834 return XML_ERROR_NONE; 3835 } 3836 /* WFC: PE Between Declarations - must check that PE contains 3837 complete markup, not only for external PEs, but also for 3838 internal PEs if the reference occurs between declarations. 3839 */ 3840 if (isParamEntity || enc != encoding) { 3841 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) 3842 == XML_ROLE_ERROR) 3843 return XML_ERROR_INCOMPLETE_PE; 3844 *nextPtr = s; 3845 return XML_ERROR_NONE; 3846 } 3847 #endif /* XML_DTD */ 3848 return XML_ERROR_NO_ELEMENTS; 3849 default: 3850 tok = -tok; 3851 next = end; 3852 break; 3853 } 3854 } 3855 role = XmlTokenRole(&prologState, tok, s, next, enc); 3856 switch (role) { 3857 case XML_ROLE_XML_DECL: 3858 { 3859 enum XML_Error result = processXmlDecl(parser, 0, s, next); 3860 if (result != XML_ERROR_NONE) 3861 return result; 3862 enc = encoding; 3863 handleDefault = XML_FALSE; 3864 } 3865 break; 3866 case XML_ROLE_DOCTYPE_NAME: 3867 if (startDoctypeDeclHandler) { 3868 doctypeName = poolStoreString(&tempPool, enc, s, next); 3869 if (!doctypeName) 3870 return XML_ERROR_NO_MEMORY; 3871 poolFinish(&tempPool); 3872 doctypePubid = NULL; 3873 handleDefault = XML_FALSE; 3874 } 3875 doctypeSysid = NULL; /* always initialize to NULL */ 3876 break; 3877 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: 3878 if (startDoctypeDeclHandler) { 3879 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid, 3880 doctypePubid, 1); 3881 doctypeName = NULL; 3882 poolClear(&tempPool); 3883 handleDefault = XML_FALSE; 3884 } 3885 break; 3886 #ifdef XML_DTD 3887 case XML_ROLE_TEXT_DECL: 3888 { 3889 enum XML_Error result = processXmlDecl(parser, 1, s, next); 3890 if (result != XML_ERROR_NONE) 3891 return result; 3892 enc = encoding; 3893 handleDefault = XML_FALSE; 3894 } 3895 break; 3896 #endif /* XML_DTD */ 3897 case XML_ROLE_DOCTYPE_PUBLIC_ID: 3898 #ifdef XML_DTD 3899 useForeignDTD = XML_FALSE; 3900 declEntity = (ENTITY *)lookup(parser, 3901 &dtd->paramEntities, 3902 externalSubsetName, 3903 sizeof(ENTITY)); 3904 if (!declEntity) 3905 return XML_ERROR_NO_MEMORY; 3906 #endif /* XML_DTD */ 3907 dtd->hasParamEntityRefs = XML_TRUE; 3908 if (startDoctypeDeclHandler) { 3909 XML_Char *pubId; 3910 if (!XmlIsPublicId(enc, s, next, eventPP)) 3911 return XML_ERROR_PUBLICID; 3912 pubId = poolStoreString(&tempPool, enc, 3913 s + enc->minBytesPerChar, 3914 next - enc->minBytesPerChar); 3915 if (!pubId) 3916 return XML_ERROR_NO_MEMORY; 3917 normalizePublicId(pubId); 3918 poolFinish(&tempPool); 3919 doctypePubid = pubId; 3920 handleDefault = XML_FALSE; 3921 goto alreadyChecked; 3922 } 3923 /* fall through */ 3924 case XML_ROLE_ENTITY_PUBLIC_ID: 3925 if (!XmlIsPublicId(enc, s, next, eventPP)) 3926 return XML_ERROR_PUBLICID; 3927 alreadyChecked: 3928 if (dtd->keepProcessing && declEntity) { 3929 XML_Char *tem = poolStoreString(&dtd->pool, 3930 enc, 3931 s + enc->minBytesPerChar, 3932 next - enc->minBytesPerChar); 3933 if (!tem) 3934 return XML_ERROR_NO_MEMORY; 3935 normalizePublicId(tem); 3936 declEntity->publicId = tem; 3937 poolFinish(&dtd->pool); 3938 if (entityDeclHandler) 3939 handleDefault = XML_FALSE; 3940 } 3941 break; 3942 case XML_ROLE_DOCTYPE_CLOSE: 3943 if (doctypeName) { 3944 startDoctypeDeclHandler(handlerArg, doctypeName, 3945 doctypeSysid, doctypePubid, 0); 3946 poolClear(&tempPool); 3947 handleDefault = XML_FALSE; 3948 } 3949 /* doctypeSysid will be non-NULL in the case of a previous 3950 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler 3951 was not set, indicating an external subset 3952 */ 3953 #ifdef XML_DTD 3954 if (doctypeSysid || useForeignDTD) { 3955 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 3956 dtd->hasParamEntityRefs = XML_TRUE; 3957 if (paramEntityParsing && externalEntityRefHandler) { 3958 ENTITY *entity = (ENTITY *)lookup(parser, 3959 &dtd->paramEntities, 3960 externalSubsetName, 3961 sizeof(ENTITY)); 3962 if (!entity) 3963 return XML_ERROR_NO_MEMORY; 3964 if (useForeignDTD) 3965 entity->base = curBase; 3966 dtd->paramEntityRead = XML_FALSE; 3967 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 3968 0, 3969 entity->base, 3970 entity->systemId, 3971 entity->publicId)) 3972 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 3973 if (dtd->paramEntityRead) { 3974 if (!dtd->standalone && 3975 notStandaloneHandler && 3976 !notStandaloneHandler(handlerArg)) 3977 return XML_ERROR_NOT_STANDALONE; 3978 } 3979 /* if we didn't read the foreign DTD then this means that there 3980 is no external subset and we must reset dtd->hasParamEntityRefs 3981 */ 3982 else if (!doctypeSysid) 3983 dtd->hasParamEntityRefs = hadParamEntityRefs; 3984 /* end of DTD - no need to update dtd->keepProcessing */ 3985 } 3986 useForeignDTD = XML_FALSE; 3987 } 3988 #endif /* XML_DTD */ 3989 if (endDoctypeDeclHandler) { 3990 endDoctypeDeclHandler(handlerArg); 3991 handleDefault = XML_FALSE; 3992 } 3993 break; 3994 case XML_ROLE_INSTANCE_START: 3995 #ifdef XML_DTD 3996 /* if there is no DOCTYPE declaration then now is the 3997 last chance to read the foreign DTD 3998 */ 3999 if (useForeignDTD) { 4000 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 4001 dtd->hasParamEntityRefs = XML_TRUE; 4002 if (paramEntityParsing && externalEntityRefHandler) { 4003 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, 4004 externalSubsetName, 4005 sizeof(ENTITY)); 4006 if (!entity) 4007 return XML_ERROR_NO_MEMORY; 4008 entity->base = curBase; 4009 dtd->paramEntityRead = XML_FALSE; 4010 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 4011 0, 4012 entity->base, 4013 entity->systemId, 4014 entity->publicId)) 4015 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 4016 if (dtd->paramEntityRead) { 4017 if (!dtd->standalone && 4018 notStandaloneHandler && 4019 !notStandaloneHandler(handlerArg)) 4020 return XML_ERROR_NOT_STANDALONE; 4021 } 4022 /* if we didn't read the foreign DTD then this means that there 4023 is no external subset and we must reset dtd->hasParamEntityRefs 4024 */ 4025 else 4026 dtd->hasParamEntityRefs = hadParamEntityRefs; 4027 /* end of DTD - no need to update dtd->keepProcessing */ 4028 } 4029 } 4030 #endif /* XML_DTD */ 4031 processor = contentProcessor; 4032 return contentProcessor(parser, s, end, nextPtr); 4033 case XML_ROLE_ATTLIST_ELEMENT_NAME: 4034 declElementType = getElementType(parser, enc, s, next); 4035 if (!declElementType) 4036 return XML_ERROR_NO_MEMORY; 4037 goto checkAttListDeclHandler; 4038 case XML_ROLE_ATTRIBUTE_NAME: 4039 declAttributeId = getAttributeId(parser, enc, s, next); 4040 if (!declAttributeId) 4041 return XML_ERROR_NO_MEMORY; 4042 declAttributeIsCdata = XML_FALSE; 4043 declAttributeType = NULL; 4044 declAttributeIsId = XML_FALSE; 4045 goto checkAttListDeclHandler; 4046 case XML_ROLE_ATTRIBUTE_TYPE_CDATA: 4047 declAttributeIsCdata = XML_TRUE; 4048 declAttributeType = atypeCDATA; 4049 goto checkAttListDeclHandler; 4050 case XML_ROLE_ATTRIBUTE_TYPE_ID: 4051 declAttributeIsId = XML_TRUE; 4052 declAttributeType = atypeID; 4053 goto checkAttListDeclHandler; 4054 case XML_ROLE_ATTRIBUTE_TYPE_IDREF: 4055 declAttributeType = atypeIDREF; 4056 goto checkAttListDeclHandler; 4057 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: 4058 declAttributeType = atypeIDREFS; 4059 goto checkAttListDeclHandler; 4060 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: 4061 declAttributeType = atypeENTITY; 4062 goto checkAttListDeclHandler; 4063 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: 4064 declAttributeType = atypeENTITIES; 4065 goto checkAttListDeclHandler; 4066 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: 4067 declAttributeType = atypeNMTOKEN; 4068 goto checkAttListDeclHandler; 4069 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: 4070 declAttributeType = atypeNMTOKENS; 4071 checkAttListDeclHandler: 4072 if (dtd->keepProcessing && attlistDeclHandler) 4073 handleDefault = XML_FALSE; 4074 break; 4075 case XML_ROLE_ATTRIBUTE_ENUM_VALUE: 4076 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: 4077 if (dtd->keepProcessing && attlistDeclHandler) { 4078 const XML_Char *prefix; 4079 if (declAttributeType) { 4080 prefix = enumValueSep; 4081 } 4082 else { 4083 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE 4084 ? notationPrefix 4085 : enumValueStart); 4086 } 4087 if (!poolAppendString(&tempPool, prefix)) 4088 return XML_ERROR_NO_MEMORY; 4089 if (!poolAppend(&tempPool, enc, s, next)) 4090 return XML_ERROR_NO_MEMORY; 4091 declAttributeType = tempPool.start; 4092 handleDefault = XML_FALSE; 4093 } 4094 break; 4095 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: 4096 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: 4097 if (dtd->keepProcessing) { 4098 if (!defineAttribute(declElementType, declAttributeId, 4099 declAttributeIsCdata, declAttributeIsId, 4100 0, parser)) 4101 return XML_ERROR_NO_MEMORY; 4102 if (attlistDeclHandler && declAttributeType) { 4103 if (*declAttributeType == XML_T(ASCII_LPAREN) 4104 || (*declAttributeType == XML_T(ASCII_N) 4105 && declAttributeType[1] == XML_T(ASCII_O))) { 4106 /* Enumerated or Notation type */ 4107 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) 4108 || !poolAppendChar(&tempPool, XML_T('\0'))) 4109 return XML_ERROR_NO_MEMORY; 4110 declAttributeType = tempPool.start; 4111 poolFinish(&tempPool); 4112 } 4113 *eventEndPP = s; 4114 attlistDeclHandler(handlerArg, declElementType->name, 4115 declAttributeId->name, declAttributeType, 4116 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); 4117 poolClear(&tempPool); 4118 handleDefault = XML_FALSE; 4119 } 4120 } 4121 break; 4122 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: 4123 case XML_ROLE_FIXED_ATTRIBUTE_VALUE: 4124 if (dtd->keepProcessing) { 4125 const XML_Char *attVal; 4126 enum XML_Error result = 4127 storeAttributeValue(parser, enc, declAttributeIsCdata, 4128 s + enc->minBytesPerChar, 4129 next - enc->minBytesPerChar, 4130 &dtd->pool); 4131 if (result) 4132 return result; 4133 attVal = poolStart(&dtd->pool); 4134 poolFinish(&dtd->pool); 4135 /* ID attributes aren't allowed to have a default */ 4136 if (!defineAttribute(declElementType, declAttributeId, 4137 declAttributeIsCdata, XML_FALSE, attVal, parser)) 4138 return XML_ERROR_NO_MEMORY; 4139 if (attlistDeclHandler && declAttributeType) { 4140 if (*declAttributeType == XML_T(ASCII_LPAREN) 4141 || (*declAttributeType == XML_T(ASCII_N) 4142 && declAttributeType[1] == XML_T(ASCII_O))) { 4143 /* Enumerated or Notation type */ 4144 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) 4145 || !poolAppendChar(&tempPool, XML_T('\0'))) 4146 return XML_ERROR_NO_MEMORY; 4147 declAttributeType = tempPool.start; 4148 poolFinish(&tempPool); 4149 } 4150 *eventEndPP = s; 4151 attlistDeclHandler(handlerArg, declElementType->name, 4152 declAttributeId->name, declAttributeType, 4153 attVal, 4154 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); 4155 poolClear(&tempPool); 4156 handleDefault = XML_FALSE; 4157 } 4158 } 4159 break; 4160 case XML_ROLE_ENTITY_VALUE: 4161 if (dtd->keepProcessing) { 4162 enum XML_Error result = storeEntityValue(parser, enc, 4163 s + enc->minBytesPerChar, 4164 next - enc->minBytesPerChar); 4165 if (declEntity) { 4166 declEntity->textPtr = poolStart(&dtd->entityValuePool); 4167 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); 4168 poolFinish(&dtd->entityValuePool); 4169 if (entityDeclHandler) { 4170 *eventEndPP = s; 4171 entityDeclHandler(handlerArg, 4172 declEntity->name, 4173 declEntity->is_param, 4174 declEntity->textPtr, 4175 declEntity->textLen, 4176 curBase, 0, 0, 0); 4177 handleDefault = XML_FALSE; 4178 } 4179 } 4180 else 4181 poolDiscard(&dtd->entityValuePool); 4182 if (result != XML_ERROR_NONE) 4183 return result; 4184 } 4185 break; 4186 case XML_ROLE_DOCTYPE_SYSTEM_ID: 4187 #ifdef XML_DTD 4188 useForeignDTD = XML_FALSE; 4189 #endif /* XML_DTD */ 4190 dtd->hasParamEntityRefs = XML_TRUE; 4191 if (startDoctypeDeclHandler) { 4192 doctypeSysid = poolStoreString(&tempPool, enc, 4193 s + enc->minBytesPerChar, 4194 next - enc->minBytesPerChar); 4195 if (doctypeSysid == NULL) 4196 return XML_ERROR_NO_MEMORY; 4197 poolFinish(&tempPool); 4198 handleDefault = XML_FALSE; 4199 } 4200 #ifdef XML_DTD 4201 else 4202 /* use externalSubsetName to make doctypeSysid non-NULL 4203 for the case where no startDoctypeDeclHandler is set */ 4204 doctypeSysid = externalSubsetName; 4205 #endif /* XML_DTD */ 4206 if (!dtd->standalone 4207 #ifdef XML_DTD 4208 && !paramEntityParsing 4209 #endif /* XML_DTD */ 4210 && notStandaloneHandler 4211 && !notStandaloneHandler(handlerArg)) 4212 return XML_ERROR_NOT_STANDALONE; 4213 #ifndef XML_DTD 4214 break; 4215 #else /* XML_DTD */ 4216 if (!declEntity) { 4217 declEntity = (ENTITY *)lookup(parser, 4218 &dtd->paramEntities, 4219 externalSubsetName, 4220 sizeof(ENTITY)); 4221 if (!declEntity) 4222 return XML_ERROR_NO_MEMORY; 4223 declEntity->publicId = NULL; 4224 } 4225 /* fall through */ 4226 #endif /* XML_DTD */ 4227 case XML_ROLE_ENTITY_SYSTEM_ID: 4228 if (dtd->keepProcessing && declEntity) { 4229 declEntity->systemId = poolStoreString(&dtd->pool, enc, 4230 s + enc->minBytesPerChar, 4231 next - enc->minBytesPerChar); 4232 if (!declEntity->systemId) 4233 return XML_ERROR_NO_MEMORY; 4234 declEntity->base = curBase; 4235 poolFinish(&dtd->pool); 4236 if (entityDeclHandler) 4237 handleDefault = XML_FALSE; 4238 } 4239 break; 4240 case XML_ROLE_ENTITY_COMPLETE: 4241 if (dtd->keepProcessing && declEntity && entityDeclHandler) { 4242 *eventEndPP = s; 4243 entityDeclHandler(handlerArg, 4244 declEntity->name, 4245 declEntity->is_param, 4246 0,0, 4247 declEntity->base, 4248 declEntity->systemId, 4249 declEntity->publicId, 4250 0); 4251 handleDefault = XML_FALSE; 4252 } 4253 break; 4254 case XML_ROLE_ENTITY_NOTATION_NAME: 4255 if (dtd->keepProcessing && declEntity) { 4256 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); 4257 if (!declEntity->notation) 4258 return XML_ERROR_NO_MEMORY; 4259 poolFinish(&dtd->pool); 4260 if (unparsedEntityDeclHandler) { 4261 *eventEndPP = s; 4262 unparsedEntityDeclHandler(handlerArg, 4263 declEntity->name, 4264 declEntity->base, 4265 declEntity->systemId, 4266 declEntity->publicId, 4267 declEntity->notation); 4268 handleDefault = XML_FALSE; 4269 } 4270 else if (entityDeclHandler) { 4271 *eventEndPP = s; 4272 entityDeclHandler(handlerArg, 4273 declEntity->name, 4274 0,0,0, 4275 declEntity->base, 4276 declEntity->systemId, 4277 declEntity->publicId, 4278 declEntity->notation); 4279 handleDefault = XML_FALSE; 4280 } 4281 } 4282 break; 4283 case XML_ROLE_GENERAL_ENTITY_NAME: 4284 { 4285 if (XmlPredefinedEntityName(enc, s, next)) { 4286 declEntity = NULL; 4287 break; 4288 } 4289 if (dtd->keepProcessing) { 4290 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); 4291 if (!name) 4292 return XML_ERROR_NO_MEMORY; 4293 declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 4294 sizeof(ENTITY)); 4295 if (!declEntity) 4296 return XML_ERROR_NO_MEMORY; 4297 if (declEntity->name != name) { 4298 poolDiscard(&dtd->pool); 4299 declEntity = NULL; 4300 } 4301 else { 4302 poolFinish(&dtd->pool); 4303 declEntity->publicId = NULL; 4304 declEntity->is_param = XML_FALSE; 4305 /* if we have a parent parser or are reading an internal parameter 4306 entity, then the entity declaration is not considered "internal" 4307 */ 4308 declEntity->is_internal = !(parentParser || openInternalEntities); 4309 if (entityDeclHandler) 4310 handleDefault = XML_FALSE; 4311 } 4312 } 4313 else { 4314 poolDiscard(&dtd->pool); 4315 declEntity = NULL; 4316 } 4317 } 4318 break; 4319 case XML_ROLE_PARAM_ENTITY_NAME: 4320 #ifdef XML_DTD 4321 if (dtd->keepProcessing) { 4322 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); 4323 if (!name) 4324 return XML_ERROR_NO_MEMORY; 4325 declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, 4326 name, sizeof(ENTITY)); 4327 if (!declEntity) 4328 return XML_ERROR_NO_MEMORY; 4329 if (declEntity->name != name) { 4330 poolDiscard(&dtd->pool); 4331 declEntity = NULL; 4332 } 4333 else { 4334 poolFinish(&dtd->pool); 4335 declEntity->publicId = NULL; 4336 declEntity->is_param = XML_TRUE; 4337 /* if we have a parent parser or are reading an internal parameter 4338 entity, then the entity declaration is not considered "internal" 4339 */ 4340 declEntity->is_internal = !(parentParser || openInternalEntities); 4341 if (entityDeclHandler) 4342 handleDefault = XML_FALSE; 4343 } 4344 } 4345 else { 4346 poolDiscard(&dtd->pool); 4347 declEntity = NULL; 4348 } 4349 #else /* not XML_DTD */ 4350 declEntity = NULL; 4351 #endif /* XML_DTD */ 4352 break; 4353 case XML_ROLE_NOTATION_NAME: 4354 declNotationPublicId = NULL; 4355 declNotationName = NULL; 4356 if (notationDeclHandler) { 4357 declNotationName = poolStoreString(&tempPool, enc, s, next); 4358 if (!declNotationName) 4359 return XML_ERROR_NO_MEMORY; 4360 poolFinish(&tempPool); 4361 handleDefault = XML_FALSE; 4362 } 4363 break; 4364 case XML_ROLE_NOTATION_PUBLIC_ID: 4365 if (!XmlIsPublicId(enc, s, next, eventPP)) 4366 return XML_ERROR_PUBLICID; 4367 if (declNotationName) { /* means notationDeclHandler != NULL */ 4368 XML_Char *tem = poolStoreString(&tempPool, 4369 enc, 4370 s + enc->minBytesPerChar, 4371 next - enc->minBytesPerChar); 4372 if (!tem) 4373 return XML_ERROR_NO_MEMORY; 4374 normalizePublicId(tem); 4375 declNotationPublicId = tem; 4376 poolFinish(&tempPool); 4377 handleDefault = XML_FALSE; 4378 } 4379 break; 4380 case XML_ROLE_NOTATION_SYSTEM_ID: 4381 if (declNotationName && notationDeclHandler) { 4382 const XML_Char *systemId 4383 = poolStoreString(&tempPool, enc, 4384 s + enc->minBytesPerChar, 4385 next - enc->minBytesPerChar); 4386 if (!systemId) 4387 return XML_ERROR_NO_MEMORY; 4388 *eventEndPP = s; 4389 notationDeclHandler(handlerArg, 4390 declNotationName, 4391 curBase, 4392 systemId, 4393 declNotationPublicId); 4394 handleDefault = XML_FALSE; 4395 } 4396 poolClear(&tempPool); 4397 break; 4398 case XML_ROLE_NOTATION_NO_SYSTEM_ID: 4399 if (declNotationPublicId && notationDeclHandler) { 4400 *eventEndPP = s; 4401 notationDeclHandler(handlerArg, 4402 declNotationName, 4403 curBase, 4404 0, 4405 declNotationPublicId); 4406 handleDefault = XML_FALSE; 4407 } 4408 poolClear(&tempPool); 4409 break; 4410 case XML_ROLE_ERROR: 4411 switch (tok) { 4412 case XML_TOK_PARAM_ENTITY_REF: 4413 /* PE references in internal subset are 4414 not allowed within declarations. */ 4415 return XML_ERROR_PARAM_ENTITY_REF; 4416 case XML_TOK_XML_DECL: 4417 return XML_ERROR_MISPLACED_XML_PI; 4418 default: 4419 return XML_ERROR_SYNTAX; 4420 } 4421 #ifdef XML_DTD 4422 case XML_ROLE_IGNORE_SECT: 4423 { 4424 enum XML_Error result; 4425 if (defaultHandler) 4426 reportDefault(parser, enc, s, next); 4427 handleDefault = XML_FALSE; 4428 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); 4429 if (result != XML_ERROR_NONE) 4430 return result; 4431 else if (!next) { 4432 processor = ignoreSectionProcessor; 4433 return result; 4434 } 4435 } 4436 break; 4437 #endif /* XML_DTD */ 4438 case XML_ROLE_GROUP_OPEN: 4439 if (prologState.level >= groupSize) { 4440 if (groupSize) { 4441 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); 4442 if (temp == NULL) 4443 return XML_ERROR_NO_MEMORY; 4444 groupConnector = temp; 4445 if (dtd->scaffIndex) { 4446 int *temp = (int *)REALLOC(dtd->scaffIndex, 4447 groupSize * sizeof(int)); 4448 if (temp == NULL) 4449 return XML_ERROR_NO_MEMORY; 4450 dtd->scaffIndex = temp; 4451 } 4452 } 4453 else { 4454 groupConnector = (char *)MALLOC(groupSize = 32); 4455 if (!groupConnector) 4456 return XML_ERROR_NO_MEMORY; 4457 } 4458 } 4459 groupConnector[prologState.level] = 0; 4460 if (dtd->in_eldecl) { 4461 int myindex = nextScaffoldPart(parser); 4462 if (myindex < 0) 4463 return XML_ERROR_NO_MEMORY; 4464 dtd->scaffIndex[dtd->scaffLevel] = myindex; 4465 dtd->scaffLevel++; 4466 dtd->scaffold[myindex].type = XML_CTYPE_SEQ; 4467 if (elementDeclHandler) 4468 handleDefault = XML_FALSE; 4469 } 4470 break; 4471 case XML_ROLE_GROUP_SEQUENCE: 4472 if (groupConnector[prologState.level] == ASCII_PIPE) 4473 return XML_ERROR_SYNTAX; 4474 groupConnector[prologState.level] = ASCII_COMMA; 4475 if (dtd->in_eldecl && elementDeclHandler) 4476 handleDefault = XML_FALSE; 4477 break; 4478 case XML_ROLE_GROUP_CHOICE: 4479 if (groupConnector[prologState.level] == ASCII_COMMA) 4480 return XML_ERROR_SYNTAX; 4481 if (dtd->in_eldecl 4482 && !groupConnector[prologState.level] 4483 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 4484 != XML_CTYPE_MIXED) 4485 ) { 4486 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 4487 = XML_CTYPE_CHOICE; 4488 if (elementDeclHandler) 4489 handleDefault = XML_FALSE; 4490 } 4491 groupConnector[prologState.level] = ASCII_PIPE; 4492 break; 4493 case XML_ROLE_PARAM_ENTITY_REF: 4494 #ifdef XML_DTD 4495 case XML_ROLE_INNER_PARAM_ENTITY_REF: 4496 dtd->hasParamEntityRefs = XML_TRUE; 4497 if (!paramEntityParsing) 4498 dtd->keepProcessing = dtd->standalone; 4499 else { 4500 const XML_Char *name; 4501 ENTITY *entity; 4502 name = poolStoreString(&dtd->pool, enc, 4503 s + enc->minBytesPerChar, 4504 next - enc->minBytesPerChar); 4505 if (!name) 4506 return XML_ERROR_NO_MEMORY; 4507 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); 4508 poolDiscard(&dtd->pool); 4509 /* first, determine if a check for an existing declaration is needed; 4510 if yes, check that the entity exists, and that it is internal, 4511 otherwise call the skipped entity handler 4512 */ 4513 if (prologState.documentEntity && 4514 (dtd->standalone 4515 ? !openInternalEntities 4516 : !dtd->hasParamEntityRefs)) { 4517 if (!entity) 4518 return XML_ERROR_UNDEFINED_ENTITY; 4519 else if (!entity->is_internal) 4520 return XML_ERROR_ENTITY_DECLARED_IN_PE; 4521 } 4522 else if (!entity) { 4523 dtd->keepProcessing = dtd->standalone; 4524 /* cannot report skipped entities in declarations */ 4525 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { 4526 skippedEntityHandler(handlerArg, name, 1); 4527 handleDefault = XML_FALSE; 4528 } 4529 break; 4530 } 4531 if (entity->open) 4532 return XML_ERROR_RECURSIVE_ENTITY_REF; 4533 if (entity->textPtr) { 4534 enum XML_Error result; 4535 XML_Bool betweenDecl = 4536 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); 4537 result = processInternalEntity(parser, entity, betweenDecl); 4538 if (result != XML_ERROR_NONE) 4539 return result; 4540 handleDefault = XML_FALSE; 4541 break; 4542 } 4543 if (externalEntityRefHandler) { 4544 dtd->paramEntityRead = XML_FALSE; 4545 entity->open = XML_TRUE; 4546 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 4547 0, 4548 entity->base, 4549 entity->systemId, 4550 entity->publicId)) { 4551 entity->open = XML_FALSE; 4552 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 4553 } 4554 entity->open = XML_FALSE; 4555 handleDefault = XML_FALSE; 4556 if (!dtd->paramEntityRead) { 4557 dtd->keepProcessing = dtd->standalone; 4558 break; 4559 } 4560 } 4561 else { 4562 dtd->keepProcessing = dtd->standalone; 4563 break; 4564 } 4565 } 4566 #endif /* XML_DTD */ 4567 if (!dtd->standalone && 4568 notStandaloneHandler && 4569 !notStandaloneHandler(handlerArg)) 4570 return XML_ERROR_NOT_STANDALONE; 4571 break; 4572 4573 /* Element declaration stuff */ 4574 4575 case XML_ROLE_ELEMENT_NAME: 4576 if (elementDeclHandler) { 4577 declElementType = getElementType(parser, enc, s, next); 4578 if (!declElementType) 4579 return XML_ERROR_NO_MEMORY; 4580 dtd->scaffLevel = 0; 4581 dtd->scaffCount = 0; 4582 dtd->in_eldecl = XML_TRUE; 4583 handleDefault = XML_FALSE; 4584 } 4585 break; 4586 4587 case XML_ROLE_CONTENT_ANY: 4588 case XML_ROLE_CONTENT_EMPTY: 4589 if (dtd->in_eldecl) { 4590 if (elementDeclHandler) { 4591 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content)); 4592 if (!content) 4593 return XML_ERROR_NO_MEMORY; 4594 content->quant = XML_CQUANT_NONE; 4595 content->name = NULL; 4596 content->numchildren = 0; 4597 content->children = NULL; 4598 content->type = ((role == XML_ROLE_CONTENT_ANY) ? 4599 XML_CTYPE_ANY : 4600 XML_CTYPE_EMPTY); 4601 *eventEndPP = s; 4602 elementDeclHandler(handlerArg, declElementType->name, content); 4603 handleDefault = XML_FALSE; 4604 } 4605 dtd->in_eldecl = XML_FALSE; 4606 } 4607 break; 4608 4609 case XML_ROLE_CONTENT_PCDATA: 4610 if (dtd->in_eldecl) { 4611 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 4612 = XML_CTYPE_MIXED; 4613 if (elementDeclHandler) 4614 handleDefault = XML_FALSE; 4615 } 4616 break; 4617 4618 case XML_ROLE_CONTENT_ELEMENT: 4619 quant = XML_CQUANT_NONE; 4620 goto elementContent; 4621 case XML_ROLE_CONTENT_ELEMENT_OPT: 4622 quant = XML_CQUANT_OPT; 4623 goto elementContent; 4624 case XML_ROLE_CONTENT_ELEMENT_REP: 4625 quant = XML_CQUANT_REP; 4626 goto elementContent; 4627 case XML_ROLE_CONTENT_ELEMENT_PLUS: 4628 quant = XML_CQUANT_PLUS; 4629 elementContent: 4630 if (dtd->in_eldecl) { 4631 ELEMENT_TYPE *el; 4632 const XML_Char *name; 4633 int nameLen; 4634 const char *nxt = (quant == XML_CQUANT_NONE 4635 ? next 4636 : next - enc->minBytesPerChar); 4637 int myindex = nextScaffoldPart(parser); 4638 if (myindex < 0) 4639 return XML_ERROR_NO_MEMORY; 4640 dtd->scaffold[myindex].type = XML_CTYPE_NAME; 4641 dtd->scaffold[myindex].quant = quant; 4642 el = getElementType(parser, enc, s, nxt); 4643 if (!el) 4644 return XML_ERROR_NO_MEMORY; 4645 name = el->name; 4646 dtd->scaffold[myindex].name = name; 4647 nameLen = 0; 4648 for (; name[nameLen++]; ); 4649 dtd->contentStringLen += nameLen; 4650 if (elementDeclHandler) 4651 handleDefault = XML_FALSE; 4652 } 4653 break; 4654 4655 case XML_ROLE_GROUP_CLOSE: 4656 quant = XML_CQUANT_NONE; 4657 goto closeGroup; 4658 case XML_ROLE_GROUP_CLOSE_OPT: 4659 quant = XML_CQUANT_OPT; 4660 goto closeGroup; 4661 case XML_ROLE_GROUP_CLOSE_REP: 4662 quant = XML_CQUANT_REP; 4663 goto closeGroup; 4664 case XML_ROLE_GROUP_CLOSE_PLUS: 4665 quant = XML_CQUANT_PLUS; 4666 closeGroup: 4667 if (dtd->in_eldecl) { 4668 if (elementDeclHandler) 4669 handleDefault = XML_FALSE; 4670 dtd->scaffLevel--; 4671 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; 4672 if (dtd->scaffLevel == 0) { 4673 if (!handleDefault) { 4674 XML_Content *model = build_model(parser); 4675 if (!model) 4676 return XML_ERROR_NO_MEMORY; 4677 *eventEndPP = s; 4678 elementDeclHandler(handlerArg, declElementType->name, model); 4679 } 4680 dtd->in_eldecl = XML_FALSE; 4681 dtd->contentStringLen = 0; 4682 } 4683 } 4684 break; 4685 /* End element declaration stuff */ 4686 4687 case XML_ROLE_PI: 4688 if (!reportProcessingInstruction(parser, enc, s, next)) 4689 return XML_ERROR_NO_MEMORY; 4690 handleDefault = XML_FALSE; 4691 break; 4692 case XML_ROLE_COMMENT: 4693 if (!reportComment(parser, enc, s, next)) 4694 return XML_ERROR_NO_MEMORY; 4695 handleDefault = XML_FALSE; 4696 break; 4697 case XML_ROLE_NONE: 4698 switch (tok) { 4699 case XML_TOK_BOM: 4700 handleDefault = XML_FALSE; 4701 break; 4702 } 4703 break; 4704 case XML_ROLE_DOCTYPE_NONE: 4705 if (startDoctypeDeclHandler) 4706 handleDefault = XML_FALSE; 4707 break; 4708 case XML_ROLE_ENTITY_NONE: 4709 if (dtd->keepProcessing && entityDeclHandler) 4710 handleDefault = XML_FALSE; 4711 break; 4712 case XML_ROLE_NOTATION_NONE: 4713 if (notationDeclHandler) 4714 handleDefault = XML_FALSE; 4715 break; 4716 case XML_ROLE_ATTLIST_NONE: 4717 if (dtd->keepProcessing && attlistDeclHandler) 4718 handleDefault = XML_FALSE; 4719 break; 4720 case XML_ROLE_ELEMENT_NONE: 4721 if (elementDeclHandler) 4722 handleDefault = XML_FALSE; 4723 break; 4724 } /* end of big switch */ 4725 4726 if (handleDefault && defaultHandler) 4727 reportDefault(parser, enc, s, next); 4728 4729 switch (ps_parsing) { 4730 case XML_SUSPENDED: 4731 *nextPtr = next; 4732 return XML_ERROR_NONE; 4733 case XML_FINISHED: 4734 return XML_ERROR_ABORTED; 4735 default: 4736 s = next; 4737 tok = XmlPrologTok(enc, s, end, &next); 4738 } 4739 } 4740 /* not reached */ 4741 } 4742 4743 static enum XML_Error PTRCALL 4744 epilogProcessor(XML_Parser parser, 4745 const char *s, 4746 const char *end, 4747 const char **nextPtr) 4748 { 4749 processor = epilogProcessor; 4750 eventPtr = s; 4751 for (;;) { 4752 const char *next = NULL; 4753 int tok = XmlPrologTok(encoding, s, end, &next); 4754 eventEndPtr = next; 4755 switch (tok) { 4756 /* report partial linebreak - it might be the last token */ 4757 case -XML_TOK_PROLOG_S: 4758 if (defaultHandler) { 4759 reportDefault(parser, encoding, s, next); 4760 if (ps_parsing == XML_FINISHED) 4761 return XML_ERROR_ABORTED; 4762 } 4763 *nextPtr = next; 4764 return XML_ERROR_NONE; 4765 case XML_TOK_NONE: 4766 *nextPtr = s; 4767 return XML_ERROR_NONE; 4768 case XML_TOK_PROLOG_S: 4769 if (defaultHandler) 4770 reportDefault(parser, encoding, s, next); 4771 break; 4772 case XML_TOK_PI: 4773 if (!reportProcessingInstruction(parser, encoding, s, next)) 4774 return XML_ERROR_NO_MEMORY; 4775 break; 4776 case XML_TOK_COMMENT: 4777 if (!reportComment(parser, encoding, s, next)) 4778 return XML_ERROR_NO_MEMORY; 4779 break; 4780 case XML_TOK_INVALID: 4781 eventPtr = next; 4782 return XML_ERROR_INVALID_TOKEN; 4783 case XML_TOK_PARTIAL: 4784 if (!ps_finalBuffer) { 4785 *nextPtr = s; 4786 return XML_ERROR_NONE; 4787 } 4788 return XML_ERROR_UNCLOSED_TOKEN; 4789 case XML_TOK_PARTIAL_CHAR: 4790 if (!ps_finalBuffer) { 4791 *nextPtr = s; 4792 return XML_ERROR_NONE; 4793 } 4794 return XML_ERROR_PARTIAL_CHAR; 4795 default: 4796 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; 4797 } 4798 eventPtr = s = next; 4799 switch (ps_parsing) { 4800 case XML_SUSPENDED: 4801 *nextPtr = next; 4802 return XML_ERROR_NONE; 4803 case XML_FINISHED: 4804 return XML_ERROR_ABORTED; 4805 default: ; 4806 } 4807 } 4808 } 4809 4810 static enum XML_Error 4811 processInternalEntity(XML_Parser parser, ENTITY *entity, 4812 XML_Bool betweenDecl) 4813 { 4814 const char *textStart, *textEnd; 4815 const char *next; 4816 enum XML_Error result; 4817 OPEN_INTERNAL_ENTITY *openEntity; 4818 4819 if (freeInternalEntities) { 4820 openEntity = freeInternalEntities; 4821 freeInternalEntities = openEntity->next; 4822 } 4823 else { 4824 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY)); 4825 if (!openEntity) 4826 return XML_ERROR_NO_MEMORY; 4827 } 4828 entity->open = XML_TRUE; 4829 entity->processed = 0; 4830 openEntity->next = openInternalEntities; 4831 openInternalEntities = openEntity; 4832 openEntity->entity = entity; 4833 openEntity->startTagLevel = tagLevel; 4834 openEntity->betweenDecl = betweenDecl; 4835 openEntity->internalEventPtr = NULL; 4836 openEntity->internalEventEndPtr = NULL; 4837 textStart = (char *)entity->textPtr; 4838 textEnd = (char *)(entity->textPtr + entity->textLen); 4839 4840 #ifdef XML_DTD 4841 if (entity->is_param) { 4842 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); 4843 result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 4844 next, &next, XML_FALSE); 4845 } 4846 else 4847 #endif /* XML_DTD */ 4848 result = doContent(parser, tagLevel, internalEncoding, textStart, 4849 textEnd, &next, XML_FALSE); 4850 4851 if (result == XML_ERROR_NONE) { 4852 if (textEnd != next && ps_parsing == XML_SUSPENDED) { 4853 entity->processed = (int)(next - textStart); 4854 processor = internalEntityProcessor; 4855 } 4856 else { 4857 entity->open = XML_FALSE; 4858 openInternalEntities = openEntity->next; 4859 /* put openEntity back in list of free instances */ 4860 openEntity->next = freeInternalEntities; 4861 freeInternalEntities = openEntity; 4862 } 4863 } 4864 return result; 4865 } 4866 4867 static enum XML_Error PTRCALL 4868 internalEntityProcessor(XML_Parser parser, 4869 const char *s, 4870 const char *end, 4871 const char **nextPtr) 4872 { 4873 ENTITY *entity; 4874 const char *textStart, *textEnd; 4875 const char *next; 4876 enum XML_Error result; 4877 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities; 4878 if (!openEntity) 4879 return XML_ERROR_UNEXPECTED_STATE; 4880 4881 entity = openEntity->entity; 4882 textStart = ((char *)entity->textPtr) + entity->processed; 4883 textEnd = (char *)(entity->textPtr + entity->textLen); 4884 4885 #ifdef XML_DTD 4886 if (entity->is_param) { 4887 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); 4888 result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 4889 next, &next, XML_FALSE); 4890 } 4891 else 4892 #endif /* XML_DTD */ 4893 result = doContent(parser, openEntity->startTagLevel, internalEncoding, 4894 textStart, textEnd, &next, XML_FALSE); 4895 4896 if (result != XML_ERROR_NONE) 4897 return result; 4898 else if (textEnd != next && ps_parsing == XML_SUSPENDED) { 4899 entity->processed = (int)(next - (char *)entity->textPtr); 4900 return result; 4901 } 4902 else { 4903 entity->open = XML_FALSE; 4904 openInternalEntities = openEntity->next; 4905 /* put openEntity back in list of free instances */ 4906 openEntity->next = freeInternalEntities; 4907 freeInternalEntities = openEntity; 4908 } 4909 4910 #ifdef XML_DTD 4911 if (entity->is_param) { 4912 int tok; 4913 processor = prologProcessor; 4914 tok = XmlPrologTok(encoding, s, end, &next); 4915 return doProlog(parser, encoding, s, end, tok, next, nextPtr, 4916 (XML_Bool)!ps_finalBuffer); 4917 } 4918 else 4919 #endif /* XML_DTD */ 4920 { 4921 processor = contentProcessor; 4922 /* see externalEntityContentProcessor vs contentProcessor */ 4923 return doContent(parser, parentParser ? 1 : 0, encoding, s, end, 4924 nextPtr, (XML_Bool)!ps_finalBuffer); 4925 } 4926 } 4927 4928 static enum XML_Error PTRCALL 4929 errorProcessor(XML_Parser parser, 4930 const char *s, 4931 const char *end, 4932 const char **nextPtr) 4933 { 4934 return errorCode; 4935 } 4936 4937 static enum XML_Error 4938 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 4939 const char *ptr, const char *end, 4940 STRING_POOL *pool) 4941 { 4942 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, 4943 end, pool); 4944 if (result) 4945 return result; 4946 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) 4947 poolChop(pool); 4948 if (!poolAppendChar(pool, XML_T('\0'))) 4949 return XML_ERROR_NO_MEMORY; 4950 return XML_ERROR_NONE; 4951 } 4952 4953 static enum XML_Error 4954 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 4955 const char *ptr, const char *end, 4956 STRING_POOL *pool) 4957 { 4958 DTD * const dtd = _dtd; /* save one level of indirection */ 4959 for (;;) { 4960 const char *next; 4961 int tok = XmlAttributeValueTok(enc, ptr, end, &next); 4962 switch (tok) { 4963 case XML_TOK_NONE: 4964 return XML_ERROR_NONE; 4965 case XML_TOK_INVALID: 4966 if (enc == encoding) 4967 eventPtr = next; 4968 return XML_ERROR_INVALID_TOKEN; 4969 case XML_TOK_PARTIAL: 4970 if (enc == encoding) 4971 eventPtr = ptr; 4972 return XML_ERROR_INVALID_TOKEN; 4973 case XML_TOK_CHAR_REF: 4974 { 4975 XML_Char buf[XML_ENCODE_MAX]; 4976 int i; 4977 int n = XmlCharRefNumber(enc, ptr); 4978 if (n < 0) { 4979 if (enc == encoding) 4980 eventPtr = ptr; 4981 return XML_ERROR_BAD_CHAR_REF; 4982 } 4983 if (!isCdata 4984 && n == 0x20 /* space */ 4985 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 4986 break; 4987 n = XmlEncode(n, (ICHAR *)buf); 4988 if (!n) { 4989 if (enc == encoding) 4990 eventPtr = ptr; 4991 return XML_ERROR_BAD_CHAR_REF; 4992 } 4993 for (i = 0; i < n; i++) { 4994 if (!poolAppendChar(pool, buf[i])) 4995 return XML_ERROR_NO_MEMORY; 4996 } 4997 } 4998 break; 4999 case XML_TOK_DATA_CHARS: 5000 if (!poolAppend(pool, enc, ptr, next)) 5001 return XML_ERROR_NO_MEMORY; 5002 break; 5003 case XML_TOK_TRAILING_CR: 5004 next = ptr + enc->minBytesPerChar; 5005 /* fall through */ 5006 case XML_TOK_ATTRIBUTE_VALUE_S: 5007 case XML_TOK_DATA_NEWLINE: 5008 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 5009 break; 5010 if (!poolAppendChar(pool, 0x20)) 5011 return XML_ERROR_NO_MEMORY; 5012 break; 5013 case XML_TOK_ENTITY_REF: 5014 { 5015 const XML_Char *name; 5016 ENTITY *entity; 5017 char checkEntityDecl; 5018 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, 5019 ptr + enc->minBytesPerChar, 5020 next - enc->minBytesPerChar); 5021 if (ch) { 5022 if (!poolAppendChar(pool, ch)) 5023 return XML_ERROR_NO_MEMORY; 5024 break; 5025 } 5026 name = poolStoreString(&temp2Pool, enc, 5027 ptr + enc->minBytesPerChar, 5028 next - enc->minBytesPerChar); 5029 if (!name) 5030 return XML_ERROR_NO_MEMORY; 5031 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); 5032 poolDiscard(&temp2Pool); 5033 /* First, determine if a check for an existing declaration is needed; 5034 if yes, check that the entity exists, and that it is internal. 5035 */ 5036 if (pool == &dtd->pool) /* are we called from prolog? */ 5037 checkEntityDecl = 5038 #ifdef XML_DTD 5039 prologState.documentEntity && 5040 #endif /* XML_DTD */ 5041 (dtd->standalone 5042 ? !openInternalEntities 5043 : !dtd->hasParamEntityRefs); 5044 else /* if (pool == &tempPool): we are called from content */ 5045 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; 5046 if (checkEntityDecl) { 5047 if (!entity) 5048 return XML_ERROR_UNDEFINED_ENTITY; 5049 else if (!entity->is_internal) 5050 return XML_ERROR_ENTITY_DECLARED_IN_PE; 5051 } 5052 else if (!entity) { 5053 /* Cannot report skipped entity here - see comments on 5054 skippedEntityHandler. 5055 if (skippedEntityHandler) 5056 skippedEntityHandler(handlerArg, name, 0); 5057 */ 5058 /* Cannot call the default handler because this would be 5059 out of sync with the call to the startElementHandler. 5060 if ((pool == &tempPool) && defaultHandler) 5061 reportDefault(parser, enc, ptr, next); 5062 */ 5063 break; 5064 } 5065 if (entity->open) { 5066 if (enc == encoding) 5067 eventPtr = ptr; 5068 return XML_ERROR_RECURSIVE_ENTITY_REF; 5069 } 5070 if (entity->notation) { 5071 if (enc == encoding) 5072 eventPtr = ptr; 5073 return XML_ERROR_BINARY_ENTITY_REF; 5074 } 5075 if (!entity->textPtr) { 5076 if (enc == encoding) 5077 eventPtr = ptr; 5078 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; 5079 } 5080 else { 5081 enum XML_Error result; 5082 const XML_Char *textEnd = entity->textPtr + entity->textLen; 5083 entity->open = XML_TRUE; 5084 result = appendAttributeValue(parser, internalEncoding, isCdata, 5085 (char *)entity->textPtr, 5086 (char *)textEnd, pool); 5087 entity->open = XML_FALSE; 5088 if (result) 5089 return result; 5090 } 5091 } 5092 break; 5093 default: 5094 if (enc == encoding) 5095 eventPtr = ptr; 5096 return XML_ERROR_UNEXPECTED_STATE; 5097 } 5098 ptr = next; 5099 } 5100 /* not reached */ 5101 } 5102 5103 static enum XML_Error 5104 storeEntityValue(XML_Parser parser, 5105 const ENCODING *enc, 5106 const char *entityTextPtr, 5107 const char *entityTextEnd) 5108 { 5109 DTD * const dtd = _dtd; /* save one level of indirection */ 5110 STRING_POOL *pool = &(dtd->entityValuePool); 5111 enum XML_Error result = XML_ERROR_NONE; 5112 #ifdef XML_DTD 5113 int oldInEntityValue = prologState.inEntityValue; 5114 prologState.inEntityValue = 1; 5115 #endif /* XML_DTD */ 5116 /* never return Null for the value argument in EntityDeclHandler, 5117 since this would indicate an external entity; therefore we 5118 have to make sure that entityValuePool.start is not null */ 5119 if (!pool->blocks) { 5120 if (!poolGrow(pool)) 5121 return XML_ERROR_NO_MEMORY; 5122 } 5123 5124 for (;;) { 5125 const char *next; 5126 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); 5127 switch (tok) { 5128 case XML_TOK_PARAM_ENTITY_REF: 5129 #ifdef XML_DTD 5130 if (isParamEntity || enc != encoding) { 5131 const XML_Char *name; 5132 ENTITY *entity; 5133 name = poolStoreString(&tempPool, enc, 5134 entityTextPtr + enc->minBytesPerChar, 5135 next - enc->minBytesPerChar); 5136 if (!name) { 5137 result = XML_ERROR_NO_MEMORY; 5138 goto endEntityValue; 5139 } 5140 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); 5141 poolDiscard(&tempPool); 5142 if (!entity) { 5143 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ 5144 /* cannot report skipped entity here - see comments on 5145 skippedEntityHandler 5146 if (skippedEntityHandler) 5147 skippedEntityHandler(handlerArg, name, 0); 5148 */ 5149 dtd->keepProcessing = dtd->standalone; 5150 goto endEntityValue; 5151 } 5152 if (entity->open) { 5153 if (enc == encoding) 5154 eventPtr = entityTextPtr; 5155 result = XML_ERROR_RECURSIVE_ENTITY_REF; 5156 goto endEntityValue; 5157 } 5158 if (entity->systemId) { 5159 if (externalEntityRefHandler) { 5160 dtd->paramEntityRead = XML_FALSE; 5161 entity->open = XML_TRUE; 5162 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 5163 0, 5164 entity->base, 5165 entity->systemId, 5166 entity->publicId)) { 5167 entity->open = XML_FALSE; 5168 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; 5169 goto endEntityValue; 5170 } 5171 entity->open = XML_FALSE; 5172 if (!dtd->paramEntityRead) 5173 dtd->keepProcessing = dtd->standalone; 5174 } 5175 else 5176 dtd->keepProcessing = dtd->standalone; 5177 } 5178 else { 5179 entity->open = XML_TRUE; 5180 result = storeEntityValue(parser, 5181 internalEncoding, 5182 (char *)entity->textPtr, 5183 (char *)(entity->textPtr 5184 + entity->textLen)); 5185 entity->open = XML_FALSE; 5186 if (result) 5187 goto endEntityValue; 5188 } 5189 break; 5190 } 5191 #endif /* XML_DTD */ 5192 /* In the internal subset, PE references are not legal 5193 within markup declarations, e.g entity values in this case. */ 5194 eventPtr = entityTextPtr; 5195 result = XML_ERROR_PARAM_ENTITY_REF; 5196 goto endEntityValue; 5197 case XML_TOK_NONE: 5198 result = XML_ERROR_NONE; 5199 goto endEntityValue; 5200 case XML_TOK_ENTITY_REF: 5201 case XML_TOK_DATA_CHARS: 5202 if (!poolAppend(pool, enc, entityTextPtr, next)) { 5203 result = XML_ERROR_NO_MEMORY; 5204 goto endEntityValue; 5205 } 5206 break; 5207 case XML_TOK_TRAILING_CR: 5208 next = entityTextPtr + enc->minBytesPerChar; 5209 /* fall through */ 5210 case XML_TOK_DATA_NEWLINE: 5211 if (pool->end == pool->ptr && !poolGrow(pool)) { 5212 result = XML_ERROR_NO_MEMORY; 5213 goto endEntityValue; 5214 } 5215 *(pool->ptr)++ = 0xA; 5216 break; 5217 case XML_TOK_CHAR_REF: 5218 { 5219 XML_Char buf[XML_ENCODE_MAX]; 5220 int i; 5221 int n = XmlCharRefNumber(enc, entityTextPtr); 5222 if (n < 0) { 5223 if (enc == encoding) 5224 eventPtr = entityTextPtr; 5225 result = XML_ERROR_BAD_CHAR_REF; 5226 goto endEntityValue; 5227 } 5228 n = XmlEncode(n, (ICHAR *)buf); 5229 if (!n) { 5230 if (enc == encoding) 5231 eventPtr = entityTextPtr; 5232 result = XML_ERROR_BAD_CHAR_REF; 5233 goto endEntityValue; 5234 } 5235 for (i = 0; i < n; i++) { 5236 if (pool->end == pool->ptr && !poolGrow(pool)) { 5237 result = XML_ERROR_NO_MEMORY; 5238 goto endEntityValue; 5239 } 5240 *(pool->ptr)++ = buf[i]; 5241 } 5242 } 5243 break; 5244 case XML_TOK_PARTIAL: 5245 if (enc == encoding) 5246 eventPtr = entityTextPtr; 5247 result = XML_ERROR_INVALID_TOKEN; 5248 goto endEntityValue; 5249 case XML_TOK_INVALID: 5250 if (enc == encoding) 5251 eventPtr = next; 5252 result = XML_ERROR_INVALID_TOKEN; 5253 goto endEntityValue; 5254 default: 5255 if (enc == encoding) 5256 eventPtr = entityTextPtr; 5257 result = XML_ERROR_UNEXPECTED_STATE; 5258 goto endEntityValue; 5259 } 5260 entityTextPtr = next; 5261 } 5262 endEntityValue: 5263 #ifdef XML_DTD 5264 prologState.inEntityValue = oldInEntityValue; 5265 #endif /* XML_DTD */ 5266 return result; 5267 } 5268 5269 static void FASTCALL 5270 normalizeLines(XML_Char *s) 5271 { 5272 XML_Char *p; 5273 for (;; s++) { 5274 if (*s == XML_T('\0')) 5275 return; 5276 if (*s == 0xD) 5277 break; 5278 } 5279 p = s; 5280 do { 5281 if (*s == 0xD) { 5282 *p++ = 0xA; 5283 if (*++s == 0xA) 5284 s++; 5285 } 5286 else 5287 *p++ = *s++; 5288 } while (*s); 5289 *p = XML_T('\0'); 5290 } 5291 5292 static int 5293 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, 5294 const char *start, const char *end) 5295 { 5296 const XML_Char *target; 5297 XML_Char *data; 5298 const char *tem; 5299 if (!processingInstructionHandler) { 5300 if (defaultHandler) 5301 reportDefault(parser, enc, start, end); 5302 return 1; 5303 } 5304 start += enc->minBytesPerChar * 2; 5305 tem = start + XmlNameLength(enc, start); 5306 target = poolStoreString(&tempPool, enc, start, tem); 5307 if (!target) 5308 return 0; 5309 poolFinish(&tempPool); 5310 data = poolStoreString(&tempPool, enc, 5311 XmlSkipS(enc, tem), 5312 end - enc->minBytesPerChar*2); 5313 if (!data) 5314 return 0; 5315 normalizeLines(data); 5316 processingInstructionHandler(handlerArg, target, data); 5317 poolClear(&tempPool); 5318 return 1; 5319 } 5320 5321 static int 5322 reportComment(XML_Parser parser, const ENCODING *enc, 5323 const char *start, const char *end) 5324 { 5325 XML_Char *data; 5326 if (!commentHandler) { 5327 if (defaultHandler) 5328 reportDefault(parser, enc, start, end); 5329 return 1; 5330 } 5331 data = poolStoreString(&tempPool, 5332 enc, 5333 start + enc->minBytesPerChar * 4, 5334 end - enc->minBytesPerChar * 3); 5335 if (!data) 5336 return 0; 5337 normalizeLines(data); 5338 commentHandler(handlerArg, data); 5339 poolClear(&tempPool); 5340 return 1; 5341 } 5342 5343 static void 5344 reportDefault(XML_Parser parser, const ENCODING *enc, 5345 const char *s, const char *end) 5346 { 5347 if (MUST_CONVERT(enc, s)) { 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 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); 5361 *eventEndPP = s; 5362 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); 5363 *eventPP = s; 5364 } while (s != end); 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 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); 6170 if (ptr == end) 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 int blockSize = (int)(pool->end - pool->start)*2; 6255 BLOCK *temp = (BLOCK *) 6256 pool->mem->realloc_fcn(pool->blocks, 6257 (offsetof(BLOCK, s) 6258 + blockSize * sizeof(XML_Char))); 6259 if (temp == NULL) 6260 return XML_FALSE; 6261 pool->blocks = temp; 6262 pool->blocks->size = blockSize; 6263 pool->ptr = pool->blocks->s + (pool->ptr - pool->start); 6264 pool->start = pool->blocks->s; 6265 pool->end = pool->start + blockSize; 6266 } 6267 else { 6268 BLOCK *tem; 6269 int blockSize = (int)(pool->end - pool->start); 6270 if (blockSize < INIT_BLOCK_SIZE) 6271 blockSize = INIT_BLOCK_SIZE; 6272 else 6273 blockSize *= 2; 6274 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) 6275 + blockSize * sizeof(XML_Char)); 6276 if (!tem) 6277 return XML_FALSE; 6278 tem->size = blockSize; 6279 tem->next = pool->blocks; 6280 pool->blocks = tem; 6281 if (pool->ptr != pool->start) 6282 memcpy(tem->s, pool->start, 6283 (pool->ptr - pool->start) * sizeof(XML_Char)); 6284 pool->ptr = tem->s + (pool->ptr - pool->start); 6285 pool->start = tem->s; 6286 pool->end = tem->s + blockSize; 6287 } 6288 return XML_TRUE; 6289 } 6290 6291 static int FASTCALL 6292 nextScaffoldPart(XML_Parser parser) 6293 { 6294 DTD * const dtd = _dtd; /* save one level of indirection */ 6295 CONTENT_SCAFFOLD * me; 6296 int next; 6297 6298 if (!dtd->scaffIndex) { 6299 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int)); 6300 if (!dtd->scaffIndex) 6301 return -1; 6302 dtd->scaffIndex[0] = 0; 6303 } 6304 6305 if (dtd->scaffCount >= dtd->scaffSize) { 6306 CONTENT_SCAFFOLD *temp; 6307 if (dtd->scaffold) { 6308 temp = (CONTENT_SCAFFOLD *) 6309 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); 6310 if (temp == NULL) 6311 return -1; 6312 dtd->scaffSize *= 2; 6313 } 6314 else { 6315 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS 6316 * sizeof(CONTENT_SCAFFOLD)); 6317 if (temp == NULL) 6318 return -1; 6319 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; 6320 } 6321 dtd->scaffold = temp; 6322 } 6323 next = dtd->scaffCount++; 6324 me = &dtd->scaffold[next]; 6325 if (dtd->scaffLevel) { 6326 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]]; 6327 if (parent->lastchild) { 6328 dtd->scaffold[parent->lastchild].nextsib = next; 6329 } 6330 if (!parent->childcnt) 6331 parent->firstchild = next; 6332 parent->lastchild = next; 6333 parent->childcnt++; 6334 } 6335 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; 6336 return next; 6337 } 6338 6339 static void 6340 build_node(XML_Parser parser, 6341 int src_node, 6342 XML_Content *dest, 6343 XML_Content **contpos, 6344 XML_Char **strpos) 6345 { 6346 DTD * const dtd = _dtd; /* save one level of indirection */ 6347 dest->type = dtd->scaffold[src_node].type; 6348 dest->quant = dtd->scaffold[src_node].quant; 6349 if (dest->type == XML_CTYPE_NAME) { 6350 const XML_Char *src; 6351 dest->name = *strpos; 6352 src = dtd->scaffold[src_node].name; 6353 for (;;) { 6354 *(*strpos)++ = *src; 6355 if (!*src) 6356 break; 6357 src++; 6358 } 6359 dest->numchildren = 0; 6360 dest->children = NULL; 6361 } 6362 else { 6363 unsigned int i; 6364 int cn; 6365 dest->numchildren = dtd->scaffold[src_node].childcnt; 6366 dest->children = *contpos; 6367 *contpos += dest->numchildren; 6368 for (i = 0, cn = dtd->scaffold[src_node].firstchild; 6369 i < dest->numchildren; 6370 i++, cn = dtd->scaffold[cn].nextsib) { 6371 build_node(parser, cn, &(dest->children[i]), contpos, strpos); 6372 } 6373 dest->name = NULL; 6374 } 6375 } 6376 6377 static XML_Content * 6378 build_model (XML_Parser parser) 6379 { 6380 DTD * const dtd = _dtd; /* save one level of indirection */ 6381 XML_Content *ret; 6382 XML_Content *cpos; 6383 XML_Char * str; 6384 int allocsize = (dtd->scaffCount * sizeof(XML_Content) 6385 + (dtd->contentStringLen * sizeof(XML_Char))); 6386 6387 ret = (XML_Content *)MALLOC(allocsize); 6388 if (!ret) 6389 return NULL; 6390 6391 str = (XML_Char *) (&ret[dtd->scaffCount]); 6392 cpos = &ret[1]; 6393 6394 build_node(parser, 0, ret, &cpos, &str); 6395 return ret; 6396 } 6397 6398 static ELEMENT_TYPE * 6399 getElementType(XML_Parser parser, 6400 const ENCODING *enc, 6401 const char *ptr, 6402 const char *end) 6403 { 6404 DTD * const dtd = _dtd; /* save one level of indirection */ 6405 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); 6406 ELEMENT_TYPE *ret; 6407 6408 if (!name) 6409 return NULL; 6410 ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); 6411 if (!ret) 6412 return NULL; 6413 if (ret->name != name) 6414 poolDiscard(&dtd->pool); 6415 else { 6416 poolFinish(&dtd->pool); 6417 if (!setElementTypePrefix(parser, ret)) 6418 return NULL; 6419 } 6420 return ret; 6421 } 6422