1/* 2The contents of this file are subject to the Mozilla Public License 3Version 1.1 (the "License"); you may not use this file except in 4compliance with the License. You may obtain a copy of the License at 5http://www.mozilla.org/MPL/ 6 7Software distributed under the License is distributed on an "AS IS" 8basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 9License for the specific language governing rights and limitations 10under the License. 11 12The Original Code is expat. 13 14The Initial Developer of the Original Code is James Clark. 15Portions created by James Clark are Copyright (C) 1998, 1999 16James Clark. All Rights Reserved. 17 18Contributor(s): 19 20Alternatively, the contents of this file may be used under the terms 21of the GNU General Public License (the "GPL"), in which case the 22provisions of the GPL are applicable instead of those above. If you 23wish to allow use of your version of this file only under the terms of 24the GPL and not to allow others to use your version of this file under 25the MPL, indicate your decision by deleting the provisions above and 26replace them with the notice and other provisions required by the 27GPL. If you do not delete the provisions above, a recipient may use 28your version of this file under either the MPL or the GPL. 29*/ 30 31#include "xmldef.h" 32#include "xmlparse.h" 33 34#ifdef XML_UNICODE 35#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX 36#define XmlConvert XmlUtf16Convert 37#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding 38#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS 39#define XmlEncode XmlUtf16Encode 40#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1)) 41typedef unsigned short ICHAR; 42#else 43#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX 44#define XmlConvert XmlUtf8Convert 45#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding 46#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS 47#define XmlEncode XmlUtf8Encode 48#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) 49typedef char ICHAR; 50#endif 51 52 53#ifndef XML_NS 54 55#define XmlInitEncodingNS XmlInitEncoding 56#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding 57#undef XmlGetInternalEncodingNS 58#define XmlGetInternalEncodingNS XmlGetInternalEncoding 59#define XmlParseXmlDeclNS XmlParseXmlDecl 60 61#endif 62 63#ifdef XML_UNICODE_WCHAR_T 64#define XML_T(x) L ## x 65#else 66#define XML_T(x) x 67#endif 68 69/* Round up n to be a multiple of sz, where sz is a power of 2. */ 70#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) 71 72#include "xmltok.h" 73#include "xmlrole.h" 74#include "hashtable.h" 75 76#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ 77#define INIT_DATA_BUF_SIZE 1024 78#define INIT_ATTS_SIZE 16 79#define INIT_BLOCK_SIZE 1024 80#define INIT_BUFFER_SIZE 1024 81 82#define EXPAND_SPARE 24 83 84typedef struct binding { 85 struct prefix *prefix; 86 struct binding *nextTagBinding; 87 struct binding *prevPrefixBinding; 88 const struct attribute_id *attId; 89 XML_Char *uri; 90 int uriLen; 91 int uriAlloc; 92} BINDING; 93 94typedef struct prefix { 95 const XML_Char *name; 96 BINDING *binding; 97} PREFIX; 98 99typedef struct { 100 const XML_Char *str; 101 const XML_Char *localPart; 102 int uriLen; 103} TAG_NAME; 104 105typedef struct tag { 106 struct tag *parent; 107 const char *rawName; 108 int rawNameLength; 109 TAG_NAME name; 110 char *buf; 111 char *bufEnd; 112 BINDING *bindings; 113} TAG; 114 115typedef struct { 116 const XML_Char *name; 117 const XML_Char *textPtr; 118 int textLen; 119 const XML_Char *systemId; 120 const XML_Char *base; 121 const XML_Char *publicId; 122 const XML_Char *notation; 123 char open; 124} ENTITY; 125 126typedef struct block { 127 struct block *next; 128 int size; 129 XML_Char s[1]; 130} BLOCK; 131 132typedef struct { 133 BLOCK *blocks; 134 BLOCK *freeBlocks; 135 const XML_Char *end; 136 XML_Char *ptr; 137 XML_Char *start; 138} STRING_POOL; 139 140/* The XML_Char before the name is used to determine whether 141an attribute has been specified. */ 142typedef struct attribute_id { 143 XML_Char *name; 144 PREFIX *prefix; 145 char maybeTokenized; 146 char xmlns; 147} ATTRIBUTE_ID; 148 149typedef struct { 150 const ATTRIBUTE_ID *id; 151 char isCdata; 152 const XML_Char *value; 153} DEFAULT_ATTRIBUTE; 154 155typedef struct content_particle { 156 struct content_particle *next; 157 int tokenType; 158 const XML_Char *name; 159} CONTENT_PARTICLE; 160 161typedef struct { 162 const XML_Char *name; 163 PREFIX *prefix; 164 int nDefaultAtts; 165 int allocDefaultAtts; 166 DEFAULT_ATTRIBUTE *defaultAtts; 167/* ericm@scriptics.com; the following vars are for storing the contentspec 168 of the element */ 169 XML_Char **contentSpec; 170 int nContentParticles; 171 int maxContentParticles; 172 XML_Char **attributes; 173 int nAttributes; 174 int maxAttributes; 175} ELEMENT_TYPE; 176 177typedef struct { 178 HASH_TABLE generalEntities; 179 HASH_TABLE elementTypes; 180 HASH_TABLE attributeIds; 181 HASH_TABLE prefixes; 182 STRING_POOL pool; 183 int complete; 184 int standalone; 185#ifdef XML_DTD 186 HASH_TABLE paramEntities; 187#endif /* XML_DTD */ 188 PREFIX defaultPrefix; 189} DTD; 190 191typedef struct open_internal_entity { 192 const char *internalEventPtr; 193 const char *internalEventEndPtr; 194 struct open_internal_entity *next; 195 ENTITY *entity; 196} OPEN_INTERNAL_ENTITY; 197 198typedef enum XML_Error Processor(XML_Parser parser, 199 const char *start, 200 const char *end, 201 const char **endPtr); 202 203static Processor prologProcessor; 204static Processor prologInitProcessor; 205static Processor contentProcessor; 206static Processor cdataSectionProcessor; 207#ifdef XML_DTD 208static Processor ignoreSectionProcessor; 209#endif /* XML_DTD */ 210static Processor epilogProcessor; 211static Processor errorProcessor; 212static Processor externalEntityInitProcessor; 213static Processor externalEntityInitProcessor2; 214static Processor externalEntityInitProcessor3; 215static Processor externalEntityContentProcessor; 216 217/* ericm@scriptics.com */ 218/* Append a given content particle to the content specification string of 219 * the given element. 220 */ 221enum XML_Error appendContent(ELEMENT_TYPE *el, int type, const XML_Char *name); 222enum XML_Error appendAttribute(ELEMENT_TYPE *el, XML_Char *name); 223 224static enum XML_Error 225handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); 226static enum XML_Error 227processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *); 228static enum XML_Error 229initializeEncoding(XML_Parser parser); 230static enum XML_Error 231doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 232 const char *end, int tok, const char *next, const char **nextPtr); 233static enum XML_Error 234processInternalParamEntity(XML_Parser parser, ENTITY *entity); 235static enum XML_Error 236doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, 237 const char *start, const char *end, const char **endPtr); 238static enum XML_Error 239doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr); 240#ifdef XML_DTD 241static enum XML_Error 242doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr); 243#endif /* XML_DTD */ 244static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s, 245 TAG_NAME *tagNamePtr, BINDING **bindingsPtr); 246static 247int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr); 248static int 249defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue); 250static enum XML_Error 251storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *, 252 STRING_POOL *); 253static enum XML_Error 254appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *, 255 STRING_POOL *); 256static ATTRIBUTE_ID * 257getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); 258static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); 259static enum XML_Error 260storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); 261static int 262reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); 263static int 264reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); 265static void 266reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); 267 268static const XML_Char *getContext(XML_Parser parser); 269static int setContext(XML_Parser parser, const XML_Char *context); 270static void normalizePublicId(XML_Char *s); 271static int dtdInit(DTD *); 272static void dtdDestroy(DTD *); 273static int dtdCopy(DTD *newDtd, const DTD *oldDtd); 274static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); 275#ifdef XML_DTD 276static void dtdSwap(DTD *, DTD *); 277#endif /* XML_DTD */ 278static void poolInit(STRING_POOL *); 279static void poolClear(STRING_POOL *); 280static void poolDestroy(STRING_POOL *); 281static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, 282 const char *ptr, const char *end); 283static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, 284 const char *ptr, const char *end); 285static int poolGrow(STRING_POOL *pool); 286static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s); 287static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); 288 289#define poolStart(pool) ((pool)->start) 290#define poolEnd(pool) ((pool)->ptr) 291#define poolLength(pool) ((pool)->ptr - (pool)->start) 292#define poolChop(pool) ((void)--(pool->ptr)) 293#define poolLastChar(pool) (((pool)->ptr)[-1]) 294#define poolDiscard(pool) ((pool)->ptr = (pool)->start) 295#define poolFinish(pool) ((pool)->start = (pool)->ptr) 296#define poolAppendChar(pool, c) \ 297 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ 298 ? 0 \ 299 : ((*((pool)->ptr)++ = c), 1)) 300 301typedef struct { 302 /* The first member must be userData so that the XML_GetUserData macro works. */ 303 void *m_userData; 304 void *m_handlerArg; 305 char *m_buffer; 306 /* first character to be parsed */ 307 const char *m_bufferPtr; 308 /* past last character to be parsed */ 309 char *m_bufferEnd; 310 /* allocated end of buffer */ 311 const char *m_bufferLim; 312 long m_parseEndByteIndex; 313 const char *m_parseEndPtr; 314 XML_Char *m_dataBuf; 315 XML_Char *m_dataBufEnd; 316 XML_StartElementHandler m_startElementHandler; 317 XML_EndElementHandler m_endElementHandler; 318 XML_CharacterDataHandler m_characterDataHandler; 319 XML_ProcessingInstructionHandler m_processingInstructionHandler; 320 XML_CommentHandler m_commentHandler; 321 XML_StartCdataSectionHandler m_startCdataSectionHandler; 322 XML_EndCdataSectionHandler m_endCdataSectionHandler; 323 XML_DefaultHandler m_defaultHandler; 324 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; 325 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; 326 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; 327 XML_NotationDeclHandler m_notationDeclHandler; 328 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; 329 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; 330 XML_NotStandaloneHandler m_notStandaloneHandler; 331 XML_ExternalEntityRefHandler m_externalEntityRefHandler; 332 /* ericm@scriptics.com */ 333 XML_ElementDeclHandler m_elementDeclHandler; 334 XML_AttlistDeclHandler m_attlistDeclHandler; 335 void *m_externalEntityRefHandlerArg; 336 XML_UnknownEncodingHandler m_unknownEncodingHandler; 337 const ENCODING *m_encoding; 338 INIT_ENCODING m_initEncoding; 339 const ENCODING *m_internalEncoding; 340 const XML_Char *m_protocolEncodingName; 341 int m_ns; 342 void *m_unknownEncodingMem; 343 void *m_unknownEncodingData; 344 void *m_unknownEncodingHandlerData; 345 void (*m_unknownEncodingRelease)(void *); 346 PROLOG_STATE m_prologState; 347 Processor *m_processor; 348 enum XML_Error m_errorCode; 349 const char *m_eventPtr; 350 const char *m_eventEndPtr; 351 const char *m_positionPtr; 352 OPEN_INTERNAL_ENTITY *m_openInternalEntities; 353 int m_defaultExpandInternalEntities; 354 int m_tagLevel; 355 ENTITY *m_declEntity; 356 const XML_Char *m_declNotationName; 357 const XML_Char *m_declNotationPublicId; 358 ELEMENT_TYPE *m_declElementType; 359 ATTRIBUTE_ID *m_declAttributeId; 360 char m_declAttributeIsCdata; 361 DTD m_dtd; 362 const XML_Char *m_curBase; 363 TAG *m_tagStack; 364 TAG *m_freeTagList; 365 BINDING *m_inheritedBindings; 366 BINDING *m_freeBindingList; 367 int m_attsSize; 368 int m_nSpecifiedAtts; 369 ATTRIBUTE *m_atts; 370 POSITION m_position; 371 STRING_POOL m_tempPool; 372 STRING_POOL m_temp2Pool; 373 char *m_groupConnector; 374 unsigned m_groupSize; 375 int m_hadExternalDoctype; 376 XML_Char m_namespaceSeparator; 377#ifdef XML_DTD 378 enum XML_ParamEntityParsing m_paramEntityParsing; 379 XML_Parser m_parentParser; 380#endif 381} Parser; 382 383#define userData (((Parser *)parser)->m_userData) 384#define handlerArg (((Parser *)parser)->m_handlerArg) 385#define startElementHandler (((Parser *)parser)->m_startElementHandler) 386#define endElementHandler (((Parser *)parser)->m_endElementHandler) 387#define characterDataHandler (((Parser *)parser)->m_characterDataHandler) 388#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler) 389#define commentHandler (((Parser *)parser)->m_commentHandler) 390#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler) 391#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler) 392#define defaultHandler (((Parser *)parser)->m_defaultHandler) 393#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler) 394#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler) 395#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler) 396#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler) 397#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler) 398#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler) 399#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler) 400#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler) 401#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg) 402#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler) 403/* ericm@scriptics.com */ 404#define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler) 405#define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler) 406/* ericm@scriptics.com */ 407#define encoding (((Parser *)parser)->m_encoding) 408#define initEncoding (((Parser *)parser)->m_initEncoding) 409#define internalEncoding (((Parser *)parser)->m_internalEncoding) 410#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem) 411#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData) 412#define unknownEncodingHandlerData \ 413 (((Parser *)parser)->m_unknownEncodingHandlerData) 414#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease) 415#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName) 416#define ns (((Parser *)parser)->m_ns) 417#define prologState (((Parser *)parser)->m_prologState) 418#define processor (((Parser *)parser)->m_processor) 419#define errorCode (((Parser *)parser)->m_errorCode) 420#define eventPtr (((Parser *)parser)->m_eventPtr) 421#define eventEndPtr (((Parser *)parser)->m_eventEndPtr) 422#define positionPtr (((Parser *)parser)->m_positionPtr) 423#define position (((Parser *)parser)->m_position) 424#define openInternalEntities (((Parser *)parser)->m_openInternalEntities) 425#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities) 426#define tagLevel (((Parser *)parser)->m_tagLevel) 427#define buffer (((Parser *)parser)->m_buffer) 428#define bufferPtr (((Parser *)parser)->m_bufferPtr) 429#define bufferEnd (((Parser *)parser)->m_bufferEnd) 430#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex) 431#define parseEndPtr (((Parser *)parser)->m_parseEndPtr) 432#define bufferLim (((Parser *)parser)->m_bufferLim) 433#define dataBuf (((Parser *)parser)->m_dataBuf) 434#define dataBufEnd (((Parser *)parser)->m_dataBufEnd) 435#define dtd (((Parser *)parser)->m_dtd) 436#define curBase (((Parser *)parser)->m_curBase) 437#define declEntity (((Parser *)parser)->m_declEntity) 438#define declNotationName (((Parser *)parser)->m_declNotationName) 439#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId) 440#define declElementType (((Parser *)parser)->m_declElementType) 441#define declAttributeId (((Parser *)parser)->m_declAttributeId) 442#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata) 443#define freeTagList (((Parser *)parser)->m_freeTagList) 444#define freeBindingList (((Parser *)parser)->m_freeBindingList) 445#define inheritedBindings (((Parser *)parser)->m_inheritedBindings) 446#define tagStack (((Parser *)parser)->m_tagStack) 447#define atts (((Parser *)parser)->m_atts) 448#define attsSize (((Parser *)parser)->m_attsSize) 449#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts) 450#define tempPool (((Parser *)parser)->m_tempPool) 451#define temp2Pool (((Parser *)parser)->m_temp2Pool) 452#define groupConnector (((Parser *)parser)->m_groupConnector) 453#define groupSize (((Parser *)parser)->m_groupSize) 454#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype) 455#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator) 456#ifdef XML_DTD 457#define parentParser (((Parser *)parser)->m_parentParser) 458#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing) 459#endif /* XML_DTD */ 460 461#ifdef _MSC_VER 462#ifdef _DEBUG 463Parser *asParser(XML_Parser parser) 464{ 465 return parser; 466} 467#endif 468#endif 469 470XML_Parser XML_ParserCreate(const XML_Char *encodingName) 471{ 472 XML_Parser parser = malloc(sizeof(Parser)); 473 if (!parser) 474 return parser; 475 processor = prologInitProcessor; 476 XmlPrologStateInit(&prologState); 477 userData = 0; 478 handlerArg = 0; 479 startElementHandler = 0; 480 endElementHandler = 0; 481 characterDataHandler = 0; 482 processingInstructionHandler = 0; 483 commentHandler = 0; 484 startCdataSectionHandler = 0; 485 endCdataSectionHandler = 0; 486 defaultHandler = 0; 487 startDoctypeDeclHandler = 0; 488 endDoctypeDeclHandler = 0; 489 unparsedEntityDeclHandler = 0; 490 notationDeclHandler = 0; 491 startNamespaceDeclHandler = 0; 492 endNamespaceDeclHandler = 0; 493 notStandaloneHandler = 0; 494 externalEntityRefHandler = 0; 495 elementDeclHandler = 0; 496 attlistDeclHandler = 0; 497 externalEntityRefHandlerArg = parser; 498 unknownEncodingHandler = 0; 499 elementDeclHandler = 0; 500 buffer = 0; 501 bufferPtr = 0; 502 bufferEnd = 0; 503 parseEndByteIndex = 0; 504 parseEndPtr = 0; 505 bufferLim = 0; 506 declElementType = 0; 507 declAttributeId = 0; 508 declEntity = 0; 509 declNotationName = 0; 510 declNotationPublicId = 0; 511 memset(&position, 0, sizeof(POSITION)); 512 errorCode = XML_ERROR_NONE; 513 eventPtr = 0; 514 eventEndPtr = 0; 515 positionPtr = 0; 516 openInternalEntities = 0; 517 tagLevel = 0; 518 tagStack = 0; 519 freeTagList = 0; 520 freeBindingList = 0; 521 inheritedBindings = 0; 522 attsSize = INIT_ATTS_SIZE; 523 atts = malloc(attsSize * sizeof(ATTRIBUTE)); 524 nSpecifiedAtts = 0; 525 dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); 526 groupSize = 0; 527 groupConnector = 0; 528 hadExternalDoctype = 0; 529 unknownEncodingMem = 0; 530 unknownEncodingRelease = 0; 531 unknownEncodingData = 0; 532 unknownEncodingHandlerData = 0; 533 namespaceSeparator = '!'; 534#ifdef XML_DTD 535 parentParser = 0; 536 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 537#endif 538 ns = 0; 539 poolInit(&tempPool); 540 poolInit(&temp2Pool); 541 protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0; 542 curBase = 0; 543 if (!dtdInit(&dtd) || !atts || !dataBuf 544 || (encodingName && !protocolEncodingName)) { 545 XML_ParserFree(parser); 546 return 0; 547 } 548 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; 549 XmlInitEncoding(&initEncoding, &encoding, 0); 550 internalEncoding = XmlGetInternalEncoding(); 551 return parser; 552} 553 554XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) 555{ 556 static 557 const XML_Char implicitContext[] = { 558 XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='), 559 XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'), 560 XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'), 561 XML_T('.'), XML_T('w'), XML_T('3'), 562 XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'), 563 XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'), 564 XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'), 565 XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'), 566 XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'), 567 XML_T('\0') 568 }; 569 570 XML_Parser parser = XML_ParserCreate(encodingName); 571 if (parser) { 572 XmlInitEncodingNS(&initEncoding, &encoding, 0); 573 ns = 1; 574 internalEncoding = XmlGetInternalEncodingNS(); 575 namespaceSeparator = nsSep; 576 } 577 if (!setContext(parser, implicitContext)) { 578 XML_ParserFree(parser); 579 return 0; 580 } 581 return parser; 582} 583 584int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) 585{ 586 if (!encodingName) 587 protocolEncodingName = 0; 588 else { 589 protocolEncodingName = poolCopyString(&tempPool, encodingName); 590 if (!protocolEncodingName) 591 return 0; 592 } 593 return 1; 594} 595 596XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, 597 const XML_Char *context, 598 const XML_Char *encodingName) 599{ 600 XML_Parser parser = oldParser; 601 DTD *oldDtd = &dtd; 602 XML_StartElementHandler oldStartElementHandler = startElementHandler; 603 XML_EndElementHandler oldEndElementHandler = endElementHandler; 604 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; 605 XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler; 606 XML_CommentHandler oldCommentHandler = commentHandler; 607 XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler; 608 XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler; 609 XML_DefaultHandler oldDefaultHandler = defaultHandler; 610 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler; 611 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler; 612 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; 613 XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler; 614 XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler; 615 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; 616 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; 617 void *oldUserData = userData; 618 void *oldHandlerArg = handlerArg; 619 int oldDefaultExpandInternalEntities = defaultExpandInternalEntities; 620 void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; 621#ifdef XML_DTD 622 int oldParamEntityParsing = paramEntityParsing; 623#endif 624 parser = (ns 625 ? XML_ParserCreateNS(encodingName, namespaceSeparator) 626 : XML_ParserCreate(encodingName)); 627 if (!parser) 628 return 0; 629 startElementHandler = oldStartElementHandler; 630 endElementHandler = oldEndElementHandler; 631 characterDataHandler = oldCharacterDataHandler; 632 processingInstructionHandler = oldProcessingInstructionHandler; 633 commentHandler = oldCommentHandler; 634 startCdataSectionHandler = oldStartCdataSectionHandler; 635 endCdataSectionHandler = oldEndCdataSectionHandler; 636 defaultHandler = oldDefaultHandler; 637 startNamespaceDeclHandler = oldStartNamespaceDeclHandler; 638 endNamespaceDeclHandler = oldEndNamespaceDeclHandler; 639 notStandaloneHandler = oldNotStandaloneHandler; 640 externalEntityRefHandler = oldExternalEntityRefHandler; 641 unknownEncodingHandler = oldUnknownEncodingHandler; 642 elementDeclHandler = oldElementDeclHandler; 643 attlistDeclHandler = oldAttlistDeclHandler; 644 userData = oldUserData; 645 if (oldUserData == oldHandlerArg) 646 handlerArg = userData; 647 else 648 handlerArg = parser; 649 if (oldExternalEntityRefHandlerArg != oldParser) 650 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; 651 defaultExpandInternalEntities = oldDefaultExpandInternalEntities; 652#ifdef XML_DTD 653 paramEntityParsing = oldParamEntityParsing; 654 if (context) { 655#endif /* XML_DTD */ 656 if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) { 657 XML_ParserFree(parser); 658 return 0; 659 } 660 processor = externalEntityInitProcessor; 661#ifdef XML_DTD 662 } 663 else { 664 dtdSwap(&dtd, oldDtd); 665 parentParser = oldParser; 666 XmlPrologStateInitExternalEntity(&prologState); 667 dtd.complete = 1; 668 hadExternalDoctype = 1; 669 } 670#endif /* XML_DTD */ 671 return parser; 672} 673 674static 675void destroyBindings(BINDING *bindings) 676{ 677 for (;;) { 678 BINDING *b = bindings; 679 if (!b) 680 break; 681 bindings = b->nextTagBinding; 682 free(b->uri); 683 free(b); 684 } 685} 686 687void XML_ParserFree(XML_Parser parser) 688{ 689 for (;;) { 690 TAG *p; 691 if (tagStack == 0) { 692 if (freeTagList == 0) 693 break; 694 tagStack = freeTagList; 695 freeTagList = 0; 696 } 697 p = tagStack; 698 tagStack = tagStack->parent; 699 free(p->buf); 700 destroyBindings(p->bindings); 701 free(p); 702 } 703 destroyBindings(freeBindingList); 704 destroyBindings(inheritedBindings); 705 poolDestroy(&tempPool); 706 poolDestroy(&temp2Pool); 707#ifdef XML_DTD 708 if (parentParser) { 709 if (hadExternalDoctype) 710 dtd.complete = 0; 711 dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd); 712 } 713#endif /* XML_DTD */ 714 dtdDestroy(&dtd); 715 free((void *)atts); 716 free(groupConnector); 717 free(buffer); 718 free(dataBuf); 719 free(unknownEncodingMem); 720 if (unknownEncodingRelease) 721 unknownEncodingRelease(unknownEncodingData); 722 free(parser); 723} 724 725void XML_UseParserAsHandlerArg(XML_Parser parser) 726{ 727 handlerArg = parser; 728} 729 730void XML_SetUserData(XML_Parser parser, void *p) 731{ 732 if (handlerArg == userData) 733 handlerArg = userData = p; 734 else 735 userData = p; 736} 737 738int XML_SetBase(XML_Parser parser, const XML_Char *p) 739{ 740 if (p) { 741 p = poolCopyString(&dtd.pool, p); 742 if (!p) 743 return 0; 744 curBase = p; 745 } 746 else 747 curBase = 0; 748 return 1; 749} 750 751const XML_Char *XML_GetBase(XML_Parser parser) 752{ 753 return curBase; 754} 755 756int XML_GetSpecifiedAttributeCount(XML_Parser parser) 757{ 758 return nSpecifiedAtts; 759} 760 761void XML_SetElementHandler(XML_Parser parser, 762 XML_StartElementHandler start, 763 XML_EndElementHandler end) 764{ 765 startElementHandler = start; 766 endElementHandler = end; 767} 768 769void XML_SetCharacterDataHandler(XML_Parser parser, 770 XML_CharacterDataHandler handler) 771{ 772 characterDataHandler = handler; 773} 774 775void XML_SetProcessingInstructionHandler(XML_Parser parser, 776 XML_ProcessingInstructionHandler handler) 777{ 778 processingInstructionHandler = handler; 779} 780 781void XML_SetCommentHandler(XML_Parser parser, 782 XML_CommentHandler handler) 783{ 784 commentHandler = handler; 785} 786 787void XML_SetCdataSectionHandler(XML_Parser parser, 788 XML_StartCdataSectionHandler start, 789 XML_EndCdataSectionHandler end) 790{ 791 startCdataSectionHandler = start; 792 endCdataSectionHandler = end; 793} 794 795void XML_SetDefaultHandler(XML_Parser parser, 796 XML_DefaultHandler handler) 797{ 798 defaultHandler = handler; 799 defaultExpandInternalEntities = 0; 800} 801 802void XML_SetDefaultHandlerExpand(XML_Parser parser, 803 XML_DefaultHandler handler) 804{ 805 defaultHandler = handler; 806 defaultExpandInternalEntities = 1; 807} 808 809void XML_SetDefaultExpandInternalEntities(XML_Parser parser, 810 int expandEntities) 811{ 812 if (expandEntities != 0) { 813 defaultExpandInternalEntities = 1; 814 } else { 815 defaultExpandInternalEntities = 0; 816 } 817} 818 819void XML_SetDoctypeDeclHandler(XML_Parser parser, 820 XML_StartDoctypeDeclHandler start, 821 XML_EndDoctypeDeclHandler end) 822{ 823 startDoctypeDeclHandler = start; 824 endDoctypeDeclHandler = end; 825} 826 827void XML_SetUnparsedEntityDeclHandler(XML_Parser parser, 828 XML_UnparsedEntityDeclHandler handler) 829{ 830 unparsedEntityDeclHandler = handler; 831} 832 833/* ericm@scriptics.com */ 834void XML_SetElementDeclHandler(XML_Parser parser, 835 XML_ElementDeclHandler handler) 836{ 837 elementDeclHandler = handler; 838} 839 840void XML_SetAttlistDeclHandler(XML_Parser parser, 841 XML_AttlistDeclHandler handler) 842{ 843 attlistDeclHandler = handler; 844} 845/* ericm@scriptics.com */ 846 847void XML_SetNotationDeclHandler(XML_Parser parser, 848 XML_NotationDeclHandler handler) 849{ 850 notationDeclHandler = handler; 851} 852 853void XML_SetNamespaceDeclHandler(XML_Parser parser, 854 XML_StartNamespaceDeclHandler start, 855 XML_EndNamespaceDeclHandler end) 856{ 857 startNamespaceDeclHandler = start; 858 endNamespaceDeclHandler = end; 859} 860 861void XML_SetNotStandaloneHandler(XML_Parser parser, 862 XML_NotStandaloneHandler handler) 863{ 864 notStandaloneHandler = handler; 865} 866 867void XML_SetExternalEntityRefHandler(XML_Parser parser, 868 XML_ExternalEntityRefHandler handler) 869{ 870 externalEntityRefHandler = handler; 871} 872 873void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) 874{ 875 if (arg) 876 externalEntityRefHandlerArg = arg; 877 else 878 externalEntityRefHandlerArg = parser; 879} 880 881void XML_SetUnknownEncodingHandler(XML_Parser parser, 882 XML_UnknownEncodingHandler handler, 883 void *data) 884{ 885 unknownEncodingHandler = handler; 886 unknownEncodingHandlerData = data; 887} 888 889int XML_SetParamEntityParsing(XML_Parser parser, 890 enum XML_ParamEntityParsing parsing) 891{ 892#ifdef XML_DTD 893 paramEntityParsing = parsing; 894 return 1; 895#else 896 return parsing == XML_PARAM_ENTITY_PARSING_NEVER; 897#endif 898} 899 900int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) 901{ 902 if (len == 0) { 903 if (!isFinal) 904 return 1; 905 positionPtr = bufferPtr; 906 errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0); 907 if (errorCode == XML_ERROR_NONE) 908 return 1; 909 eventEndPtr = eventPtr; 910 processor = errorProcessor; 911 return 0; 912 } 913 else if (bufferPtr == bufferEnd) { 914 const char *end; 915 int nLeftOver; 916 parseEndByteIndex += len; 917 positionPtr = s; 918 if (isFinal) { 919 errorCode = processor(parser, s, parseEndPtr = s + len, 0); 920 if (errorCode == XML_ERROR_NONE) 921 return 1; 922 eventEndPtr = eventPtr; 923 processor = errorProcessor; 924 return 0; 925 } 926 errorCode = processor(parser, s, parseEndPtr = s + len, &end); 927 if (errorCode != XML_ERROR_NONE) { 928 eventEndPtr = eventPtr; 929 processor = errorProcessor; 930 return 0; 931 } 932 XmlUpdatePosition(encoding, positionPtr, end, &position); 933 nLeftOver = s + len - end; 934 if (nLeftOver) { 935 if (buffer == 0 || nLeftOver > bufferLim - buffer) { 936 /* FIXME avoid integer overflow */ 937 buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2); 938 /* FIXME storage leak if realloc fails */ 939 if (!buffer) { 940 errorCode = XML_ERROR_NO_MEMORY; 941 eventPtr = eventEndPtr = 0; 942 processor = errorProcessor; 943 return 0; 944 } 945 bufferLim = buffer + len * 2; 946 } 947 memcpy(buffer, end, nLeftOver); 948 bufferPtr = buffer; 949 bufferEnd = buffer + nLeftOver; 950 } 951 return 1; 952 } 953 else { 954 memcpy(XML_GetBuffer(parser, len), s, len); 955 return XML_ParseBuffer(parser, len, isFinal); 956 } 957} 958 959int XML_ParseBuffer(XML_Parser parser, int len, int isFinal) 960{ 961 const char *start = bufferPtr; 962 positionPtr = start; 963 bufferEnd += len; 964 parseEndByteIndex += len; 965 errorCode = processor(parser, start, parseEndPtr = bufferEnd, 966 isFinal ? (const char **)0 : &bufferPtr); 967 if (errorCode == XML_ERROR_NONE) { 968 if (!isFinal) 969 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); 970 return 1; 971 } 972 else { 973 eventEndPtr = eventPtr; 974 processor = errorProcessor; 975 return 0; 976 } 977} 978 979void *XML_GetBuffer(XML_Parser parser, int len) 980{ 981 if (len > bufferLim - bufferEnd) { 982 /* FIXME avoid integer overflow */ 983 int neededSize = len + (bufferEnd - bufferPtr); 984 if (neededSize <= bufferLim - buffer) { 985 memmove(buffer, bufferPtr, bufferEnd - bufferPtr); 986 bufferEnd = buffer + (bufferEnd - bufferPtr); 987 bufferPtr = buffer; 988 } 989 else { 990 char *newBuf; 991 int bufferSize = bufferLim - bufferPtr; 992 if (bufferSize == 0) 993 bufferSize = INIT_BUFFER_SIZE; 994 do { 995 bufferSize *= 2; 996 } while (bufferSize < neededSize); 997 newBuf = malloc(bufferSize); 998 if (newBuf == 0) { 999 errorCode = XML_ERROR_NO_MEMORY; 1000 return 0; 1001 } 1002 bufferLim = newBuf + bufferSize; 1003 if (bufferPtr) { 1004 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); 1005 free(buffer); 1006 } 1007 bufferEnd = newBuf + (bufferEnd - bufferPtr); 1008 bufferPtr = buffer = newBuf; 1009 } 1010 } 1011 return bufferEnd; 1012} 1013 1014enum XML_Error XML_GetErrorCode(XML_Parser parser) 1015{ 1016 return errorCode; 1017} 1018 1019long XML_GetCurrentByteIndex(XML_Parser parser) 1020{ 1021 if (eventPtr) 1022 return parseEndByteIndex - (parseEndPtr - eventPtr); 1023 return -1; 1024} 1025 1026int XML_GetCurrentByteCount(XML_Parser parser) 1027{ 1028 if (eventEndPtr && eventPtr) 1029 return eventEndPtr - eventPtr; 1030 return 0; 1031} 1032 1033int XML_GetCurrentLineNumber(XML_Parser parser) 1034{ 1035 if (eventPtr) { 1036 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); 1037 positionPtr = eventPtr; 1038 } 1039 return position.lineNumber + 1; 1040} 1041 1042int XML_GetCurrentColumnNumber(XML_Parser parser) 1043{ 1044 if (eventPtr) { 1045 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); 1046 positionPtr = eventPtr; 1047 } 1048 return position.columnNumber; 1049} 1050 1051void XML_DefaultCurrent(XML_Parser parser) 1052{ 1053 if (defaultHandler) { 1054 if (openInternalEntities) 1055 reportDefault(parser, 1056 internalEncoding, 1057 openInternalEntities->internalEventPtr, 1058 openInternalEntities->internalEventEndPtr); 1059 else 1060 reportDefault(parser, encoding, eventPtr, eventEndPtr); 1061 } 1062} 1063 1064const XML_LChar *XML_ErrorString(int code) 1065{ 1066 static const XML_LChar *message[] = { 1067 0, 1068 XML_T("out of memory"), 1069 XML_T("syntax error"), 1070 XML_T("no element found"), 1071 XML_T("not well-formed"), 1072 XML_T("unclosed token"), 1073 XML_T("unclosed token"), 1074 XML_T("mismatched tag"), 1075 XML_T("duplicate attribute"), 1076 XML_T("junk after document element"), 1077 XML_T("illegal parameter entity reference"), 1078 XML_T("undefined entity"), 1079 XML_T("recursive entity reference"), 1080 XML_T("asynchronous entity"), 1081 XML_T("reference to invalid character number"), 1082 XML_T("reference to binary entity"), 1083 XML_T("reference to external entity in attribute"), 1084 XML_T("xml processing instruction not at start of external entity"), 1085 XML_T("unknown encoding"), 1086 XML_T("encoding specified in XML declaration is incorrect"), 1087 XML_T("unclosed CDATA section"), 1088 XML_T("error in processing external entity reference"), 1089 XML_T("document is not standalone"), 1090 XML_T("duplicate element declaration") 1091 }; 1092 if (code > 0 && code < sizeof(message)/sizeof(message[0])) 1093 return message[code]; 1094 return 0; 1095} 1096 1097static 1098enum XML_Error contentProcessor(XML_Parser parser, 1099 const char *start, 1100 const char *end, 1101 const char **endPtr) 1102{ 1103 return doContent(parser, 0, encoding, start, end, endPtr); 1104} 1105 1106static 1107enum XML_Error externalEntityInitProcessor(XML_Parser parser, 1108 const char *start, 1109 const char *end, 1110 const char **endPtr) 1111{ 1112 enum XML_Error result = initializeEncoding(parser); 1113 if (result != XML_ERROR_NONE) 1114 return result; 1115 processor = externalEntityInitProcessor2; 1116 return externalEntityInitProcessor2(parser, start, end, endPtr); 1117} 1118 1119static 1120enum XML_Error externalEntityInitProcessor2(XML_Parser parser, 1121 const char *start, 1122 const char *end, 1123 const char **endPtr) 1124{ 1125 const char *next; 1126 int tok = XmlContentTok(encoding, start, end, &next); 1127 switch (tok) { 1128 case XML_TOK_BOM: 1129 start = next; 1130 break; 1131 case XML_TOK_PARTIAL: 1132 if (endPtr) { 1133 *endPtr = start; 1134 return XML_ERROR_NONE; 1135 } 1136 eventPtr = start; 1137 return XML_ERROR_UNCLOSED_TOKEN; 1138 case XML_TOK_PARTIAL_CHAR: 1139 if (endPtr) { 1140 *endPtr = start; 1141 return XML_ERROR_NONE; 1142 } 1143 eventPtr = start; 1144 return XML_ERROR_PARTIAL_CHAR; 1145 } 1146 processor = externalEntityInitProcessor3; 1147 return externalEntityInitProcessor3(parser, start, end, endPtr); 1148} 1149 1150static 1151enum XML_Error externalEntityInitProcessor3(XML_Parser parser, 1152 const char *start, 1153 const char *end, 1154 const char **endPtr) 1155{ 1156 const char *next; 1157 int tok = XmlContentTok(encoding, start, end, &next); 1158 switch (tok) { 1159 case XML_TOK_XML_DECL: 1160 { 1161 enum XML_Error result = processXmlDecl(parser, 1, start, next); 1162 if (result != XML_ERROR_NONE) 1163 return result; 1164 start = next; 1165 } 1166 break; 1167 case XML_TOK_PARTIAL: 1168 if (endPtr) { 1169 *endPtr = start; 1170 return XML_ERROR_NONE; 1171 } 1172 eventPtr = start; 1173 return XML_ERROR_UNCLOSED_TOKEN; 1174 case XML_TOK_PARTIAL_CHAR: 1175 if (endPtr) { 1176 *endPtr = start; 1177 return XML_ERROR_NONE; 1178 } 1179 eventPtr = start; 1180 return XML_ERROR_PARTIAL_CHAR; 1181 } 1182 processor = externalEntityContentProcessor; 1183 tagLevel = 1; 1184 return doContent(parser, 1, encoding, start, end, endPtr); 1185} 1186 1187static 1188enum XML_Error externalEntityContentProcessor(XML_Parser parser, 1189 const char *start, 1190 const char *end, 1191 const char **endPtr) 1192{ 1193 return doContent(parser, 1, encoding, start, end, endPtr); 1194} 1195 1196static enum XML_Error 1197doContent(XML_Parser parser, 1198 int startTagLevel, 1199 const ENCODING *enc, 1200 const char *s, 1201 const char *end, 1202 const char **nextPtr) 1203{ 1204 const char **eventPP; 1205 const char **eventEndPP; 1206 if (enc == encoding) { 1207 eventPP = &eventPtr; 1208 eventEndPP = &eventEndPtr; 1209 } 1210 else { 1211 eventPP = &(openInternalEntities->internalEventPtr); 1212 eventEndPP = &(openInternalEntities->internalEventEndPtr); 1213 } 1214 *eventPP = s; 1215 for (;;) { 1216 const char *next = s; /* XmlContentTok doesn't always set the last arg */ 1217 int tok = XmlContentTok(enc, s, end, &next); 1218 *eventEndPP = next; 1219 switch (tok) { 1220 case XML_TOK_TRAILING_CR: 1221 if (nextPtr) { 1222 *nextPtr = s; 1223 return XML_ERROR_NONE; 1224 } 1225 *eventEndPP = end; 1226 if (characterDataHandler) { 1227 XML_Char c = 0xA; 1228 characterDataHandler(handlerArg, &c, 1); 1229 } 1230 else if (defaultHandler) 1231 reportDefault(parser, enc, s, end); 1232 if (startTagLevel == 0) 1233 return XML_ERROR_NO_ELEMENTS; 1234 if (tagLevel != startTagLevel) 1235 return XML_ERROR_ASYNC_ENTITY; 1236 return XML_ERROR_NONE; 1237 case XML_TOK_NONE: 1238 if (nextPtr) { 1239 *nextPtr = s; 1240 return XML_ERROR_NONE; 1241 } 1242 if (startTagLevel > 0) { 1243 if (tagLevel != startTagLevel) 1244 return XML_ERROR_ASYNC_ENTITY; 1245 return XML_ERROR_NONE; 1246 } 1247 return XML_ERROR_NO_ELEMENTS; 1248 case XML_TOK_INVALID: 1249 *eventPP = next; 1250 return XML_ERROR_INVALID_TOKEN; 1251 case XML_TOK_PARTIAL: 1252 if (nextPtr) { 1253 *nextPtr = s; 1254 return XML_ERROR_NONE; 1255 } 1256 return XML_ERROR_UNCLOSED_TOKEN; 1257 case XML_TOK_PARTIAL_CHAR: 1258 if (nextPtr) { 1259 *nextPtr = s; 1260 return XML_ERROR_NONE; 1261 } 1262 return XML_ERROR_PARTIAL_CHAR; 1263 case XML_TOK_ENTITY_REF: 1264 { 1265 const XML_Char *name; 1266 ENTITY *entity; 1267 XML_Char ch = XmlPredefinedEntityName(enc, 1268 s + enc->minBytesPerChar, 1269 next - enc->minBytesPerChar); 1270 if (ch) { 1271 if (characterDataHandler) 1272 characterDataHandler(handlerArg, &ch, 1); 1273 else if (defaultHandler) 1274 reportDefault(parser, enc, s, next); 1275 break; 1276 } 1277 name = poolStoreString(&dtd.pool, enc, 1278 s + enc->minBytesPerChar, 1279 next - enc->minBytesPerChar); 1280 if (!name) 1281 return XML_ERROR_NO_MEMORY; 1282 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0); 1283 poolDiscard(&dtd.pool); 1284 if (!entity) { 1285 if (dtd.complete || dtd.standalone) 1286 return XML_ERROR_UNDEFINED_ENTITY; 1287 if (defaultHandler) 1288 reportDefault(parser, enc, s, next); 1289 break; 1290 } 1291 if (entity->open) 1292 return XML_ERROR_RECURSIVE_ENTITY_REF; 1293 if (entity->notation) 1294 return XML_ERROR_BINARY_ENTITY_REF; 1295 if (entity) { 1296 if (entity->textPtr) { 1297 enum XML_Error result; 1298 OPEN_INTERNAL_ENTITY openEntity; 1299 if (defaultHandler && !defaultExpandInternalEntities) { 1300 reportDefault(parser, enc, s, next); 1301 break; 1302 } 1303 entity->open = 1; 1304 openEntity.next = openInternalEntities; 1305 openInternalEntities = &openEntity; 1306 openEntity.entity = entity; 1307 openEntity.internalEventPtr = 0; 1308 openEntity.internalEventEndPtr = 0; 1309 result = doContent(parser, 1310 tagLevel, 1311 internalEncoding, 1312 (char *)entity->textPtr, 1313 (char *)(entity->textPtr + entity->textLen), 1314 0); 1315 entity->open = 0; 1316 openInternalEntities = openEntity.next; 1317 if (result) 1318 return result; 1319 } 1320 else if (externalEntityRefHandler) { 1321 const XML_Char *context; 1322 entity->open = 1; 1323 context = getContext(parser); 1324 entity->open = 0; 1325 if (!context) 1326 return XML_ERROR_NO_MEMORY; 1327 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 1328 context, 1329 entity->base, 1330 entity->systemId, 1331 entity->publicId)) 1332 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 1333 poolDiscard(&tempPool); 1334 } 1335 else if (defaultHandler) 1336 reportDefault(parser, enc, s, next); 1337 } 1338 break; 1339 } 1340 case XML_TOK_START_TAG_WITH_ATTS: 1341 if (!startElementHandler) { 1342 enum XML_Error result = storeAtts(parser, enc, s, 0, 0); 1343 if (result) 1344 return result; 1345 } 1346 /* fall through */ 1347 case XML_TOK_START_TAG_NO_ATTS: 1348 { 1349 TAG *tag; 1350 if (freeTagList) { 1351 tag = freeTagList; 1352 freeTagList = freeTagList->parent; 1353 } 1354 else { 1355 tag = malloc(sizeof(TAG)); 1356 if (!tag) 1357 return XML_ERROR_NO_MEMORY; 1358 tag->buf = malloc(INIT_TAG_BUF_SIZE); 1359 if (!tag->buf) 1360 return XML_ERROR_NO_MEMORY; 1361 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; 1362 } 1363 tag->bindings = 0; 1364 tag->parent = tagStack; 1365 tagStack = tag; 1366 tag->name.localPart = 0; 1367 tag->rawName = s + enc->minBytesPerChar; 1368 tag->rawNameLength = XmlNameLength(enc, tag->rawName); 1369 if (nextPtr) { 1370 /* Need to guarantee that: 1371 tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */ 1372 if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) { 1373 int bufSize = tag->rawNameLength * 4; 1374 bufSize = ROUND_UP(bufSize, sizeof(XML_Char)); 1375 tag->buf = realloc(tag->buf, bufSize); 1376 if (!tag->buf) 1377 return XML_ERROR_NO_MEMORY; 1378 tag->bufEnd = tag->buf + bufSize; 1379 } 1380 memcpy(tag->buf, tag->rawName, tag->rawNameLength); 1381 tag->rawName = tag->buf; 1382 } 1383 ++tagLevel; 1384 if (startElementHandler) { 1385 enum XML_Error result; 1386 XML_Char *toPtr; 1387 for (;;) { 1388 const char *rawNameEnd = tag->rawName + tag->rawNameLength; 1389 const char *fromPtr = tag->rawName; 1390 int bufSize; 1391 if (nextPtr) 1392 toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char))); 1393 else 1394 toPtr = (XML_Char *)tag->buf; 1395 tag->name.str = toPtr; 1396 XmlConvert(enc, 1397 &fromPtr, rawNameEnd, 1398 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); 1399 if (fromPtr == rawNameEnd) 1400 break; 1401 bufSize = (tag->bufEnd - tag->buf) << 1; 1402 tag->buf = realloc(tag->buf, bufSize); 1403 if (!tag->buf) 1404 return XML_ERROR_NO_MEMORY; 1405 tag->bufEnd = tag->buf + bufSize; 1406 if (nextPtr) 1407 tag->rawName = tag->buf; 1408 } 1409 *toPtr = XML_T('\0'); 1410 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); 1411 if (result) 1412 return result; 1413 startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts); 1414 poolClear(&tempPool); 1415 } 1416 else { 1417 tag->name.str = 0; 1418 if (defaultHandler) 1419 reportDefault(parser, enc, s, next); 1420 } 1421 break; 1422 } 1423 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: 1424 if (!startElementHandler) { 1425 enum XML_Error result = storeAtts(parser, enc, s, 0, 0); 1426 if (result) 1427 return result; 1428 } 1429 /* fall through */ 1430 case XML_TOK_EMPTY_ELEMENT_NO_ATTS: 1431 if (startElementHandler || endElementHandler) { 1432 const char *rawName = s + enc->minBytesPerChar; 1433 enum XML_Error result; 1434 BINDING *bindings = 0; 1435 TAG_NAME name; 1436 name.str = poolStoreString(&tempPool, enc, rawName, 1437 rawName + XmlNameLength(enc, rawName)); 1438 if (!name.str) 1439 return XML_ERROR_NO_MEMORY; 1440 poolFinish(&tempPool); 1441 result = storeAtts(parser, enc, s, &name, &bindings); 1442 if (result) 1443 return result; 1444 poolFinish(&tempPool); 1445 if (startElementHandler) 1446 startElementHandler(handlerArg, name.str, (const XML_Char **)atts); 1447 if (endElementHandler) { 1448 if (startElementHandler) 1449 *eventPP = *eventEndPP; 1450 endElementHandler(handlerArg, name.str); 1451 } 1452 poolClear(&tempPool); 1453 while (bindings) { 1454 BINDING *b = bindings; 1455 if (endNamespaceDeclHandler) 1456 endNamespaceDeclHandler(handlerArg, b->prefix->name); 1457 bindings = bindings->nextTagBinding; 1458 b->nextTagBinding = freeBindingList; 1459 freeBindingList = b; 1460 b->prefix->binding = b->prevPrefixBinding; 1461 } 1462 } 1463 else if (defaultHandler) 1464 reportDefault(parser, enc, s, next); 1465 if (tagLevel == 0) 1466 return epilogProcessor(parser, next, end, nextPtr); 1467 break; 1468 case XML_TOK_END_TAG: 1469 if (tagLevel == startTagLevel) 1470 return XML_ERROR_ASYNC_ENTITY; 1471 else { 1472 int len; 1473 const char *rawName; 1474 TAG *tag = tagStack; 1475 tagStack = tag->parent; 1476 tag->parent = freeTagList; 1477 freeTagList = tag; 1478 rawName = s + enc->minBytesPerChar*2; 1479 len = XmlNameLength(enc, rawName); 1480 if (len != tag->rawNameLength 1481 || memcmp(tag->rawName, rawName, len) != 0) { 1482 *eventPP = rawName; 1483 return XML_ERROR_TAG_MISMATCH; 1484 } 1485 --tagLevel; 1486 if (endElementHandler && tag->name.str) { 1487 if (tag->name.localPart) { 1488 XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen; 1489 const XML_Char *from = tag->name.localPart; 1490 while ((*to++ = *from++) != 0) 1491 ; 1492 } 1493 endElementHandler(handlerArg, tag->name.str); 1494 } 1495 else if (defaultHandler) 1496 reportDefault(parser, enc, s, next); 1497 while (tag->bindings) { 1498 BINDING *b = tag->bindings; 1499 if (endNamespaceDeclHandler) 1500 endNamespaceDeclHandler(handlerArg, b->prefix->name); 1501 tag->bindings = tag->bindings->nextTagBinding; 1502 b->nextTagBinding = freeBindingList; 1503 freeBindingList = b; 1504 b->prefix->binding = b->prevPrefixBinding; 1505 } 1506 if (tagLevel == 0) 1507 return epilogProcessor(parser, next, end, nextPtr); 1508 } 1509 break; 1510 case XML_TOK_CHAR_REF: 1511 { 1512 int n = XmlCharRefNumber(enc, s); 1513 if (n < 0) 1514 return XML_ERROR_BAD_CHAR_REF; 1515 if (characterDataHandler) { 1516 XML_Char buf[XML_ENCODE_MAX]; 1517 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); 1518 } 1519 else if (defaultHandler) 1520 reportDefault(parser, enc, s, next); 1521 } 1522 break; 1523 case XML_TOK_XML_DECL: 1524 return XML_ERROR_MISPLACED_XML_PI; 1525 case XML_TOK_DATA_NEWLINE: 1526 if (characterDataHandler) { 1527 XML_Char c = 0xA; 1528 characterDataHandler(handlerArg, &c, 1); 1529 } 1530 else if (defaultHandler) 1531 reportDefault(parser, enc, s, next); 1532 break; 1533 case XML_TOK_CDATA_SECT_OPEN: 1534 { 1535 enum XML_Error result; 1536 if (startCdataSectionHandler) 1537 startCdataSectionHandler(handlerArg); 1538#if 0 1539 /* Suppose you doing a transformation on a document that involves 1540 changing only the character data. You set up a defaultHandler 1541 and a characterDataHandler. The defaultHandler simply copies 1542 characters through. The characterDataHandler does the transformation 1543 and writes the characters out escaping them as necessary. This case 1544 will fail to work if we leave out the following two lines (because & 1545 and < inside CDATA sections will be incorrectly escaped). 1546 1547 However, now we have a start/endCdataSectionHandler, so it seems 1548 easier to let the user deal with this. */ 1549 1550 else if (characterDataHandler) 1551 characterDataHandler(handlerArg, dataBuf, 0); 1552#endif 1553 else if (defaultHandler) 1554 reportDefault(parser, enc, s, next); 1555 result = doCdataSection(parser, enc, &next, end, nextPtr); 1556 if (!next) { 1557 processor = cdataSectionProcessor; 1558 return result; 1559 } 1560 } 1561 break; 1562 case XML_TOK_TRAILING_RSQB: 1563 if (nextPtr) { 1564 *nextPtr = s; 1565 return XML_ERROR_NONE; 1566 } 1567 if (characterDataHandler) { 1568 if (MUST_CONVERT(enc, s)) { 1569 ICHAR *dataPtr = (ICHAR *)dataBuf; 1570 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); 1571 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); 1572 } 1573 else 1574 characterDataHandler(handlerArg, 1575 (XML_Char *)s, 1576 (XML_Char *)end - (XML_Char *)s); 1577 } 1578 else if (defaultHandler) 1579 reportDefault(parser, enc, s, end); 1580 if (startTagLevel == 0) { 1581 *eventPP = end; 1582 return XML_ERROR_NO_ELEMENTS; 1583 } 1584 if (tagLevel != startTagLevel) { 1585 *eventPP = end; 1586 return XML_ERROR_ASYNC_ENTITY; 1587 } 1588 return XML_ERROR_NONE; 1589 case XML_TOK_DATA_CHARS: 1590 if (characterDataHandler) { 1591 if (MUST_CONVERT(enc, s)) { 1592 for (;;) { 1593 ICHAR *dataPtr = (ICHAR *)dataBuf; 1594 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); 1595 *eventEndPP = s; 1596 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); 1597 if (s == next) 1598 break; 1599 *eventPP = s; 1600 } 1601 } 1602 else 1603 characterDataHandler(handlerArg, 1604 (XML_Char *)s, 1605 (XML_Char *)next - (XML_Char *)s); 1606 } 1607 else if (defaultHandler) 1608 reportDefault(parser, enc, s, next); 1609 break; 1610 case XML_TOK_PI: 1611 if (!reportProcessingInstruction(parser, enc, s, next)) 1612 return XML_ERROR_NO_MEMORY; 1613 break; 1614 case XML_TOK_COMMENT: 1615 if (!reportComment(parser, enc, s, next)) 1616 return XML_ERROR_NO_MEMORY; 1617 break; 1618 default: 1619 if (defaultHandler) 1620 reportDefault(parser, enc, s, next); 1621 break; 1622 } 1623 *eventPP = s = next; 1624 } 1625 /* not reached */ 1626} 1627 1628/* If tagNamePtr is non-null, build a real list of attributes, 1629otherwise just check the attributes for well-formedness. */ 1630 1631static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, 1632 const char *attStr, TAG_NAME *tagNamePtr, 1633 BINDING **bindingsPtr) 1634{ 1635 ELEMENT_TYPE *elementType = 0; 1636 int nDefaultAtts = 0; 1637 const XML_Char **appAtts; 1638 int attIndex = 0; 1639 int i; 1640 int n; 1641 int nPrefixes = 0; 1642 BINDING *binding; 1643 const XML_Char *localPart; 1644 1645 if (tagNamePtr) { 1646 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0); 1647 if (!elementType) { 1648 tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str); 1649 if (!tagNamePtr->str) 1650 return XML_ERROR_NO_MEMORY; 1651 elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE)); 1652 if (!elementType) 1653 return XML_ERROR_NO_MEMORY; 1654 if (ns && !setElementTypePrefix(parser, elementType)) 1655 return XML_ERROR_NO_MEMORY; 1656 } 1657 nDefaultAtts = elementType->nDefaultAtts; 1658 } 1659 n = XmlGetAttributes(enc, attStr, attsSize, atts); 1660 if (n + nDefaultAtts > attsSize) { 1661 int oldAttsSize = attsSize; 1662 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; 1663 atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE)); 1664 if (!atts) 1665 return XML_ERROR_NO_MEMORY; 1666 if (n > oldAttsSize) 1667 XmlGetAttributes(enc, attStr, n, atts); 1668 } 1669 appAtts = (const XML_Char **)atts; 1670 for (i = 0; i < n; i++) { 1671 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name, 1672 atts[i].name 1673 + XmlNameLength(enc, atts[i].name)); 1674 if (!attId) 1675 return XML_ERROR_NO_MEMORY; 1676 if ((attId->name)[-1]) { 1677 if (enc == encoding) 1678 eventPtr = atts[i].name; 1679 return XML_ERROR_DUPLICATE_ATTRIBUTE; 1680 } 1681 (attId->name)[-1] = 1; 1682 appAtts[attIndex++] = attId->name; 1683 if (!atts[i].normalized) { 1684 enum XML_Error result; 1685 int isCdata = 1; 1686 1687 if (attId->maybeTokenized) { 1688 int j; 1689 for (j = 0; j < nDefaultAtts; j++) { 1690 if (attId == elementType->defaultAtts[j].id) { 1691 isCdata = elementType->defaultAtts[j].isCdata; 1692 break; 1693 } 1694 } 1695 } 1696 1697 result = storeAttributeValue(parser, enc, isCdata, 1698 atts[i].valuePtr, atts[i].valueEnd, 1699 &tempPool); 1700 if (result) 1701 return result; 1702 if (tagNamePtr) { 1703 appAtts[attIndex] = poolStart(&tempPool); 1704 poolFinish(&tempPool); 1705 } 1706 else 1707 poolDiscard(&tempPool); 1708 } 1709 else if (tagNamePtr) { 1710 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd); 1711 if (appAtts[attIndex] == 0) 1712 return XML_ERROR_NO_MEMORY; 1713 poolFinish(&tempPool); 1714 } 1715 if (attId->prefix && tagNamePtr) { 1716 if (attId->xmlns) { 1717 if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr)) 1718 return XML_ERROR_NO_MEMORY; 1719 --attIndex; 1720 } 1721 else { 1722 attIndex++; 1723 nPrefixes++; 1724 (attId->name)[-1] = 2; 1725 } 1726 } 1727 else 1728 attIndex++; 1729 } 1730 nSpecifiedAtts = attIndex; 1731 if (tagNamePtr) { 1732 int j; 1733 for (j = 0; j < nDefaultAtts; j++) { 1734 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j; 1735 if (!(da->id->name)[-1] && da->value) { 1736 if (da->id->prefix) { 1737 if (da->id->xmlns) { 1738 if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr)) 1739 return XML_ERROR_NO_MEMORY; 1740 } 1741 else { 1742 (da->id->name)[-1] = 2; 1743 nPrefixes++; 1744 appAtts[attIndex++] = da->id->name; 1745 appAtts[attIndex++] = da->value; 1746 } 1747 } 1748 else { 1749 (da->id->name)[-1] = 1; 1750 appAtts[attIndex++] = da->id->name; 1751 appAtts[attIndex++] = da->value; 1752 } 1753 } 1754 } 1755 appAtts[attIndex] = 0; 1756 } 1757 i = 0; 1758 if (nPrefixes) { 1759 for (; i < attIndex; i += 2) { 1760 if (appAtts[i][-1] == 2) { 1761 ATTRIBUTE_ID *id; 1762 ((XML_Char *)(appAtts[i]))[-1] = 0; 1763 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0); 1764 if (id->prefix->binding) { 1765 int j; 1766 const BINDING *b = id->prefix->binding; 1767 const XML_Char *s = appAtts[i]; 1768 for (j = 0; j < b->uriLen; j++) { 1769 if (!poolAppendChar(&tempPool, b->uri[j])) 1770 return XML_ERROR_NO_MEMORY; 1771 } 1772 while (*s++ != ':') 1773 ; 1774 do { 1775 if (!poolAppendChar(&tempPool, *s)) 1776 return XML_ERROR_NO_MEMORY; 1777 } while (*s++); 1778 appAtts[i] = poolStart(&tempPool); 1779 poolFinish(&tempPool); 1780 } 1781 if (!--nPrefixes) 1782 break; 1783 } 1784 else 1785 ((XML_Char *)(appAtts[i]))[-1] = 0; 1786 } 1787 } 1788 for (; i < attIndex; i += 2) 1789 ((XML_Char *)(appAtts[i]))[-1] = 0; 1790 if (!tagNamePtr) 1791 return XML_ERROR_NONE; 1792 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) 1793 binding->attId->name[-1] = 0; 1794 if (elementType->prefix) { 1795 binding = elementType->prefix->binding; 1796 if (!binding) 1797 return XML_ERROR_NONE; 1798 localPart = tagNamePtr->str; 1799 while (*localPart++ != XML_T(':')) 1800 ; 1801 } 1802 else if (dtd.defaultPrefix.binding) { 1803 binding = dtd.defaultPrefix.binding; 1804 localPart = tagNamePtr->str; 1805 } 1806 else 1807 return XML_ERROR_NONE; 1808 tagNamePtr->localPart = localPart; 1809 tagNamePtr->uriLen = binding->uriLen; 1810 i = binding->uriLen; 1811 do { 1812 if (i == binding->uriAlloc) { 1813 binding->uri = realloc(binding->uri, binding->uriAlloc *= 2); 1814 if (!binding->uri) 1815 return XML_ERROR_NO_MEMORY; 1816 } 1817 binding->uri[i++] = *localPart; 1818 } while (*localPart++); 1819 tagNamePtr->str = binding->uri; 1820 return XML_ERROR_NONE; 1821} 1822 1823static 1824int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) 1825{ 1826 BINDING *b; 1827 int len; 1828 for (len = 0; uri[len]; len++) 1829 ; 1830 if (namespaceSeparator) 1831 len++; 1832 if (freeBindingList) { 1833 b = freeBindingList; 1834 if (len > b->uriAlloc) { 1835 b->uri = realloc(b->uri, len + EXPAND_SPARE); 1836 if (!b->uri) 1837 return 0; 1838 b->uriAlloc = len + EXPAND_SPARE; 1839 } 1840 freeBindingList = b->nextTagBinding; 1841 } 1842 else { 1843 b = malloc(sizeof(BINDING)); 1844 if (!b) 1845 return 0; 1846 b->uri = malloc(sizeof(XML_Char) * len + EXPAND_SPARE); 1847 if (!b->uri) { 1848 free(b); 1849 return 0; 1850 } 1851 b->uriAlloc = len; 1852 } 1853 b->uriLen = len; 1854 memcpy(b->uri, uri, len * sizeof(XML_Char)); 1855 if (namespaceSeparator) 1856 b->uri[len - 1] = namespaceSeparator; 1857 b->prefix = prefix; 1858 b->attId = attId; 1859 b->prevPrefixBinding = prefix->binding; 1860 if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix) 1861 prefix->binding = 0; 1862 else 1863 prefix->binding = b; 1864 b->nextTagBinding = *bindingsPtr; 1865 *bindingsPtr = b; 1866 if (startNamespaceDeclHandler) 1867 startNamespaceDeclHandler(handlerArg, prefix->name, 1868 prefix->binding ? uri : 0); 1869 return 1; 1870} 1871 1872/* The idea here is to avoid using stack for each CDATA section when 1873the whole file is parsed with one call. */ 1874 1875static 1876enum XML_Error cdataSectionProcessor(XML_Parser parser, 1877 const char *start, 1878 const char *end, 1879 const char **endPtr) 1880{ 1881 enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr); 1882 if (start) { 1883 processor = contentProcessor; 1884 return contentProcessor(parser, start, end, endPtr); 1885 } 1886 return result; 1887} 1888 1889/* startPtr gets set to non-null is the section is closed, and to null if 1890the section is not yet closed. */ 1891 1892static 1893enum XML_Error doCdataSection(XML_Parser parser, 1894 const ENCODING *enc, 1895 const char **startPtr, 1896 const char *end, 1897 const char **nextPtr) 1898{ 1899 const char *s = *startPtr; 1900 const char **eventPP; 1901 const char **eventEndPP; 1902 if (enc == encoding) { 1903 eventPP = &eventPtr; 1904 *eventPP = s; 1905 eventEndPP = &eventEndPtr; 1906 } 1907 else { 1908 eventPP = &(openInternalEntities->internalEventPtr); 1909 eventEndPP = &(openInternalEntities->internalEventEndPtr); 1910 } 1911 *eventPP = s; 1912 *startPtr = 0; 1913 for (;;) { 1914 const char *next; 1915 int tok = XmlCdataSectionTok(enc, s, end, &next); 1916 *eventEndPP = next; 1917 switch (tok) { 1918 case XML_TOK_CDATA_SECT_CLOSE: 1919 if (endCdataSectionHandler) 1920 endCdataSectionHandler(handlerArg); 1921#if 0 1922 /* see comment under XML_TOK_CDATA_SECT_OPEN */ 1923 else if (characterDataHandler) 1924 characterDataHandler(handlerArg, dataBuf, 0); 1925#endif 1926 else if (defaultHandler) 1927 reportDefault(parser, enc, s, next); 1928 *startPtr = next; 1929 return XML_ERROR_NONE; 1930 case XML_TOK_DATA_NEWLINE: 1931 if (characterDataHandler) { 1932 XML_Char c = 0xA; 1933 characterDataHandler(handlerArg, &c, 1); 1934 } 1935 else if (defaultHandler) 1936 reportDefault(parser, enc, s, next); 1937 break; 1938 case XML_TOK_DATA_CHARS: 1939 if (characterDataHandler) { 1940 if (MUST_CONVERT(enc, s)) { 1941 for (;;) { 1942 ICHAR *dataPtr = (ICHAR *)dataBuf; 1943 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); 1944 *eventEndPP = next; 1945 characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); 1946 if (s == next) 1947 break; 1948 *eventPP = s; 1949 } 1950 } 1951 else 1952 characterDataHandler(handlerArg, 1953 (XML_Char *)s, 1954 (XML_Char *)next - (XML_Char *)s); 1955 } 1956 else if (defaultHandler) 1957 reportDefault(parser, enc, s, next); 1958 break; 1959 case XML_TOK_INVALID: 1960 *eventPP = next; 1961 return XML_ERROR_INVALID_TOKEN; 1962 case XML_TOK_PARTIAL_CHAR: 1963 if (nextPtr) { 1964 *nextPtr = s; 1965 return XML_ERROR_NONE; 1966 } 1967 return XML_ERROR_PARTIAL_CHAR; 1968 case XML_TOK_PARTIAL: 1969 case XML_TOK_NONE: 1970 if (nextPtr) { 1971 *nextPtr = s; 1972 return XML_ERROR_NONE; 1973 } 1974 return XML_ERROR_UNCLOSED_CDATA_SECTION; 1975 default: 1976 abort(); 1977 } 1978 *eventPP = s = next; 1979 } 1980 /* not reached */ 1981} 1982 1983#ifdef XML_DTD 1984 1985/* The idea here is to avoid using stack for each IGNORE section when 1986the whole file is parsed with one call. */ 1987 1988static 1989enum XML_Error ignoreSectionProcessor(XML_Parser parser, 1990 const char *start, 1991 const char *end, 1992 const char **endPtr) 1993{ 1994 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr); 1995 if (start) { 1996 processor = prologProcessor; 1997 return prologProcessor(parser, start, end, endPtr); 1998 } 1999 return result; 2000} 2001 2002/* startPtr gets set to non-null is the section is closed, and to null if 2003the section is not yet closed. */ 2004 2005static 2006enum XML_Error doIgnoreSection(XML_Parser parser, 2007 const ENCODING *enc, 2008 const char **startPtr, 2009 const char *end, 2010 const char **nextPtr) 2011{ 2012 const char *next; 2013 int tok; 2014 const char *s = *startPtr; 2015 const char **eventPP; 2016 const char **eventEndPP; 2017 if (enc == encoding) { 2018 eventPP = &eventPtr; 2019 *eventPP = s; 2020 eventEndPP = &eventEndPtr; 2021 } 2022 else { 2023 eventPP = &(openInternalEntities->internalEventPtr); 2024 eventEndPP = &(openInternalEntities->internalEventEndPtr); 2025 } 2026 *eventPP = s; 2027 *startPtr = 0; 2028 tok = XmlIgnoreSectionTok(enc, s, end, &next); 2029 *eventEndPP = next; 2030 switch (tok) { 2031 case XML_TOK_IGNORE_SECT: 2032 if (defaultHandler) 2033 reportDefault(parser, enc, s, next); 2034 *startPtr = next; 2035 return XML_ERROR_NONE; 2036 case XML_TOK_INVALID: 2037 *eventPP = next; 2038 return XML_ERROR_INVALID_TOKEN; 2039 case XML_TOK_PARTIAL_CHAR: 2040 if (nextPtr) { 2041 *nextPtr = s; 2042 return XML_ERROR_NONE; 2043 } 2044 return XML_ERROR_PARTIAL_CHAR; 2045 case XML_TOK_PARTIAL: 2046 case XML_TOK_NONE: 2047 if (nextPtr) { 2048 *nextPtr = s; 2049 return XML_ERROR_NONE; 2050 } 2051 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ 2052 default: 2053 abort(); 2054 } 2055 /* not reached */ 2056} 2057 2058#endif /* XML_DTD */ 2059 2060static enum XML_Error 2061initializeEncoding(XML_Parser parser) 2062{ 2063 const char *s; 2064#ifdef XML_UNICODE 2065 char encodingBuf[128]; 2066 if (!protocolEncodingName) 2067 s = 0; 2068 else { 2069 int i; 2070 for (i = 0; protocolEncodingName[i]; i++) { 2071 if (i == sizeof(encodingBuf) - 1 2072 || protocolEncodingName[i] >= 0x80 2073 || protocolEncodingName[i] < 0) { 2074 encodingBuf[0] = '\0'; 2075 break; 2076 } 2077 encodingBuf[i] = (char)protocolEncodingName[i]; 2078 } 2079 encodingBuf[i] = '\0'; 2080 s = encodingBuf; 2081 } 2082#else 2083 s = protocolEncodingName; 2084#endif 2085 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) 2086 return XML_ERROR_NONE; 2087 return handleUnknownEncoding(parser, protocolEncodingName); 2088} 2089 2090static enum XML_Error 2091processXmlDecl(XML_Parser parser, int isGeneralTextEntity, 2092 const char *s, const char *next) 2093{ 2094 const char *encodingName = 0; 2095 const ENCODING *newEncoding = 0; 2096 const char *version; 2097 int standalone = -1; 2098 if (!(ns 2099 ? XmlParseXmlDeclNS 2100 : XmlParseXmlDecl)(isGeneralTextEntity, 2101 encoding, 2102 s, 2103 next, 2104 &eventPtr, 2105 &version, 2106 &encodingName, 2107 &newEncoding, 2108 &standalone)) 2109 return XML_ERROR_SYNTAX; 2110 if (!isGeneralTextEntity && standalone == 1) { 2111 dtd.standalone = 1; 2112#ifdef XML_DTD 2113 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) 2114 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 2115#endif /* XML_DTD */ 2116 } 2117 if (defaultHandler) 2118 reportDefault(parser, encoding, s, next); 2119 if (!protocolEncodingName) { 2120 if (newEncoding) { 2121 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { 2122 eventPtr = encodingName; 2123 return XML_ERROR_INCORRECT_ENCODING; 2124 } 2125 encoding = newEncoding; 2126 } 2127 else if (encodingName) { 2128 enum XML_Error result; 2129 const XML_Char *s = poolStoreString(&tempPool, 2130 encoding, 2131 encodingName, 2132 encodingName 2133 + XmlNameLength(encoding, encodingName)); 2134 if (!s) 2135 return XML_ERROR_NO_MEMORY; 2136 result = handleUnknownEncoding(parser, s); 2137 poolDiscard(&tempPool); 2138 if (result == XML_ERROR_UNKNOWN_ENCODING) 2139 eventPtr = encodingName; 2140 return result; 2141 } 2142 } 2143 return XML_ERROR_NONE; 2144} 2145 2146static enum XML_Error 2147handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) 2148{ 2149 if (unknownEncodingHandler) { 2150 XML_Encoding info; 2151 int i; 2152 for (i = 0; i < 256; i++) 2153 info.map[i] = -1; 2154 info.convert = 0; 2155 info.data = 0; 2156 info.release = 0; 2157 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) { 2158 ENCODING *enc; 2159 unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding()); 2160 if (!unknownEncodingMem) { 2161 if (info.release) 2162 info.release(info.data); 2163 return XML_ERROR_NO_MEMORY; 2164 } 2165 enc = (ns 2166 ? XmlInitUnknownEncodingNS 2167 : XmlInitUnknownEncoding)(unknownEncodingMem, 2168 info.map, 2169 info.convert, 2170 info.data); 2171 if (enc) { 2172 unknownEncodingData = info.data; 2173 unknownEncodingRelease = info.release; 2174 encoding = enc; 2175 return XML_ERROR_NONE; 2176 } 2177 } 2178 if (info.release) 2179 info.release(info.data); 2180 } 2181 return XML_ERROR_UNKNOWN_ENCODING; 2182} 2183 2184static enum XML_Error 2185prologInitProcessor(XML_Parser parser, 2186 const char *s, 2187 const char *end, 2188 const char **nextPtr) 2189{ 2190 enum XML_Error result = initializeEncoding(parser); 2191 if (result != XML_ERROR_NONE) 2192 return result; 2193 processor = prologProcessor; 2194 return prologProcessor(parser, s, end, nextPtr); 2195} 2196 2197static enum XML_Error 2198prologProcessor(XML_Parser parser, 2199 const char *s, 2200 const char *end, 2201 const char **nextPtr) 2202{ 2203 const char *next; 2204 int tok = XmlPrologTok(encoding, s, end, &next); 2205 return doProlog(parser, encoding, s, end, tok, next, nextPtr); 2206} 2207 2208static enum XML_Error 2209doProlog(XML_Parser parser, 2210 const ENCODING *enc, 2211 const char *s, 2212 const char *end, 2213 int tok, 2214 const char *next, 2215 const char **nextPtr) 2216{ 2217#ifdef XML_DTD 2218 static const XML_Char externalSubsetName[] = { '#' , '\0' }; 2219#endif /* XML_DTD */ 2220 2221 const char **eventPP; 2222 const char **eventEndPP; 2223 if (enc == encoding) { 2224 eventPP = &eventPtr; 2225 eventEndPP = &eventEndPtr; 2226 } 2227 else { 2228 eventPP = &(openInternalEntities->internalEventPtr); 2229 eventEndPP = &(openInternalEntities->internalEventEndPtr); 2230 } 2231 for (;;) { 2232 int role; 2233 *eventPP = s; 2234 *eventEndPP = next; 2235 if (tok <= 0) { 2236 if (nextPtr != 0 && tok != XML_TOK_INVALID) { 2237 *nextPtr = s; 2238 return XML_ERROR_NONE; 2239 } 2240 switch (tok) { 2241 case XML_TOK_INVALID: 2242 *eventPP = next; 2243 return XML_ERROR_INVALID_TOKEN; 2244 case XML_TOK_PARTIAL: 2245 return XML_ERROR_UNCLOSED_TOKEN; 2246 case XML_TOK_PARTIAL_CHAR: 2247 return XML_ERROR_PARTIAL_CHAR; 2248 case XML_TOK_NONE: 2249#ifdef XML_DTD 2250 if (enc != encoding) 2251 return XML_ERROR_NONE; 2252 if (parentParser) { 2253 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) 2254 == XML_ROLE_ERROR) 2255 return XML_ERROR_SYNTAX; 2256 hadExternalDoctype = 0; 2257 return XML_ERROR_NONE; 2258 } 2259#endif /* XML_DTD */ 2260 return XML_ERROR_NO_ELEMENTS; 2261 default: 2262 tok = -tok; 2263 next = end; 2264 break; 2265 } 2266 } 2267 role = XmlTokenRole(&prologState, tok, s, next, enc); 2268 switch (role) { 2269 case XML_ROLE_XML_DECL: 2270 { 2271 enum XML_Error result = processXmlDecl(parser, 0, s, next); 2272 if (result != XML_ERROR_NONE) 2273 return result; 2274 enc = encoding; 2275 } 2276 break; 2277 case XML_ROLE_DOCTYPE_NAME: 2278 if (startDoctypeDeclHandler) { 2279 const XML_Char *name = poolStoreString(&tempPool, enc, s, next); 2280 if (!name) 2281 return XML_ERROR_NO_MEMORY; 2282 startDoctypeDeclHandler(handlerArg, name); 2283 poolClear(&tempPool); 2284 } 2285 break; 2286#ifdef XML_DTD 2287 case XML_ROLE_TEXT_DECL: 2288 { 2289 enum XML_Error result = processXmlDecl(parser, 1, s, next); 2290 if (result != XML_ERROR_NONE) 2291 return result; 2292 enc = encoding; 2293 } 2294 break; 2295#endif /* XML_DTD */ 2296 case XML_ROLE_DOCTYPE_PUBLIC_ID: 2297#ifdef XML_DTD 2298 declEntity = (ENTITY *)lookup(&dtd.paramEntities, 2299 externalSubsetName, 2300 sizeof(ENTITY)); 2301 if (!declEntity) 2302 return XML_ERROR_NO_MEMORY; 2303#endif /* XML_DTD */ 2304 /* fall through */ 2305 case XML_ROLE_ENTITY_PUBLIC_ID: 2306 if (!XmlIsPublicId(enc, s, next, eventPP)) 2307 return XML_ERROR_SYNTAX; 2308 if (declEntity) { 2309 XML_Char *tem = poolStoreString(&dtd.pool, 2310 enc, 2311 s + enc->minBytesPerChar, 2312 next - enc->minBytesPerChar); 2313 if (!tem) 2314 return XML_ERROR_NO_MEMORY; 2315 normalizePublicId(tem); 2316 declEntity->publicId = tem; 2317 poolFinish(&dtd.pool); 2318 } 2319 break; 2320 case XML_ROLE_DOCTYPE_CLOSE: 2321 if (dtd.complete && hadExternalDoctype) { 2322 dtd.complete = 0; 2323#ifdef XML_DTD 2324 if (paramEntityParsing && externalEntityRefHandler) { 2325 ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities, 2326 externalSubsetName, 2327 0); 2328 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 2329 0, 2330 entity->base, 2331 entity->systemId, 2332 entity->publicId)) 2333 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 2334 } 2335#endif /* XML_DTD */ 2336 if (!dtd.complete 2337 && !dtd.standalone 2338 && notStandaloneHandler 2339 && !notStandaloneHandler(handlerArg)) 2340 return XML_ERROR_NOT_STANDALONE; 2341 } 2342 if (endDoctypeDeclHandler) 2343 endDoctypeDeclHandler(handlerArg); 2344 break; 2345 case XML_ROLE_INSTANCE_START: 2346 processor = contentProcessor; 2347 return contentProcessor(parser, s, end, nextPtr); 2348 2349/* ericm@scriptics.com, 1999.09.10. Additions made to allow user access to 2350 information read from the DTD, including the names and content 2351 specifications of every element encountered. 2352*/ 2353 case XML_ROLE_ELEMENT_NAME: 2354 { 2355 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); 2356 if (!name) { 2357 return(XML_ERROR_NO_MEMORY); 2358 } 2359 2360 /* Find (or create) the element type structure in the element 2361 * types hashtable 2362 */ 2363 declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, 2364 name, sizeof(ELEMENT_TYPE)); 2365 2366 if (!declElementType) 2367 return XML_ERROR_NO_MEMORY; 2368 2369 /* Per the XML Spec, it is illegal to have multiple declarations 2370 * of a given element type. Therefore, check to see if this 2371 * element has already been defined, by seeing if contentSpec 2372 * has been set. If the element type structure was created by a 2373 * previous element decl, then contentSpec will be non-NULL. If 2374 * it was created by being referenced in an attlist decl, then 2375 * contentSpec will be NULL. 2376 * NOTE: This should probably only bail out if we are in 2377 * validating mode. 2378 */ 2379 if (declElementType->contentSpec != NULL) { 2380 return XML_ERROR_DUPLICATE_ELEMENT; 2381 } 2382 2383 if (declElementType->name != name) 2384 poolDiscard(&dtd.pool); 2385 else { 2386 poolFinish(&dtd.pool); 2387 if (!setElementTypePrefix(parser, declElementType)) 2388 return XML_ERROR_NO_MEMORY; 2389 } 2390 break; 2391 } 2392 2393 case XML_ROLE_ELEMENT_DECL_CLOSE: 2394 { 2395 if (elementDeclHandler) { 2396 elementDeclHandler(handlerArg, 2397 declElementType->name, &declElementType->contentSpec); 2398 } 2399 break; 2400 } 2401 2402 2403 case XML_ROLE_ATTLIST_DECL_CLOSE: 2404 { 2405 if (attlistDeclHandler) { 2406 attlistDeclHandler(handlerArg, 2407 declElementType->name, &declElementType->attributes); 2408 } 2409 break; 2410 } 2411 2412/* ericm@scriptics.com */ 2413 2414 case XML_ROLE_ATTLIST_ELEMENT_NAME: 2415 { 2416 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); 2417 if (!name) 2418 return XML_ERROR_NO_MEMORY; 2419 declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE)); 2420 if (!declElementType) 2421 return XML_ERROR_NO_MEMORY; 2422 if (declElementType->name != name) 2423 poolDiscard(&dtd.pool); 2424 else { 2425 poolFinish(&dtd.pool); 2426 if (!setElementTypePrefix(parser, declElementType)) 2427 return XML_ERROR_NO_MEMORY; 2428 } 2429 break; 2430 } 2431 case XML_ROLE_ATTRIBUTE_NAME: 2432 { 2433 enum XML_Error result; 2434 declAttributeId = getAttributeId(parser, enc, s, next); 2435 if (!declAttributeId) 2436 return XML_ERROR_NO_MEMORY; 2437 declAttributeIsCdata = 0; 2438 result = appendAttribute(declElementType, declAttributeId->name); 2439 if (result) { 2440 return result; 2441 } 2442 break; 2443 } 2444 2445 case XML_ROLE_ATTRIBUTE_TYPE_CDATA: 2446 declAttributeIsCdata = 1; 2447 break; 2448 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: 2449 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: 2450 if (dtd.complete 2451 && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0)) 2452 return XML_ERROR_NO_MEMORY; 2453 break; 2454 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: 2455 case XML_ROLE_FIXED_ATTRIBUTE_VALUE: 2456 { 2457 const XML_Char *attVal; 2458 enum XML_Error result 2459 = storeAttributeValue(parser, enc, declAttributeIsCdata, 2460 s + enc->minBytesPerChar, 2461 next - enc->minBytesPerChar, 2462 &dtd.pool); 2463 if (result) 2464 return result; 2465 attVal = poolStart(&dtd.pool); 2466 poolFinish(&dtd.pool); 2467 if (dtd.complete 2468 && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal)) 2469 return XML_ERROR_NO_MEMORY; 2470 break; 2471 } 2472 case XML_ROLE_ENTITY_VALUE: 2473 { 2474 enum XML_Error result = storeEntityValue(parser, enc, 2475 s + enc->minBytesPerChar, 2476 next - enc->minBytesPerChar); 2477 if (declEntity) { 2478 declEntity->textPtr = poolStart(&dtd.pool); 2479 declEntity->textLen = poolLength(&dtd.pool); 2480 poolFinish(&dtd.pool); 2481 } 2482 else 2483 poolDiscard(&dtd.pool); 2484 if (result != XML_ERROR_NONE) 2485 return result; 2486 } 2487 break; 2488 case XML_ROLE_DOCTYPE_SYSTEM_ID: 2489 if (!dtd.standalone 2490#ifdef XML_DTD 2491 && !paramEntityParsing 2492#endif /* XML_DTD */ 2493 && notStandaloneHandler 2494 && !notStandaloneHandler(handlerArg)) 2495 return XML_ERROR_NOT_STANDALONE; 2496 hadExternalDoctype = 1; 2497#ifndef XML_DTD 2498 break; 2499#else /* XML_DTD */ 2500 if (!declEntity) { 2501 declEntity = (ENTITY *)lookup(&dtd.paramEntities, 2502 externalSubsetName, 2503 sizeof(ENTITY)); 2504 if (!declEntity) 2505 return XML_ERROR_NO_MEMORY; 2506 } 2507 /* fall through */ 2508#endif /* XML_DTD */ 2509 case XML_ROLE_ENTITY_SYSTEM_ID: 2510 if (declEntity) { 2511 declEntity->systemId = poolStoreString(&dtd.pool, enc, 2512 s + enc->minBytesPerChar, 2513 next - enc->minBytesPerChar); 2514 if (!declEntity->systemId) 2515 return XML_ERROR_NO_MEMORY; 2516 declEntity->base = curBase; 2517 poolFinish(&dtd.pool); 2518 } 2519 break; 2520 case XML_ROLE_ENTITY_NOTATION_NAME: 2521 if (declEntity) { 2522 declEntity->notation = poolStoreString(&dtd.pool, enc, s, next); 2523 if (!declEntity->notation) 2524 return XML_ERROR_NO_MEMORY; 2525 poolFinish(&dtd.pool); 2526 if (unparsedEntityDeclHandler) { 2527 *eventEndPP = s; 2528 unparsedEntityDeclHandler(handlerArg, 2529 declEntity->name, 2530 declEntity->base, 2531 declEntity->systemId, 2532 declEntity->publicId, 2533 declEntity->notation); 2534 } 2535 2536 } 2537 break; 2538 case XML_ROLE_GENERAL_ENTITY_NAME: 2539 { 2540 const XML_Char *name; 2541 if (XmlPredefinedEntityName(enc, s, next)) { 2542 declEntity = 0; 2543 break; 2544 } 2545 name = poolStoreString(&dtd.pool, enc, s, next); 2546 if (!name) 2547 return XML_ERROR_NO_MEMORY; 2548 if (dtd.complete) { 2549 declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY)); 2550 if (!declEntity) 2551 return XML_ERROR_NO_MEMORY; 2552 if (declEntity->name != name) { 2553 poolDiscard(&dtd.pool); 2554 declEntity = 0; 2555 } 2556 else 2557 poolFinish(&dtd.pool); 2558 } 2559 else { 2560 poolDiscard(&dtd.pool); 2561 declEntity = 0; 2562 } 2563 } 2564 break; 2565 case XML_ROLE_PARAM_ENTITY_NAME: 2566#ifdef XML_DTD 2567 if (dtd.complete) { 2568 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); 2569 if (!name) 2570 return XML_ERROR_NO_MEMORY; 2571 declEntity = (ENTITY *)lookup(&dtd.paramEntities, name, sizeof(ENTITY)); 2572 if (!declEntity) 2573 return XML_ERROR_NO_MEMORY; 2574 if (declEntity->name != name) { 2575 poolDiscard(&dtd.pool); 2576 declEntity = 0; 2577 } 2578 else 2579 poolFinish(&dtd.pool); 2580 } 2581#else /* not XML_DTD */ 2582 declEntity = 0; 2583#endif /* not XML_DTD */ 2584 break; 2585 case XML_ROLE_NOTATION_NAME: 2586 declNotationPublicId = 0; 2587 declNotationName = 0; 2588 if (notationDeclHandler) { 2589 declNotationName = poolStoreString(&tempPool, enc, s, next); 2590 if (!declNotationName) 2591 return XML_ERROR_NO_MEMORY; 2592 poolFinish(&tempPool); 2593 } 2594 break; 2595 case XML_ROLE_NOTATION_PUBLIC_ID: 2596 if (!XmlIsPublicId(enc, s, next, eventPP)) 2597 return XML_ERROR_SYNTAX; 2598 if (declNotationName) { 2599 XML_Char *tem = poolStoreString(&tempPool, 2600 enc, 2601 s + enc->minBytesPerChar, 2602 next - enc->minBytesPerChar); 2603 if (!tem) 2604 return XML_ERROR_NO_MEMORY; 2605 normalizePublicId(tem); 2606 declNotationPublicId = tem; 2607 poolFinish(&tempPool); 2608 } 2609 break; 2610 case XML_ROLE_NOTATION_SYSTEM_ID: 2611 if (declNotationName && notationDeclHandler) { 2612 const XML_Char *systemId 2613 = poolStoreString(&tempPool, enc, 2614 s + enc->minBytesPerChar, 2615 next - enc->minBytesPerChar); 2616 if (!systemId) 2617 return XML_ERROR_NO_MEMORY; 2618 *eventEndPP = s; 2619 notationDeclHandler(handlerArg, 2620 declNotationName, 2621 curBase, 2622 systemId, 2623 declNotationPublicId); 2624 } 2625 poolClear(&tempPool); 2626 break; 2627 case XML_ROLE_NOTATION_NO_SYSTEM_ID: 2628 if (declNotationPublicId && notationDeclHandler) { 2629 *eventEndPP = s; 2630 notationDeclHandler(handlerArg, 2631 declNotationName, 2632 curBase, 2633 0, 2634 declNotationPublicId); 2635 } 2636 poolClear(&tempPool); 2637 break; 2638 case XML_ROLE_ERROR: 2639 switch (tok) { 2640 case XML_TOK_PARAM_ENTITY_REF: 2641 return XML_ERROR_PARAM_ENTITY_REF; 2642 case XML_TOK_XML_DECL: 2643 return XML_ERROR_MISPLACED_XML_PI; 2644 default: 2645 return XML_ERROR_SYNTAX; 2646 } 2647#ifdef XML_DTD 2648 case XML_ROLE_IGNORE_SECT: 2649 { 2650 enum XML_Error result; 2651 if (defaultHandler) 2652 reportDefault(parser, enc, s, next); 2653 result = doIgnoreSection(parser, enc, &next, end, nextPtr); 2654 if (!next) { 2655 processor = ignoreSectionProcessor; 2656 return result; 2657 } 2658 } 2659 break; 2660#endif /* XML_DTD */ 2661 case XML_ROLE_GROUP_OPEN: 2662 { 2663 enum XML_Error result; 2664 if (prologState.level >= groupSize) { 2665 if (groupSize) 2666 groupConnector = realloc(groupConnector, groupSize *= 2); 2667 else 2668 groupConnector = malloc(groupSize = 32); 2669 if (!groupConnector) 2670 return XML_ERROR_NO_MEMORY; 2671 } 2672 groupConnector[prologState.level] = 0; 2673 2674 result = appendContent(declElementType, XML_ROLE_GROUP_OPEN, NULL); 2675 if (result) { 2676 return result; 2677 } 2678 break; 2679 } 2680 case XML_ROLE_GROUP_SEQUENCE: 2681 { 2682 enum XML_Error result; 2683 if (groupConnector[prologState.level] == '|') 2684 return XML_ERROR_SYNTAX; 2685 groupConnector[prologState.level] = ','; 2686 2687 result = appendContent(declElementType, XML_ROLE_GROUP_SEQUENCE, NULL); 2688 if (result) { 2689 return result; 2690 } 2691 break; 2692 } 2693 case XML_ROLE_GROUP_CHOICE: 2694 { 2695 enum XML_Error result; 2696 if (groupConnector[prologState.level] == ',') 2697 return XML_ERROR_SYNTAX; 2698 groupConnector[prologState.level] = '|'; 2699 2700 result = appendContent(declElementType, XML_ROLE_GROUP_CHOICE, NULL); 2701 if (result) { 2702 return result; 2703 } 2704 break; 2705 } 2706 2707/* ericm@scriptics.com, 1999.09.10; additions enable tracking contentspec's */ 2708 2709 case XML_ROLE_GROUP_CLOSE: 2710 case XML_ROLE_GROUP_CLOSE_REP: 2711 case XML_ROLE_GROUP_CLOSE_OPT: 2712 case XML_ROLE_GROUP_CLOSE_PLUS: 2713 case XML_ROLE_CONTENT_PCDATA: 2714 case XML_ROLE_CONTENT_ANY: 2715 case XML_ROLE_CONTENT_EMPTY: 2716 { 2717 enum XML_Error result; 2718 result = appendContent(declElementType, role, NULL); 2719 if (result) { 2720 return result; 2721 } 2722 break; 2723 2724 } 2725 case XML_ROLE_CONTENT_ELEMENT: 2726 case XML_ROLE_CONTENT_ELEMENT_REP: 2727 case XML_ROLE_CONTENT_ELEMENT_OPT: 2728 case XML_ROLE_CONTENT_ELEMENT_PLUS: 2729 { 2730 enum XML_Error result; 2731 const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next); 2732 2733 if (!name) 2734 return XML_ERROR_NO_MEMORY; 2735 result = appendContent(declElementType, role, name); 2736 if (result) { 2737 return result; 2738 } 2739 poolFinish(&dtd.pool); 2740 2741 break; 2742 } 2743/* ericm@scriptics.com */ 2744 2745 2746 2747 case XML_ROLE_PARAM_ENTITY_REF: 2748#ifdef XML_DTD 2749 case XML_ROLE_INNER_PARAM_ENTITY_REF: 2750 if (paramEntityParsing 2751 && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) { 2752 const XML_Char *name; 2753 ENTITY *entity; 2754 name = poolStoreString(&dtd.pool, enc, 2755 s + enc->minBytesPerChar, 2756 next - enc->minBytesPerChar); 2757 if (!name) 2758 return XML_ERROR_NO_MEMORY; 2759 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0); 2760 poolDiscard(&dtd.pool); 2761 if (!entity) { 2762 /* FIXME what to do if !dtd.complete? */ 2763 return XML_ERROR_UNDEFINED_ENTITY; 2764 } 2765 if (entity->open) 2766 return XML_ERROR_RECURSIVE_ENTITY_REF; 2767 if (entity->textPtr) { 2768 enum XML_Error result; 2769 result = processInternalParamEntity(parser, entity); 2770 if (result != XML_ERROR_NONE) 2771 return result; 2772 break; 2773 } 2774 if (role == XML_ROLE_INNER_PARAM_ENTITY_REF) 2775 return XML_ERROR_PARAM_ENTITY_REF; 2776 if (externalEntityRefHandler) { 2777 dtd.complete = 0; 2778 entity->open = 1; 2779 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 2780 0, 2781 entity->base, 2782 entity->systemId, 2783 entity->publicId)) { 2784 entity->open = 0; 2785 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 2786 } 2787 entity->open = 0; 2788 if (dtd.complete) 2789 break; 2790 } 2791 } 2792#endif /* XML_DTD */ 2793 if (!dtd.standalone 2794 && notStandaloneHandler 2795 && !notStandaloneHandler(handlerArg)) 2796 return XML_ERROR_NOT_STANDALONE; 2797 dtd.complete = 0; 2798 if (defaultHandler) 2799 reportDefault(parser, enc, s, next); 2800 break; 2801 case XML_ROLE_NONE: 2802 switch (tok) { 2803 case XML_TOK_PI: 2804 if (!reportProcessingInstruction(parser, enc, s, next)) 2805 return XML_ERROR_NO_MEMORY; 2806 break; 2807 case XML_TOK_COMMENT: 2808 if (!reportComment(parser, enc, s, next)) 2809 return XML_ERROR_NO_MEMORY; 2810 break; 2811 } 2812 break; 2813 } 2814 if (defaultHandler) { 2815 switch (tok) { 2816 case XML_TOK_PI: 2817 case XML_TOK_COMMENT: 2818 case XML_TOK_BOM: 2819 case XML_TOK_XML_DECL: 2820#ifdef XML_DTD 2821 case XML_TOK_IGNORE_SECT: 2822#endif /* XML_DTD */ 2823 case XML_TOK_PARAM_ENTITY_REF: 2824 break; 2825 default: 2826 /* SRB: 20020814: XML_ROLE_IGNORE_SECT is not defined... */ 2827 /*if (role != XML_ROLE_IGNORE_SECT)*/ 2828 reportDefault(parser, enc, s, next); 2829 } 2830 } 2831 s = next; 2832 tok = XmlPrologTok(enc, s, end, &next); 2833 } 2834 /* not reached */ 2835} 2836 2837static 2838enum XML_Error epilogProcessor(XML_Parser parser, 2839 const char *s, 2840 const char *end, 2841 const char **nextPtr) 2842{ 2843 processor = epilogProcessor; 2844 eventPtr = s; 2845 for (;;) { 2846 const char *next; 2847 int tok = XmlPrologTok(encoding, s, end, &next); 2848 eventEndPtr = next; 2849 switch (tok) { 2850 case -XML_TOK_PROLOG_S: 2851 if (defaultHandler) { 2852 eventEndPtr = end; 2853 reportDefault(parser, encoding, s, end); 2854 } 2855 /* fall through */ 2856 case XML_TOK_NONE: 2857 if (nextPtr) 2858 *nextPtr = end; 2859 return XML_ERROR_NONE; 2860 case XML_TOK_PROLOG_S: 2861 if (defaultHandler) 2862 reportDefault(parser, encoding, s, next); 2863 break; 2864 case XML_TOK_PI: 2865 if (!reportProcessingInstruction(parser, encoding, s, next)) 2866 return XML_ERROR_NO_MEMORY; 2867 break; 2868 case XML_TOK_COMMENT: 2869 if (!reportComment(parser, encoding, s, next)) 2870 return XML_ERROR_NO_MEMORY; 2871 break; 2872 case XML_TOK_INVALID: 2873 eventPtr = next; 2874 return XML_ERROR_INVALID_TOKEN; 2875 case XML_TOK_PARTIAL: 2876 if (nextPtr) { 2877 *nextPtr = s; 2878 return XML_ERROR_NONE; 2879 } 2880 return XML_ERROR_UNCLOSED_TOKEN; 2881 case XML_TOK_PARTIAL_CHAR: 2882 if (nextPtr) { 2883 *nextPtr = s; 2884 return XML_ERROR_NONE; 2885 } 2886 return XML_ERROR_PARTIAL_CHAR; 2887 default: 2888 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; 2889 } 2890 eventPtr = s = next; 2891 } 2892} 2893 2894#ifdef XML_DTD 2895 2896static enum XML_Error 2897processInternalParamEntity(XML_Parser parser, ENTITY *entity) 2898{ 2899 const char *s, *end, *next; 2900 int tok; 2901 enum XML_Error result; 2902 OPEN_INTERNAL_ENTITY openEntity; 2903 entity->open = 1; 2904 openEntity.next = openInternalEntities; 2905 openInternalEntities = &openEntity; 2906 openEntity.entity = entity; 2907 openEntity.internalEventPtr = 0; 2908 openEntity.internalEventEndPtr = 0; 2909 s = (char *)entity->textPtr; 2910 end = (char *)(entity->textPtr + entity->textLen); 2911 tok = XmlPrologTok(internalEncoding, s, end, &next); 2912 result = doProlog(parser, internalEncoding, s, end, tok, next, 0); 2913 entity->open = 0; 2914 openInternalEntities = openEntity.next; 2915 return result; 2916} 2917 2918#endif /* XML_DTD */ 2919 2920static 2921enum XML_Error errorProcessor(XML_Parser parser, 2922 const char *s, 2923 const char *end, 2924 const char **nextPtr) 2925{ 2926 return errorCode; 2927} 2928 2929static enum XML_Error 2930storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, 2931 const char *ptr, const char *end, 2932 STRING_POOL *pool) 2933{ 2934 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool); 2935 if (result) 2936 return result; 2937 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) 2938 poolChop(pool); 2939 if (!poolAppendChar(pool, XML_T('\0'))) 2940 return XML_ERROR_NO_MEMORY; 2941 return XML_ERROR_NONE; 2942} 2943 2944static enum XML_Error 2945appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, 2946 const char *ptr, const char *end, 2947 STRING_POOL *pool) 2948{ 2949 for (;;) { 2950 const char *next; 2951 int tok = XmlAttributeValueTok(enc, ptr, end, &next); 2952 switch (tok) { 2953 case XML_TOK_NONE: 2954 return XML_ERROR_NONE; 2955 case XML_TOK_INVALID: 2956 if (enc == encoding) 2957 eventPtr = next; 2958 return XML_ERROR_INVALID_TOKEN; 2959 case XML_TOK_PARTIAL: 2960 if (enc == encoding) 2961 eventPtr = ptr; 2962 return XML_ERROR_INVALID_TOKEN; 2963 case XML_TOK_CHAR_REF: 2964 { 2965 XML_Char buf[XML_ENCODE_MAX]; 2966 int i; 2967 int n = XmlCharRefNumber(enc, ptr); 2968 if (n < 0) { 2969 if (enc == encoding) 2970 eventPtr = ptr; 2971 return XML_ERROR_BAD_CHAR_REF; 2972 } 2973 if (!isCdata 2974 && n == 0x20 /* space */ 2975 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 2976 break; 2977 n = XmlEncode(n, (ICHAR *)buf); 2978 if (!n) { 2979 if (enc == encoding) 2980 eventPtr = ptr; 2981 return XML_ERROR_BAD_CHAR_REF; 2982 } 2983 for (i = 0; i < n; i++) { 2984 if (!poolAppendChar(pool, buf[i])) 2985 return XML_ERROR_NO_MEMORY; 2986 } 2987 } 2988 break; 2989 case XML_TOK_DATA_CHARS: 2990 if (!poolAppend(pool, enc, ptr, next)) 2991 return XML_ERROR_NO_MEMORY; 2992 break; 2993 break; 2994 case XML_TOK_TRAILING_CR: 2995 next = ptr + enc->minBytesPerChar; 2996 /* fall through */ 2997 case XML_TOK_ATTRIBUTE_VALUE_S: 2998 case XML_TOK_DATA_NEWLINE: 2999 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 3000 break; 3001 if (!poolAppendChar(pool, 0x20)) 3002 return XML_ERROR_NO_MEMORY; 3003 break; 3004 case XML_TOK_ENTITY_REF: 3005 { 3006 const XML_Char *name; 3007 ENTITY *entity; 3008 XML_Char ch = XmlPredefinedEntityName(enc, 3009 ptr + enc->minBytesPerChar, 3010 next - enc->minBytesPerChar); 3011 if (ch) { 3012 if (!poolAppendChar(pool, ch)) 3013 return XML_ERROR_NO_MEMORY; 3014 break; 3015 } 3016 name = poolStoreString(&temp2Pool, enc, 3017 ptr + enc->minBytesPerChar, 3018 next - enc->minBytesPerChar); 3019 if (!name) 3020 return XML_ERROR_NO_MEMORY; 3021 entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0); 3022 poolDiscard(&temp2Pool); 3023 if (!entity) { 3024 if (dtd.complete) { 3025 if (enc == encoding) 3026 eventPtr = ptr; 3027 return XML_ERROR_UNDEFINED_ENTITY; 3028 } 3029 } 3030 else if (entity->open) { 3031 if (enc == encoding) 3032 eventPtr = ptr; 3033 return XML_ERROR_RECURSIVE_ENTITY_REF; 3034 } 3035 else if (entity->notation) { 3036 if (enc == encoding) 3037 eventPtr = ptr; 3038 return XML_ERROR_BINARY_ENTITY_REF; 3039 } 3040 else if (!entity->textPtr) { 3041 if (enc == encoding) 3042 eventPtr = ptr; 3043 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; 3044 } 3045 else { 3046 enum XML_Error result; 3047 const XML_Char *textEnd = entity->textPtr + entity->textLen; 3048 entity->open = 1; 3049 result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); 3050 entity->open = 0; 3051 if (result) 3052 return result; 3053 } 3054 } 3055 break; 3056 default: 3057 abort(); 3058 } 3059 ptr = next; 3060 } 3061 /* not reached */ 3062} 3063 3064static 3065enum XML_Error storeEntityValue(XML_Parser parser, 3066 const ENCODING *enc, 3067 const char *entityTextPtr, 3068 const char *entityTextEnd) 3069{ 3070 STRING_POOL *pool = &(dtd.pool); 3071 for (;;) { 3072 const char *next; 3073 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); 3074 switch (tok) { 3075 case XML_TOK_PARAM_ENTITY_REF: 3076#ifdef XML_DTD 3077 if (parentParser || enc != encoding) { 3078 enum XML_Error result; 3079 const XML_Char *name; 3080 ENTITY *entity; 3081 name = poolStoreString(&tempPool, enc, 3082 entityTextPtr + enc->minBytesPerChar, 3083 next - enc->minBytesPerChar); 3084 if (!name) 3085 return XML_ERROR_NO_MEMORY; 3086 entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0); 3087 poolDiscard(&tempPool); 3088 if (!entity) { 3089 if (enc == encoding) 3090 eventPtr = entityTextPtr; 3091 return XML_ERROR_UNDEFINED_ENTITY; 3092 } 3093 if (entity->open) { 3094 if (enc == encoding) 3095 eventPtr = entityTextPtr; 3096 return XML_ERROR_RECURSIVE_ENTITY_REF; 3097 } 3098 if (entity->systemId) { 3099 if (enc == encoding) 3100 eventPtr = entityTextPtr; 3101 return XML_ERROR_PARAM_ENTITY_REF; 3102 } 3103 entity->open = 1; 3104 result = storeEntityValue(parser, 3105 internalEncoding, 3106 (char *)entity->textPtr, 3107 (char *)(entity->textPtr + entity->textLen)); 3108 entity->open = 0; 3109 if (result) 3110 return result; 3111 break; 3112 } 3113#endif /* XML_DTD */ 3114 eventPtr = entityTextPtr; 3115 return XML_ERROR_SYNTAX; 3116 case XML_TOK_NONE: 3117 return XML_ERROR_NONE; 3118 case XML_TOK_ENTITY_REF: 3119 case XML_TOK_DATA_CHARS: 3120 if (!poolAppend(pool, enc, entityTextPtr, next)) 3121 return XML_ERROR_NO_MEMORY; 3122 break; 3123 case XML_TOK_TRAILING_CR: 3124 next = entityTextPtr + enc->minBytesPerChar; 3125 /* fall through */ 3126 case XML_TOK_DATA_NEWLINE: 3127 if (pool->end == pool->ptr && !poolGrow(pool)) 3128 return XML_ERROR_NO_MEMORY; 3129 *(pool->ptr)++ = 0xA; 3130 break; 3131 case XML_TOK_CHAR_REF: 3132 { 3133 XML_Char buf[XML_ENCODE_MAX]; 3134 int i; 3135 int n = XmlCharRefNumber(enc, entityTextPtr); 3136 if (n < 0) { 3137 if (enc == encoding) 3138 eventPtr = entityTextPtr; 3139 return XML_ERROR_BAD_CHAR_REF; 3140 } 3141 n = XmlEncode(n, (ICHAR *)buf); 3142 if (!n) { 3143 if (enc == encoding) 3144 eventPtr = entityTextPtr; 3145 return XML_ERROR_BAD_CHAR_REF; 3146 } 3147 for (i = 0; i < n; i++) { 3148 if (pool->end == pool->ptr && !poolGrow(pool)) 3149 return XML_ERROR_NO_MEMORY; 3150 *(pool->ptr)++ = buf[i]; 3151 } 3152 } 3153 break; 3154 case XML_TOK_PARTIAL: 3155 if (enc == encoding) 3156 eventPtr = entityTextPtr; 3157 return XML_ERROR_INVALID_TOKEN; 3158 case XML_TOK_INVALID: 3159 if (enc == encoding) 3160 eventPtr = next; 3161 return XML_ERROR_INVALID_TOKEN; 3162 default: 3163 abort(); 3164 } 3165 entityTextPtr = next; 3166 } 3167 /* not reached */ 3168} 3169 3170static void 3171normalizeLines(XML_Char *s) 3172{ 3173 XML_Char *p; 3174 for (;; s++) { 3175 if (*s == XML_T('\0')) 3176 return; 3177 if (*s == 0xD) 3178 break; 3179 } 3180 p = s; 3181 do { 3182 if (*s == 0xD) { 3183 *p++ = 0xA; 3184 if (*++s == 0xA) 3185 s++; 3186 } 3187 else 3188 *p++ = *s++; 3189 } while (*s); 3190 *p = XML_T('\0'); 3191} 3192 3193static int 3194reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) 3195{ 3196 const XML_Char *target; 3197 XML_Char *data; 3198 const char *tem; 3199 if (!processingInstructionHandler) { 3200 if (defaultHandler) 3201 reportDefault(parser, enc, start, end); 3202 return 1; 3203 } 3204 start += enc->minBytesPerChar * 2; 3205 tem = start + XmlNameLength(enc, start); 3206 target = poolStoreString(&tempPool, enc, start, tem); 3207 if (!target) 3208 return 0; 3209 poolFinish(&tempPool); 3210 data = poolStoreString(&tempPool, enc, 3211 XmlSkipS(enc, tem), 3212 end - enc->minBytesPerChar*2); 3213 if (!data) 3214 return 0; 3215 normalizeLines(data); 3216 processingInstructionHandler(handlerArg, target, data); 3217 poolClear(&tempPool); 3218 return 1; 3219} 3220 3221static int 3222reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) 3223{ 3224 XML_Char *data; 3225 if (!commentHandler) { 3226 if (defaultHandler) 3227 reportDefault(parser, enc, start, end); 3228 return 1; 3229 } 3230 data = poolStoreString(&tempPool, 3231 enc, 3232 start + enc->minBytesPerChar * 4, 3233 end - enc->minBytesPerChar * 3); 3234 if (!data) 3235 return 0; 3236 normalizeLines(data); 3237 commentHandler(handlerArg, data); 3238 poolClear(&tempPool); 3239 return 1; 3240} 3241 3242static void 3243reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end) 3244{ 3245 if (MUST_CONVERT(enc, s)) { 3246 const char **eventPP; 3247 const char **eventEndPP; 3248 if (enc == encoding) { 3249 eventPP = &eventPtr; 3250 eventEndPP = &eventEndPtr; 3251 } 3252 else { 3253 eventPP = &(openInternalEntities->internalEventPtr); 3254 eventEndPP = &(openInternalEntities->internalEventEndPtr); 3255 } 3256 do { 3257 ICHAR *dataPtr = (ICHAR *)dataBuf; 3258 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); 3259 *eventEndPP = s; 3260 defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); 3261 *eventPP = s; 3262 } while (s != end); 3263 } 3264 else 3265 defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s); 3266} 3267 3268 3269static int 3270defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value) 3271{ 3272 DEFAULT_ATTRIBUTE *att; 3273 if (value) { 3274 /* The handling of default attributes gets messed up if we have 3275 a default which duplicates a non-default. */ 3276 int i; 3277 for (i = 0; i < type->nDefaultAtts; i++) 3278 if (attId == type->defaultAtts[i].id) 3279 return 1; 3280 } 3281 if (type->nDefaultAtts == type->allocDefaultAtts) { 3282 if (type->allocDefaultAtts == 0) { 3283 type->allocDefaultAtts = 8; 3284 type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); 3285 } 3286 else { 3287 type->allocDefaultAtts *= 2; 3288 type->defaultAtts = realloc(type->defaultAtts, 3289 type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); 3290 } 3291 if (!type->defaultAtts) 3292 return 0; 3293 } 3294 att = type->defaultAtts + type->nDefaultAtts; 3295 att->id = attId; 3296 att->value = value; 3297 att->isCdata = isCdata; 3298 if (!isCdata) 3299 attId->maybeTokenized = 1; 3300 type->nDefaultAtts += 1; 3301 return 1; 3302} 3303 3304static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) 3305{ 3306 const XML_Char *name; 3307 for (name = elementType->name; *name; name++) { 3308 if (*name == XML_T(':')) { 3309 PREFIX *prefix; 3310 const XML_Char *s; 3311 for (s = elementType->name; s != name; s++) { 3312 if (!poolAppendChar(&dtd.pool, *s)) 3313 return 0; 3314 } 3315 if (!poolAppendChar(&dtd.pool, XML_T('\0'))) 3316 return 0; 3317 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX)); 3318 if (!prefix) 3319 return 0; 3320 if (prefix->name == poolStart(&dtd.pool)) 3321 poolFinish(&dtd.pool); 3322 else 3323 poolDiscard(&dtd.pool); 3324 elementType->prefix = prefix; 3325 3326 } 3327 } 3328 return 1; 3329} 3330 3331static ATTRIBUTE_ID * 3332getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) 3333{ 3334 ATTRIBUTE_ID *id; 3335 const XML_Char *name; 3336 if (!poolAppendChar(&dtd.pool, XML_T('\0'))) 3337 return 0; 3338 name = poolStoreString(&dtd.pool, enc, start, end); 3339 if (!name) 3340 return 0; 3341 ++name; 3342 id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID)); 3343 if (!id) 3344 return 0; 3345 if (id->name != name) 3346 poolDiscard(&dtd.pool); 3347 else { 3348 poolFinish(&dtd.pool); 3349 if (!ns) 3350 ; 3351 else if (name[0] == 'x' 3352 && name[1] == 'm' 3353 && name[2] == 'l' 3354 && name[3] == 'n' 3355 && name[4] == 's' 3356 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) { 3357 if (name[5] == '\0') 3358 id->prefix = &dtd.defaultPrefix; 3359 else 3360 id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX)); 3361 id->xmlns = 1; 3362 } 3363 else { 3364 int i; 3365 for (i = 0; name[i]; i++) { 3366 if (name[i] == XML_T(':')) { 3367 int j; 3368 for (j = 0; j < i; j++) { 3369 if (!poolAppendChar(&dtd.pool, name[j])) 3370 return 0; 3371 } 3372 if (!poolAppendChar(&dtd.pool, XML_T('\0'))) 3373 return 0; 3374 id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX)); 3375 if (id->prefix->name == poolStart(&dtd.pool)) 3376 poolFinish(&dtd.pool); 3377 else 3378 poolDiscard(&dtd.pool); 3379 break; 3380 } 3381 } 3382 } 3383 } 3384 return id; 3385} 3386 3387#define CONTEXT_SEP XML_T('\f') 3388 3389static 3390const XML_Char *getContext(XML_Parser parser) 3391{ 3392 HASH_TABLE_ITER iter; 3393 int needSep = 0; 3394 3395 if (dtd.defaultPrefix.binding) { 3396 int i; 3397 int len; 3398 if (!poolAppendChar(&tempPool, XML_T('='))) 3399 return 0; 3400 len = dtd.defaultPrefix.binding->uriLen; 3401 if (namespaceSeparator != XML_T('\0')) 3402 len--; 3403 for (i = 0; i < len; i++) 3404 if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i])) 3405 return 0; 3406 needSep = 1; 3407 } 3408 3409 hashTableIterInit(&iter, &(dtd.prefixes)); 3410 for (;;) { 3411 int i; 3412 int len; 3413 const XML_Char *s; 3414 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); 3415 if (!prefix) 3416 break; 3417 if (!prefix->binding) 3418 continue; 3419 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) 3420 return 0; 3421 for (s = prefix->name; *s; s++) 3422 if (!poolAppendChar(&tempPool, *s)) 3423 return 0; 3424 if (!poolAppendChar(&tempPool, XML_T('='))) 3425 return 0; 3426 len = prefix->binding->uriLen; 3427 if (namespaceSeparator != XML_T('\0')) 3428 len--; 3429 for (i = 0; i < len; i++) 3430 if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) 3431 return 0; 3432 needSep = 1; 3433 } 3434 3435 3436 hashTableIterInit(&iter, &(dtd.generalEntities)); 3437 for (;;) { 3438 const XML_Char *s; 3439 ENTITY *e = (ENTITY *)hashTableIterNext(&iter); 3440 if (!e) 3441 break; 3442 if (!e->open) 3443 continue; 3444 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) 3445 return 0; 3446 for (s = e->name; *s; s++) 3447 if (!poolAppendChar(&tempPool, *s)) 3448 return 0; 3449 needSep = 1; 3450 } 3451 3452 if (!poolAppendChar(&tempPool, XML_T('\0'))) 3453 return 0; 3454 return tempPool.start; 3455} 3456 3457static 3458int setContext(XML_Parser parser, const XML_Char *context) 3459{ 3460 const XML_Char *s = context; 3461 3462 while (*context != XML_T('\0')) { 3463 if (*s == CONTEXT_SEP || *s == XML_T('\0')) { 3464 ENTITY *e; 3465 if (!poolAppendChar(&tempPool, XML_T('\0'))) 3466 return 0; 3467 e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0); 3468 if (e) 3469 e->open = 1; 3470 if (*s != XML_T('\0')) 3471 s++; 3472 context = s; 3473 poolDiscard(&tempPool); 3474 } 3475 else if (*s == '=') { 3476 PREFIX *prefix; 3477 if (poolLength(&tempPool) == 0) 3478 prefix = &dtd.defaultPrefix; 3479 else { 3480 if (!poolAppendChar(&tempPool, XML_T('\0'))) 3481 return 0; 3482 prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX)); 3483 if (!prefix) 3484 return 0; 3485 if (prefix->name == poolStart(&tempPool)) 3486 poolFinish(&tempPool); 3487 else 3488 poolDiscard(&tempPool); 3489 } 3490 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++) 3491 if (!poolAppendChar(&tempPool, *context)) 3492 return 0; 3493 if (!poolAppendChar(&tempPool, XML_T('\0'))) 3494 return 0; 3495 if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings)) 3496 return 0; 3497 poolDiscard(&tempPool); 3498 if (*context != XML_T('\0')) 3499 ++context; 3500 s = context; 3501 } 3502 else { 3503 if (!poolAppendChar(&tempPool, *s)) 3504 return 0; 3505 s++; 3506 } 3507 } 3508 return 1; 3509} 3510 3511 3512static 3513void normalizePublicId(XML_Char *publicId) 3514{ 3515 XML_Char *p = publicId; 3516 XML_Char *s; 3517 for (s = publicId; *s; s++) { 3518 switch (*s) { 3519 case 0x20: 3520 case 0xD: 3521 case 0xA: 3522 if (p != publicId && p[-1] != 0x20) 3523 *p++ = 0x20; 3524 break; 3525 default: 3526 *p++ = *s; 3527 } 3528 } 3529 if (p != publicId && p[-1] == 0x20) 3530 --p; 3531 *p = XML_T('\0'); 3532} 3533 3534static int dtdInit(DTD *p) 3535{ 3536 poolInit(&(p->pool)); 3537 hashTableInit(&(p->generalEntities)); 3538 hashTableInit(&(p->elementTypes)); 3539 hashTableInit(&(p->attributeIds)); 3540 hashTableInit(&(p->prefixes)); 3541 p->complete = 1; 3542 p->standalone = 0; 3543#ifdef XML_DTD 3544 hashTableInit(&(p->paramEntities)); 3545#endif /* XML_DTD */ 3546 p->defaultPrefix.name = 0; 3547 p->defaultPrefix.binding = 0; 3548 return 1; 3549} 3550 3551#ifdef XML_DTD 3552 3553static void dtdSwap(DTD *p1, DTD *p2) 3554{ 3555 DTD tem; 3556 memcpy(&tem, p1, sizeof(DTD)); 3557 memcpy(p1, p2, sizeof(DTD)); 3558 memcpy(p2, &tem, sizeof(DTD)); 3559} 3560 3561#endif /* XML_DTD */ 3562 3563static void dtdDestroy(DTD *p) 3564{ 3565 HASH_TABLE_ITER iter; 3566 hashTableIterInit(&iter, &(p->elementTypes)); 3567 for (;;) { 3568 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); 3569 if (!e) 3570 break; 3571 if (e->allocDefaultAtts != 0) 3572 free(e->defaultAtts); 3573 if (e->contentSpec != 0) { 3574 free(e->contentSpec); 3575 } 3576 if (e->attributes != 0) { 3577 free(e->attributes); 3578 } 3579 } 3580 hashTableDestroy(&(p->generalEntities)); 3581#ifdef XML_DTD 3582 hashTableDestroy(&(p->paramEntities)); 3583#endif /* XML_DTD */ 3584 hashTableDestroy(&(p->elementTypes)); 3585 hashTableDestroy(&(p->attributeIds)); 3586 hashTableDestroy(&(p->prefixes)); 3587 poolDestroy(&(p->pool)); 3588} 3589 3590/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise. 3591The new DTD has already been initialized. */ 3592 3593static int dtdCopy(DTD *newDtd, const DTD *oldDtd) 3594{ 3595 HASH_TABLE_ITER iter; 3596 3597 /* Copy the prefix table. */ 3598 3599 hashTableIterInit(&iter, &(oldDtd->prefixes)); 3600 for (;;) { 3601 const XML_Char *name; 3602 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); 3603 if (!oldP) 3604 break; 3605 name = poolCopyString(&(newDtd->pool), oldP->name); 3606 if (!name) 3607 return 0; 3608 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX))) 3609 return 0; 3610 } 3611 3612 hashTableIterInit(&iter, &(oldDtd->attributeIds)); 3613 3614 /* Copy the attribute id table. */ 3615 3616 for (;;) { 3617 ATTRIBUTE_ID *newA; 3618 const XML_Char *name; 3619 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); 3620 3621 if (!oldA) 3622 break; 3623 /* Remember to allocate the scratch byte before the name. */ 3624 if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) 3625 return 0; 3626 name = poolCopyString(&(newDtd->pool), oldA->name); 3627 if (!name) 3628 return 0; 3629 ++name; 3630 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); 3631 if (!newA) 3632 return 0; 3633 newA->maybeTokenized = oldA->maybeTokenized; 3634 if (oldA->prefix) { 3635 newA->xmlns = oldA->xmlns; 3636 if (oldA->prefix == &oldDtd->defaultPrefix) 3637 newA->prefix = &newDtd->defaultPrefix; 3638 else 3639 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0); 3640 } 3641 } 3642 3643 /* Copy the element type table. */ 3644 3645 hashTableIterInit(&iter, &(oldDtd->elementTypes)); 3646 3647 for (;;) { 3648 int i; 3649 ELEMENT_TYPE *newE; 3650 const XML_Char *name; 3651 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); 3652 if (!oldE) 3653 break; 3654 name = poolCopyString(&(newDtd->pool), oldE->name); 3655 if (!name) 3656 return 0; 3657 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); 3658 if (!newE) 3659 return 0; 3660 if (oldE->nDefaultAtts) { 3661 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); 3662 if (!newE->defaultAtts) 3663 return 0; 3664 } 3665 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; 3666 if (oldE->prefix) 3667 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0); 3668 for (i = 0; i < newE->nDefaultAtts; i++) { 3669 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); 3670 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; 3671 if (oldE->defaultAtts[i].value) { 3672 newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); 3673 if (!newE->defaultAtts[i].value) 3674 return 0; 3675 } 3676 else 3677 newE->defaultAtts[i].value = 0; 3678 } 3679 } 3680 3681 /* Copy the entity tables. */ 3682 if (!copyEntityTable(&(newDtd->generalEntities), 3683 &(newDtd->pool), 3684 &(oldDtd->generalEntities))) 3685 return 0; 3686 3687#ifdef XML_DTD 3688 if (!copyEntityTable(&(newDtd->paramEntities), 3689 &(newDtd->pool), 3690 &(oldDtd->paramEntities))) 3691 return 0; 3692#endif /* XML_DTD */ 3693 3694 newDtd->complete = oldDtd->complete; 3695 newDtd->standalone = oldDtd->standalone; 3696 return 1; 3697} 3698 3699static int copyEntityTable(HASH_TABLE *newTable, 3700 STRING_POOL *newPool, 3701 const HASH_TABLE *oldTable) 3702{ 3703 HASH_TABLE_ITER iter; 3704 const XML_Char *cachedOldBase = 0; 3705 const XML_Char *cachedNewBase = 0; 3706 3707 hashTableIterInit(&iter, oldTable); 3708 3709 for (;;) { 3710 ENTITY *newE; 3711 const XML_Char *name; 3712 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); 3713 if (!oldE) 3714 break; 3715 name = poolCopyString(newPool, oldE->name); 3716 if (!name) 3717 return 0; 3718 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY)); 3719 if (!newE) 3720 return 0; 3721 if (oldE->systemId) { 3722 const XML_Char *tem = poolCopyString(newPool, oldE->systemId); 3723 if (!tem) 3724 return 0; 3725 newE->systemId = tem; 3726 if (oldE->base) { 3727 if (oldE->base == cachedOldBase) 3728 newE->base = cachedNewBase; 3729 else { 3730 cachedOldBase = oldE->base; 3731 tem = poolCopyString(newPool, cachedOldBase); 3732 if (!tem) 3733 return 0; 3734 cachedNewBase = newE->base = tem; 3735 } 3736 } 3737 } 3738 else { 3739 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); 3740 if (!tem) 3741 return 0; 3742 newE->textPtr = tem; 3743 newE->textLen = oldE->textLen; 3744 } 3745 if (oldE->notation) { 3746 const XML_Char *tem = poolCopyString(newPool, oldE->notation); 3747 if (!tem) 3748 return 0; 3749 newE->notation = tem; 3750 } 3751 } 3752 return 1; 3753} 3754 3755static 3756void poolInit(STRING_POOL *pool) 3757{ 3758 pool->blocks = 0; 3759 pool->freeBlocks = 0; 3760 pool->start = 0; 3761 pool->ptr = 0; 3762 pool->end = 0; 3763} 3764 3765static 3766void poolClear(STRING_POOL *pool) 3767{ 3768 if (!pool->freeBlocks) 3769 pool->freeBlocks = pool->blocks; 3770 else { 3771 BLOCK *p = pool->blocks; 3772 while (p) { 3773 BLOCK *tem = p->next; 3774 p->next = pool->freeBlocks; 3775 pool->freeBlocks = p; 3776 p = tem; 3777 } 3778 } 3779 pool->blocks = 0; 3780 pool->start = 0; 3781 pool->ptr = 0; 3782 pool->end = 0; 3783} 3784 3785static 3786void poolDestroy(STRING_POOL *pool) 3787{ 3788 BLOCK *p = pool->blocks; 3789 while (p) { 3790 BLOCK *tem = p->next; 3791 free(p); 3792 p = tem; 3793 } 3794 pool->blocks = 0; 3795 p = pool->freeBlocks; 3796 while (p) { 3797 BLOCK *tem = p->next; 3798 free(p); 3799 p = tem; 3800 } 3801 pool->freeBlocks = 0; 3802 pool->ptr = 0; 3803 pool->start = 0; 3804 pool->end = 0; 3805} 3806 3807static 3808XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, 3809 const char *ptr, const char *end) 3810{ 3811 if (!pool->ptr && !poolGrow(pool)) 3812 return 0; 3813 for (;;) { 3814 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); 3815 if (ptr == end) 3816 break; 3817 if (!poolGrow(pool)) 3818 return 0; 3819 } 3820 return pool->start; 3821} 3822 3823static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s) 3824{ 3825 do { 3826 if (!poolAppendChar(pool, *s)) 3827 return 0; 3828 } while (*s++); 3829 s = pool->start; 3830 poolFinish(pool); 3831 return s; 3832} 3833 3834static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) 3835{ 3836 if (!pool->ptr && !poolGrow(pool)) 3837 return 0; 3838 for (; n > 0; --n, s++) { 3839 if (!poolAppendChar(pool, *s)) 3840 return 0; 3841 3842 } 3843 s = pool->start; 3844 poolFinish(pool); 3845 return s; 3846} 3847 3848static 3849XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, 3850 const char *ptr, const char *end) 3851{ 3852 if (!poolAppend(pool, enc, ptr, end)) 3853 return 0; 3854 if (pool->ptr == pool->end && !poolGrow(pool)) 3855 return 0; 3856 *(pool->ptr)++ = 0; 3857 return pool->start; 3858} 3859 3860static 3861int poolGrow(STRING_POOL *pool) 3862{ 3863 if (pool->freeBlocks) { 3864 if (pool->start == 0) { 3865 pool->blocks = pool->freeBlocks; 3866 pool->freeBlocks = pool->freeBlocks->next; 3867 pool->blocks->next = 0; 3868 pool->start = pool->blocks->s; 3869 pool->end = pool->start + pool->blocks->size; 3870 pool->ptr = pool->start; 3871 return 1; 3872 } 3873 if (pool->end - pool->start < pool->freeBlocks->size) { 3874 BLOCK *tem = pool->freeBlocks->next; 3875 pool->freeBlocks->next = pool->blocks; 3876 pool->blocks = pool->freeBlocks; 3877 pool->freeBlocks = tem; 3878 memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char)); 3879 pool->ptr = pool->blocks->s + (pool->ptr - pool->start); 3880 pool->start = pool->blocks->s; 3881 pool->end = pool->start + pool->blocks->size; 3882 return 1; 3883 } 3884 } 3885 if (pool->blocks && pool->start == pool->blocks->s) { 3886 int blockSize = (pool->end - pool->start)*2; 3887 pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char)); 3888 if (!pool->blocks) 3889 return 0; 3890 pool->blocks->size = blockSize; 3891 pool->ptr = pool->blocks->s + (pool->ptr - pool->start); 3892 pool->start = pool->blocks->s; 3893 pool->end = pool->start + blockSize; 3894 } 3895 else { 3896 BLOCK *tem; 3897 int blockSize = pool->end - pool->start; 3898 if (blockSize < INIT_BLOCK_SIZE) 3899 blockSize = INIT_BLOCK_SIZE; 3900 else 3901 blockSize *= 2; 3902 tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char)); 3903 if (!tem) 3904 return 0; 3905 tem->size = blockSize; 3906 tem->next = pool->blocks; 3907 pool->blocks = tem; 3908 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); 3909 pool->ptr = tem->s + (pool->ptr - pool->start); 3910 pool->start = tem->s; 3911 pool->end = tem->s + blockSize; 3912 } 3913 return 1; 3914} 3915 3916/* ericm@scriptics */ 3917 3918/* 3919 *---------------------------------------------------------------------- 3920 * 3921 * appendContent -- 3922 * 3923 * Add a content particle to the content spec for a given element. 3924 * el pointer to the element to modify 3925 * type type of content particle to add, one of the XML_ROLE_* 3926 * enumerations defined in xmlrole.h 3927 * name pointer to the name of the element indicated by the content 3928 * particle (ie, if the content particle is an "element" 3929 * particle of some sort); for non-element content particles 3930 * (group, or's, comma's, etc), it is NULL. 3931 * 3932 * Results: 3933 * enum XML_Error; XML_ERROR_NO_MEMORY if there is insufficient free 3934 * memory; XML_ERROR_NONE if there was no problem. 3935 * 3936 * Side effects: 3937 * May grow the contentSpec array of the element pointed to by el. 3938 * 3939 *---------------------------------------------------------------------- 3940 */ 3941 3942enum XML_Error 3943appendContent(ELEMENT_TYPE *el, int type, const XML_Char *name) 3944{ 3945 int i; 3946 XML_Char **result; 3947 /* Grow the content spec array, if necessary */ 3948 if (el->nContentParticles + 1 >= el->maxContentParticles) { 3949 if (el->contentSpec) { 3950 el->maxContentParticles *= 2; 3951 result = 3952 realloc(el->contentSpec, 3953 (el->maxContentParticles * sizeof(XML_Char *))); 3954 if (!result) { 3955 return XML_ERROR_NO_MEMORY; 3956 } 3957 el->contentSpec = result; 3958 for (i = el->nContentParticles; i < el->maxContentParticles; i++) { 3959 el->contentSpec[i] = NULL; 3960 } 3961 } else { 3962 el->maxContentParticles = 16; 3963 el->contentSpec = 3964 calloc(el->maxContentParticles, sizeof(XML_Char *)); 3965 if (!el->contentSpec) { 3966 return XML_ERROR_NO_MEMORY; 3967 } 3968 } 3969 } 3970 3971 switch (type) { 3972 case XML_ROLE_CONTENT_ANY: 3973 el->contentSpec[el->nContentParticles++] = "ANY"; 3974 break; 3975 case XML_ROLE_CONTENT_EMPTY: 3976 el->contentSpec[el->nContentParticles++] = "EMPTY"; 3977 break; 3978 case XML_ROLE_CONTENT_PCDATA: 3979 el->contentSpec[el->nContentParticles++] = "#PCDATA"; 3980 break; 3981 case XML_ROLE_GROUP_OPEN: 3982 el->contentSpec[el->nContentParticles++] = "("; 3983 break; 3984 case XML_ROLE_GROUP_CLOSE: 3985 el->contentSpec[el->nContentParticles++] = ")"; 3986 break; 3987 case XML_ROLE_GROUP_CLOSE_REP: 3988 el->contentSpec[el->nContentParticles++] = ")*"; 3989 break; 3990 case XML_ROLE_GROUP_CLOSE_OPT: 3991 el->contentSpec[el->nContentParticles++] = ")?"; 3992 break; 3993 case XML_ROLE_GROUP_CLOSE_PLUS: 3994 el->contentSpec[el->nContentParticles++] = ")+"; 3995 break; 3996 case XML_ROLE_GROUP_CHOICE: 3997 el->contentSpec[el->nContentParticles++] = "|"; 3998 break; 3999 case XML_ROLE_GROUP_SEQUENCE: 4000 el->contentSpec[el->nContentParticles++] = ","; 4001 break; 4002 case XML_ROLE_CONTENT_ELEMENT: 4003 case XML_ROLE_CONTENT_ELEMENT_REP: 4004 case XML_ROLE_CONTENT_ELEMENT_OPT: 4005 case XML_ROLE_CONTENT_ELEMENT_PLUS: 4006 el->contentSpec[el->nContentParticles++] = (XML_Char *)name; 4007 break; 4008 } 4009 return XML_ERROR_NONE; 4010} 4011 4012 4013/* 4014 *---------------------------------------------------------------------- 4015 * 4016 * appendAttribute -- 4017 * 4018 * Add an attribute to the list of attributes for a given element. 4019 * 4020 * Results: 4021 * enum XML_Error; XML_ERROR_NO_MEMORY if there is insufficient memory for 4022 * the operation; XML_ERROR_NONE if there was no problem. 4023 * 4024 * Side effects: 4025 * May grow the attribute array of the element pointed to by el. 4026 * 4027 *---------------------------------------------------------------------- 4028 */ 4029 4030enum XML_Error 4031appendAttribute(ELEMENT_TYPE *el, XML_Char *name) 4032{ 4033 int i; 4034 XML_Char **result; 4035 4036 /* First see if this attribute is already part of the list */ 4037 /* TODO This is *NOT* the best way to avoid duplicate attributes */ 4038 for (i = 0; i < el->nAttributes; i++) { 4039 if (el->attributes[i] == name) { 4040 return XML_ERROR_NONE; 4041 } 4042 } 4043 4044 /* Grow the attribute array, if necessary */ 4045 if (el->nAttributes + 1 >= el->maxAttributes) { 4046 if (el->attributes) { 4047 el->maxAttributes *= 2; 4048 4049 result = 4050 realloc(el->attributes, 4051 (el->maxAttributes * sizeof(XML_Char *))); 4052 if (!result) { 4053 return XML_ERROR_NO_MEMORY; 4054 } 4055 el->attributes = result; 4056 for (i = el->nAttributes; i < el->maxAttributes; i++) { 4057 el->attributes[i] = NULL; 4058 } 4059 } else { 4060 el->maxAttributes = 8; 4061 el->attributes = 4062 calloc(el->maxAttributes, sizeof(XML_Char *)); 4063 if (!el->attributes) { 4064 return XML_ERROR_NO_MEMORY; 4065 } 4066 } 4067 } 4068 4069 4070 el->attributes[el->nAttributes++] = name; 4071 return XML_ERROR_NONE; 4072} 4073 4074 4075