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