Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxmlparse.c
Go to the documentation of this file.
00001 /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd 00002 See the file COPYING for copying permission. 00003 */ 00004 00005 #include <stddef.h> 00006 #include <string.h> /* memset(), memcpy() */ 00007 #include <assert.h> 00008 00009 #define XML_BUILDING_EXPAT 1 00010 00011 #ifdef COMPILED_FROM_DSP 00012 #include "winconfig.h" 00013 #elif defined(MACOS_CLASSIC) 00014 #include "macconfig.h" 00015 #elif defined(__amigaos4__) 00016 #include "amigaconfig.h" 00017 #elif defined(HAVE_EXPAT_CONFIG_H) 00018 #include <expat_config.h> 00019 #endif /* ndef COMPILED_FROM_DSP */ 00020 00021 #include "expat.h" 00022 00023 #ifdef XML_UNICODE 00024 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX 00025 #define XmlConvert XmlUtf16Convert 00026 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding 00027 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS 00028 #define XmlEncode XmlUtf16Encode 00029 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1)) 00030 typedef unsigned short ICHAR; 00031 #else 00032 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX 00033 #define XmlConvert XmlUtf8Convert 00034 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding 00035 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS 00036 #define XmlEncode XmlUtf8Encode 00037 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8) 00038 typedef char ICHAR; 00039 #endif 00040 00041 00042 #ifndef XML_NS 00043 00044 #define XmlInitEncodingNS XmlInitEncoding 00045 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding 00046 #undef XmlGetInternalEncodingNS 00047 #define XmlGetInternalEncodingNS XmlGetInternalEncoding 00048 #define XmlParseXmlDeclNS XmlParseXmlDecl 00049 00050 #endif 00051 00052 #ifdef XML_UNICODE 00053 00054 #ifdef XML_UNICODE_WCHAR_T 00055 #define XML_T(x) (const wchar_t)x 00056 #define XML_L(x) L ## x 00057 #else 00058 #define XML_T(x) (const unsigned short)x 00059 #define XML_L(x) x 00060 #endif 00061 00062 #else 00063 00064 #define XML_T(x) x 00065 #define XML_L(x) x 00066 00067 #endif 00068 00069 /* Round up n to be a multiple of sz, where sz is a power of 2. */ 00070 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) 00071 00072 /* Handle the case where memmove() doesn't exist. */ 00073 #ifndef HAVE_MEMMOVE 00074 #ifdef HAVE_BCOPY 00075 #define memmove(d,s,l) bcopy((s),(d),(l)) 00076 #else 00077 #error memmove does not exist on this platform, nor is a substitute available 00078 #endif /* HAVE_BCOPY */ 00079 #endif /* HAVE_MEMMOVE */ 00080 00081 #include "internal.h" 00082 #include "xmltok.h" 00083 #include "xmlrole.h" 00084 00085 typedef const XML_Char *KEY; 00086 00087 typedef struct { 00088 KEY name; 00089 } NAMED; 00090 00091 typedef struct { 00092 NAMED **v; 00093 unsigned char power; 00094 size_t size; 00095 size_t used; 00096 const XML_Memory_Handling_Suite *mem; 00097 } HASH_TABLE; 00098 00099 /* Basic character hash algorithm, taken from Python's string hash: 00100 h = h * 1000003 ^ character, the constant being a prime number. 00101 00102 */ 00103 #ifdef XML_UNICODE 00104 #define CHAR_HASH(h, c) \ 00105 (((h) * 0xF4243) ^ (unsigned short)(c)) 00106 #else 00107 #define CHAR_HASH(h, c) \ 00108 (((h) * 0xF4243) ^ (unsigned char)(c)) 00109 #endif 00110 00111 /* For probing (after a collision) we need a step size relative prime 00112 to the hash table size, which is a power of 2. We use double-hashing, 00113 since we can calculate a second hash value cheaply by taking those bits 00114 of the first hash value that were discarded (masked out) when the table 00115 index was calculated: index = hash & mask, where mask = table->size - 1. 00116 We limit the maximum step size to table->size / 4 (mask >> 2) and make 00117 it odd, since odd numbers are always relative prime to a power of 2. 00118 */ 00119 #define SECOND_HASH(hash, mask, power) \ 00120 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) 00121 #define PROBE_STEP(hash, mask, power) \ 00122 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) 00123 00124 typedef struct { 00125 NAMED **p; 00126 NAMED **end; 00127 } HASH_TABLE_ITER; 00128 00129 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ 00130 #define INIT_DATA_BUF_SIZE 1024 00131 #define INIT_ATTS_SIZE 16 00132 #define INIT_ATTS_VERSION 0xFFFFFFFF 00133 #define INIT_BLOCK_SIZE 1024 00134 #define INIT_BUFFER_SIZE 1024 00135 00136 #define EXPAND_SPARE 24 00137 00138 typedef struct binding { 00139 struct prefix *prefix; 00140 struct binding *nextTagBinding; 00141 struct binding *prevPrefixBinding; 00142 const struct attribute_id *attId; 00143 XML_Char *uri; 00144 int uriLen; 00145 int uriAlloc; 00146 } BINDING; 00147 00148 typedef struct prefix { 00149 const XML_Char *name; 00150 BINDING *binding; 00151 } PREFIX; 00152 00153 typedef struct { 00154 const XML_Char *str; 00155 const XML_Char *localPart; 00156 const XML_Char *prefix; 00157 int strLen; 00158 int uriLen; 00159 int prefixLen; 00160 } TAG_NAME; 00161 00162 /* TAG represents an open element. 00163 The name of the element is stored in both the document and API 00164 encodings. The memory buffer 'buf' is a separately-allocated 00165 memory area which stores the name. During the XML_Parse()/ 00166 XMLParseBuffer() when the element is open, the memory for the 'raw' 00167 version of the name (in the document encoding) is shared with the 00168 document buffer. If the element is open across calls to 00169 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to 00170 contain the 'raw' name as well. 00171 00172 A parser re-uses these structures, maintaining a list of allocated 00173 TAG objects in a free list. 00174 */ 00175 typedef struct tag { 00176 struct tag *parent; /* parent of this element */ 00177 const char *rawName; /* tagName in the original encoding */ 00178 int rawNameLength; 00179 TAG_NAME name; /* tagName in the API encoding */ 00180 char *buf; /* buffer for name components */ 00181 char *bufEnd; /* end of the buffer */ 00182 BINDING *bindings; 00183 } TAG; 00184 00185 typedef struct { 00186 const XML_Char *name; 00187 const XML_Char *textPtr; 00188 int textLen; /* length in XML_Chars */ 00189 int processed; /* # of processed bytes - when suspended */ 00190 const XML_Char *systemId; 00191 const XML_Char *base; 00192 const XML_Char *publicId; 00193 const XML_Char *notation; 00194 XML_Bool open; 00195 XML_Bool is_param; 00196 XML_Bool is_internal; /* true if declared in internal subset outside PE */ 00197 } ENTITY; 00198 00199 typedef struct { 00200 enum XML_Content_Type type; 00201 enum XML_Content_Quant quant; 00202 const XML_Char * name; 00203 int firstchild; 00204 int lastchild; 00205 int childcnt; 00206 int nextsib; 00207 } CONTENT_SCAFFOLD; 00208 00209 #define INIT_SCAFFOLD_ELEMENTS 32 00210 00211 typedef struct block { 00212 struct block *next; 00213 int size; 00214 XML_Char s[1]; 00215 } BLOCK; 00216 00217 typedef struct { 00218 BLOCK *blocks; 00219 BLOCK *freeBlocks; 00220 const XML_Char *end; 00221 XML_Char *ptr; 00222 XML_Char *start; 00223 const XML_Memory_Handling_Suite *mem; 00224 } STRING_POOL; 00225 00226 /* The XML_Char before the name is used to determine whether 00227 an attribute has been specified. */ 00228 typedef struct attribute_id { 00229 XML_Char *name; 00230 PREFIX *prefix; 00231 XML_Bool maybeTokenized; 00232 XML_Bool xmlns; 00233 } ATTRIBUTE_ID; 00234 00235 typedef struct { 00236 const ATTRIBUTE_ID *id; 00237 XML_Bool isCdata; 00238 const XML_Char *value; 00239 } DEFAULT_ATTRIBUTE; 00240 00241 typedef struct { 00242 unsigned long version; 00243 unsigned long hash; 00244 const XML_Char *uriName; 00245 } NS_ATT; 00246 00247 typedef struct { 00248 const XML_Char *name; 00249 PREFIX *prefix; 00250 const ATTRIBUTE_ID *idAtt; 00251 int nDefaultAtts; 00252 int allocDefaultAtts; 00253 DEFAULT_ATTRIBUTE *defaultAtts; 00254 } ELEMENT_TYPE; 00255 00256 typedef struct { 00257 HASH_TABLE generalEntities; 00258 HASH_TABLE elementTypes; 00259 HASH_TABLE attributeIds; 00260 HASH_TABLE prefixes; 00261 STRING_POOL pool; 00262 STRING_POOL entityValuePool; 00263 /* false once a parameter entity reference has been skipped */ 00264 XML_Bool keepProcessing; 00265 /* true once an internal or external PE reference has been encountered; 00266 this includes the reference to an external subset */ 00267 XML_Bool hasParamEntityRefs; 00268 XML_Bool standalone; 00269 #ifdef XML_DTD 00270 /* indicates if external PE has been read */ 00271 XML_Bool paramEntityRead; 00272 HASH_TABLE paramEntities; 00273 #endif /* XML_DTD */ 00274 PREFIX defaultPrefix; 00275 /* === scaffolding for building content model === */ 00276 XML_Bool in_eldecl; 00277 CONTENT_SCAFFOLD *scaffold; 00278 unsigned contentStringLen; 00279 unsigned scaffSize; 00280 unsigned scaffCount; 00281 int scaffLevel; 00282 int *scaffIndex; 00283 } DTD; 00284 00285 typedef struct open_internal_entity { 00286 const char *internalEventPtr; 00287 const char *internalEventEndPtr; 00288 struct open_internal_entity *next; 00289 ENTITY *entity; 00290 int startTagLevel; 00291 XML_Bool betweenDecl; /* WFC: PE Between Declarations */ 00292 } OPEN_INTERNAL_ENTITY; 00293 00294 typedef enum XML_Error PTRCALL Processor(XML_Parser parser, 00295 const char *start, 00296 const char *end, 00297 const char **endPtr); 00298 00299 static Processor prologProcessor; 00300 static Processor prologInitProcessor; 00301 static Processor contentProcessor; 00302 static Processor cdataSectionProcessor; 00303 #ifdef XML_DTD 00304 static Processor ignoreSectionProcessor; 00305 static Processor externalParEntProcessor; 00306 static Processor externalParEntInitProcessor; 00307 static Processor entityValueProcessor; 00308 static Processor entityValueInitProcessor; 00309 #endif /* XML_DTD */ 00310 static Processor epilogProcessor; 00311 static Processor errorProcessor; 00312 static Processor externalEntityInitProcessor; 00313 static Processor externalEntityInitProcessor2; 00314 static Processor externalEntityInitProcessor3; 00315 static Processor externalEntityContentProcessor; 00316 static Processor internalEntityProcessor; 00317 00318 static enum XML_Error 00319 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); 00320 static enum XML_Error 00321 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, 00322 const char *s, const char *next); 00323 static enum XML_Error 00324 initializeEncoding(XML_Parser parser); 00325 static enum XML_Error 00326 doProlog(XML_Parser parser, const ENCODING *enc, const char *s, 00327 const char *end, int tok, const char *next, const char **nextPtr, 00328 XML_Bool haveMore); 00329 static enum XML_Error 00330 processInternalEntity(XML_Parser parser, ENTITY *entity, 00331 XML_Bool betweenDecl); 00332 static enum XML_Error 00333 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, 00334 const char *start, const char *end, const char **endPtr, 00335 XML_Bool haveMore); 00336 static enum XML_Error 00337 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, 00338 const char *end, const char **nextPtr, XML_Bool haveMore); 00339 #ifdef XML_DTD 00340 static enum XML_Error 00341 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, 00342 const char *end, const char **nextPtr, XML_Bool haveMore); 00343 #endif /* XML_DTD */ 00344 00345 static enum XML_Error 00346 storeAtts(XML_Parser parser, const ENCODING *, const char *s, 00347 TAG_NAME *tagNamePtr, BINDING **bindingsPtr); 00348 static enum XML_Error 00349 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, 00350 const XML_Char *uri, BINDING **bindingsPtr); 00351 static int 00352 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 00353 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser); 00354 static enum XML_Error 00355 storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, 00356 const char *, const char *, STRING_POOL *); 00357 static enum XML_Error 00358 appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, 00359 const char *, const char *, STRING_POOL *); 00360 static ATTRIBUTE_ID * 00361 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, 00362 const char *end); 00363 static int 00364 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); 00365 static enum XML_Error 00366 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, 00367 const char *end); 00368 static int 00369 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, 00370 const char *start, const char *end); 00371 static int 00372 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, 00373 const char *end); 00374 static void 00375 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, 00376 const char *end); 00377 00378 static const XML_Char * getContext(XML_Parser parser); 00379 static XML_Bool 00380 setContext(XML_Parser parser, const XML_Char *context); 00381 00382 static void FASTCALL normalizePublicId(XML_Char *s); 00383 00384 static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms); 00385 /* do not call if parentParser != NULL */ 00386 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); 00387 static void 00388 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms); 00389 static int 00390 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms); 00391 static int 00392 copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); 00393 00394 static NAMED * 00395 lookup(HASH_TABLE *table, KEY name, size_t createSize); 00396 static void FASTCALL 00397 hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms); 00398 static void FASTCALL hashTableClear(HASH_TABLE *); 00399 static void FASTCALL hashTableDestroy(HASH_TABLE *); 00400 static void FASTCALL 00401 hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); 00402 static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *); 00403 00404 static void FASTCALL 00405 poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms); 00406 static void FASTCALL poolClear(STRING_POOL *); 00407 static void FASTCALL poolDestroy(STRING_POOL *); 00408 static XML_Char * 00409 poolAppend(STRING_POOL *pool, const ENCODING *enc, 00410 const char *ptr, const char *end); 00411 static XML_Char * 00412 poolStoreString(STRING_POOL *pool, const ENCODING *enc, 00413 const char *ptr, const char *end); 00414 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); 00415 static const XML_Char * FASTCALL 00416 poolCopyString(STRING_POOL *pool, const XML_Char *s); 00417 static const XML_Char * 00418 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); 00419 static const XML_Char * FASTCALL 00420 poolAppendString(STRING_POOL *pool, const XML_Char *s); 00421 00422 static int FASTCALL nextScaffoldPart(XML_Parser parser); 00423 static XML_Content * build_model(XML_Parser parser); 00424 static ELEMENT_TYPE * 00425 getElementType(XML_Parser parser, const ENCODING *enc, 00426 const char *ptr, const char *end); 00427 00428 static XML_Parser 00429 parserCreate(const XML_Char *encodingName, 00430 const XML_Memory_Handling_Suite *memsuite, 00431 const XML_Char *nameSep, 00432 DTD *dtd); 00433 static void 00434 parserInit(XML_Parser parser, const XML_Char *encodingName); 00435 00436 #define poolStart(pool) ((pool)->start) 00437 #define poolEnd(pool) ((pool)->ptr) 00438 #define poolLength(pool) ((pool)->ptr - (pool)->start) 00439 #define poolChop(pool) ((void)--(pool->ptr)) 00440 #define poolLastChar(pool) (((pool)->ptr)[-1]) 00441 #define poolDiscard(pool) ((pool)->ptr = (pool)->start) 00442 #define poolFinish(pool) ((pool)->start = (pool)->ptr) 00443 #define poolAppendChar(pool, c) \ 00444 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ 00445 ? 0 \ 00446 : ((*((pool)->ptr)++ = c), 1)) 00447 00448 struct XML_ParserStruct { 00449 /* The first member must be userData so that the XML_GetUserData 00450 macro works. */ 00451 void *m_userData; 00452 void *m_handlerArg; 00453 char *m_buffer; 00454 const XML_Memory_Handling_Suite m_mem; 00455 /* first character to be parsed */ 00456 const char *m_bufferPtr; 00457 /* past last character to be parsed */ 00458 char *m_bufferEnd; 00459 /* allocated end of buffer */ 00460 const char *m_bufferLim; 00461 XML_Index m_parseEndByteIndex; 00462 const char *m_parseEndPtr; 00463 XML_Char *m_dataBuf; 00464 XML_Char *m_dataBufEnd; 00465 XML_StartElementHandler m_startElementHandler; 00466 XML_EndElementHandler m_endElementHandler; 00467 XML_CharacterDataHandler m_characterDataHandler; 00468 XML_ProcessingInstructionHandler m_processingInstructionHandler; 00469 XML_CommentHandler m_commentHandler; 00470 XML_StartCdataSectionHandler m_startCdataSectionHandler; 00471 XML_EndCdataSectionHandler m_endCdataSectionHandler; 00472 XML_DefaultHandler m_defaultHandler; 00473 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; 00474 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; 00475 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; 00476 XML_NotationDeclHandler m_notationDeclHandler; 00477 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; 00478 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; 00479 XML_NotStandaloneHandler m_notStandaloneHandler; 00480 XML_ExternalEntityRefHandler m_externalEntityRefHandler; 00481 XML_Parser m_externalEntityRefHandlerArg; 00482 XML_SkippedEntityHandler m_skippedEntityHandler; 00483 XML_UnknownEncodingHandler m_unknownEncodingHandler; 00484 XML_ElementDeclHandler m_elementDeclHandler; 00485 XML_AttlistDeclHandler m_attlistDeclHandler; 00486 XML_EntityDeclHandler m_entityDeclHandler; 00487 XML_XmlDeclHandler m_xmlDeclHandler; 00488 const ENCODING *m_encoding; 00489 INIT_ENCODING m_initEncoding; 00490 const ENCODING *m_internalEncoding; 00491 const XML_Char *m_protocolEncodingName; 00492 XML_Bool m_ns; 00493 XML_Bool m_ns_triplets; 00494 void *m_unknownEncodingMem; 00495 void *m_unknownEncodingData; 00496 void *m_unknownEncodingHandlerData; 00497 void (XMLCALL *m_unknownEncodingRelease)(void *); 00498 PROLOG_STATE m_prologState; 00499 Processor *m_processor; 00500 enum XML_Error m_errorCode; 00501 const char *m_eventPtr; 00502 const char *m_eventEndPtr; 00503 const char *m_positionPtr; 00504 OPEN_INTERNAL_ENTITY *m_openInternalEntities; 00505 OPEN_INTERNAL_ENTITY *m_freeInternalEntities; 00506 XML_Bool m_defaultExpandInternalEntities; 00507 int m_tagLevel; 00508 ENTITY *m_declEntity; 00509 const XML_Char *m_doctypeName; 00510 const XML_Char *m_doctypeSysid; 00511 const XML_Char *m_doctypePubid; 00512 const XML_Char *m_declAttributeType; 00513 const XML_Char *m_declNotationName; 00514 const XML_Char *m_declNotationPublicId; 00515 ELEMENT_TYPE *m_declElementType; 00516 ATTRIBUTE_ID *m_declAttributeId; 00517 XML_Bool m_declAttributeIsCdata; 00518 XML_Bool m_declAttributeIsId; 00519 DTD *m_dtd; 00520 const XML_Char *m_curBase; 00521 TAG *m_tagStack; 00522 TAG *m_freeTagList; 00523 BINDING *m_inheritedBindings; 00524 BINDING *m_freeBindingList; 00525 int m_attsSize; 00526 int m_nSpecifiedAtts; 00527 int m_idAttIndex; 00528 ATTRIBUTE *m_atts; 00529 NS_ATT *m_nsAtts; 00530 unsigned long m_nsAttsVersion; 00531 unsigned char m_nsAttsPower; 00532 POSITION m_position; 00533 STRING_POOL m_tempPool; 00534 STRING_POOL m_temp2Pool; 00535 char *m_groupConnector; 00536 unsigned int m_groupSize; 00537 XML_Char m_namespaceSeparator; 00538 XML_Parser m_parentParser; 00539 XML_ParsingStatus m_parsingStatus; 00540 #ifdef XML_DTD 00541 XML_Bool m_isParamEntity; 00542 XML_Bool m_useForeignDTD; 00543 enum XML_ParamEntityParsing m_paramEntityParsing; 00544 #endif 00545 }; 00546 00547 #define MALLOC(s) (parser->m_mem.malloc_fcn((s))) 00548 #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s))) 00549 #define FREE(p) (parser->m_mem.free_fcn((p))) 00550 00551 #define userData (parser->m_userData) 00552 #define handlerArg (parser->m_handlerArg) 00553 #define startElementHandler (parser->m_startElementHandler) 00554 #define endElementHandler (parser->m_endElementHandler) 00555 #define characterDataHandler (parser->m_characterDataHandler) 00556 #define processingInstructionHandler \ 00557 (parser->m_processingInstructionHandler) 00558 #define commentHandler (parser->m_commentHandler) 00559 #define startCdataSectionHandler \ 00560 (parser->m_startCdataSectionHandler) 00561 #define endCdataSectionHandler (parser->m_endCdataSectionHandler) 00562 #define defaultHandler (parser->m_defaultHandler) 00563 #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler) 00564 #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler) 00565 #define unparsedEntityDeclHandler \ 00566 (parser->m_unparsedEntityDeclHandler) 00567 #define notationDeclHandler (parser->m_notationDeclHandler) 00568 #define startNamespaceDeclHandler \ 00569 (parser->m_startNamespaceDeclHandler) 00570 #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler) 00571 #define notStandaloneHandler (parser->m_notStandaloneHandler) 00572 #define externalEntityRefHandler \ 00573 (parser->m_externalEntityRefHandler) 00574 #define externalEntityRefHandlerArg \ 00575 (parser->m_externalEntityRefHandlerArg) 00576 #define internalEntityRefHandler \ 00577 (parser->m_internalEntityRefHandler) 00578 #define skippedEntityHandler (parser->m_skippedEntityHandler) 00579 #define unknownEncodingHandler (parser->m_unknownEncodingHandler) 00580 #define elementDeclHandler (parser->m_elementDeclHandler) 00581 #define attlistDeclHandler (parser->m_attlistDeclHandler) 00582 #define entityDeclHandler (parser->m_entityDeclHandler) 00583 #define xmlDeclHandler (parser->m_xmlDeclHandler) 00584 #define encoding (parser->m_encoding) 00585 #define initEncoding (parser->m_initEncoding) 00586 #define internalEncoding (parser->m_internalEncoding) 00587 #define unknownEncodingMem (parser->m_unknownEncodingMem) 00588 #define unknownEncodingData (parser->m_unknownEncodingData) 00589 #define unknownEncodingHandlerData \ 00590 (parser->m_unknownEncodingHandlerData) 00591 #define unknownEncodingRelease (parser->m_unknownEncodingRelease) 00592 #define protocolEncodingName (parser->m_protocolEncodingName) 00593 #define ns (parser->m_ns) 00594 #define ns_triplets (parser->m_ns_triplets) 00595 #define prologState (parser->m_prologState) 00596 #define processor (parser->m_processor) 00597 #define errorCode (parser->m_errorCode) 00598 #define eventPtr (parser->m_eventPtr) 00599 #define eventEndPtr (parser->m_eventEndPtr) 00600 #define positionPtr (parser->m_positionPtr) 00601 #define position (parser->m_position) 00602 #define openInternalEntities (parser->m_openInternalEntities) 00603 #define freeInternalEntities (parser->m_freeInternalEntities) 00604 #define defaultExpandInternalEntities \ 00605 (parser->m_defaultExpandInternalEntities) 00606 #define tagLevel (parser->m_tagLevel) 00607 #define buffer (parser->m_buffer) 00608 #define bufferPtr (parser->m_bufferPtr) 00609 #define bufferEnd (parser->m_bufferEnd) 00610 #define parseEndByteIndex (parser->m_parseEndByteIndex) 00611 #define parseEndPtr (parser->m_parseEndPtr) 00612 #define bufferLim (parser->m_bufferLim) 00613 #define dataBuf (parser->m_dataBuf) 00614 #define dataBufEnd (parser->m_dataBufEnd) 00615 #define _dtd (parser->m_dtd) 00616 #define curBase (parser->m_curBase) 00617 #define declEntity (parser->m_declEntity) 00618 #define doctypeName (parser->m_doctypeName) 00619 #define doctypeSysid (parser->m_doctypeSysid) 00620 #define doctypePubid (parser->m_doctypePubid) 00621 #define declAttributeType (parser->m_declAttributeType) 00622 #define declNotationName (parser->m_declNotationName) 00623 #define declNotationPublicId (parser->m_declNotationPublicId) 00624 #define declElementType (parser->m_declElementType) 00625 #define declAttributeId (parser->m_declAttributeId) 00626 #define declAttributeIsCdata (parser->m_declAttributeIsCdata) 00627 #define declAttributeIsId (parser->m_declAttributeIsId) 00628 #define freeTagList (parser->m_freeTagList) 00629 #define freeBindingList (parser->m_freeBindingList) 00630 #define inheritedBindings (parser->m_inheritedBindings) 00631 #define tagStack (parser->m_tagStack) 00632 #define atts (parser->m_atts) 00633 #define attsSize (parser->m_attsSize) 00634 #define nSpecifiedAtts (parser->m_nSpecifiedAtts) 00635 #define idAttIndex (parser->m_idAttIndex) 00636 #define nsAtts (parser->m_nsAtts) 00637 #define nsAttsVersion (parser->m_nsAttsVersion) 00638 #define nsAttsPower (parser->m_nsAttsPower) 00639 #define tempPool (parser->m_tempPool) 00640 #define temp2Pool (parser->m_temp2Pool) 00641 #define groupConnector (parser->m_groupConnector) 00642 #define groupSize (parser->m_groupSize) 00643 #define namespaceSeparator (parser->m_namespaceSeparator) 00644 #define parentParser (parser->m_parentParser) 00645 #define ps_parsing (parser->m_parsingStatus.parsing) 00646 #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer) 00647 #ifdef XML_DTD 00648 #define isParamEntity (parser->m_isParamEntity) 00649 #define useForeignDTD (parser->m_useForeignDTD) 00650 #define paramEntityParsing (parser->m_paramEntityParsing) 00651 #endif /* XML_DTD */ 00652 00653 XML_Parser XMLCALL 00654 XML_ParserCreate(const XML_Char *encodingName) 00655 { 00656 return XML_ParserCreate_MM(encodingName, NULL, NULL); 00657 } 00658 00659 XML_Parser XMLCALL 00660 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) 00661 { 00662 XML_Char tmp[2]; 00663 *tmp = nsSep; 00664 return XML_ParserCreate_MM(encodingName, NULL, tmp); 00665 } 00666 00667 static const XML_Char implicitContext[] = { 00668 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/', 00669 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/', 00670 'X', 'M', 'L', '/', '1', '9', '9', '8', '/', 00671 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0' 00672 }; 00673 00674 XML_Parser XMLCALL 00675 XML_ParserCreate_MM(const XML_Char *encodingName, 00676 const XML_Memory_Handling_Suite *memsuite, 00677 const XML_Char *nameSep) 00678 { 00679 XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL); 00680 if (parser != NULL && ns) { 00681 /* implicit context only set for root parser, since child 00682 parsers (i.e. external entity parsers) will inherit it 00683 */ 00684 if (!setContext(parser, implicitContext)) { 00685 XML_ParserFree(parser); 00686 return NULL; 00687 } 00688 } 00689 return parser; 00690 } 00691 00692 static XML_Parser 00693 parserCreate(const XML_Char *encodingName, 00694 const XML_Memory_Handling_Suite *memsuite, 00695 const XML_Char *nameSep, 00696 DTD *dtd) 00697 { 00698 XML_Parser parser; 00699 00700 if (memsuite) { 00701 XML_Memory_Handling_Suite *mtemp; 00702 parser = (XML_Parser) 00703 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); 00704 if (parser != NULL) { 00705 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); 00706 mtemp->malloc_fcn = memsuite->malloc_fcn; 00707 mtemp->realloc_fcn = memsuite->realloc_fcn; 00708 mtemp->free_fcn = memsuite->free_fcn; 00709 } 00710 } 00711 else { 00712 XML_Memory_Handling_Suite *mtemp; 00713 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); 00714 if (parser != NULL) { 00715 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); 00716 mtemp->malloc_fcn = malloc; 00717 mtemp->realloc_fcn = realloc; 00718 mtemp->free_fcn = free; 00719 } 00720 } 00721 00722 if (!parser) 00723 return parser; 00724 00725 buffer = NULL; 00726 bufferLim = NULL; 00727 00728 attsSize = INIT_ATTS_SIZE; 00729 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE)); 00730 if (atts == NULL) { 00731 FREE(parser); 00732 return NULL; 00733 } 00734 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); 00735 if (dataBuf == NULL) { 00736 FREE(atts); 00737 FREE(parser); 00738 return NULL; 00739 } 00740 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; 00741 00742 if (dtd) 00743 _dtd = dtd; 00744 else { 00745 _dtd = dtdCreate(&parser->m_mem); 00746 if (_dtd == NULL) { 00747 FREE(dataBuf); 00748 FREE(atts); 00749 FREE(parser); 00750 return NULL; 00751 } 00752 } 00753 00754 freeBindingList = NULL; 00755 freeTagList = NULL; 00756 freeInternalEntities = NULL; 00757 00758 groupSize = 0; 00759 groupConnector = NULL; 00760 00761 unknownEncodingHandler = NULL; 00762 unknownEncodingHandlerData = NULL; 00763 00764 namespaceSeparator = '!'; 00765 ns = XML_FALSE; 00766 ns_triplets = XML_FALSE; 00767 00768 nsAtts = NULL; 00769 nsAttsVersion = 0; 00770 nsAttsPower = 0; 00771 00772 poolInit(&tempPool, &(parser->m_mem)); 00773 poolInit(&temp2Pool, &(parser->m_mem)); 00774 parserInit(parser, encodingName); 00775 00776 if (encodingName && !protocolEncodingName) { 00777 XML_ParserFree(parser); 00778 return NULL; 00779 } 00780 00781 if (nameSep) { 00782 ns = XML_TRUE; 00783 internalEncoding = XmlGetInternalEncodingNS(); 00784 namespaceSeparator = *nameSep; 00785 } 00786 else { 00787 internalEncoding = XmlGetInternalEncoding(); 00788 } 00789 00790 return parser; 00791 } 00792 00793 static void 00794 parserInit(XML_Parser parser, const XML_Char *encodingName) 00795 { 00796 processor = prologInitProcessor; 00797 XmlPrologStateInit(&prologState); 00798 protocolEncodingName = (encodingName != NULL 00799 ? poolCopyString(&tempPool, encodingName) 00800 : NULL); 00801 curBase = NULL; 00802 XmlInitEncoding(&initEncoding, &encoding, 0); 00803 userData = NULL; 00804 handlerArg = NULL; 00805 startElementHandler = NULL; 00806 endElementHandler = NULL; 00807 characterDataHandler = NULL; 00808 processingInstructionHandler = NULL; 00809 commentHandler = NULL; 00810 startCdataSectionHandler = NULL; 00811 endCdataSectionHandler = NULL; 00812 defaultHandler = NULL; 00813 startDoctypeDeclHandler = NULL; 00814 endDoctypeDeclHandler = NULL; 00815 unparsedEntityDeclHandler = NULL; 00816 notationDeclHandler = NULL; 00817 startNamespaceDeclHandler = NULL; 00818 endNamespaceDeclHandler = NULL; 00819 notStandaloneHandler = NULL; 00820 externalEntityRefHandler = NULL; 00821 externalEntityRefHandlerArg = parser; 00822 skippedEntityHandler = NULL; 00823 elementDeclHandler = NULL; 00824 attlistDeclHandler = NULL; 00825 entityDeclHandler = NULL; 00826 xmlDeclHandler = NULL; 00827 bufferPtr = buffer; 00828 bufferEnd = buffer; 00829 parseEndByteIndex = 0; 00830 parseEndPtr = NULL; 00831 declElementType = NULL; 00832 declAttributeId = NULL; 00833 declEntity = NULL; 00834 doctypeName = NULL; 00835 doctypeSysid = NULL; 00836 doctypePubid = NULL; 00837 declAttributeType = NULL; 00838 declNotationName = NULL; 00839 declNotationPublicId = NULL; 00840 declAttributeIsCdata = XML_FALSE; 00841 declAttributeIsId = XML_FALSE; 00842 memset(&position, 0, sizeof(POSITION)); 00843 errorCode = XML_ERROR_NONE; 00844 eventPtr = NULL; 00845 eventEndPtr = NULL; 00846 positionPtr = NULL; 00847 openInternalEntities = NULL; 00848 defaultExpandInternalEntities = XML_TRUE; 00849 tagLevel = 0; 00850 tagStack = NULL; 00851 inheritedBindings = NULL; 00852 nSpecifiedAtts = 0; 00853 unknownEncodingMem = NULL; 00854 unknownEncodingRelease = NULL; 00855 unknownEncodingData = NULL; 00856 parentParser = NULL; 00857 ps_parsing = XML_INITIALIZED; 00858 #ifdef XML_DTD 00859 isParamEntity = XML_FALSE; 00860 useForeignDTD = XML_FALSE; 00861 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 00862 #endif 00863 } 00864 00865 /* moves list of bindings to freeBindingList */ 00866 static void FASTCALL 00867 moveToFreeBindingList(XML_Parser parser, BINDING *bindings) 00868 { 00869 while (bindings) { 00870 BINDING *b = bindings; 00871 bindings = bindings->nextTagBinding; 00872 b->nextTagBinding = freeBindingList; 00873 freeBindingList = b; 00874 } 00875 } 00876 00877 XML_Bool XMLCALL 00878 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) 00879 { 00880 TAG *tStk; 00881 OPEN_INTERNAL_ENTITY *openEntityList; 00882 if (parentParser) 00883 return XML_FALSE; 00884 /* move tagStack to freeTagList */ 00885 tStk = tagStack; 00886 while (tStk) { 00887 TAG *tag = tStk; 00888 tStk = tStk->parent; 00889 tag->parent = freeTagList; 00890 moveToFreeBindingList(parser, tag->bindings); 00891 tag->bindings = NULL; 00892 freeTagList = tag; 00893 } 00894 /* move openInternalEntities to freeInternalEntities */ 00895 openEntityList = openInternalEntities; 00896 while (openEntityList) { 00897 OPEN_INTERNAL_ENTITY *openEntity = openEntityList; 00898 openEntityList = openEntity->next; 00899 openEntity->next = freeInternalEntities; 00900 freeInternalEntities = openEntity; 00901 } 00902 moveToFreeBindingList(parser, inheritedBindings); 00903 FREE(unknownEncodingMem); 00904 if (unknownEncodingRelease) 00905 unknownEncodingRelease(unknownEncodingData); 00906 poolClear(&tempPool); 00907 poolClear(&temp2Pool); 00908 parserInit(parser, encodingName); 00909 dtdReset(_dtd, &parser->m_mem); 00910 return setContext(parser, implicitContext); 00911 } 00912 00913 enum XML_Status XMLCALL 00914 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) 00915 { 00916 /* Block after XML_Parse()/XML_ParseBuffer() has been called. 00917 XXX There's no way for the caller to determine which of the 00918 XXX possible error cases caused the XML_STATUS_ERROR return. 00919 */ 00920 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 00921 return XML_STATUS_ERROR; 00922 if (encodingName == NULL) 00923 protocolEncodingName = NULL; 00924 else { 00925 protocolEncodingName = poolCopyString(&tempPool, encodingName); 00926 if (!protocolEncodingName) 00927 return XML_STATUS_ERROR; 00928 } 00929 return XML_STATUS_OK; 00930 } 00931 00932 XML_Parser XMLCALL 00933 XML_ExternalEntityParserCreate(XML_Parser oldParser, 00934 const XML_Char *context, 00935 const XML_Char *encodingName) 00936 { 00937 XML_Parser parser = oldParser; 00938 DTD *newDtd = NULL; 00939 DTD *oldDtd = _dtd; 00940 XML_StartElementHandler oldStartElementHandler = startElementHandler; 00941 XML_EndElementHandler oldEndElementHandler = endElementHandler; 00942 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; 00943 XML_ProcessingInstructionHandler oldProcessingInstructionHandler 00944 = processingInstructionHandler; 00945 XML_CommentHandler oldCommentHandler = commentHandler; 00946 XML_StartCdataSectionHandler oldStartCdataSectionHandler 00947 = startCdataSectionHandler; 00948 XML_EndCdataSectionHandler oldEndCdataSectionHandler 00949 = endCdataSectionHandler; 00950 XML_DefaultHandler oldDefaultHandler = defaultHandler; 00951 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler 00952 = unparsedEntityDeclHandler; 00953 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; 00954 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler 00955 = startNamespaceDeclHandler; 00956 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler 00957 = endNamespaceDeclHandler; 00958 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; 00959 XML_ExternalEntityRefHandler oldExternalEntityRefHandler 00960 = externalEntityRefHandler; 00961 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler; 00962 XML_UnknownEncodingHandler oldUnknownEncodingHandler 00963 = unknownEncodingHandler; 00964 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; 00965 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; 00966 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler; 00967 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler; 00968 ELEMENT_TYPE * oldDeclElementType = declElementType; 00969 00970 void *oldUserData = userData; 00971 void *oldHandlerArg = handlerArg; 00972 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities; 00973 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; 00974 #ifdef XML_DTD 00975 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing; 00976 int oldInEntityValue = prologState.inEntityValue; 00977 #endif 00978 XML_Bool oldns_triplets = ns_triplets; 00979 00980 #ifdef XML_DTD 00981 if (!context) 00982 newDtd = oldDtd; 00983 #endif /* XML_DTD */ 00984 00985 /* Note that the magical uses of the pre-processor to make field 00986 access look more like C++ require that `parser' be overwritten 00987 here. This makes this function more painful to follow than it 00988 would be otherwise. 00989 */ 00990 if (ns) { 00991 XML_Char tmp[2]; 00992 *tmp = namespaceSeparator; 00993 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); 00994 } 00995 else { 00996 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); 00997 } 00998 00999 if (!parser) 01000 return NULL; 01001 01002 startElementHandler = oldStartElementHandler; 01003 endElementHandler = oldEndElementHandler; 01004 characterDataHandler = oldCharacterDataHandler; 01005 processingInstructionHandler = oldProcessingInstructionHandler; 01006 commentHandler = oldCommentHandler; 01007 startCdataSectionHandler = oldStartCdataSectionHandler; 01008 endCdataSectionHandler = oldEndCdataSectionHandler; 01009 defaultHandler = oldDefaultHandler; 01010 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; 01011 notationDeclHandler = oldNotationDeclHandler; 01012 startNamespaceDeclHandler = oldStartNamespaceDeclHandler; 01013 endNamespaceDeclHandler = oldEndNamespaceDeclHandler; 01014 notStandaloneHandler = oldNotStandaloneHandler; 01015 externalEntityRefHandler = oldExternalEntityRefHandler; 01016 skippedEntityHandler = oldSkippedEntityHandler; 01017 unknownEncodingHandler = oldUnknownEncodingHandler; 01018 elementDeclHandler = oldElementDeclHandler; 01019 attlistDeclHandler = oldAttlistDeclHandler; 01020 entityDeclHandler = oldEntityDeclHandler; 01021 xmlDeclHandler = oldXmlDeclHandler; 01022 declElementType = oldDeclElementType; 01023 userData = oldUserData; 01024 if (oldUserData == oldHandlerArg) 01025 handlerArg = userData; 01026 else 01027 handlerArg = parser; 01028 if (oldExternalEntityRefHandlerArg != oldParser) 01029 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; 01030 defaultExpandInternalEntities = oldDefaultExpandInternalEntities; 01031 ns_triplets = oldns_triplets; 01032 parentParser = oldParser; 01033 #ifdef XML_DTD 01034 paramEntityParsing = oldParamEntityParsing; 01035 prologState.inEntityValue = oldInEntityValue; 01036 if (context) { 01037 #endif /* XML_DTD */ 01038 if (!dtdCopy(_dtd, oldDtd, &parser->m_mem) 01039 || !setContext(parser, context)) { 01040 XML_ParserFree(parser); 01041 return NULL; 01042 } 01043 processor = externalEntityInitProcessor; 01044 #ifdef XML_DTD 01045 } 01046 else { 01047 /* The DTD instance referenced by _dtd is shared between the document's 01048 root parser and external PE parsers, therefore one does not need to 01049 call setContext. In addition, one also *must* not call setContext, 01050 because this would overwrite existing prefix->binding pointers in 01051 _dtd with ones that get destroyed with the external PE parser. 01052 This would leave those prefixes with dangling pointers. 01053 */ 01054 isParamEntity = XML_TRUE; 01055 XmlPrologStateInitExternalEntity(&prologState); 01056 processor = externalParEntInitProcessor; 01057 } 01058 #endif /* XML_DTD */ 01059 return parser; 01060 } 01061 01062 static void FASTCALL 01063 destroyBindings(BINDING *bindings, XML_Parser parser) 01064 { 01065 for (;;) { 01066 BINDING *b = bindings; 01067 if (!b) 01068 break; 01069 bindings = b->nextTagBinding; 01070 FREE(b->uri); 01071 FREE(b); 01072 } 01073 } 01074 01075 void XMLCALL 01076 XML_ParserFree(XML_Parser parser) 01077 { 01078 TAG *tagList; 01079 OPEN_INTERNAL_ENTITY *entityList; 01080 if (parser == NULL) 01081 return; 01082 /* free tagStack and freeTagList */ 01083 tagList = tagStack; 01084 for (;;) { 01085 TAG *p; 01086 if (tagList == NULL) { 01087 if (freeTagList == NULL) 01088 break; 01089 tagList = freeTagList; 01090 freeTagList = NULL; 01091 } 01092 p = tagList; 01093 tagList = tagList->parent; 01094 FREE(p->buf); 01095 destroyBindings(p->bindings, parser); 01096 FREE(p); 01097 } 01098 /* free openInternalEntities and freeInternalEntities */ 01099 entityList = openInternalEntities; 01100 for (;;) { 01101 OPEN_INTERNAL_ENTITY *openEntity; 01102 if (entityList == NULL) { 01103 if (freeInternalEntities == NULL) 01104 break; 01105 entityList = freeInternalEntities; 01106 freeInternalEntities = NULL; 01107 } 01108 openEntity = entityList; 01109 entityList = entityList->next; 01110 FREE(openEntity); 01111 } 01112 01113 destroyBindings(freeBindingList, parser); 01114 destroyBindings(inheritedBindings, parser); 01115 poolDestroy(&tempPool); 01116 poolDestroy(&temp2Pool); 01117 #ifdef XML_DTD 01118 /* external parameter entity parsers share the DTD structure 01119 parser->m_dtd with the root parser, so we must not destroy it 01120 */ 01121 if (!isParamEntity && _dtd) 01122 #else 01123 if (_dtd) 01124 #endif /* XML_DTD */ 01125 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem); 01126 FREE((void *)atts); 01127 FREE(groupConnector); 01128 FREE(buffer); 01129 FREE(dataBuf); 01130 FREE(nsAtts); 01131 FREE(unknownEncodingMem); 01132 if (unknownEncodingRelease) 01133 unknownEncodingRelease(unknownEncodingData); 01134 FREE(parser); 01135 } 01136 01137 void XMLCALL 01138 XML_UseParserAsHandlerArg(XML_Parser parser) 01139 { 01140 handlerArg = parser; 01141 } 01142 01143 enum XML_Error XMLCALL 01144 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) 01145 { 01146 #ifdef XML_DTD 01147 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 01148 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 01149 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; 01150 useForeignDTD = useDTD; 01151 return XML_ERROR_NONE; 01152 #else 01153 return XML_ERROR_FEATURE_REQUIRES_XML_DTD; 01154 #endif 01155 } 01156 01157 void XMLCALL 01158 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) 01159 { 01160 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 01161 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 01162 return; 01163 ns_triplets = do_nst ? XML_TRUE : XML_FALSE; 01164 } 01165 01166 void XMLCALL 01167 XML_SetUserData(XML_Parser parser, void *p) 01168 { 01169 if (handlerArg == userData) 01170 handlerArg = userData = p; 01171 else 01172 userData = p; 01173 } 01174 01175 enum XML_Status XMLCALL 01176 XML_SetBase(XML_Parser parser, const XML_Char *p) 01177 { 01178 if (p) { 01179 p = poolCopyString(&_dtd->pool, p); 01180 if (!p) 01181 return XML_STATUS_ERROR; 01182 curBase = p; 01183 } 01184 else 01185 curBase = NULL; 01186 return XML_STATUS_OK; 01187 } 01188 01189 const XML_Char * XMLCALL 01190 XML_GetBase(XML_Parser parser) 01191 { 01192 return curBase; 01193 } 01194 01195 int XMLCALL 01196 XML_GetSpecifiedAttributeCount(XML_Parser parser) 01197 { 01198 return nSpecifiedAtts; 01199 } 01200 01201 int XMLCALL 01202 XML_GetIdAttributeIndex(XML_Parser parser) 01203 { 01204 return idAttIndex; 01205 } 01206 01207 void XMLCALL 01208 XML_SetElementHandler(XML_Parser parser, 01209 XML_StartElementHandler start, 01210 XML_EndElementHandler end) 01211 { 01212 startElementHandler = start; 01213 endElementHandler = end; 01214 } 01215 01216 void XMLCALL 01217 XML_SetStartElementHandler(XML_Parser parser, 01218 XML_StartElementHandler start) { 01219 startElementHandler = start; 01220 } 01221 01222 void XMLCALL 01223 XML_SetEndElementHandler(XML_Parser parser, 01224 XML_EndElementHandler end) { 01225 endElementHandler = end; 01226 } 01227 01228 void XMLCALL 01229 XML_SetCharacterDataHandler(XML_Parser parser, 01230 XML_CharacterDataHandler handler) 01231 { 01232 characterDataHandler = handler; 01233 } 01234 01235 void XMLCALL 01236 XML_SetProcessingInstructionHandler(XML_Parser parser, 01237 XML_ProcessingInstructionHandler handler) 01238 { 01239 processingInstructionHandler = handler; 01240 } 01241 01242 void XMLCALL 01243 XML_SetCommentHandler(XML_Parser parser, 01244 XML_CommentHandler handler) 01245 { 01246 commentHandler = handler; 01247 } 01248 01249 void XMLCALL 01250 XML_SetCdataSectionHandler(XML_Parser parser, 01251 XML_StartCdataSectionHandler start, 01252 XML_EndCdataSectionHandler end) 01253 { 01254 startCdataSectionHandler = start; 01255 endCdataSectionHandler = end; 01256 } 01257 01258 void XMLCALL 01259 XML_SetStartCdataSectionHandler(XML_Parser parser, 01260 XML_StartCdataSectionHandler start) { 01261 startCdataSectionHandler = start; 01262 } 01263 01264 void XMLCALL 01265 XML_SetEndCdataSectionHandler(XML_Parser parser, 01266 XML_EndCdataSectionHandler end) { 01267 endCdataSectionHandler = end; 01268 } 01269 01270 void XMLCALL 01271 XML_SetDefaultHandler(XML_Parser parser, 01272 XML_DefaultHandler handler) 01273 { 01274 defaultHandler = handler; 01275 defaultExpandInternalEntities = XML_FALSE; 01276 } 01277 01278 void XMLCALL 01279 XML_SetDefaultHandlerExpand(XML_Parser parser, 01280 XML_DefaultHandler handler) 01281 { 01282 defaultHandler = handler; 01283 defaultExpandInternalEntities = XML_TRUE; 01284 } 01285 01286 void XMLCALL 01287 XML_SetDoctypeDeclHandler(XML_Parser parser, 01288 XML_StartDoctypeDeclHandler start, 01289 XML_EndDoctypeDeclHandler end) 01290 { 01291 startDoctypeDeclHandler = start; 01292 endDoctypeDeclHandler = end; 01293 } 01294 01295 void XMLCALL 01296 XML_SetStartDoctypeDeclHandler(XML_Parser parser, 01297 XML_StartDoctypeDeclHandler start) { 01298 startDoctypeDeclHandler = start; 01299 } 01300 01301 void XMLCALL 01302 XML_SetEndDoctypeDeclHandler(XML_Parser parser, 01303 XML_EndDoctypeDeclHandler end) { 01304 endDoctypeDeclHandler = end; 01305 } 01306 01307 void XMLCALL 01308 XML_SetUnparsedEntityDeclHandler(XML_Parser parser, 01309 XML_UnparsedEntityDeclHandler handler) 01310 { 01311 unparsedEntityDeclHandler = handler; 01312 } 01313 01314 void XMLCALL 01315 XML_SetNotationDeclHandler(XML_Parser parser, 01316 XML_NotationDeclHandler handler) 01317 { 01318 notationDeclHandler = handler; 01319 } 01320 01321 void XMLCALL 01322 XML_SetNamespaceDeclHandler(XML_Parser parser, 01323 XML_StartNamespaceDeclHandler start, 01324 XML_EndNamespaceDeclHandler end) 01325 { 01326 startNamespaceDeclHandler = start; 01327 endNamespaceDeclHandler = end; 01328 } 01329 01330 void XMLCALL 01331 XML_SetStartNamespaceDeclHandler(XML_Parser parser, 01332 XML_StartNamespaceDeclHandler start) { 01333 startNamespaceDeclHandler = start; 01334 } 01335 01336 void XMLCALL 01337 XML_SetEndNamespaceDeclHandler(XML_Parser parser, 01338 XML_EndNamespaceDeclHandler end) { 01339 endNamespaceDeclHandler = end; 01340 } 01341 01342 void XMLCALL 01343 XML_SetNotStandaloneHandler(XML_Parser parser, 01344 XML_NotStandaloneHandler handler) 01345 { 01346 notStandaloneHandler = handler; 01347 } 01348 01349 void XMLCALL 01350 XML_SetExternalEntityRefHandler(XML_Parser parser, 01351 XML_ExternalEntityRefHandler handler) 01352 { 01353 externalEntityRefHandler = handler; 01354 } 01355 01356 void XMLCALL 01357 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) 01358 { 01359 if (arg) 01360 externalEntityRefHandlerArg = (XML_Parser)arg; 01361 else 01362 externalEntityRefHandlerArg = parser; 01363 } 01364 01365 void XMLCALL 01366 XML_SetSkippedEntityHandler(XML_Parser parser, 01367 XML_SkippedEntityHandler handler) 01368 { 01369 skippedEntityHandler = handler; 01370 } 01371 01372 void XMLCALL 01373 XML_SetUnknownEncodingHandler(XML_Parser parser, 01374 XML_UnknownEncodingHandler handler, 01375 void *data) 01376 { 01377 unknownEncodingHandler = handler; 01378 unknownEncodingHandlerData = data; 01379 } 01380 01381 void XMLCALL 01382 XML_SetElementDeclHandler(XML_Parser parser, 01383 XML_ElementDeclHandler eldecl) 01384 { 01385 elementDeclHandler = eldecl; 01386 } 01387 01388 void XMLCALL 01389 XML_SetAttlistDeclHandler(XML_Parser parser, 01390 XML_AttlistDeclHandler attdecl) 01391 { 01392 attlistDeclHandler = attdecl; 01393 } 01394 01395 void XMLCALL 01396 XML_SetEntityDeclHandler(XML_Parser parser, 01397 XML_EntityDeclHandler handler) 01398 { 01399 entityDeclHandler = handler; 01400 } 01401 01402 void XMLCALL 01403 XML_SetXmlDeclHandler(XML_Parser parser, 01404 XML_XmlDeclHandler handler) { 01405 xmlDeclHandler = handler; 01406 } 01407 01408 int XMLCALL 01409 XML_SetParamEntityParsing(XML_Parser parser, 01410 enum XML_ParamEntityParsing peParsing) 01411 { 01412 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 01413 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) 01414 return 0; 01415 #ifdef XML_DTD 01416 paramEntityParsing = peParsing; 01417 return 1; 01418 #else 01419 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; 01420 #endif 01421 } 01422 01423 enum XML_Status XMLCALL 01424 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) 01425 { 01426 switch (ps_parsing) { 01427 case XML_SUSPENDED: 01428 errorCode = XML_ERROR_SUSPENDED; 01429 return XML_STATUS_ERROR; 01430 case XML_FINISHED: 01431 errorCode = XML_ERROR_FINISHED; 01432 return XML_STATUS_ERROR; 01433 default: 01434 ps_parsing = XML_PARSING; 01435 } 01436 01437 if (len == 0) { 01438 ps_finalBuffer = (XML_Bool)isFinal; 01439 if (!isFinal) 01440 return XML_STATUS_OK; 01441 positionPtr = bufferPtr; 01442 parseEndPtr = bufferEnd; 01443 01444 /* If data are left over from last buffer, and we now know that these 01445 data are the final chunk of input, then we have to check them again 01446 to detect errors based on that fact. 01447 */ 01448 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); 01449 01450 if (errorCode == XML_ERROR_NONE) { 01451 switch (ps_parsing) { 01452 case XML_SUSPENDED: 01453 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); 01454 positionPtr = bufferPtr; 01455 return XML_STATUS_SUSPENDED; 01456 case XML_INITIALIZED: 01457 case XML_PARSING: 01458 ps_parsing = XML_FINISHED; 01459 /* fall through */ 01460 default: 01461 return XML_STATUS_OK; 01462 } 01463 } 01464 eventEndPtr = eventPtr; 01465 processor = errorProcessor; 01466 return XML_STATUS_ERROR; 01467 } 01468 #ifndef XML_CONTEXT_BYTES 01469 else if (bufferPtr == bufferEnd) { 01470 const char *end; 01471 int nLeftOver; 01472 enum XML_Error result; 01473 parseEndByteIndex += len; 01474 positionPtr = s; 01475 ps_finalBuffer = (XML_Bool)isFinal; 01476 01477 errorCode = processor(parser, s, parseEndPtr = s + len, &end); 01478 01479 if (errorCode != XML_ERROR_NONE) { 01480 eventEndPtr = eventPtr; 01481 processor = errorProcessor; 01482 return XML_STATUS_ERROR; 01483 } 01484 else { 01485 switch (ps_parsing) { 01486 case XML_SUSPENDED: 01487 result = XML_STATUS_SUSPENDED; 01488 break; 01489 case XML_INITIALIZED: 01490 case XML_PARSING: 01491 result = XML_STATUS_OK; 01492 if (isFinal) { 01493 ps_parsing = XML_FINISHED; 01494 return result; 01495 } 01496 } 01497 } 01498 01499 XmlUpdatePosition(encoding, positionPtr, end, &position); 01500 nLeftOver = s + len - end; 01501 if (nLeftOver) { 01502 if (buffer == NULL || nLeftOver > bufferLim - buffer) { 01503 /* FIXME avoid integer overflow */ 01504 char *temp; 01505 temp = (buffer == NULL 01506 ? (char *)MALLOC(len * 2) 01507 : (char *)REALLOC(buffer, len * 2)); 01508 if (temp == NULL) { 01509 errorCode = XML_ERROR_NO_MEMORY; 01510 return XML_STATUS_ERROR; 01511 } 01512 buffer = temp; 01513 if (!buffer) { 01514 errorCode = XML_ERROR_NO_MEMORY; 01515 eventPtr = eventEndPtr = NULL; 01516 processor = errorProcessor; 01517 return XML_STATUS_ERROR; 01518 } 01519 bufferLim = buffer + len * 2; 01520 } 01521 memcpy(buffer, end, nLeftOver); 01522 } 01523 bufferPtr = buffer; 01524 bufferEnd = buffer + nLeftOver; 01525 positionPtr = bufferPtr; 01526 parseEndPtr = bufferEnd; 01527 eventPtr = bufferPtr; 01528 eventEndPtr = bufferPtr; 01529 return result; 01530 } 01531 #endif /* not defined XML_CONTEXT_BYTES */ 01532 else { 01533 void *buff = XML_GetBuffer(parser, len); 01534 if (buff == NULL) 01535 return XML_STATUS_ERROR; 01536 else { 01537 memcpy(buff, s, len); 01538 return XML_ParseBuffer(parser, len, isFinal); 01539 } 01540 } 01541 } 01542 01543 enum XML_Status XMLCALL 01544 XML_ParseBuffer(XML_Parser parser, int len, int isFinal) 01545 { 01546 const char *start; 01547 enum XML_Status result = XML_STATUS_OK; 01548 01549 switch (ps_parsing) { 01550 case XML_SUSPENDED: 01551 errorCode = XML_ERROR_SUSPENDED; 01552 return XML_STATUS_ERROR; 01553 case XML_FINISHED: 01554 errorCode = XML_ERROR_FINISHED; 01555 return XML_STATUS_ERROR; 01556 default: 01557 ps_parsing = XML_PARSING; 01558 } 01559 01560 start = bufferPtr; 01561 positionPtr = start; 01562 bufferEnd += len; 01563 parseEndPtr = bufferEnd; 01564 parseEndByteIndex += len; 01565 ps_finalBuffer = (XML_Bool)isFinal; 01566 01567 errorCode = processor(parser, start, parseEndPtr, &bufferPtr); 01568 01569 if (errorCode != XML_ERROR_NONE) { 01570 eventEndPtr = eventPtr; 01571 processor = errorProcessor; 01572 return XML_STATUS_ERROR; 01573 } 01574 else { 01575 switch (ps_parsing) { 01576 case XML_SUSPENDED: 01577 result = XML_STATUS_SUSPENDED; 01578 break; 01579 case XML_INITIALIZED: 01580 case XML_PARSING: 01581 if (isFinal) { 01582 ps_parsing = XML_FINISHED; 01583 return result; 01584 } 01585 default: ; /* should not happen */ 01586 } 01587 } 01588 01589 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); 01590 positionPtr = bufferPtr; 01591 return result; 01592 } 01593 01594 void * XMLCALL 01595 XML_GetBuffer(XML_Parser parser, int len) 01596 { 01597 switch (ps_parsing) { 01598 case XML_SUSPENDED: 01599 errorCode = XML_ERROR_SUSPENDED; 01600 return NULL; 01601 case XML_FINISHED: 01602 errorCode = XML_ERROR_FINISHED; 01603 return NULL; 01604 default: ; 01605 } 01606 01607 if (len > bufferLim - bufferEnd) { 01608 /* FIXME avoid integer overflow */ 01609 int neededSize = len + (int)(bufferEnd - bufferPtr); 01610 #ifdef XML_CONTEXT_BYTES 01611 int keep = (int)(bufferPtr - buffer); 01612 01613 if (keep > XML_CONTEXT_BYTES) 01614 keep = XML_CONTEXT_BYTES; 01615 neededSize += keep; 01616 #endif /* defined XML_CONTEXT_BYTES */ 01617 if (neededSize <= bufferLim - buffer) { 01618 #ifdef XML_CONTEXT_BYTES 01619 if (keep < bufferPtr - buffer) { 01620 int offset = (int)(bufferPtr - buffer) - keep; 01621 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep); 01622 bufferEnd -= offset; 01623 bufferPtr -= offset; 01624 } 01625 #else 01626 memmove(buffer, bufferPtr, bufferEnd - bufferPtr); 01627 bufferEnd = buffer + (bufferEnd - bufferPtr); 01628 bufferPtr = buffer; 01629 #endif /* not defined XML_CONTEXT_BYTES */ 01630 } 01631 else { 01632 char *newBuf; 01633 int bufferSize = (int)(bufferLim - bufferPtr); 01634 if (bufferSize == 0) 01635 bufferSize = INIT_BUFFER_SIZE; 01636 do { 01637 bufferSize *= 2; 01638 } while (bufferSize < neededSize); 01639 newBuf = (char *)MALLOC(bufferSize); 01640 if (newBuf == 0) { 01641 errorCode = XML_ERROR_NO_MEMORY; 01642 return NULL; 01643 } 01644 bufferLim = newBuf + bufferSize; 01645 #ifdef XML_CONTEXT_BYTES 01646 if (bufferPtr) { 01647 int keep = (int)(bufferPtr - buffer); 01648 if (keep > XML_CONTEXT_BYTES) 01649 keep = XML_CONTEXT_BYTES; 01650 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep); 01651 FREE(buffer); 01652 buffer = newBuf; 01653 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep; 01654 bufferPtr = buffer + keep; 01655 } 01656 else { 01657 bufferEnd = newBuf + (bufferEnd - bufferPtr); 01658 bufferPtr = buffer = newBuf; 01659 } 01660 #else 01661 if (bufferPtr) { 01662 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); 01663 FREE(buffer); 01664 } 01665 bufferEnd = newBuf + (bufferEnd - bufferPtr); 01666 bufferPtr = buffer = newBuf; 01667 #endif /* not defined XML_CONTEXT_BYTES */ 01668 } 01669 } 01670 return bufferEnd; 01671 } 01672 01673 enum XML_Status XMLCALL 01674 XML_StopParser(XML_Parser parser, XML_Bool resumable) 01675 { 01676 switch (ps_parsing) { 01677 case XML_SUSPENDED: 01678 if (resumable) { 01679 errorCode = XML_ERROR_SUSPENDED; 01680 return XML_STATUS_ERROR; 01681 } 01682 ps_parsing = XML_FINISHED; 01683 break; 01684 case XML_FINISHED: 01685 errorCode = XML_ERROR_FINISHED; 01686 return XML_STATUS_ERROR; 01687 default: 01688 if (resumable) { 01689 #ifdef XML_DTD 01690 if (isParamEntity) { 01691 errorCode = XML_ERROR_SUSPEND_PE; 01692 return XML_STATUS_ERROR; 01693 } 01694 #endif 01695 ps_parsing = XML_SUSPENDED; 01696 } 01697 else 01698 ps_parsing = XML_FINISHED; 01699 } 01700 return XML_STATUS_OK; 01701 } 01702 01703 enum XML_Status XMLCALL 01704 XML_ResumeParser(XML_Parser parser) 01705 { 01706 enum XML_Status result = XML_STATUS_OK; 01707 01708 if (ps_parsing != XML_SUSPENDED) { 01709 errorCode = XML_ERROR_NOT_SUSPENDED; 01710 return XML_STATUS_ERROR; 01711 } 01712 ps_parsing = XML_PARSING; 01713 01714 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); 01715 01716 if (errorCode != XML_ERROR_NONE) { 01717 eventEndPtr = eventPtr; 01718 processor = errorProcessor; 01719 return XML_STATUS_ERROR; 01720 } 01721 else { 01722 switch (ps_parsing) { 01723 case XML_SUSPENDED: 01724 result = XML_STATUS_SUSPENDED; 01725 break; 01726 case XML_INITIALIZED: 01727 case XML_PARSING: 01728 if (ps_finalBuffer) { 01729 ps_parsing = XML_FINISHED; 01730 return result; 01731 } 01732 default: ; 01733 } 01734 } 01735 01736 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); 01737 positionPtr = bufferPtr; 01738 return result; 01739 } 01740 01741 void XMLCALL 01742 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) 01743 { 01744 assert(status != NULL); 01745 *status = parser->m_parsingStatus; 01746 } 01747 01748 enum XML_Error XMLCALL 01749 XML_GetErrorCode(XML_Parser parser) 01750 { 01751 return errorCode; 01752 } 01753 01754 XML_Index XMLCALL 01755 XML_GetCurrentByteIndex(XML_Parser parser) 01756 { 01757 if (eventPtr) 01758 return parseEndByteIndex - (parseEndPtr - eventPtr); 01759 return -1; 01760 } 01761 01762 int XMLCALL 01763 XML_GetCurrentByteCount(XML_Parser parser) 01764 { 01765 if (eventEndPtr && eventPtr) 01766 return (int)(eventEndPtr - eventPtr); 01767 return 0; 01768 } 01769 01770 const char * XMLCALL 01771 XML_GetInputContext(XML_Parser parser, int *offset, int *size) 01772 { 01773 #ifdef XML_CONTEXT_BYTES 01774 if (eventPtr && buffer) { 01775 *offset = (int)(eventPtr - buffer); 01776 *size = (int)(bufferEnd - buffer); 01777 return buffer; 01778 } 01779 #endif /* defined XML_CONTEXT_BYTES */ 01780 return (char *) 0; 01781 } 01782 01783 XML_Size XMLCALL 01784 XML_GetCurrentLineNumber(XML_Parser parser) 01785 { 01786 if (eventPtr && eventPtr >= positionPtr) { 01787 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); 01788 positionPtr = eventPtr; 01789 } 01790 return position.lineNumber + 1; 01791 } 01792 01793 XML_Size XMLCALL 01794 XML_GetCurrentColumnNumber(XML_Parser parser) 01795 { 01796 if (eventPtr && eventPtr >= positionPtr) { 01797 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); 01798 positionPtr = eventPtr; 01799 } 01800 return position.columnNumber; 01801 } 01802 01803 void XMLCALL 01804 XML_FreeContentModel(XML_Parser parser, XML_Content *model) 01805 { 01806 FREE(model); 01807 } 01808 01809 void * XMLCALL 01810 XML_MemMalloc(XML_Parser parser, size_t size) 01811 { 01812 return MALLOC(size); 01813 } 01814 01815 void * XMLCALL 01816 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) 01817 { 01818 return REALLOC(ptr, size); 01819 } 01820 01821 void XMLCALL 01822 XML_MemFree(XML_Parser parser, void *ptr) 01823 { 01824 FREE(ptr); 01825 } 01826 01827 void XMLCALL 01828 XML_DefaultCurrent(XML_Parser parser) 01829 { 01830 if (defaultHandler) { 01831 if (openInternalEntities) 01832 reportDefault(parser, 01833 internalEncoding, 01834 openInternalEntities->internalEventPtr, 01835 openInternalEntities->internalEventEndPtr); 01836 else 01837 reportDefault(parser, encoding, eventPtr, eventEndPtr); 01838 } 01839 } 01840 01841 const XML_LChar * XMLCALL 01842 XML_ErrorString(enum XML_Error code) 01843 { 01844 static const XML_LChar* const message[] = { 01845 0, 01846 XML_L("out of memory"), 01847 XML_L("syntax error"), 01848 XML_L("no element found"), 01849 XML_L("not well-formed (invalid token)"), 01850 XML_L("unclosed token"), 01851 XML_L("partial character"), 01852 XML_L("mismatched tag"), 01853 XML_L("duplicate attribute"), 01854 XML_L("junk after document element"), 01855 XML_L("illegal parameter entity reference"), 01856 XML_L("undefined entity"), 01857 XML_L("recursive entity reference"), 01858 XML_L("asynchronous entity"), 01859 XML_L("reference to invalid character number"), 01860 XML_L("reference to binary entity"), 01861 XML_L("reference to external entity in attribute"), 01862 XML_L("XML or text declaration not at start of entity"), 01863 XML_L("unknown encoding"), 01864 XML_L("encoding specified in XML declaration is incorrect"), 01865 XML_L("unclosed CDATA section"), 01866 XML_L("error in processing external entity reference"), 01867 XML_L("document is not standalone"), 01868 XML_L("unexpected parser state - please send a bug report"), 01869 XML_L("entity declared in parameter entity"), 01870 XML_L("requested feature requires XML_DTD support in Expat"), 01871 XML_L("cannot change setting once parsing has begun"), 01872 XML_L("unbound prefix"), 01873 XML_L("must not undeclare prefix"), 01874 XML_L("incomplete markup in parameter entity"), 01875 XML_L("XML declaration not well-formed"), 01876 XML_L("text declaration not well-formed"), 01877 XML_L("illegal character(s) in public id"), 01878 XML_L("parser suspended"), 01879 XML_L("parser not suspended"), 01880 XML_L("parsing aborted"), 01881 XML_L("parsing finished"), 01882 XML_L("cannot suspend in external parameter entity"), 01883 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"), 01884 XML_L("reserved prefix (xmlns) must not be declared or undeclared"), 01885 XML_L("prefix must not be bound to one of the reserved namespace names") 01886 }; 01887 if (code > 0 && code < sizeof(message)/sizeof(message[0])) 01888 return message[code]; 01889 return NULL; 01890 } 01891 01892 const XML_LChar * XMLCALL 01893 XML_ExpatVersion(void) { 01894 01895 /* V1 is used to string-ize the version number. However, it would 01896 string-ize the actual version macro *names* unless we get them 01897 substituted before being passed to V1. CPP is defined to expand 01898 a macro, then rescan for more expansions. Thus, we use V2 to expand 01899 the version macros, then CPP will expand the resulting V1() macro 01900 with the correct numerals. */ 01901 /* ### I'm assuming cpp is portable in this respect... */ 01902 01903 #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) 01904 #define V2(a,b,c) XML_L("expat_")V1(a,b,c) 01905 01906 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); 01907 01908 #undef V1 01909 #undef V2 01910 } 01911 01912 XML_Expat_Version XMLCALL 01913 XML_ExpatVersionInfo(void) 01914 { 01915 XML_Expat_Version version; 01916 01917 version.major = XML_MAJOR_VERSION; 01918 version.minor = XML_MINOR_VERSION; 01919 version.micro = XML_MICRO_VERSION; 01920 01921 return version; 01922 } 01923 01924 const XML_Feature * XMLCALL 01925 XML_GetFeatureList(void) 01926 { 01927 static const XML_Feature features[] = { 01928 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 01929 sizeof(XML_Char)}, 01930 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 01931 sizeof(XML_LChar)}, 01932 #ifdef XML_UNICODE 01933 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, 01934 #endif 01935 #ifdef XML_UNICODE_WCHAR_T 01936 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, 01937 #endif 01938 #ifdef XML_DTD 01939 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, 01940 #endif 01941 #ifdef XML_CONTEXT_BYTES 01942 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), 01943 XML_CONTEXT_BYTES}, 01944 #endif 01945 #ifdef XML_MIN_SIZE 01946 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, 01947 #endif 01948 #ifdef XML_NS 01949 {XML_FEATURE_NS, XML_L("XML_NS"), 0}, 01950 #endif 01951 {XML_FEATURE_END, NULL, 0} 01952 }; 01953 01954 return features; 01955 } 01956 01957 /* Initially tag->rawName always points into the parse buffer; 01958 for those TAG instances opened while the current parse buffer was 01959 processed, and not yet closed, we need to store tag->rawName in a more 01960 permanent location, since the parse buffer is about to be discarded. 01961 */ 01962 static XML_Bool 01963 storeRawNames(XML_Parser parser) 01964 { 01965 TAG *tag = tagStack; 01966 while (tag) { 01967 int bufSize; 01968 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); 01969 char *rawNameBuf = tag->buf + nameLen; 01970 /* Stop if already stored. Since tagStack is a stack, we can stop 01971 at the first entry that has already been copied; everything 01972 below it in the stack is already been accounted for in a 01973 previous call to this function. 01974 */ 01975 if (tag->rawName == rawNameBuf) 01976 break; 01977 /* For re-use purposes we need to ensure that the 01978 size of tag->buf is a multiple of sizeof(XML_Char). 01979 */ 01980 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); 01981 if (bufSize > tag->bufEnd - tag->buf) { 01982 char *temp = (char *)REALLOC(tag->buf, bufSize); 01983 if (temp == NULL) 01984 return XML_FALSE; 01985 /* if tag->name.str points to tag->buf (only when namespace 01986 processing is off) then we have to update it 01987 */ 01988 if (tag->name.str == (XML_Char *)tag->buf) 01989 tag->name.str = (XML_Char *)temp; 01990 /* if tag->name.localPart is set (when namespace processing is on) 01991 then update it as well, since it will always point into tag->buf 01992 */ 01993 if (tag->name.localPart) 01994 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - 01995 (XML_Char *)tag->buf); 01996 tag->buf = temp; 01997 tag->bufEnd = temp + bufSize; 01998 rawNameBuf = temp + nameLen; 01999 } 02000 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); 02001 tag->rawName = rawNameBuf; 02002 tag = tag->parent; 02003 } 02004 return XML_TRUE; 02005 } 02006 02007 static enum XML_Error PTRCALL 02008 contentProcessor(XML_Parser parser, 02009 const char *start, 02010 const char *end, 02011 const char **endPtr) 02012 { 02013 enum XML_Error result = doContent(parser, 0, encoding, start, end, 02014 endPtr, (XML_Bool)!ps_finalBuffer); 02015 if (result == XML_ERROR_NONE) { 02016 if (!storeRawNames(parser)) 02017 return XML_ERROR_NO_MEMORY; 02018 } 02019 return result; 02020 } 02021 02022 static enum XML_Error PTRCALL 02023 externalEntityInitProcessor(XML_Parser parser, 02024 const char *start, 02025 const char *end, 02026 const char **endPtr) 02027 { 02028 enum XML_Error result = initializeEncoding(parser); 02029 if (result != XML_ERROR_NONE) 02030 return result; 02031 processor = externalEntityInitProcessor2; 02032 return externalEntityInitProcessor2(parser, start, end, endPtr); 02033 } 02034 02035 static enum XML_Error PTRCALL 02036 externalEntityInitProcessor2(XML_Parser parser, 02037 const char *start, 02038 const char *end, 02039 const char **endPtr) 02040 { 02041 const char *next = start; /* XmlContentTok doesn't always set the last arg */ 02042 int tok = XmlContentTok(encoding, start, end, &next); 02043 switch (tok) { 02044 case XML_TOK_BOM: 02045 /* If we are at the end of the buffer, this would cause the next stage, 02046 i.e. externalEntityInitProcessor3, to pass control directly to 02047 doContent (by detecting XML_TOK_NONE) without processing any xml text 02048 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. 02049 */ 02050 if (next == end && !ps_finalBuffer) { 02051 *endPtr = next; 02052 return XML_ERROR_NONE; 02053 } 02054 start = next; 02055 break; 02056 case XML_TOK_PARTIAL: 02057 if (!ps_finalBuffer) { 02058 *endPtr = start; 02059 return XML_ERROR_NONE; 02060 } 02061 eventPtr = start; 02062 return XML_ERROR_UNCLOSED_TOKEN; 02063 case XML_TOK_PARTIAL_CHAR: 02064 if (!ps_finalBuffer) { 02065 *endPtr = start; 02066 return XML_ERROR_NONE; 02067 } 02068 eventPtr = start; 02069 return XML_ERROR_PARTIAL_CHAR; 02070 } 02071 processor = externalEntityInitProcessor3; 02072 return externalEntityInitProcessor3(parser, start, end, endPtr); 02073 } 02074 02075 static enum XML_Error PTRCALL 02076 externalEntityInitProcessor3(XML_Parser parser, 02077 const char *start, 02078 const char *end, 02079 const char **endPtr) 02080 { 02081 int tok; 02082 const char *next = start; /* XmlContentTok doesn't always set the last arg */ 02083 eventPtr = start; 02084 tok = XmlContentTok(encoding, start, end, &next); 02085 eventEndPtr = next; 02086 02087 switch (tok) { 02088 case XML_TOK_XML_DECL: 02089 { 02090 enum XML_Error result; 02091 result = processXmlDecl(parser, 1, start, next); 02092 if (result != XML_ERROR_NONE) 02093 return result; 02094 switch (ps_parsing) { 02095 case XML_SUSPENDED: 02096 *endPtr = next; 02097 return XML_ERROR_NONE; 02098 case XML_FINISHED: 02099 return XML_ERROR_ABORTED; 02100 default: 02101 start = next; 02102 } 02103 } 02104 break; 02105 case XML_TOK_PARTIAL: 02106 if (!ps_finalBuffer) { 02107 *endPtr = start; 02108 return XML_ERROR_NONE; 02109 } 02110 return XML_ERROR_UNCLOSED_TOKEN; 02111 case XML_TOK_PARTIAL_CHAR: 02112 if (!ps_finalBuffer) { 02113 *endPtr = start; 02114 return XML_ERROR_NONE; 02115 } 02116 return XML_ERROR_PARTIAL_CHAR; 02117 } 02118 processor = externalEntityContentProcessor; 02119 tagLevel = 1; 02120 return externalEntityContentProcessor(parser, start, end, endPtr); 02121 } 02122 02123 static enum XML_Error PTRCALL 02124 externalEntityContentProcessor(XML_Parser parser, 02125 const char *start, 02126 const char *end, 02127 const char **endPtr) 02128 { 02129 enum XML_Error result = doContent(parser, 1, encoding, start, end, 02130 endPtr, (XML_Bool)!ps_finalBuffer); 02131 if (result == XML_ERROR_NONE) { 02132 if (!storeRawNames(parser)) 02133 return XML_ERROR_NO_MEMORY; 02134 } 02135 return result; 02136 } 02137 02138 static enum XML_Error 02139 doContent(XML_Parser parser, 02140 int startTagLevel, 02141 const ENCODING *enc, 02142 const char *s, 02143 const char *end, 02144 const char **nextPtr, 02145 XML_Bool haveMore) 02146 { 02147 /* save one level of indirection */ 02148 DTD * const dtd = _dtd; 02149 02150 const char **eventPP; 02151 const char **eventEndPP; 02152 if (enc == encoding) { 02153 eventPP = &eventPtr; 02154 eventEndPP = &eventEndPtr; 02155 } 02156 else { 02157 eventPP = &(openInternalEntities->internalEventPtr); 02158 eventEndPP = &(openInternalEntities->internalEventEndPtr); 02159 } 02160 *eventPP = s; 02161 02162 for (;;) { 02163 const char *next = s; /* XmlContentTok doesn't always set the last arg */ 02164 int tok = XmlContentTok(enc, s, end, &next); 02165 *eventEndPP = next; 02166 switch (tok) { 02167 case XML_TOK_TRAILING_CR: 02168 if (haveMore) { 02169 *nextPtr = s; 02170 return XML_ERROR_NONE; 02171 } 02172 *eventEndPP = end; 02173 if (characterDataHandler) { 02174 XML_Char c = 0xA; 02175 characterDataHandler(handlerArg, &c, 1); 02176 } 02177 else if (defaultHandler) 02178 reportDefault(parser, enc, s, end); 02179 /* We are at the end of the final buffer, should we check for 02180 XML_SUSPENDED, XML_FINISHED? 02181 */ 02182 if (startTagLevel == 0) 02183 return XML_ERROR_NO_ELEMENTS; 02184 if (tagLevel != startTagLevel) 02185 return XML_ERROR_ASYNC_ENTITY; 02186 *nextPtr = end; 02187 return XML_ERROR_NONE; 02188 case XML_TOK_NONE: 02189 if (haveMore) { 02190 *nextPtr = s; 02191 return XML_ERROR_NONE; 02192 } 02193 if (startTagLevel > 0) { 02194 if (tagLevel != startTagLevel) 02195 return XML_ERROR_ASYNC_ENTITY; 02196 *nextPtr = s; 02197 return XML_ERROR_NONE; 02198 } 02199 return XML_ERROR_NO_ELEMENTS; 02200 case XML_TOK_INVALID: 02201 *eventPP = next; 02202 return XML_ERROR_INVALID_TOKEN; 02203 case XML_TOK_PARTIAL: 02204 if (haveMore) { 02205 *nextPtr = s; 02206 return XML_ERROR_NONE; 02207 } 02208 return XML_ERROR_UNCLOSED_TOKEN; 02209 case XML_TOK_PARTIAL_CHAR: 02210 if (haveMore) { 02211 *nextPtr = s; 02212 return XML_ERROR_NONE; 02213 } 02214 return XML_ERROR_PARTIAL_CHAR; 02215 case XML_TOK_ENTITY_REF: 02216 { 02217 const XML_Char *name; 02218 ENTITY *entity; 02219 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, 02220 s + enc->minBytesPerChar, 02221 next - enc->minBytesPerChar); 02222 if (ch) { 02223 if (characterDataHandler) 02224 characterDataHandler(handlerArg, &ch, 1); 02225 else if (defaultHandler) 02226 reportDefault(parser, enc, s, next); 02227 break; 02228 } 02229 name = poolStoreString(&dtd->pool, enc, 02230 s + enc->minBytesPerChar, 02231 next - enc->minBytesPerChar); 02232 if (!name) 02233 return XML_ERROR_NO_MEMORY; 02234 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0); 02235 poolDiscard(&dtd->pool); 02236 /* First, determine if a check for an existing declaration is needed; 02237 if yes, check that the entity exists, and that it is internal, 02238 otherwise call the skipped entity or default handler. 02239 */ 02240 if (!dtd->hasParamEntityRefs || dtd->standalone) { 02241 if (!entity) 02242 return XML_ERROR_UNDEFINED_ENTITY; 02243 else if (!entity->is_internal) 02244 return XML_ERROR_ENTITY_DECLARED_IN_PE; 02245 } 02246 else if (!entity) { 02247 if (skippedEntityHandler) 02248 skippedEntityHandler(handlerArg, name, 0); 02249 else if (defaultHandler) 02250 reportDefault(parser, enc, s, next); 02251 break; 02252 } 02253 if (entity->open) 02254 return XML_ERROR_RECURSIVE_ENTITY_REF; 02255 if (entity->notation) 02256 return XML_ERROR_BINARY_ENTITY_REF; 02257 if (entity->textPtr) { 02258 enum XML_Error result; 02259 if (!defaultExpandInternalEntities) { 02260 if (skippedEntityHandler) 02261 skippedEntityHandler(handlerArg, entity->name, 0); 02262 else if (defaultHandler) 02263 reportDefault(parser, enc, s, next); 02264 break; 02265 } 02266 result = processInternalEntity(parser, entity, XML_FALSE); 02267 if (result != XML_ERROR_NONE) 02268 return result; 02269 } 02270 else if (externalEntityRefHandler) { 02271 const XML_Char *context; 02272 entity->open = XML_TRUE; 02273 context = getContext(parser); 02274 entity->open = XML_FALSE; 02275 if (!context) 02276 return XML_ERROR_NO_MEMORY; 02277 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 02278 context, 02279 entity->base, 02280 entity->systemId, 02281 entity->publicId)) 02282 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 02283 poolDiscard(&tempPool); 02284 } 02285 else if (defaultHandler) 02286 reportDefault(parser, enc, s, next); 02287 break; 02288 } 02289 case XML_TOK_START_TAG_NO_ATTS: 02290 /* fall through */ 02291 case XML_TOK_START_TAG_WITH_ATTS: 02292 { 02293 TAG *tag; 02294 enum XML_Error result; 02295 XML_Char *toPtr; 02296 if (freeTagList) { 02297 tag = freeTagList; 02298 freeTagList = freeTagList->parent; 02299 } 02300 else { 02301 tag = (TAG *)MALLOC(sizeof(TAG)); 02302 if (!tag) 02303 return XML_ERROR_NO_MEMORY; 02304 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE); 02305 if (!tag->buf) { 02306 FREE(tag); 02307 return XML_ERROR_NO_MEMORY; 02308 } 02309 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; 02310 } 02311 tag->bindings = NULL; 02312 tag->parent = tagStack; 02313 tagStack = tag; 02314 tag->name.localPart = NULL; 02315 tag->name.prefix = NULL; 02316 tag->rawName = s + enc->minBytesPerChar; 02317 tag->rawNameLength = XmlNameLength(enc, tag->rawName); 02318 ++tagLevel; 02319 { 02320 const char *rawNameEnd = tag->rawName + tag->rawNameLength; 02321 const char *fromPtr = tag->rawName; 02322 toPtr = (XML_Char *)tag->buf; 02323 for (;;) { 02324 int bufSize; 02325 int convLen; 02326 XmlConvert(enc, 02327 &fromPtr, rawNameEnd, 02328 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); 02329 convLen = (int)(toPtr - (XML_Char *)tag->buf); 02330 if (fromPtr == rawNameEnd) { 02331 tag->name.strLen = convLen; 02332 break; 02333 } 02334 bufSize = (int)(tag->bufEnd - tag->buf) << 1; 02335 { 02336 char *temp = (char *)REALLOC(tag->buf, bufSize); 02337 if (temp == NULL) 02338 return XML_ERROR_NO_MEMORY; 02339 tag->buf = temp; 02340 tag->bufEnd = temp + bufSize; 02341 toPtr = (XML_Char *)temp + convLen; 02342 } 02343 } 02344 } 02345 tag->name.str = (XML_Char *)tag->buf; 02346 *toPtr = XML_T('\0'); 02347 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); 02348 if (result) 02349 return result; 02350 if (startElementHandler) 02351 startElementHandler(handlerArg, tag->name.str, 02352 (const XML_Char **)atts); 02353 else if (defaultHandler) 02354 reportDefault(parser, enc, s, next); 02355 poolClear(&tempPool); 02356 break; 02357 } 02358 case XML_TOK_EMPTY_ELEMENT_NO_ATTS: 02359 /* fall through */ 02360 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: 02361 { 02362 const char *rawName = s + enc->minBytesPerChar; 02363 enum XML_Error result; 02364 BINDING *bindings = NULL; 02365 XML_Bool noElmHandlers = XML_TRUE; 02366 TAG_NAME name; 02367 name.str = poolStoreString(&tempPool, enc, rawName, 02368 rawName + XmlNameLength(enc, rawName)); 02369 if (!name.str) 02370 return XML_ERROR_NO_MEMORY; 02371 poolFinish(&tempPool); 02372 result = storeAtts(parser, enc, s, &name, &bindings); 02373 if (result) 02374 return result; 02375 poolFinish(&tempPool); 02376 if (startElementHandler) { 02377 startElementHandler(handlerArg, name.str, (const XML_Char **)atts); 02378 noElmHandlers = XML_FALSE; 02379 } 02380 if (endElementHandler) { 02381 if (startElementHandler) 02382 *eventPP = *eventEndPP; 02383 endElementHandler(handlerArg, name.str); 02384 noElmHandlers = XML_FALSE; 02385 } 02386 if (noElmHandlers && defaultHandler) 02387 reportDefault(parser, enc, s, next); 02388 poolClear(&tempPool); 02389 while (bindings) { 02390 BINDING *b = bindings; 02391 if (endNamespaceDeclHandler) 02392 endNamespaceDeclHandler(handlerArg, b->prefix->name); 02393 bindings = bindings->nextTagBinding; 02394 b->nextTagBinding = freeBindingList; 02395 freeBindingList = b; 02396 b->prefix->binding = b->prevPrefixBinding; 02397 } 02398 } 02399 if (tagLevel == 0) 02400 return epilogProcessor(parser, next, end, nextPtr); 02401 break; 02402 case XML_TOK_END_TAG: 02403 if (tagLevel == startTagLevel) 02404 return XML_ERROR_ASYNC_ENTITY; 02405 else { 02406 int len; 02407 const char *rawName; 02408 TAG *tag = tagStack; 02409 tagStack = tag->parent; 02410 tag->parent = freeTagList; 02411 freeTagList = tag; 02412 rawName = s + enc->minBytesPerChar*2; 02413 len = XmlNameLength(enc, rawName); 02414 if (len != tag->rawNameLength 02415 || memcmp(tag->rawName, rawName, len) != 0) { 02416 *eventPP = rawName; 02417 return XML_ERROR_TAG_MISMATCH; 02418 } 02419 --tagLevel; 02420 if (endElementHandler) { 02421 const XML_Char *localPart; 02422 const XML_Char *prefix; 02423 XML_Char *uri; 02424 localPart = tag->name.localPart; 02425 if (ns && localPart) { 02426 /* localPart and prefix may have been overwritten in 02427 tag->name.str, since this points to the binding->uri 02428 buffer which gets re-used; so we have to add them again 02429 */ 02430 uri = (XML_Char *)tag->name.str + tag->name.uriLen; 02431 /* don't need to check for space - already done in storeAtts() */ 02432 while (*localPart) *uri++ = *localPart++; 02433 prefix = (XML_Char *)tag->name.prefix; 02434 if (ns_triplets && prefix) { 02435 *uri++ = namespaceSeparator; 02436 while (*prefix) *uri++ = *prefix++; 02437 } 02438 *uri = XML_T('\0'); 02439 } 02440 endElementHandler(handlerArg, tag->name.str); 02441 } 02442 else if (defaultHandler) 02443 reportDefault(parser, enc, s, next); 02444 while (tag->bindings) { 02445 BINDING *b = tag->bindings; 02446 if (endNamespaceDeclHandler) 02447 endNamespaceDeclHandler(handlerArg, b->prefix->name); 02448 tag->bindings = tag->bindings->nextTagBinding; 02449 b->nextTagBinding = freeBindingList; 02450 freeBindingList = b; 02451 b->prefix->binding = b->prevPrefixBinding; 02452 } 02453 if (tagLevel == 0) 02454 return epilogProcessor(parser, next, end, nextPtr); 02455 } 02456 break; 02457 case XML_TOK_CHAR_REF: 02458 { 02459 int n = XmlCharRefNumber(enc, s); 02460 if (n < 0) 02461 return XML_ERROR_BAD_CHAR_REF; 02462 if (characterDataHandler) { 02463 XML_Char buf[XML_ENCODE_MAX]; 02464 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); 02465 } 02466 else if (defaultHandler) 02467 reportDefault(parser, enc, s, next); 02468 } 02469 break; 02470 case XML_TOK_XML_DECL: 02471 return XML_ERROR_MISPLACED_XML_PI; 02472 case XML_TOK_DATA_NEWLINE: 02473 if (characterDataHandler) { 02474 XML_Char c = 0xA; 02475 characterDataHandler(handlerArg, &c, 1); 02476 } 02477 else if (defaultHandler) 02478 reportDefault(parser, enc, s, next); 02479 break; 02480 case XML_TOK_CDATA_SECT_OPEN: 02481 { 02482 enum XML_Error result; 02483 if (startCdataSectionHandler) 02484 startCdataSectionHandler(handlerArg); 02485 #if 0 02486 /* Suppose you doing a transformation on a document that involves 02487 changing only the character data. You set up a defaultHandler 02488 and a characterDataHandler. The defaultHandler simply copies 02489 characters through. The characterDataHandler does the 02490 transformation and writes the characters out escaping them as 02491 necessary. This case will fail to work if we leave out the 02492 following two lines (because & and < inside CDATA sections will 02493 be incorrectly escaped). 02494 02495 However, now we have a start/endCdataSectionHandler, so it seems 02496 easier to let the user deal with this. 02497 */ 02498 else if (characterDataHandler) 02499 characterDataHandler(handlerArg, dataBuf, 0); 02500 #endif 02501 else if (defaultHandler) 02502 reportDefault(parser, enc, s, next); 02503 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); 02504 if (result != XML_ERROR_NONE) 02505 return result; 02506 else if (!next) { 02507 processor = cdataSectionProcessor; 02508 return result; 02509 } 02510 } 02511 break; 02512 case XML_TOK_TRAILING_RSQB: 02513 if (haveMore) { 02514 *nextPtr = s; 02515 return XML_ERROR_NONE; 02516 } 02517 if (characterDataHandler) { 02518 if (MUST_CONVERT(enc, s)) { 02519 ICHAR *dataPtr = (ICHAR *)dataBuf; 02520 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); 02521 characterDataHandler(handlerArg, dataBuf, 02522 (int)(dataPtr - (ICHAR *)dataBuf)); 02523 } 02524 else 02525 characterDataHandler(handlerArg, 02526 (XML_Char *)s, 02527 (int)((XML_Char *)end - (XML_Char *)s)); 02528 } 02529 else if (defaultHandler) 02530 reportDefault(parser, enc, s, end); 02531 /* We are at the end of the final buffer, should we check for 02532 XML_SUSPENDED, XML_FINISHED? 02533 */ 02534 if (startTagLevel == 0) { 02535 *eventPP = end; 02536 return XML_ERROR_NO_ELEMENTS; 02537 } 02538 if (tagLevel != startTagLevel) { 02539 *eventPP = end; 02540 return XML_ERROR_ASYNC_ENTITY; 02541 } 02542 *nextPtr = end; 02543 return XML_ERROR_NONE; 02544 case XML_TOK_DATA_CHARS: 02545 if (characterDataHandler) { 02546 if (MUST_CONVERT(enc, s)) { 02547 for (;;) { 02548 ICHAR *dataPtr = (ICHAR *)dataBuf; 02549 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); 02550 *eventEndPP = s; 02551 characterDataHandler(handlerArg, dataBuf, 02552 (int)(dataPtr - (ICHAR *)dataBuf)); 02553 if (s == next) 02554 break; 02555 *eventPP = s; 02556 } 02557 } 02558 else 02559 characterDataHandler(handlerArg, 02560 (XML_Char *)s, 02561 (int)((XML_Char *)next - (XML_Char *)s)); 02562 } 02563 else if (defaultHandler) 02564 reportDefault(parser, enc, s, next); 02565 break; 02566 case XML_TOK_PI: 02567 if (!reportProcessingInstruction(parser, enc, s, next)) 02568 return XML_ERROR_NO_MEMORY; 02569 break; 02570 case XML_TOK_COMMENT: 02571 if (!reportComment(parser, enc, s, next)) 02572 return XML_ERROR_NO_MEMORY; 02573 break; 02574 default: 02575 if (defaultHandler) 02576 reportDefault(parser, enc, s, next); 02577 break; 02578 } 02579 *eventPP = s = next; 02580 switch (ps_parsing) { 02581 case XML_SUSPENDED: 02582 *nextPtr = next; 02583 return XML_ERROR_NONE; 02584 case XML_FINISHED: 02585 return XML_ERROR_ABORTED; 02586 default: ; 02587 } 02588 } 02589 /* not reached */ 02590 } 02591 02592 /* Precondition: all arguments must be non-NULL; 02593 Purpose: 02594 - normalize attributes 02595 - check attributes for well-formedness 02596 - generate namespace aware attribute names (URI, prefix) 02597 - build list of attributes for startElementHandler 02598 - default attributes 02599 - process namespace declarations (check and report them) 02600 - generate namespace aware element name (URI, prefix) 02601 */ 02602 static enum XML_Error 02603 storeAtts(XML_Parser parser, const ENCODING *enc, 02604 const char *attStr, TAG_NAME *tagNamePtr, 02605 BINDING **bindingsPtr) 02606 { 02607 DTD * const dtd = _dtd; /* save one level of indirection */ 02608 ELEMENT_TYPE *elementType; 02609 int nDefaultAtts; 02610 const XML_Char **appAtts; /* the attribute list for the application */ 02611 int attIndex = 0; 02612 int prefixLen; 02613 int i; 02614 int n; 02615 XML_Char *uri; 02616 int nPrefixes = 0; 02617 BINDING *binding; 02618 const XML_Char *localPart; 02619 02620 /* lookup the element type name */ 02621 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0); 02622 if (!elementType) { 02623 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); 02624 if (!name) 02625 return XML_ERROR_NO_MEMORY; 02626 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name, 02627 sizeof(ELEMENT_TYPE)); 02628 if (!elementType) 02629 return XML_ERROR_NO_MEMORY; 02630 if (ns && !setElementTypePrefix(parser, elementType)) 02631 return XML_ERROR_NO_MEMORY; 02632 } 02633 nDefaultAtts = elementType->nDefaultAtts; 02634 02635 /* get the attributes from the tokenizer */ 02636 n = XmlGetAttributes(enc, attStr, attsSize, atts); 02637 if (n + nDefaultAtts > attsSize) { 02638 int oldAttsSize = attsSize; 02639 ATTRIBUTE *temp; 02640 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; 02641 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); 02642 if (temp == NULL) 02643 return XML_ERROR_NO_MEMORY; 02644 atts = temp; 02645 if (n > oldAttsSize) 02646 XmlGetAttributes(enc, attStr, n, atts); 02647 } 02648 02649 appAtts = (const XML_Char **)atts; 02650 for (i = 0; i < n; i++) { 02651 /* add the name and value to the attribute list */ 02652 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name, 02653 atts[i].name 02654 + XmlNameLength(enc, atts[i].name)); 02655 if (!attId) 02656 return XML_ERROR_NO_MEMORY; 02657 /* Detect duplicate attributes by their QNames. This does not work when 02658 namespace processing is turned on and different prefixes for the same 02659 namespace are used. For this case we have a check further down. 02660 */ 02661 if ((attId->name)[-1]) { 02662 if (enc == encoding) 02663 eventPtr = atts[i].name; 02664 return XML_ERROR_DUPLICATE_ATTRIBUTE; 02665 } 02666 (attId->name)[-1] = 1; 02667 appAtts[attIndex++] = attId->name; 02668 if (!atts[i].normalized) { 02669 enum XML_Error result; 02670 XML_Bool isCdata = XML_TRUE; 02671 02672 /* figure out whether declared as other than CDATA */ 02673 if (attId->maybeTokenized) { 02674 int j; 02675 for (j = 0; j < nDefaultAtts; j++) { 02676 if (attId == elementType->defaultAtts[j].id) { 02677 isCdata = elementType->defaultAtts[j].isCdata; 02678 break; 02679 } 02680 } 02681 } 02682 02683 /* normalize the attribute value */ 02684 result = storeAttributeValue(parser, enc, isCdata, 02685 atts[i].valuePtr, atts[i].valueEnd, 02686 &tempPool); 02687 if (result) 02688 return result; 02689 appAtts[attIndex] = poolStart(&tempPool); 02690 poolFinish(&tempPool); 02691 } 02692 else { 02693 /* the value did not need normalizing */ 02694 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, 02695 atts[i].valueEnd); 02696 if (appAtts[attIndex] == 0) 02697 return XML_ERROR_NO_MEMORY; 02698 poolFinish(&tempPool); 02699 } 02700 /* handle prefixed attribute names */ 02701 if (attId->prefix) { 02702 if (attId->xmlns) { 02703 /* deal with namespace declarations here */ 02704 enum XML_Error result = addBinding(parser, attId->prefix, attId, 02705 appAtts[attIndex], bindingsPtr); 02706 if (result) 02707 return result; 02708 --attIndex; 02709 } 02710 else { 02711 /* deal with other prefixed names later */ 02712 attIndex++; 02713 nPrefixes++; 02714 (attId->name)[-1] = 2; 02715 } 02716 } 02717 else 02718 attIndex++; 02719 } 02720 02721 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ 02722 nSpecifiedAtts = attIndex; 02723 if (elementType->idAtt && (elementType->idAtt->name)[-1]) { 02724 for (i = 0; i < attIndex; i += 2) 02725 if (appAtts[i] == elementType->idAtt->name) { 02726 idAttIndex = i; 02727 break; 02728 } 02729 } 02730 else 02731 idAttIndex = -1; 02732 02733 /* do attribute defaulting */ 02734 for (i = 0; i < nDefaultAtts; i++) { 02735 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; 02736 if (!(da->id->name)[-1] && da->value) { 02737 if (da->id->prefix) { 02738 if (da->id->xmlns) { 02739 enum XML_Error result = addBinding(parser, da->id->prefix, da->id, 02740 da->value, bindingsPtr); 02741 if (result) 02742 return result; 02743 } 02744 else { 02745 (da->id->name)[-1] = 2; 02746 nPrefixes++; 02747 appAtts[attIndex++] = da->id->name; 02748 appAtts[attIndex++] = da->value; 02749 } 02750 } 02751 else { 02752 (da->id->name)[-1] = 1; 02753 appAtts[attIndex++] = da->id->name; 02754 appAtts[attIndex++] = da->value; 02755 } 02756 } 02757 } 02758 appAtts[attIndex] = 0; 02759 02760 /* expand prefixed attribute names, check for duplicates, 02761 and clear flags that say whether attributes were specified */ 02762 i = 0; 02763 if (nPrefixes) { 02764 int j; /* hash table index */ 02765 unsigned long version = nsAttsVersion; 02766 int nsAttsSize = (int)1 << nsAttsPower; 02767 /* size of hash table must be at least 2 * (# of prefixed attributes) */ 02768 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */ 02769 NS_ATT *temp; 02770 /* hash table size must also be a power of 2 and >= 8 */ 02771 while (nPrefixes >> nsAttsPower++); 02772 if (nsAttsPower < 3) 02773 nsAttsPower = 3; 02774 nsAttsSize = (int)1 << nsAttsPower; 02775 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT)); 02776 if (!temp) 02777 return XML_ERROR_NO_MEMORY; 02778 nsAtts = temp; 02779 version = 0; /* force re-initialization of nsAtts hash table */ 02780 } 02781 /* using a version flag saves us from initializing nsAtts every time */ 02782 if (!version) { /* initialize version flags when version wraps around */ 02783 version = INIT_ATTS_VERSION; 02784 for (j = nsAttsSize; j != 0; ) 02785 nsAtts[--j].version = version; 02786 } 02787 nsAttsVersion = --version; 02788 02789 /* expand prefixed names and check for duplicates */ 02790 for (; i < attIndex; i += 2) { 02791 const XML_Char *s = appAtts[i]; 02792 if (s[-1] == 2) { /* prefixed */ 02793 ATTRIBUTE_ID *id; 02794 const BINDING *b; 02795 unsigned long uriHash = 0; 02796 ((XML_Char *)s)[-1] = 0; /* clear flag */ 02797 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0); 02798 b = id->prefix->binding; 02799 if (!b) 02800 return XML_ERROR_UNBOUND_PREFIX; 02801 02802 /* as we expand the name we also calculate its hash value */ 02803 for (j = 0; j < b->uriLen; j++) { 02804 const XML_Char c = b->uri[j]; 02805 if (!poolAppendChar(&tempPool, c)) 02806 return XML_ERROR_NO_MEMORY; 02807 uriHash = CHAR_HASH(uriHash, c); 02808 } 02809 while (*s++ != XML_T(':')) 02810 ; 02811 do { /* copies null terminator */ 02812 const XML_Char c = *s; 02813 if (!poolAppendChar(&tempPool, *s)) 02814 return XML_ERROR_NO_MEMORY; 02815 uriHash = CHAR_HASH(uriHash, c); 02816 } while (*s++); 02817 02818 { /* Check hash table for duplicate of expanded name (uriName). 02819 Derived from code in lookup(HASH_TABLE *table, ...). 02820 */ 02821 unsigned char step = 0; 02822 unsigned long mask = nsAttsSize - 1; 02823 j = uriHash & mask; /* index into hash table */ 02824 while (nsAtts[j].version == version) { 02825 /* for speed we compare stored hash values first */ 02826 if (uriHash == nsAtts[j].hash) { 02827 const XML_Char *s1 = poolStart(&tempPool); 02828 const XML_Char *s2 = nsAtts[j].uriName; 02829 /* s1 is null terminated, but not s2 */ 02830 for (; *s1 == *s2 && *s1 != 0; s1++, s2++); 02831 if (*s1 == 0) 02832 return XML_ERROR_DUPLICATE_ATTRIBUTE; 02833 } 02834 if (!step) 02835 step = PROBE_STEP(uriHash, mask, nsAttsPower); 02836 j < step ? (j += nsAttsSize - step) : (j -= step); 02837 } 02838 } 02839 02840 if (ns_triplets) { /* append namespace separator and prefix */ 02841 tempPool.ptr[-1] = namespaceSeparator; 02842 s = b->prefix->name; 02843 do { 02844 if (!poolAppendChar(&tempPool, *s)) 02845 return XML_ERROR_NO_MEMORY; 02846 } while (*s++); 02847 } 02848 02849 /* store expanded name in attribute list */ 02850 s = poolStart(&tempPool); 02851 poolFinish(&tempPool); 02852 appAtts[i] = s; 02853 02854 /* fill empty slot with new version, uriName and hash value */ 02855 nsAtts[j].version = version; 02856 nsAtts[j].hash = uriHash; 02857 nsAtts[j].uriName = s; 02858 02859 if (!--nPrefixes) { 02860 i += 2; 02861 break; 02862 } 02863 } 02864 else /* not prefixed */ 02865 ((XML_Char *)s)[-1] = 0; /* clear flag */ 02866 } 02867 } 02868 /* clear flags for the remaining attributes */ 02869 for (; i < attIndex; i += 2) 02870 ((XML_Char *)(appAtts[i]))[-1] = 0; 02871 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) 02872 binding->attId->name[-1] = 0; 02873 02874 if (!ns) 02875 return XML_ERROR_NONE; 02876 02877 /* expand the element type name */ 02878 if (elementType->prefix) { 02879 binding = elementType->prefix->binding; 02880 if (!binding) 02881 return XML_ERROR_UNBOUND_PREFIX; 02882 localPart = tagNamePtr->str; 02883 while (*localPart++ != XML_T(':')) 02884 ; 02885 } 02886 else if (dtd->defaultPrefix.binding) { 02887 binding = dtd->defaultPrefix.binding; 02888 localPart = tagNamePtr->str; 02889 } 02890 else 02891 return XML_ERROR_NONE; 02892 prefixLen = 0; 02893 if (ns_triplets && binding->prefix->name) { 02894 for (; binding->prefix->name[prefixLen++];) 02895 ; /* prefixLen includes null terminator */ 02896 } 02897 tagNamePtr->localPart = localPart; 02898 tagNamePtr->uriLen = binding->uriLen; 02899 tagNamePtr->prefix = binding->prefix->name; 02900 tagNamePtr->prefixLen = prefixLen; 02901 for (i = 0; localPart[i++];) 02902 ; /* i includes null terminator */ 02903 n = i + binding->uriLen + prefixLen; 02904 if (n > binding->uriAlloc) { 02905 TAG *p; 02906 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char)); 02907 if (!uri) 02908 return XML_ERROR_NO_MEMORY; 02909 binding->uriAlloc = n + EXPAND_SPARE; 02910 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); 02911 for (p = tagStack; p; p = p->parent) 02912 if (p->name.str == binding->uri) 02913 p->name.str = uri; 02914 FREE(binding->uri); 02915 binding->uri = uri; 02916 } 02917 /* if namespaceSeparator != '\0' then uri includes it already */ 02918 uri = binding->uri + binding->uriLen; 02919 memcpy(uri, localPart, i * sizeof(XML_Char)); 02920 /* we always have a namespace separator between localPart and prefix */ 02921 if (prefixLen) { 02922 uri += i - 1; 02923 *uri = namespaceSeparator; /* replace null terminator */ 02924 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); 02925 } 02926 tagNamePtr->str = binding->uri; 02927 return XML_ERROR_NONE; 02928 } 02929 02930 /* addBinding() overwrites the value of prefix->binding without checking. 02931 Therefore one must keep track of the old value outside of addBinding(). 02932 */ 02933 static enum XML_Error 02934 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, 02935 const XML_Char *uri, BINDING **bindingsPtr) 02936 { 02937 static const XML_Char xmlNamespace[] = { 02938 'h', 't', 't', 'p', ':', '/', '/', 02939 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/', 02940 'X', 'M', 'L', '/', '1', '9', '9', '8', '/', 02941 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0' 02942 }; 02943 static const int xmlLen = 02944 (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1; 02945 static const XML_Char xmlnsNamespace[] = { 02946 'h', 't', 't', 'p', ':', '/', '/', 02947 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/', 02948 '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0' 02949 }; 02950 static const int xmlnsLen = 02951 (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1; 02952 02953 XML_Bool mustBeXML = XML_FALSE; 02954 XML_Bool isXML = XML_TRUE; 02955 XML_Bool isXMLNS = XML_TRUE; 02956 02957 BINDING *b; 02958 int len; 02959 02960 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ 02961 if (*uri == XML_T('\0') && prefix->name) 02962 return XML_ERROR_UNDECLARING_PREFIX; 02963 02964 if (prefix->name 02965 && prefix->name[0] == XML_T('x') 02966 && prefix->name[1] == XML_T('m') 02967 && prefix->name[2] == XML_T('l')) { 02968 02969 /* Not allowed to bind xmlns */ 02970 if (prefix->name[3] == XML_T('n') 02971 && prefix->name[4] == XML_T('s') 02972 && prefix->name[5] == XML_T('\0')) 02973 return XML_ERROR_RESERVED_PREFIX_XMLNS; 02974 02975 if (prefix->name[3] == XML_T('\0')) 02976 mustBeXML = XML_TRUE; 02977 } 02978 02979 for (len = 0; uri[len]; len++) { 02980 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) 02981 isXML = XML_FALSE; 02982 02983 if (!mustBeXML && isXMLNS 02984 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) 02985 isXMLNS = XML_FALSE; 02986 } 02987 isXML = isXML && len == xmlLen; 02988 isXMLNS = isXMLNS && len == xmlnsLen; 02989 02990 if (mustBeXML != isXML) 02991 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML 02992 : XML_ERROR_RESERVED_NAMESPACE_URI; 02993 02994 if (isXMLNS) 02995 return XML_ERROR_RESERVED_NAMESPACE_URI; 02996 02997 if (namespaceSeparator) 02998 len++; 02999 if (freeBindingList) { 03000 b = freeBindingList; 03001 if (len > b->uriAlloc) { 03002 XML_Char *temp = (XML_Char *)REALLOC(b->uri, 03003 sizeof(XML_Char) * (len + EXPAND_SPARE)); 03004 if (temp == NULL) 03005 return XML_ERROR_NO_MEMORY; 03006 b->uri = temp; 03007 b->uriAlloc = len + EXPAND_SPARE; 03008 } 03009 freeBindingList = b->nextTagBinding; 03010 } 03011 else { 03012 b = (BINDING *)MALLOC(sizeof(BINDING)); 03013 if (!b) 03014 return XML_ERROR_NO_MEMORY; 03015 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE)); 03016 if (!b->uri) { 03017 FREE(b); 03018 return XML_ERROR_NO_MEMORY; 03019 } 03020 b->uriAlloc = len + EXPAND_SPARE; 03021 } 03022 b->uriLen = len; 03023 memcpy(b->uri, uri, len * sizeof(XML_Char)); 03024 if (namespaceSeparator) 03025 b->uri[len - 1] = namespaceSeparator; 03026 b->prefix = prefix; 03027 b->attId = attId; 03028 b->prevPrefixBinding = prefix->binding; 03029 /* NULL binding when default namespace undeclared */ 03030 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix) 03031 prefix->binding = NULL; 03032 else 03033 prefix->binding = b; 03034 b->nextTagBinding = *bindingsPtr; 03035 *bindingsPtr = b; 03036 /* if attId == NULL then we are not starting a namespace scope */ 03037 if (attId && startNamespaceDeclHandler) 03038 startNamespaceDeclHandler(handlerArg, prefix->name, 03039 prefix->binding ? uri : 0); 03040 return XML_ERROR_NONE; 03041 } 03042 03043 /* The idea here is to avoid using stack for each CDATA section when 03044 the whole file is parsed with one call. 03045 */ 03046 static enum XML_Error PTRCALL 03047 cdataSectionProcessor(XML_Parser parser, 03048 const char *start, 03049 const char *end, 03050 const char **endPtr) 03051 { 03052 enum XML_Error result = doCdataSection(parser, encoding, &start, end, 03053 endPtr, (XML_Bool)!ps_finalBuffer); 03054 if (result != XML_ERROR_NONE) 03055 return result; 03056 if (start) { 03057 if (parentParser) { /* we are parsing an external entity */ 03058 processor = externalEntityContentProcessor; 03059 return externalEntityContentProcessor(parser, start, end, endPtr); 03060 } 03061 else { 03062 processor = contentProcessor; 03063 return contentProcessor(parser, start, end, endPtr); 03064 } 03065 } 03066 return result; 03067 } 03068 03069 /* startPtr gets set to non-null if the section is closed, and to null if 03070 the section is not yet closed. 03071 */ 03072 static enum XML_Error 03073 doCdataSection(XML_Parser parser, 03074 const ENCODING *enc, 03075 const char **startPtr, 03076 const char *end, 03077 const char **nextPtr, 03078 XML_Bool haveMore) 03079 { 03080 const char *s = *startPtr; 03081 const char **eventPP; 03082 const char **eventEndPP; 03083 if (enc == encoding) { 03084 eventPP = &eventPtr; 03085 *eventPP = s; 03086 eventEndPP = &eventEndPtr; 03087 } 03088 else { 03089 eventPP = &(openInternalEntities->internalEventPtr); 03090 eventEndPP = &(openInternalEntities->internalEventEndPtr); 03091 } 03092 *eventPP = s; 03093 *startPtr = NULL; 03094 03095 for (;;) { 03096 const char *next; 03097 int tok = XmlCdataSectionTok(enc, s, end, &next); 03098 *eventEndPP = next; 03099 switch (tok) { 03100 case XML_TOK_CDATA_SECT_CLOSE: 03101 if (endCdataSectionHandler) 03102 endCdataSectionHandler(handlerArg); 03103 #if 0 03104 /* see comment under XML_TOK_CDATA_SECT_OPEN */ 03105 else if (characterDataHandler) 03106 characterDataHandler(handlerArg, dataBuf, 0); 03107 #endif 03108 else if (defaultHandler) 03109 reportDefault(parser, enc, s, next); 03110 *startPtr = next; 03111 *nextPtr = next; 03112 if (ps_parsing == XML_FINISHED) 03113 return XML_ERROR_ABORTED; 03114 else 03115 return XML_ERROR_NONE; 03116 case XML_TOK_DATA_NEWLINE: 03117 if (characterDataHandler) { 03118 XML_Char c = 0xA; 03119 characterDataHandler(handlerArg, &c, 1); 03120 } 03121 else if (defaultHandler) 03122 reportDefault(parser, enc, s, next); 03123 break; 03124 case XML_TOK_DATA_CHARS: 03125 if (characterDataHandler) { 03126 if (MUST_CONVERT(enc, s)) { 03127 for (;;) { 03128 ICHAR *dataPtr = (ICHAR *)dataBuf; 03129 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); 03130 *eventEndPP = next; 03131 characterDataHandler(handlerArg, dataBuf, 03132 (int)(dataPtr - (ICHAR *)dataBuf)); 03133 if (s == next) 03134 break; 03135 *eventPP = s; 03136 } 03137 } 03138 else 03139 characterDataHandler(handlerArg, 03140 (XML_Char *)s, 03141 (int)((XML_Char *)next - (XML_Char *)s)); 03142 } 03143 else if (defaultHandler) 03144 reportDefault(parser, enc, s, next); 03145 break; 03146 case XML_TOK_INVALID: 03147 *eventPP = next; 03148 return XML_ERROR_INVALID_TOKEN; 03149 case XML_TOK_PARTIAL_CHAR: 03150 if (haveMore) { 03151 *nextPtr = s; 03152 return XML_ERROR_NONE; 03153 } 03154 return XML_ERROR_PARTIAL_CHAR; 03155 case XML_TOK_PARTIAL: 03156 case XML_TOK_NONE: 03157 if (haveMore) { 03158 *nextPtr = s; 03159 return XML_ERROR_NONE; 03160 } 03161 return XML_ERROR_UNCLOSED_CDATA_SECTION; 03162 default: 03163 *eventPP = next; 03164 return XML_ERROR_UNEXPECTED_STATE; 03165 } 03166 03167 *eventPP = s = next; 03168 switch (ps_parsing) { 03169 case XML_SUSPENDED: 03170 *nextPtr = next; 03171 return XML_ERROR_NONE; 03172 case XML_FINISHED: 03173 return XML_ERROR_ABORTED; 03174 default: ; 03175 } 03176 } 03177 /* not reached */ 03178 } 03179 03180 #ifdef XML_DTD 03181 03182 /* The idea here is to avoid using stack for each IGNORE section when 03183 the whole file is parsed with one call. 03184 */ 03185 static enum XML_Error PTRCALL 03186 ignoreSectionProcessor(XML_Parser parser, 03187 const char *start, 03188 const char *end, 03189 const char **endPtr) 03190 { 03191 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 03192 endPtr, (XML_Bool)!ps_finalBuffer); 03193 if (result != XML_ERROR_NONE) 03194 return result; 03195 if (start) { 03196 processor = prologProcessor; 03197 return prologProcessor(parser, start, end, endPtr); 03198 } 03199 return result; 03200 } 03201 03202 /* startPtr gets set to non-null is the section is closed, and to null 03203 if the section is not yet closed. 03204 */ 03205 static enum XML_Error 03206 doIgnoreSection(XML_Parser parser, 03207 const ENCODING *enc, 03208 const char **startPtr, 03209 const char *end, 03210 const char **nextPtr, 03211 XML_Bool haveMore) 03212 { 03213 const char *next; 03214 int tok; 03215 const char *s = *startPtr; 03216 const char **eventPP; 03217 const char **eventEndPP; 03218 if (enc == encoding) { 03219 eventPP = &eventPtr; 03220 *eventPP = s; 03221 eventEndPP = &eventEndPtr; 03222 } 03223 else { 03224 eventPP = &(openInternalEntities->internalEventPtr); 03225 eventEndPP = &(openInternalEntities->internalEventEndPtr); 03226 } 03227 *eventPP = s; 03228 *startPtr = NULL; 03229 tok = XmlIgnoreSectionTok(enc, s, end, &next); 03230 *eventEndPP = next; 03231 switch (tok) { 03232 case XML_TOK_IGNORE_SECT: 03233 if (defaultHandler) 03234 reportDefault(parser, enc, s, next); 03235 *startPtr = next; 03236 *nextPtr = next; 03237 if (ps_parsing == XML_FINISHED) 03238 return XML_ERROR_ABORTED; 03239 else 03240 return XML_ERROR_NONE; 03241 case XML_TOK_INVALID: 03242 *eventPP = next; 03243 return XML_ERROR_INVALID_TOKEN; 03244 case XML_TOK_PARTIAL_CHAR: 03245 if (haveMore) { 03246 *nextPtr = s; 03247 return XML_ERROR_NONE; 03248 } 03249 return XML_ERROR_PARTIAL_CHAR; 03250 case XML_TOK_PARTIAL: 03251 case XML_TOK_NONE: 03252 if (haveMore) { 03253 *nextPtr = s; 03254 return XML_ERROR_NONE; 03255 } 03256 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ 03257 default: 03258 *eventPP = next; 03259 return XML_ERROR_UNEXPECTED_STATE; 03260 } 03261 /* not reached */ 03262 } 03263 03264 #endif /* XML_DTD */ 03265 03266 static enum XML_Error 03267 initializeEncoding(XML_Parser parser) 03268 { 03269 const char *s; 03270 #ifdef XML_UNICODE 03271 char encodingBuf[128]; 03272 if (!protocolEncodingName) 03273 s = NULL; 03274 else { 03275 int i; 03276 for (i = 0; protocolEncodingName[i]; i++) { 03277 if (i == sizeof(encodingBuf) - 1 03278 || (protocolEncodingName[i] & ~0x7f) != 0) { 03279 encodingBuf[0] = '\0'; 03280 break; 03281 } 03282 encodingBuf[i] = (char)protocolEncodingName[i]; 03283 } 03284 encodingBuf[i] = '\0'; 03285 s = encodingBuf; 03286 } 03287 #else 03288 s = protocolEncodingName; 03289 #endif 03290 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) 03291 return XML_ERROR_NONE; 03292 return handleUnknownEncoding(parser, protocolEncodingName); 03293 } 03294 03295 static enum XML_Error 03296 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, 03297 const char *s, const char *next) 03298 { 03299 const char *encodingName = NULL; 03300 const XML_Char *storedEncName = NULL; 03301 const ENCODING *newEncoding = NULL; 03302 const char *version = NULL; 03303 const char *versionend; 03304 const XML_Char *storedversion = NULL; 03305 int standalone = -1; 03306 if (!(ns 03307 ? XmlParseXmlDeclNS 03308 : XmlParseXmlDecl)(isGeneralTextEntity, 03309 encoding, 03310 s, 03311 next, 03312 &eventPtr, 03313 &version, 03314 &versionend, 03315 &encodingName, 03316 &newEncoding, 03317 &standalone)) { 03318 if (isGeneralTextEntity) 03319 return XML_ERROR_TEXT_DECL; 03320 else 03321 return XML_ERROR_XML_DECL; 03322 } 03323 if (!isGeneralTextEntity && standalone == 1) { 03324 _dtd->standalone = XML_TRUE; 03325 #ifdef XML_DTD 03326 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) 03327 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 03328 #endif /* XML_DTD */ 03329 } 03330 if (xmlDeclHandler) { 03331 if (encodingName != NULL) { 03332 storedEncName = poolStoreString(&temp2Pool, 03333 encoding, 03334 encodingName, 03335 encodingName 03336 + XmlNameLength(encoding, encodingName)); 03337 if (!storedEncName) 03338 return XML_ERROR_NO_MEMORY; 03339 poolFinish(&temp2Pool); 03340 } 03341 if (version) { 03342 storedversion = poolStoreString(&temp2Pool, 03343 encoding, 03344 version, 03345 versionend - encoding->minBytesPerChar); 03346 if (!storedversion) 03347 return XML_ERROR_NO_MEMORY; 03348 } 03349 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); 03350 } 03351 else if (defaultHandler) 03352 reportDefault(parser, encoding, s, next); 03353 if (protocolEncodingName == NULL) { 03354 if (newEncoding) { 03355 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { 03356 eventPtr = encodingName; 03357 return XML_ERROR_INCORRECT_ENCODING; 03358 } 03359 encoding = newEncoding; 03360 } 03361 else if (encodingName) { 03362 enum XML_Error result; 03363 if (!storedEncName) { 03364 storedEncName = poolStoreString( 03365 &temp2Pool, encoding, encodingName, 03366 encodingName + XmlNameLength(encoding, encodingName)); 03367 if (!storedEncName) 03368 return XML_ERROR_NO_MEMORY; 03369 } 03370 result = handleUnknownEncoding(parser, storedEncName); 03371 poolClear(&temp2Pool); 03372 if (result == XML_ERROR_UNKNOWN_ENCODING) 03373 eventPtr = encodingName; 03374 return result; 03375 } 03376 } 03377 03378 if (storedEncName || storedversion) 03379 poolClear(&temp2Pool); 03380 03381 return XML_ERROR_NONE; 03382 } 03383 03384 static enum XML_Error 03385 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) 03386 { 03387 if (unknownEncodingHandler) { 03388 XML_Encoding info; 03389 int i; 03390 for (i = 0; i < 256; i++) 03391 info.map[i] = -1; 03392 info.convert = NULL; 03393 info.data = NULL; 03394 info.release = NULL; 03395 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, 03396 &info)) { 03397 ENCODING *enc; 03398 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding()); 03399 if (!unknownEncodingMem) { 03400 if (info.release) 03401 info.release(info.data); 03402 return XML_ERROR_NO_MEMORY; 03403 } 03404 enc = (ns 03405 ? XmlInitUnknownEncodingNS 03406 : XmlInitUnknownEncoding)(unknownEncodingMem, 03407 info.map, 03408 info.convert, 03409 info.data); 03410 if (enc) { 03411 unknownEncodingData = info.data; 03412 unknownEncodingRelease = info.release; 03413 encoding = enc; 03414 return XML_ERROR_NONE; 03415 } 03416 } 03417 if (info.release != NULL) 03418 info.release(info.data); 03419 } 03420 return XML_ERROR_UNKNOWN_ENCODING; 03421 } 03422 03423 static enum XML_Error PTRCALL 03424 prologInitProcessor(XML_Parser parser, 03425 const char *s, 03426 const char *end, 03427 const char **nextPtr) 03428 { 03429 enum XML_Error result = initializeEncoding(parser); 03430 if (result != XML_ERROR_NONE) 03431 return result; 03432 processor = prologProcessor; 03433 return prologProcessor(parser, s, end, nextPtr); 03434 } 03435 03436 #ifdef XML_DTD 03437 03438 static enum XML_Error PTRCALL 03439 externalParEntInitProcessor(XML_Parser parser, 03440 const char *s, 03441 const char *end, 03442 const char **nextPtr) 03443 { 03444 enum XML_Error result = initializeEncoding(parser); 03445 if (result != XML_ERROR_NONE) 03446 return result; 03447 03448 /* we know now that XML_Parse(Buffer) has been called, 03449 so we consider the external parameter entity read */ 03450 _dtd->paramEntityRead = XML_TRUE; 03451 03452 if (prologState.inEntityValue) { 03453 processor = entityValueInitProcessor; 03454 return entityValueInitProcessor(parser, s, end, nextPtr); 03455 } 03456 else { 03457 processor = externalParEntProcessor; 03458 return externalParEntProcessor(parser, s, end, nextPtr); 03459 } 03460 } 03461 03462 static enum XML_Error PTRCALL 03463 entityValueInitProcessor(XML_Parser parser, 03464 const char *s, 03465 const char *end, 03466 const char **nextPtr) 03467 { 03468 int tok; 03469 const char *start = s; 03470 const char *next = start; 03471 eventPtr = start; 03472 03473 for (;;) { 03474 tok = XmlPrologTok(encoding, start, end, &next); 03475 eventEndPtr = next; 03476 if (tok <= 0) { 03477 if (!ps_finalBuffer && tok != XML_TOK_INVALID) { 03478 *nextPtr = s; 03479 return XML_ERROR_NONE; 03480 } 03481 switch (tok) { 03482 case XML_TOK_INVALID: 03483 return XML_ERROR_INVALID_TOKEN; 03484 case XML_TOK_PARTIAL: 03485 return XML_ERROR_UNCLOSED_TOKEN; 03486 case XML_TOK_PARTIAL_CHAR: 03487 return XML_ERROR_PARTIAL_CHAR; 03488 case XML_TOK_NONE: /* start == end */ 03489 default: 03490 break; 03491 } 03492 /* found end of entity value - can store it now */ 03493 return storeEntityValue(parser, encoding, s, end); 03494 } 03495 else if (tok == XML_TOK_XML_DECL) { 03496 enum XML_Error result; 03497 result = processXmlDecl(parser, 0, start, next); 03498 if (result != XML_ERROR_NONE) 03499 return result; 03500 switch (ps_parsing) { 03501 case XML_SUSPENDED: 03502 *nextPtr = next; 03503 return XML_ERROR_NONE; 03504 case XML_FINISHED: 03505 return XML_ERROR_ABORTED; 03506 default: 03507 *nextPtr = next; 03508 } 03509 /* stop scanning for text declaration - we found one */ 03510 processor = entityValueProcessor; 03511 return entityValueProcessor(parser, next, end, nextPtr); 03512 } 03513 /* If we are at the end of the buffer, this would cause XmlPrologTok to 03514 return XML_TOK_NONE on the next call, which would then cause the 03515 function to exit with *nextPtr set to s - that is what we want for other 03516 tokens, but not for the BOM - we would rather like to skip it; 03517 then, when this routine is entered the next time, XmlPrologTok will 03518 return XML_TOK_INVALID, since the BOM is still in the buffer 03519 */ 03520 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) { 03521 *nextPtr = next; 03522 return XML_ERROR_NONE; 03523 } 03524 start = next; 03525 eventPtr = start; 03526 } 03527 } 03528 03529 static enum XML_Error PTRCALL 03530 externalParEntProcessor(XML_Parser parser, 03531 const char *s, 03532 const char *end, 03533 const char **nextPtr) 03534 { 03535 const char *next = s; 03536 int tok; 03537 03538 tok = XmlPrologTok(encoding, s, end, &next); 03539 if (tok <= 0) { 03540 if (!ps_finalBuffer && tok != XML_TOK_INVALID) { 03541 *nextPtr = s; 03542 return XML_ERROR_NONE; 03543 } 03544 switch (tok) { 03545 case XML_TOK_INVALID: 03546 return XML_ERROR_INVALID_TOKEN; 03547 case XML_TOK_PARTIAL: 03548 return XML_ERROR_UNCLOSED_TOKEN; 03549 case XML_TOK_PARTIAL_CHAR: 03550 return XML_ERROR_PARTIAL_CHAR; 03551 case XML_TOK_NONE: /* start == end */ 03552 default: 03553 break; 03554 } 03555 } 03556 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. 03557 However, when parsing an external subset, doProlog will not accept a BOM 03558 as valid, and report a syntax error, so we have to skip the BOM 03559 */ 03560 else if (tok == XML_TOK_BOM) { 03561 s = next; 03562 tok = XmlPrologTok(encoding, s, end, &next); 03563 } 03564 03565 processor = prologProcessor; 03566 return doProlog(parser, encoding, s, end, tok, next, 03567 nextPtr, (XML_Bool)!ps_finalBuffer); 03568 } 03569 03570 static enum XML_Error PTRCALL 03571 entityValueProcessor(XML_Parser parser, 03572 const char *s, 03573 const char *end, 03574 const char **nextPtr) 03575 { 03576 const char *start = s; 03577 const char *next = s; 03578 const ENCODING *enc = encoding; 03579 int tok; 03580 03581 for (;;) { 03582 tok = XmlPrologTok(enc, start, end, &next); 03583 if (tok <= 0) { 03584 if (!ps_finalBuffer && tok != XML_TOK_INVALID) { 03585 *nextPtr = s; 03586 return XML_ERROR_NONE; 03587 } 03588 switch (tok) { 03589 case XML_TOK_INVALID: 03590 return XML_ERROR_INVALID_TOKEN; 03591 case XML_TOK_PARTIAL: 03592 return XML_ERROR_UNCLOSED_TOKEN; 03593 case XML_TOK_PARTIAL_CHAR: 03594 return XML_ERROR_PARTIAL_CHAR; 03595 case XML_TOK_NONE: /* start == end */ 03596 default: 03597 break; 03598 } 03599 /* found end of entity value - can store it now */ 03600 return storeEntityValue(parser, enc, s, end); 03601 } 03602 start = next; 03603 } 03604 } 03605 03606 #endif /* XML_DTD */ 03607 03608 static enum XML_Error PTRCALL 03609 prologProcessor(XML_Parser parser, 03610 const char *s, 03611 const char *end, 03612 const char **nextPtr) 03613 { 03614 const char *next = s; 03615 int tok = XmlPrologTok(encoding, s, end, &next); 03616 return doProlog(parser, encoding, s, end, tok, next, 03617 nextPtr, (XML_Bool)!ps_finalBuffer); 03618 } 03619 03620 static enum XML_Error 03621 doProlog(XML_Parser parser, 03622 const ENCODING *enc, 03623 const char *s, 03624 const char *end, 03625 int tok, 03626 const char *next, 03627 const char **nextPtr, 03628 XML_Bool haveMore) 03629 { 03630 #ifdef XML_DTD 03631 static const XML_Char externalSubsetName[] = { '#' , '\0' }; 03632 #endif /* XML_DTD */ 03633 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' }; 03634 static const XML_Char atypeID[] = { 'I', 'D', '\0' }; 03635 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' }; 03636 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' }; 03637 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' }; 03638 static const XML_Char atypeENTITIES[] = 03639 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' }; 03640 static const XML_Char atypeNMTOKEN[] = { 03641 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' }; 03642 static const XML_Char atypeNMTOKENS[] = { 03643 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' }; 03644 static const XML_Char notationPrefix[] = { 03645 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' }; 03646 static const XML_Char enumValueSep[] = { '|', '\0' }; 03647 static const XML_Char enumValueStart[] = { '(', '\0' }; 03648 03649 /* save one level of indirection */ 03650 DTD * const dtd = _dtd; 03651 03652 const char **eventPP; 03653 const char **eventEndPP; 03654 enum XML_Content_Quant quant; 03655 03656 if (enc == encoding) { 03657 eventPP = &eventPtr; 03658 eventEndPP = &eventEndPtr; 03659 } 03660 else { 03661 eventPP = &(openInternalEntities->internalEventPtr); 03662 eventEndPP = &(openInternalEntities->internalEventEndPtr); 03663 } 03664 03665 for (;;) { 03666 int role; 03667 XML_Bool handleDefault = XML_TRUE; 03668 *eventPP = s; 03669 *eventEndPP = next; 03670 if (tok <= 0) { 03671 if (haveMore && tok != XML_TOK_INVALID) { 03672 *nextPtr = s; 03673 return XML_ERROR_NONE; 03674 } 03675 switch (tok) { 03676 case XML_TOK_INVALID: 03677 *eventPP = next; 03678 return XML_ERROR_INVALID_TOKEN; 03679 case XML_TOK_PARTIAL: 03680 return XML_ERROR_UNCLOSED_TOKEN; 03681 case XML_TOK_PARTIAL_CHAR: 03682 return XML_ERROR_PARTIAL_CHAR; 03683 case XML_TOK_NONE: 03684 #ifdef XML_DTD 03685 /* for internal PE NOT referenced between declarations */ 03686 if (enc != encoding && !openInternalEntities->betweenDecl) { 03687 *nextPtr = s; 03688 return XML_ERROR_NONE; 03689 } 03690 /* WFC: PE Between Declarations - must check that PE contains 03691 complete markup, not only for external PEs, but also for 03692 internal PEs if the reference occurs between declarations. 03693 */ 03694 if (isParamEntity || enc != encoding) { 03695 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) 03696 == XML_ROLE_ERROR) 03697 return XML_ERROR_INCOMPLETE_PE; 03698 *nextPtr = s; 03699 return XML_ERROR_NONE; 03700 } 03701 #endif /* XML_DTD */ 03702 return XML_ERROR_NO_ELEMENTS; 03703 default: 03704 tok = -tok; 03705 next = end; 03706 break; 03707 } 03708 } 03709 role = XmlTokenRole(&prologState, tok, s, next, enc); 03710 switch (role) { 03711 case XML_ROLE_XML_DECL: 03712 { 03713 enum XML_Error result = processXmlDecl(parser, 0, s, next); 03714 if (result != XML_ERROR_NONE) 03715 return result; 03716 enc = encoding; 03717 handleDefault = XML_FALSE; 03718 } 03719 break; 03720 case XML_ROLE_DOCTYPE_NAME: 03721 if (startDoctypeDeclHandler) { 03722 doctypeName = poolStoreString(&tempPool, enc, s, next); 03723 if (!doctypeName) 03724 return XML_ERROR_NO_MEMORY; 03725 poolFinish(&tempPool); 03726 doctypePubid = NULL; 03727 handleDefault = XML_FALSE; 03728 } 03729 doctypeSysid = NULL; /* always initialize to NULL */ 03730 break; 03731 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: 03732 if (startDoctypeDeclHandler) { 03733 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid, 03734 doctypePubid, 1); 03735 doctypeName = NULL; 03736 poolClear(&tempPool); 03737 handleDefault = XML_FALSE; 03738 } 03739 break; 03740 #ifdef XML_DTD 03741 case XML_ROLE_TEXT_DECL: 03742 { 03743 enum XML_Error result = processXmlDecl(parser, 1, s, next); 03744 if (result != XML_ERROR_NONE) 03745 return result; 03746 enc = encoding; 03747 handleDefault = XML_FALSE; 03748 } 03749 break; 03750 #endif /* XML_DTD */ 03751 case XML_ROLE_DOCTYPE_PUBLIC_ID: 03752 #ifdef XML_DTD 03753 useForeignDTD = XML_FALSE; 03754 declEntity = (ENTITY *)lookup(&dtd->paramEntities, 03755 externalSubsetName, 03756 sizeof(ENTITY)); 03757 if (!declEntity) 03758 return XML_ERROR_NO_MEMORY; 03759 #endif /* XML_DTD */ 03760 dtd->hasParamEntityRefs = XML_TRUE; 03761 if (startDoctypeDeclHandler) { 03762 if (!XmlIsPublicId(enc, s, next, eventPP)) 03763 return XML_ERROR_PUBLICID; 03764 doctypePubid = poolStoreString(&tempPool, enc, 03765 s + enc->minBytesPerChar, 03766 next - enc->minBytesPerChar); 03767 if (!doctypePubid) 03768 return XML_ERROR_NO_MEMORY; 03769 normalizePublicId((XML_Char *)doctypePubid); 03770 poolFinish(&tempPool); 03771 handleDefault = XML_FALSE; 03772 goto alreadyChecked; 03773 } 03774 /* fall through */ 03775 case XML_ROLE_ENTITY_PUBLIC_ID: 03776 if (!XmlIsPublicId(enc, s, next, eventPP)) 03777 return XML_ERROR_PUBLICID; 03778 alreadyChecked: 03779 if (dtd->keepProcessing && declEntity) { 03780 XML_Char *tem = poolStoreString(&dtd->pool, 03781 enc, 03782 s + enc->minBytesPerChar, 03783 next - enc->minBytesPerChar); 03784 if (!tem) 03785 return XML_ERROR_NO_MEMORY; 03786 normalizePublicId(tem); 03787 declEntity->publicId = tem; 03788 poolFinish(&dtd->pool); 03789 if (entityDeclHandler) 03790 handleDefault = XML_FALSE; 03791 } 03792 break; 03793 case XML_ROLE_DOCTYPE_CLOSE: 03794 if (doctypeName) { 03795 startDoctypeDeclHandler(handlerArg, doctypeName, 03796 doctypeSysid, doctypePubid, 0); 03797 poolClear(&tempPool); 03798 handleDefault = XML_FALSE; 03799 } 03800 /* doctypeSysid will be non-NULL in the case of a previous 03801 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler 03802 was not set, indicating an external subset 03803 */ 03804 #ifdef XML_DTD 03805 if (doctypeSysid || useForeignDTD) { 03806 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 03807 dtd->hasParamEntityRefs = XML_TRUE; 03808 if (paramEntityParsing && externalEntityRefHandler) { 03809 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities, 03810 externalSubsetName, 03811 sizeof(ENTITY)); 03812 if (!entity) 03813 return XML_ERROR_NO_MEMORY; 03814 if (useForeignDTD) 03815 entity->base = curBase; 03816 dtd->paramEntityRead = XML_FALSE; 03817 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 03818 0, 03819 entity->base, 03820 entity->systemId, 03821 entity->publicId)) 03822 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 03823 if (dtd->paramEntityRead) { 03824 if (!dtd->standalone && 03825 notStandaloneHandler && 03826 !notStandaloneHandler(handlerArg)) 03827 return XML_ERROR_NOT_STANDALONE; 03828 } 03829 /* if we didn't read the foreign DTD then this means that there 03830 is no external subset and we must reset dtd->hasParamEntityRefs 03831 */ 03832 else if (!doctypeSysid) 03833 dtd->hasParamEntityRefs = hadParamEntityRefs; 03834 /* end of DTD - no need to update dtd->keepProcessing */ 03835 } 03836 useForeignDTD = XML_FALSE; 03837 } 03838 #endif /* XML_DTD */ 03839 if (endDoctypeDeclHandler) { 03840 endDoctypeDeclHandler(handlerArg); 03841 handleDefault = XML_FALSE; 03842 } 03843 break; 03844 case XML_ROLE_INSTANCE_START: 03845 #ifdef XML_DTD 03846 /* if there is no DOCTYPE declaration then now is the 03847 last chance to read the foreign DTD 03848 */ 03849 if (useForeignDTD) { 03850 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 03851 dtd->hasParamEntityRefs = XML_TRUE; 03852 if (paramEntityParsing && externalEntityRefHandler) { 03853 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities, 03854 externalSubsetName, 03855 sizeof(ENTITY)); 03856 if (!entity) 03857 return XML_ERROR_NO_MEMORY; 03858 entity->base = curBase; 03859 dtd->paramEntityRead = XML_FALSE; 03860 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 03861 0, 03862 entity->base, 03863 entity->systemId, 03864 entity->publicId)) 03865 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 03866 if (dtd->paramEntityRead) { 03867 if (!dtd->standalone && 03868 notStandaloneHandler && 03869 !notStandaloneHandler(handlerArg)) 03870 return XML_ERROR_NOT_STANDALONE; 03871 } 03872 /* if we didn't read the foreign DTD then this means that there 03873 is no external subset and we must reset dtd->hasParamEntityRefs 03874 */ 03875 else 03876 dtd->hasParamEntityRefs = hadParamEntityRefs; 03877 /* end of DTD - no need to update dtd->keepProcessing */ 03878 } 03879 } 03880 #endif /* XML_DTD */ 03881 processor = contentProcessor; 03882 return contentProcessor(parser, s, end, nextPtr); 03883 case XML_ROLE_ATTLIST_ELEMENT_NAME: 03884 declElementType = getElementType(parser, enc, s, next); 03885 if (!declElementType) 03886 return XML_ERROR_NO_MEMORY; 03887 goto checkAttListDeclHandler; 03888 case XML_ROLE_ATTRIBUTE_NAME: 03889 declAttributeId = getAttributeId(parser, enc, s, next); 03890 if (!declAttributeId) 03891 return XML_ERROR_NO_MEMORY; 03892 declAttributeIsCdata = XML_FALSE; 03893 declAttributeType = NULL; 03894 declAttributeIsId = XML_FALSE; 03895 goto checkAttListDeclHandler; 03896 case XML_ROLE_ATTRIBUTE_TYPE_CDATA: 03897 declAttributeIsCdata = XML_TRUE; 03898 declAttributeType = atypeCDATA; 03899 goto checkAttListDeclHandler; 03900 case XML_ROLE_ATTRIBUTE_TYPE_ID: 03901 declAttributeIsId = XML_TRUE; 03902 declAttributeType = atypeID; 03903 goto checkAttListDeclHandler; 03904 case XML_ROLE_ATTRIBUTE_TYPE_IDREF: 03905 declAttributeType = atypeIDREF; 03906 goto checkAttListDeclHandler; 03907 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: 03908 declAttributeType = atypeIDREFS; 03909 goto checkAttListDeclHandler; 03910 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: 03911 declAttributeType = atypeENTITY; 03912 goto checkAttListDeclHandler; 03913 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: 03914 declAttributeType = atypeENTITIES; 03915 goto checkAttListDeclHandler; 03916 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: 03917 declAttributeType = atypeNMTOKEN; 03918 goto checkAttListDeclHandler; 03919 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: 03920 declAttributeType = atypeNMTOKENS; 03921 checkAttListDeclHandler: 03922 if (dtd->keepProcessing && attlistDeclHandler) 03923 handleDefault = XML_FALSE; 03924 break; 03925 case XML_ROLE_ATTRIBUTE_ENUM_VALUE: 03926 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: 03927 if (dtd->keepProcessing && attlistDeclHandler) { 03928 const XML_Char *prefix; 03929 if (declAttributeType) { 03930 prefix = enumValueSep; 03931 } 03932 else { 03933 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE 03934 ? notationPrefix 03935 : enumValueStart); 03936 } 03937 if (!poolAppendString(&tempPool, prefix)) 03938 return XML_ERROR_NO_MEMORY; 03939 if (!poolAppend(&tempPool, enc, s, next)) 03940 return XML_ERROR_NO_MEMORY; 03941 declAttributeType = tempPool.start; 03942 handleDefault = XML_FALSE; 03943 } 03944 break; 03945 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: 03946 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: 03947 if (dtd->keepProcessing) { 03948 if (!defineAttribute(declElementType, declAttributeId, 03949 declAttributeIsCdata, declAttributeIsId, 03950 0, parser)) 03951 return XML_ERROR_NO_MEMORY; 03952 if (attlistDeclHandler && declAttributeType) { 03953 if (*declAttributeType == XML_T('(') 03954 || (*declAttributeType == XML_T('N') 03955 && declAttributeType[1] == XML_T('O'))) { 03956 /* Enumerated or Notation type */ 03957 if (!poolAppendChar(&tempPool, XML_T(')')) 03958 || !poolAppendChar(&tempPool, XML_T('\0'))) 03959 return XML_ERROR_NO_MEMORY; 03960 declAttributeType = tempPool.start; 03961 poolFinish(&tempPool); 03962 } 03963 *eventEndPP = s; 03964 attlistDeclHandler(handlerArg, declElementType->name, 03965 declAttributeId->name, declAttributeType, 03966 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); 03967 poolClear(&tempPool); 03968 handleDefault = XML_FALSE; 03969 } 03970 } 03971 break; 03972 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: 03973 case XML_ROLE_FIXED_ATTRIBUTE_VALUE: 03974 if (dtd->keepProcessing) { 03975 const XML_Char *attVal; 03976 enum XML_Error result = 03977 storeAttributeValue(parser, enc, declAttributeIsCdata, 03978 s + enc->minBytesPerChar, 03979 next - enc->minBytesPerChar, 03980 &dtd->pool); 03981 if (result) 03982 return result; 03983 attVal = poolStart(&dtd->pool); 03984 poolFinish(&dtd->pool); 03985 /* ID attributes aren't allowed to have a default */ 03986 if (!defineAttribute(declElementType, declAttributeId, 03987 declAttributeIsCdata, XML_FALSE, attVal, parser)) 03988 return XML_ERROR_NO_MEMORY; 03989 if (attlistDeclHandler && declAttributeType) { 03990 if (*declAttributeType == XML_T('(') 03991 || (*declAttributeType == XML_T('N') 03992 && declAttributeType[1] == XML_T('O'))) { 03993 /* Enumerated or Notation type */ 03994 if (!poolAppendChar(&tempPool, XML_T(')')) 03995 || !poolAppendChar(&tempPool, XML_T('\0'))) 03996 return XML_ERROR_NO_MEMORY; 03997 declAttributeType = tempPool.start; 03998 poolFinish(&tempPool); 03999 } 04000 *eventEndPP = s; 04001 attlistDeclHandler(handlerArg, declElementType->name, 04002 declAttributeId->name, declAttributeType, 04003 attVal, 04004 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); 04005 poolClear(&tempPool); 04006 handleDefault = XML_FALSE; 04007 } 04008 } 04009 break; 04010 case XML_ROLE_ENTITY_VALUE: 04011 if (dtd->keepProcessing) { 04012 enum XML_Error result = storeEntityValue(parser, enc, 04013 s + enc->minBytesPerChar, 04014 next - enc->minBytesPerChar); 04015 if (declEntity) { 04016 declEntity->textPtr = poolStart(&dtd->entityValuePool); 04017 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); 04018 poolFinish(&dtd->entityValuePool); 04019 if (entityDeclHandler) { 04020 *eventEndPP = s; 04021 entityDeclHandler(handlerArg, 04022 declEntity->name, 04023 declEntity->is_param, 04024 declEntity->textPtr, 04025 declEntity->textLen, 04026 curBase, 0, 0, 0); 04027 handleDefault = XML_FALSE; 04028 } 04029 } 04030 else 04031 poolDiscard(&dtd->entityValuePool); 04032 if (result != XML_ERROR_NONE) 04033 return result; 04034 } 04035 break; 04036 case XML_ROLE_DOCTYPE_SYSTEM_ID: 04037 #ifdef XML_DTD 04038 useForeignDTD = XML_FALSE; 04039 #endif /* XML_DTD */ 04040 dtd->hasParamEntityRefs = XML_TRUE; 04041 if (startDoctypeDeclHandler) { 04042 doctypeSysid = poolStoreString(&tempPool, enc, 04043 s + enc->minBytesPerChar, 04044 next - enc->minBytesPerChar); 04045 if (doctypeSysid == NULL) 04046 return XML_ERROR_NO_MEMORY; 04047 poolFinish(&tempPool); 04048 handleDefault = XML_FALSE; 04049 } 04050 #ifdef XML_DTD 04051 else 04052 /* use externalSubsetName to make doctypeSysid non-NULL 04053 for the case where no startDoctypeDeclHandler is set */ 04054 doctypeSysid = externalSubsetName; 04055 #endif /* XML_DTD */ 04056 if (!dtd->standalone 04057 #ifdef XML_DTD 04058 && !paramEntityParsing 04059 #endif /* XML_DTD */ 04060 && notStandaloneHandler 04061 && !notStandaloneHandler(handlerArg)) 04062 return XML_ERROR_NOT_STANDALONE; 04063 #ifndef XML_DTD 04064 break; 04065 #else /* XML_DTD */ 04066 if (!declEntity) { 04067 declEntity = (ENTITY *)lookup(&dtd->paramEntities, 04068 externalSubsetName, 04069 sizeof(ENTITY)); 04070 if (!declEntity) 04071 return XML_ERROR_NO_MEMORY; 04072 declEntity->publicId = NULL; 04073 } 04074 /* fall through */ 04075 #endif /* XML_DTD */ 04076 case XML_ROLE_ENTITY_SYSTEM_ID: 04077 if (dtd->keepProcessing && declEntity) { 04078 declEntity->systemId = poolStoreString(&dtd->pool, enc, 04079 s + enc->minBytesPerChar, 04080 next - enc->minBytesPerChar); 04081 if (!declEntity->systemId) 04082 return XML_ERROR_NO_MEMORY; 04083 declEntity->base = curBase; 04084 poolFinish(&dtd->pool); 04085 if (entityDeclHandler) 04086 handleDefault = XML_FALSE; 04087 } 04088 break; 04089 case XML_ROLE_ENTITY_COMPLETE: 04090 if (dtd->keepProcessing && declEntity && entityDeclHandler) { 04091 *eventEndPP = s; 04092 entityDeclHandler(handlerArg, 04093 declEntity->name, 04094 declEntity->is_param, 04095 0,0, 04096 declEntity->base, 04097 declEntity->systemId, 04098 declEntity->publicId, 04099 0); 04100 handleDefault = XML_FALSE; 04101 } 04102 break; 04103 case XML_ROLE_ENTITY_NOTATION_NAME: 04104 if (dtd->keepProcessing && declEntity) { 04105 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); 04106 if (!declEntity->notation) 04107 return XML_ERROR_NO_MEMORY; 04108 poolFinish(&dtd->pool); 04109 if (unparsedEntityDeclHandler) { 04110 *eventEndPP = s; 04111 unparsedEntityDeclHandler(handlerArg, 04112 declEntity->name, 04113 declEntity->base, 04114 declEntity->systemId, 04115 declEntity->publicId, 04116 declEntity->notation); 04117 handleDefault = XML_FALSE; 04118 } 04119 else if (entityDeclHandler) { 04120 *eventEndPP = s; 04121 entityDeclHandler(handlerArg, 04122 declEntity->name, 04123 0,0,0, 04124 declEntity->base, 04125 declEntity->systemId, 04126 declEntity->publicId, 04127 declEntity->notation); 04128 handleDefault = XML_FALSE; 04129 } 04130 } 04131 break; 04132 case XML_ROLE_GENERAL_ENTITY_NAME: 04133 { 04134 if (XmlPredefinedEntityName(enc, s, next)) { 04135 declEntity = NULL; 04136 break; 04137 } 04138 if (dtd->keepProcessing) { 04139 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); 04140 if (!name) 04141 return XML_ERROR_NO_MEMORY; 04142 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name, 04143 sizeof(ENTITY)); 04144 if (!declEntity) 04145 return XML_ERROR_NO_MEMORY; 04146 if (declEntity->name != name) { 04147 poolDiscard(&dtd->pool); 04148 declEntity = NULL; 04149 } 04150 else { 04151 poolFinish(&dtd->pool); 04152 declEntity->publicId = NULL; 04153 declEntity->is_param = XML_FALSE; 04154 /* if we have a parent parser or are reading an internal parameter 04155 entity, then the entity declaration is not considered "internal" 04156 */ 04157 declEntity->is_internal = !(parentParser || openInternalEntities); 04158 if (entityDeclHandler) 04159 handleDefault = XML_FALSE; 04160 } 04161 } 04162 else { 04163 poolDiscard(&dtd->pool); 04164 declEntity = NULL; 04165 } 04166 } 04167 break; 04168 case XML_ROLE_PARAM_ENTITY_NAME: 04169 #ifdef XML_DTD 04170 if (dtd->keepProcessing) { 04171 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); 04172 if (!name) 04173 return XML_ERROR_NO_MEMORY; 04174 declEntity = (ENTITY *)lookup(&dtd->paramEntities, 04175 name, sizeof(ENTITY)); 04176 if (!declEntity) 04177 return XML_ERROR_NO_MEMORY; 04178 if (declEntity->name != name) { 04179 poolDiscard(&dtd->pool); 04180 declEntity = NULL; 04181 } 04182 else { 04183 poolFinish(&dtd->pool); 04184 declEntity->publicId = NULL; 04185 declEntity->is_param = XML_TRUE; 04186 /* if we have a parent parser or are reading an internal parameter 04187 entity, then the entity declaration is not considered "internal" 04188 */ 04189 declEntity->is_internal = !(parentParser || openInternalEntities); 04190 if (entityDeclHandler) 04191 handleDefault = XML_FALSE; 04192 } 04193 } 04194 else { 04195 poolDiscard(&dtd->pool); 04196 declEntity = NULL; 04197 } 04198 #else /* not XML_DTD */ 04199 declEntity = NULL; 04200 #endif /* XML_DTD */ 04201 break; 04202 case XML_ROLE_NOTATION_NAME: 04203 declNotationPublicId = NULL; 04204 declNotationName = NULL; 04205 if (notationDeclHandler) { 04206 declNotationName = poolStoreString(&tempPool, enc, s, next); 04207 if (!declNotationName) 04208 return XML_ERROR_NO_MEMORY; 04209 poolFinish(&tempPool); 04210 handleDefault = XML_FALSE; 04211 } 04212 break; 04213 case XML_ROLE_NOTATION_PUBLIC_ID: 04214 if (!XmlIsPublicId(enc, s, next, eventPP)) 04215 return XML_ERROR_PUBLICID; 04216 if (declNotationName) { /* means notationDeclHandler != NULL */ 04217 XML_Char *tem = poolStoreString(&tempPool, 04218 enc, 04219 s + enc->minBytesPerChar, 04220 next - enc->minBytesPerChar); 04221 if (!tem) 04222 return XML_ERROR_NO_MEMORY; 04223 normalizePublicId(tem); 04224 declNotationPublicId = tem; 04225 poolFinish(&tempPool); 04226 handleDefault = XML_FALSE; 04227 } 04228 break; 04229 case XML_ROLE_NOTATION_SYSTEM_ID: 04230 if (declNotationName && notationDeclHandler) { 04231 const XML_Char *systemId 04232 = poolStoreString(&tempPool, enc, 04233 s + enc->minBytesPerChar, 04234 next - enc->minBytesPerChar); 04235 if (!systemId) 04236 return XML_ERROR_NO_MEMORY; 04237 *eventEndPP = s; 04238 notationDeclHandler(handlerArg, 04239 declNotationName, 04240 curBase, 04241 systemId, 04242 declNotationPublicId); 04243 handleDefault = XML_FALSE; 04244 } 04245 poolClear(&tempPool); 04246 break; 04247 case XML_ROLE_NOTATION_NO_SYSTEM_ID: 04248 if (declNotationPublicId && notationDeclHandler) { 04249 *eventEndPP = s; 04250 notationDeclHandler(handlerArg, 04251 declNotationName, 04252 curBase, 04253 0, 04254 declNotationPublicId); 04255 handleDefault = XML_FALSE; 04256 } 04257 poolClear(&tempPool); 04258 break; 04259 case XML_ROLE_ERROR: 04260 switch (tok) { 04261 case XML_TOK_PARAM_ENTITY_REF: 04262 /* PE references in internal subset are 04263 not allowed within declarations. */ 04264 return XML_ERROR_PARAM_ENTITY_REF; 04265 case XML_TOK_XML_DECL: 04266 return XML_ERROR_MISPLACED_XML_PI; 04267 default: 04268 return XML_ERROR_SYNTAX; 04269 } 04270 #ifdef XML_DTD 04271 case XML_ROLE_IGNORE_SECT: 04272 { 04273 enum XML_Error result; 04274 if (defaultHandler) 04275 reportDefault(parser, enc, s, next); 04276 handleDefault = XML_FALSE; 04277 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); 04278 if (result != XML_ERROR_NONE) 04279 return result; 04280 else if (!next) { 04281 processor = ignoreSectionProcessor; 04282 return result; 04283 } 04284 } 04285 break; 04286 #endif /* XML_DTD */ 04287 case XML_ROLE_GROUP_OPEN: 04288 if (prologState.level >= groupSize) { 04289 if (groupSize) { 04290 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); 04291 if (temp == NULL) 04292 return XML_ERROR_NO_MEMORY; 04293 groupConnector = temp; 04294 if (dtd->scaffIndex) { 04295 int *temp = (int *)REALLOC(dtd->scaffIndex, 04296 groupSize * sizeof(int)); 04297 if (temp == NULL) 04298 return XML_ERROR_NO_MEMORY; 04299 dtd->scaffIndex = temp; 04300 } 04301 } 04302 else { 04303 groupConnector = (char *)MALLOC(groupSize = 32); 04304 if (!groupConnector) 04305 return XML_ERROR_NO_MEMORY; 04306 } 04307 } 04308 groupConnector[prologState.level] = 0; 04309 if (dtd->in_eldecl) { 04310 int myindex = nextScaffoldPart(parser); 04311 if (myindex < 0) 04312 return XML_ERROR_NO_MEMORY; 04313 dtd->scaffIndex[dtd->scaffLevel] = myindex; 04314 dtd->scaffLevel++; 04315 dtd->scaffold[myindex].type = XML_CTYPE_SEQ; 04316 if (elementDeclHandler) 04317 handleDefault = XML_FALSE; 04318 } 04319 break; 04320 case XML_ROLE_GROUP_SEQUENCE: 04321 if (groupConnector[prologState.level] == '|') 04322 return XML_ERROR_SYNTAX; 04323 groupConnector[prologState.level] = ','; 04324 if (dtd->in_eldecl && elementDeclHandler) 04325 handleDefault = XML_FALSE; 04326 break; 04327 case XML_ROLE_GROUP_CHOICE: 04328 if (groupConnector[prologState.level] == ',') 04329 return XML_ERROR_SYNTAX; 04330 if (dtd->in_eldecl 04331 && !groupConnector[prologState.level] 04332 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 04333 != XML_CTYPE_MIXED) 04334 ) { 04335 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 04336 = XML_CTYPE_CHOICE; 04337 if (elementDeclHandler) 04338 handleDefault = XML_FALSE; 04339 } 04340 groupConnector[prologState.level] = '|'; 04341 break; 04342 case XML_ROLE_PARAM_ENTITY_REF: 04343 #ifdef XML_DTD 04344 case XML_ROLE_INNER_PARAM_ENTITY_REF: 04345 dtd->hasParamEntityRefs = XML_TRUE; 04346 if (!paramEntityParsing) 04347 dtd->keepProcessing = dtd->standalone; 04348 else { 04349 const XML_Char *name; 04350 ENTITY *entity; 04351 name = poolStoreString(&dtd->pool, enc, 04352 s + enc->minBytesPerChar, 04353 next - enc->minBytesPerChar); 04354 if (!name) 04355 return XML_ERROR_NO_MEMORY; 04356 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0); 04357 poolDiscard(&dtd->pool); 04358 /* first, determine if a check for an existing declaration is needed; 04359 if yes, check that the entity exists, and that it is internal, 04360 otherwise call the skipped entity handler 04361 */ 04362 if (prologState.documentEntity && 04363 (dtd->standalone 04364 ? !openInternalEntities 04365 : !dtd->hasParamEntityRefs)) { 04366 if (!entity) 04367 return XML_ERROR_UNDEFINED_ENTITY; 04368 else if (!entity->is_internal) 04369 return XML_ERROR_ENTITY_DECLARED_IN_PE; 04370 } 04371 else if (!entity) { 04372 dtd->keepProcessing = dtd->standalone; 04373 /* cannot report skipped entities in declarations */ 04374 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { 04375 skippedEntityHandler(handlerArg, name, 1); 04376 handleDefault = XML_FALSE; 04377 } 04378 break; 04379 } 04380 if (entity->open) 04381 return XML_ERROR_RECURSIVE_ENTITY_REF; 04382 if (entity->textPtr) { 04383 enum XML_Error result; 04384 XML_Bool betweenDecl = 04385 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); 04386 result = processInternalEntity(parser, entity, betweenDecl); 04387 if (result != XML_ERROR_NONE) 04388 return result; 04389 handleDefault = XML_FALSE; 04390 break; 04391 } 04392 if (externalEntityRefHandler) { 04393 dtd->paramEntityRead = XML_FALSE; 04394 entity->open = XML_TRUE; 04395 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 04396 0, 04397 entity->base, 04398 entity->systemId, 04399 entity->publicId)) { 04400 entity->open = XML_FALSE; 04401 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 04402 } 04403 entity->open = XML_FALSE; 04404 handleDefault = XML_FALSE; 04405 if (!dtd->paramEntityRead) { 04406 dtd->keepProcessing = dtd->standalone; 04407 break; 04408 } 04409 } 04410 else { 04411 dtd->keepProcessing = dtd->standalone; 04412 break; 04413 } 04414 } 04415 #endif /* XML_DTD */ 04416 if (!dtd->standalone && 04417 notStandaloneHandler && 04418 !notStandaloneHandler(handlerArg)) 04419 return XML_ERROR_NOT_STANDALONE; 04420 break; 04421 04422 /* Element declaration stuff */ 04423 04424 case XML_ROLE_ELEMENT_NAME: 04425 if (elementDeclHandler) { 04426 declElementType = getElementType(parser, enc, s, next); 04427 if (!declElementType) 04428 return XML_ERROR_NO_MEMORY; 04429 dtd->scaffLevel = 0; 04430 dtd->scaffCount = 0; 04431 dtd->in_eldecl = XML_TRUE; 04432 handleDefault = XML_FALSE; 04433 } 04434 break; 04435 04436 case XML_ROLE_CONTENT_ANY: 04437 case XML_ROLE_CONTENT_EMPTY: 04438 if (dtd->in_eldecl) { 04439 if (elementDeclHandler) { 04440 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content)); 04441 if (!content) 04442 return XML_ERROR_NO_MEMORY; 04443 content->quant = XML_CQUANT_NONE; 04444 content->name = NULL; 04445 content->numchildren = 0; 04446 content->children = NULL; 04447 content->type = ((role == XML_ROLE_CONTENT_ANY) ? 04448 XML_CTYPE_ANY : 04449 XML_CTYPE_EMPTY); 04450 *eventEndPP = s; 04451 elementDeclHandler(handlerArg, declElementType->name, content); 04452 handleDefault = XML_FALSE; 04453 } 04454 dtd->in_eldecl = XML_FALSE; 04455 } 04456 break; 04457 04458 case XML_ROLE_CONTENT_PCDATA: 04459 if (dtd->in_eldecl) { 04460 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 04461 = XML_CTYPE_MIXED; 04462 if (elementDeclHandler) 04463 handleDefault = XML_FALSE; 04464 } 04465 break; 04466 04467 case XML_ROLE_CONTENT_ELEMENT: 04468 quant = XML_CQUANT_NONE; 04469 goto elementContent; 04470 case XML_ROLE_CONTENT_ELEMENT_OPT: 04471 quant = XML_CQUANT_OPT; 04472 goto elementContent; 04473 case XML_ROLE_CONTENT_ELEMENT_REP: 04474 quant = XML_CQUANT_REP; 04475 goto elementContent; 04476 case XML_ROLE_CONTENT_ELEMENT_PLUS: 04477 quant = XML_CQUANT_PLUS; 04478 elementContent: 04479 if (dtd->in_eldecl) { 04480 ELEMENT_TYPE *el; 04481 const XML_Char *name; 04482 int nameLen; 04483 const char *nxt = (quant == XML_CQUANT_NONE 04484 ? next 04485 : next - enc->minBytesPerChar); 04486 int myindex = nextScaffoldPart(parser); 04487 if (myindex < 0) 04488 return XML_ERROR_NO_MEMORY; 04489 dtd->scaffold[myindex].type = XML_CTYPE_NAME; 04490 dtd->scaffold[myindex].quant = quant; 04491 el = getElementType(parser, enc, s, nxt); 04492 if (!el) 04493 return XML_ERROR_NO_MEMORY; 04494 name = el->name; 04495 dtd->scaffold[myindex].name = name; 04496 nameLen = 0; 04497 for (; name[nameLen++]; ); 04498 dtd->contentStringLen += nameLen; 04499 if (elementDeclHandler) 04500 handleDefault = XML_FALSE; 04501 } 04502 break; 04503 04504 case XML_ROLE_GROUP_CLOSE: 04505 quant = XML_CQUANT_NONE; 04506 goto closeGroup; 04507 case XML_ROLE_GROUP_CLOSE_OPT: 04508 quant = XML_CQUANT_OPT; 04509 goto closeGroup; 04510 case XML_ROLE_GROUP_CLOSE_REP: 04511 quant = XML_CQUANT_REP; 04512 goto closeGroup; 04513 case XML_ROLE_GROUP_CLOSE_PLUS: 04514 quant = XML_CQUANT_PLUS; 04515 closeGroup: 04516 if (dtd->in_eldecl) { 04517 if (elementDeclHandler) 04518 handleDefault = XML_FALSE; 04519 dtd->scaffLevel--; 04520 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; 04521 if (dtd->scaffLevel == 0) { 04522 if (!handleDefault) { 04523 XML_Content *model = build_model(parser); 04524 if (!model) 04525 return XML_ERROR_NO_MEMORY; 04526 *eventEndPP = s; 04527 elementDeclHandler(handlerArg, declElementType->name, model); 04528 } 04529 dtd->in_eldecl = XML_FALSE; 04530 dtd->contentStringLen = 0; 04531 } 04532 } 04533 break; 04534 /* End element declaration stuff */ 04535 04536 case XML_ROLE_PI: 04537 if (!reportProcessingInstruction(parser, enc, s, next)) 04538 return XML_ERROR_NO_MEMORY; 04539 handleDefault = XML_FALSE; 04540 break; 04541 case XML_ROLE_COMMENT: 04542 if (!reportComment(parser, enc, s, next)) 04543 return XML_ERROR_NO_MEMORY; 04544 handleDefault = XML_FALSE; 04545 break; 04546 case XML_ROLE_NONE: 04547 switch (tok) { 04548 case XML_TOK_BOM: 04549 handleDefault = XML_FALSE; 04550 break; 04551 } 04552 break; 04553 case XML_ROLE_DOCTYPE_NONE: 04554 if (startDoctypeDeclHandler) 04555 handleDefault = XML_FALSE; 04556 break; 04557 case XML_ROLE_ENTITY_NONE: 04558 if (dtd->keepProcessing && entityDeclHandler) 04559 handleDefault = XML_FALSE; 04560 break; 04561 case XML_ROLE_NOTATION_NONE: 04562 if (notationDeclHandler) 04563 handleDefault = XML_FALSE; 04564 break; 04565 case XML_ROLE_ATTLIST_NONE: 04566 if (dtd->keepProcessing && attlistDeclHandler) 04567 handleDefault = XML_FALSE; 04568 break; 04569 case XML_ROLE_ELEMENT_NONE: 04570 if (elementDeclHandler) 04571 handleDefault = XML_FALSE; 04572 break; 04573 } /* end of big switch */ 04574 04575 if (handleDefault && defaultHandler) 04576 reportDefault(parser, enc, s, next); 04577 04578 switch (ps_parsing) { 04579 case XML_SUSPENDED: 04580 *nextPtr = next; 04581 return XML_ERROR_NONE; 04582 case XML_FINISHED: 04583 return XML_ERROR_ABORTED; 04584 default: 04585 s = next; 04586 tok = XmlPrologTok(enc, s, end, &next); 04587 } 04588 } 04589 /* not reached */ 04590 } 04591 04592 static enum XML_Error PTRCALL 04593 epilogProcessor(XML_Parser parser, 04594 const char *s, 04595 const char *end, 04596 const char **nextPtr) 04597 { 04598 processor = epilogProcessor; 04599 eventPtr = s; 04600 for (;;) { 04601 const char *next = NULL; 04602 int tok = XmlPrologTok(encoding, s, end, &next); 04603 eventEndPtr = next; 04604 switch (tok) { 04605 /* report partial linebreak - it might be the last token */ 04606 case -XML_TOK_PROLOG_S: 04607 if (defaultHandler) { 04608 reportDefault(parser, encoding, s, next); 04609 if (ps_parsing == XML_FINISHED) 04610 return XML_ERROR_ABORTED; 04611 } 04612 *nextPtr = next; 04613 return XML_ERROR_NONE; 04614 case XML_TOK_NONE: 04615 *nextPtr = s; 04616 return XML_ERROR_NONE; 04617 case XML_TOK_PROLOG_S: 04618 if (defaultHandler) 04619 reportDefault(parser, encoding, s, next); 04620 break; 04621 case XML_TOK_PI: 04622 if (!reportProcessingInstruction(parser, encoding, s, next)) 04623 return XML_ERROR_NO_MEMORY; 04624 break; 04625 case XML_TOK_COMMENT: 04626 if (!reportComment(parser, encoding, s, next)) 04627 return XML_ERROR_NO_MEMORY; 04628 break; 04629 case XML_TOK_INVALID: 04630 eventPtr = next; 04631 return XML_ERROR_INVALID_TOKEN; 04632 case XML_TOK_PARTIAL: 04633 if (!ps_finalBuffer) { 04634 *nextPtr = s; 04635 return XML_ERROR_NONE; 04636 } 04637 return XML_ERROR_UNCLOSED_TOKEN; 04638 case XML_TOK_PARTIAL_CHAR: 04639 if (!ps_finalBuffer) { 04640 *nextPtr = s; 04641 return XML_ERROR_NONE; 04642 } 04643 return XML_ERROR_PARTIAL_CHAR; 04644 default: 04645 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; 04646 } 04647 eventPtr = s = next; 04648 switch (ps_parsing) { 04649 case XML_SUSPENDED: 04650 *nextPtr = next; 04651 return XML_ERROR_NONE; 04652 case XML_FINISHED: 04653 return XML_ERROR_ABORTED; 04654 default: ; 04655 } 04656 } 04657 } 04658 04659 static enum XML_Error 04660 processInternalEntity(XML_Parser parser, ENTITY *entity, 04661 XML_Bool betweenDecl) 04662 { 04663 const char *textStart, *textEnd; 04664 const char *next; 04665 enum XML_Error result; 04666 OPEN_INTERNAL_ENTITY *openEntity; 04667 04668 if (freeInternalEntities) { 04669 openEntity = freeInternalEntities; 04670 freeInternalEntities = openEntity->next; 04671 } 04672 else { 04673 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY)); 04674 if (!openEntity) 04675 return XML_ERROR_NO_MEMORY; 04676 } 04677 entity->open = XML_TRUE; 04678 entity->processed = 0; 04679 openEntity->next = openInternalEntities; 04680 openInternalEntities = openEntity; 04681 openEntity->entity = entity; 04682 openEntity->startTagLevel = tagLevel; 04683 openEntity->betweenDecl = betweenDecl; 04684 openEntity->internalEventPtr = NULL; 04685 openEntity->internalEventEndPtr = NULL; 04686 textStart = (char *)entity->textPtr; 04687 textEnd = (char *)(entity->textPtr + entity->textLen); 04688 04689 #ifdef XML_DTD 04690 if (entity->is_param) { 04691 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); 04692 result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 04693 next, &next, XML_FALSE); 04694 } 04695 else 04696 #endif /* XML_DTD */ 04697 result = doContent(parser, tagLevel, internalEncoding, textStart, 04698 textEnd, &next, XML_FALSE); 04699 04700 if (result == XML_ERROR_NONE) { 04701 if (textEnd != next && ps_parsing == XML_SUSPENDED) { 04702 entity->processed = (int)(next - textStart); 04703 processor = internalEntityProcessor; 04704 } 04705 else { 04706 entity->open = XML_FALSE; 04707 openInternalEntities = openEntity->next; 04708 /* put openEntity back in list of free instances */ 04709 openEntity->next = freeInternalEntities; 04710 freeInternalEntities = openEntity; 04711 } 04712 } 04713 return result; 04714 } 04715 04716 static enum XML_Error PTRCALL 04717 internalEntityProcessor(XML_Parser parser, 04718 const char *s, 04719 const char *end, 04720 const char **nextPtr) 04721 { 04722 ENTITY *entity; 04723 const char *textStart, *textEnd; 04724 const char *next; 04725 enum XML_Error result; 04726 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities; 04727 if (!openEntity) 04728 return XML_ERROR_UNEXPECTED_STATE; 04729 04730 entity = openEntity->entity; 04731 textStart = ((char *)entity->textPtr) + entity->processed; 04732 textEnd = (char *)(entity->textPtr + entity->textLen); 04733 04734 #ifdef XML_DTD 04735 if (entity->is_param) { 04736 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); 04737 result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 04738 next, &next, XML_FALSE); 04739 } 04740 else 04741 #endif /* XML_DTD */ 04742 result = doContent(parser, openEntity->startTagLevel, internalEncoding, 04743 textStart, textEnd, &next, XML_FALSE); 04744 04745 if (result != XML_ERROR_NONE) 04746 return result; 04747 else if (textEnd != next && ps_parsing == XML_SUSPENDED) { 04748 entity->processed = (int)(next - (char *)entity->textPtr); 04749 return result; 04750 } 04751 else { 04752 entity->open = XML_FALSE; 04753 openInternalEntities = openEntity->next; 04754 /* put openEntity back in list of free instances */ 04755 openEntity->next = freeInternalEntities; 04756 freeInternalEntities = openEntity; 04757 } 04758 04759 #ifdef XML_DTD 04760 if (entity->is_param) { 04761 int tok; 04762 processor = prologProcessor; 04763 tok = XmlPrologTok(encoding, s, end, &next); 04764 return doProlog(parser, encoding, s, end, tok, next, nextPtr, 04765 (XML_Bool)!ps_finalBuffer); 04766 } 04767 else 04768 #endif /* XML_DTD */ 04769 { 04770 processor = contentProcessor; 04771 /* see externalEntityContentProcessor vs contentProcessor */ 04772 return doContent(parser, parentParser ? 1 : 0, encoding, s, end, 04773 nextPtr, (XML_Bool)!ps_finalBuffer); 04774 } 04775 } 04776 04777 static enum XML_Error PTRCALL 04778 errorProcessor(XML_Parser parser, 04779 const char *s, 04780 const char *end, 04781 const char **nextPtr) 04782 { 04783 return errorCode; 04784 } 04785 04786 static enum XML_Error 04787 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 04788 const char *ptr, const char *end, 04789 STRING_POOL *pool) 04790 { 04791 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, 04792 end, pool); 04793 if (result) 04794 return result; 04795 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) 04796 poolChop(pool); 04797 if (!poolAppendChar(pool, XML_T('\0'))) 04798 return XML_ERROR_NO_MEMORY; 04799 return XML_ERROR_NONE; 04800 } 04801 04802 static enum XML_Error 04803 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 04804 const char *ptr, const char *end, 04805 STRING_POOL *pool) 04806 { 04807 DTD * const dtd = _dtd; /* save one level of indirection */ 04808 for (;;) { 04809 const char *next; 04810 int tok = XmlAttributeValueTok(enc, ptr, end, &next); 04811 switch (tok) { 04812 case XML_TOK_NONE: 04813 return XML_ERROR_NONE; 04814 case XML_TOK_INVALID: 04815 if (enc == encoding) 04816 eventPtr = next; 04817 return XML_ERROR_INVALID_TOKEN; 04818 case XML_TOK_PARTIAL: 04819 if (enc == encoding) 04820 eventPtr = ptr; 04821 return XML_ERROR_INVALID_TOKEN; 04822 case XML_TOK_CHAR_REF: 04823 { 04824 XML_Char buf[XML_ENCODE_MAX]; 04825 int i; 04826 int n = XmlCharRefNumber(enc, ptr); 04827 if (n < 0) { 04828 if (enc == encoding) 04829 eventPtr = ptr; 04830 return XML_ERROR_BAD_CHAR_REF; 04831 } 04832 if (!isCdata 04833 && n == 0x20 /* space */ 04834 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 04835 break; 04836 n = XmlEncode(n, (ICHAR *)buf); 04837 if (!n) { 04838 if (enc == encoding) 04839 eventPtr = ptr; 04840 return XML_ERROR_BAD_CHAR_REF; 04841 } 04842 for (i = 0; i < n; i++) { 04843 if (!poolAppendChar(pool, buf[i])) 04844 return XML_ERROR_NO_MEMORY; 04845 } 04846 } 04847 break; 04848 case XML_TOK_DATA_CHARS: 04849 if (!poolAppend(pool, enc, ptr, next)) 04850 return XML_ERROR_NO_MEMORY; 04851 break; 04852 case XML_TOK_TRAILING_CR: 04853 next = ptr + enc->minBytesPerChar; 04854 /* fall through */ 04855 case XML_TOK_ATTRIBUTE_VALUE_S: 04856 case XML_TOK_DATA_NEWLINE: 04857 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 04858 break; 04859 if (!poolAppendChar(pool, 0x20)) 04860 return XML_ERROR_NO_MEMORY; 04861 break; 04862 case XML_TOK_ENTITY_REF: 04863 { 04864 const XML_Char *name; 04865 ENTITY *entity; 04866 char checkEntityDecl; 04867 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, 04868 ptr + enc->minBytesPerChar, 04869 next - enc->minBytesPerChar); 04870 if (ch) { 04871 if (!poolAppendChar(pool, ch)) 04872 return XML_ERROR_NO_MEMORY; 04873 break; 04874 } 04875 name = poolStoreString(&temp2Pool, enc, 04876 ptr + enc->minBytesPerChar, 04877 next - enc->minBytesPerChar); 04878 if (!name) 04879 return XML_ERROR_NO_MEMORY; 04880 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0); 04881 poolDiscard(&temp2Pool); 04882 /* First, determine if a check for an existing declaration is needed; 04883 if yes, check that the entity exists, and that it is internal. 04884 */ 04885 if (pool == &dtd->pool) /* are we called from prolog? */ 04886 checkEntityDecl = 04887 #ifdef XML_DTD 04888 prologState.documentEntity && 04889 #endif /* XML_DTD */ 04890 (dtd->standalone 04891 ? !openInternalEntities 04892 : !dtd->hasParamEntityRefs); 04893 else /* if (pool == &tempPool): we are called from content */ 04894 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; 04895 if (checkEntityDecl) { 04896 if (!entity) 04897 return XML_ERROR_UNDEFINED_ENTITY; 04898 else if (!entity->is_internal) 04899 return XML_ERROR_ENTITY_DECLARED_IN_PE; 04900 } 04901 else if (!entity) { 04902 /* Cannot report skipped entity here - see comments on 04903 skippedEntityHandler. 04904 if (skippedEntityHandler) 04905 skippedEntityHandler(handlerArg, name, 0); 04906 */ 04907 /* Cannot call the default handler because this would be 04908 out of sync with the call to the startElementHandler. 04909 if ((pool == &tempPool) && defaultHandler) 04910 reportDefault(parser, enc, ptr, next); 04911 */ 04912 break; 04913 } 04914 if (entity->open) { 04915 if (enc == encoding) 04916 eventPtr = ptr; 04917 return XML_ERROR_RECURSIVE_ENTITY_REF; 04918 } 04919 if (entity->notation) { 04920 if (enc == encoding) 04921 eventPtr = ptr; 04922 return XML_ERROR_BINARY_ENTITY_REF; 04923 } 04924 if (!entity->textPtr) { 04925 if (enc == encoding) 04926 eventPtr = ptr; 04927 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; 04928 } 04929 else { 04930 enum XML_Error result; 04931 const XML_Char *textEnd = entity->textPtr + entity->textLen; 04932 entity->open = XML_TRUE; 04933 result = appendAttributeValue(parser, internalEncoding, isCdata, 04934 (char *)entity->textPtr, 04935 (char *)textEnd, pool); 04936 entity->open = XML_FALSE; 04937 if (result) 04938 return result; 04939 } 04940 } 04941 break; 04942 default: 04943 if (enc == encoding) 04944 eventPtr = ptr; 04945 return XML_ERROR_UNEXPECTED_STATE; 04946 } 04947 ptr = next; 04948 } 04949 /* not reached */ 04950 } 04951 04952 static enum XML_Error 04953 storeEntityValue(XML_Parser parser, 04954 const ENCODING *enc, 04955 const char *entityTextPtr, 04956 const char *entityTextEnd) 04957 { 04958 DTD * const dtd = _dtd; /* save one level of indirection */ 04959 STRING_POOL *pool = &(dtd->entityValuePool); 04960 enum XML_Error result = XML_ERROR_NONE; 04961 #ifdef XML_DTD 04962 int oldInEntityValue = prologState.inEntityValue; 04963 prologState.inEntityValue = 1; 04964 #endif /* XML_DTD */ 04965 /* never return Null for the value argument in EntityDeclHandler, 04966 since this would indicate an external entity; therefore we 04967 have to make sure that entityValuePool.start is not null */ 04968 if (!pool->blocks) { 04969 if (!poolGrow(pool)) 04970 return XML_ERROR_NO_MEMORY; 04971 } 04972 04973 for (;;) { 04974 const char *next; 04975 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); 04976 switch (tok) { 04977 case XML_TOK_PARAM_ENTITY_REF: 04978 #ifdef XML_DTD 04979 if (isParamEntity || enc != encoding) { 04980 const XML_Char *name; 04981 ENTITY *entity; 04982 name = poolStoreString(&tempPool, enc, 04983 entityTextPtr + enc->minBytesPerChar, 04984 next - enc->minBytesPerChar); 04985 if (!name) { 04986 result = XML_ERROR_NO_MEMORY; 04987 goto endEntityValue; 04988 } 04989 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0); 04990 poolDiscard(&tempPool); 04991 if (!entity) { 04992 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ 04993 /* cannot report skipped entity here - see comments on 04994 skippedEntityHandler 04995 if (skippedEntityHandler) 04996 skippedEntityHandler(handlerArg, name, 0); 04997 */ 04998 dtd->keepProcessing = dtd->standalone; 04999 goto endEntityValue; 05000 } 05001 if (entity->open) { 05002 if (enc == encoding) 05003 eventPtr = entityTextPtr; 05004 result = XML_ERROR_RECURSIVE_ENTITY_REF; 05005 goto endEntityValue; 05006 } 05007 if (entity->systemId) { 05008 if (externalEntityRefHandler) { 05009 dtd->paramEntityRead = XML_FALSE; 05010 entity->open = XML_TRUE; 05011 if (!externalEntityRefHandler(externalEntityRefHandlerArg, 05012 0, 05013 entity->base, 05014 entity->systemId, 05015 entity->publicId)) { 05016 entity->open = XML_FALSE; 05017 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; 05018 goto endEntityValue; 05019 } 05020 entity->open = XML_FALSE; 05021 if (!dtd->paramEntityRead) 05022 dtd->keepProcessing = dtd->standalone; 05023 } 05024 else 05025 dtd->keepProcessing = dtd->standalone; 05026 } 05027 else { 05028 entity->open = XML_TRUE; 05029 result = storeEntityValue(parser, 05030 internalEncoding, 05031 (char *)entity->textPtr, 05032 (char *)(entity->textPtr 05033 + entity->textLen)); 05034 entity->open = XML_FALSE; 05035 if (result) 05036 goto endEntityValue; 05037 } 05038 break; 05039 } 05040 #endif /* XML_DTD */ 05041 /* In the internal subset, PE references are not legal 05042 within markup declarations, e.g entity values in this case. */ 05043 eventPtr = entityTextPtr; 05044 result = XML_ERROR_PARAM_ENTITY_REF; 05045 goto endEntityValue; 05046 case XML_TOK_NONE: 05047 result = XML_ERROR_NONE; 05048 goto endEntityValue; 05049 case XML_TOK_ENTITY_REF: 05050 case XML_TOK_DATA_CHARS: 05051 if (!poolAppend(pool, enc, entityTextPtr, next)) { 05052 result = XML_ERROR_NO_MEMORY; 05053 goto endEntityValue; 05054 } 05055 break; 05056 case XML_TOK_TRAILING_CR: 05057 next = entityTextPtr + enc->minBytesPerChar; 05058 /* fall through */ 05059 case XML_TOK_DATA_NEWLINE: 05060 if (pool->end == pool->ptr && !poolGrow(pool)) { 05061 result = XML_ERROR_NO_MEMORY; 05062 goto endEntityValue; 05063 } 05064 *(pool->ptr)++ = 0xA; 05065 break; 05066 case XML_TOK_CHAR_REF: 05067 { 05068 XML_Char buf[XML_ENCODE_MAX]; 05069 int i; 05070 int n = XmlCharRefNumber(enc, entityTextPtr); 05071 if (n < 0) { 05072 if (enc == encoding) 05073 eventPtr = entityTextPtr; 05074 result = XML_ERROR_BAD_CHAR_REF; 05075 goto endEntityValue; 05076 } 05077 n = XmlEncode(n, (ICHAR *)buf); 05078 if (!n) { 05079 if (enc == encoding) 05080 eventPtr = entityTextPtr; 05081 result = XML_ERROR_BAD_CHAR_REF; 05082 goto endEntityValue; 05083 } 05084 for (i = 0; i < n; i++) { 05085 if (pool->end == pool->ptr && !poolGrow(pool)) { 05086 result = XML_ERROR_NO_MEMORY; 05087 goto endEntityValue; 05088 } 05089 *(pool->ptr)++ = buf[i]; 05090 } 05091 } 05092 break; 05093 case XML_TOK_PARTIAL: 05094 if (enc == encoding) 05095 eventPtr = entityTextPtr; 05096 result = XML_ERROR_INVALID_TOKEN; 05097 goto endEntityValue; 05098 case XML_TOK_INVALID: 05099 if (enc == encoding) 05100 eventPtr = next; 05101 result = XML_ERROR_INVALID_TOKEN; 05102 goto endEntityValue; 05103 default: 05104 if (enc == encoding) 05105 eventPtr = entityTextPtr; 05106 result = XML_ERROR_UNEXPECTED_STATE; 05107 goto endEntityValue; 05108 } 05109 entityTextPtr = next; 05110 } 05111 endEntityValue: 05112 #ifdef XML_DTD 05113 prologState.inEntityValue = oldInEntityValue; 05114 #endif /* XML_DTD */ 05115 return result; 05116 } 05117 05118 static void FASTCALL 05119 normalizeLines(XML_Char *s) 05120 { 05121 XML_Char *p; 05122 for (;; s++) { 05123 if (*s == XML_T('\0')) 05124 return; 05125 if (*s == 0xD) 05126 break; 05127 } 05128 p = s; 05129 do { 05130 if (*s == 0xD) { 05131 *p++ = 0xA; 05132 if (*++s == 0xA) 05133 s++; 05134 } 05135 else 05136 *p++ = *s++; 05137 } while (*s); 05138 *p = XML_T('\0'); 05139 } 05140 05141 static int 05142 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, 05143 const char *start, const char *end) 05144 { 05145 const XML_Char *target; 05146 XML_Char *data; 05147 const char *tem; 05148 if (!processingInstructionHandler) { 05149 if (defaultHandler) 05150 reportDefault(parser, enc, start, end); 05151 return 1; 05152 } 05153 start += enc->minBytesPerChar * 2; 05154 tem = start + XmlNameLength(enc, start); 05155 target = poolStoreString(&tempPool, enc, start, tem); 05156 if (!target) 05157 return 0; 05158 poolFinish(&tempPool); 05159 data = poolStoreString(&tempPool, enc, 05160 XmlSkipS(enc, tem), 05161 end - enc->minBytesPerChar*2); 05162 if (!data) 05163 return 0; 05164 normalizeLines(data); 05165 processingInstructionHandler(handlerArg, target, data); 05166 poolClear(&tempPool); 05167 return 1; 05168 } 05169 05170 static int 05171 reportComment(XML_Parser parser, const ENCODING *enc, 05172 const char *start, const char *end) 05173 { 05174 XML_Char *data; 05175 if (!commentHandler) { 05176 if (defaultHandler) 05177 reportDefault(parser, enc, start, end); 05178 return 1; 05179 } 05180 data = poolStoreString(&tempPool, 05181 enc, 05182 start + enc->minBytesPerChar * 4, 05183 end - enc->minBytesPerChar * 3); 05184 if (!data) 05185 return 0; 05186 normalizeLines(data); 05187 commentHandler(handlerArg, data); 05188 poolClear(&tempPool); 05189 return 1; 05190 } 05191 05192 static void 05193 reportDefault(XML_Parser parser, const ENCODING *enc, 05194 const char *s, const char *end) 05195 { 05196 if (MUST_CONVERT(enc, s)) { 05197 const char **eventPP; 05198 const char **eventEndPP; 05199 if (enc == encoding) { 05200 eventPP = &eventPtr; 05201 eventEndPP = &eventEndPtr; 05202 } 05203 else { 05204 eventPP = &(openInternalEntities->internalEventPtr); 05205 eventEndPP = &(openInternalEntities->internalEventEndPtr); 05206 } 05207 do { 05208 ICHAR *dataPtr = (ICHAR *)dataBuf; 05209 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); 05210 *eventEndPP = s; 05211 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); 05212 *eventPP = s; 05213 } while (s != end); 05214 } 05215 else 05216 defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); 05217 } 05218 05219 05220 static int 05221 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, 05222 XML_Bool isId, const XML_Char *value, XML_Parser parser) 05223 { 05224 DEFAULT_ATTRIBUTE *att; 05225 if (value || isId) { 05226 /* The handling of default attributes gets messed up if we have 05227 a default which duplicates a non-default. */ 05228 int i; 05229 for (i = 0; i < type->nDefaultAtts; i++) 05230 if (attId == type->defaultAtts[i].id) 05231 return 1; 05232 if (isId && !type->idAtt && !attId->xmlns) 05233 type->idAtt = attId; 05234 } 05235 if (type->nDefaultAtts == type->allocDefaultAtts) { 05236 if (type->allocDefaultAtts == 0) { 05237 type->allocDefaultAtts = 8; 05238 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts 05239 * sizeof(DEFAULT_ATTRIBUTE)); 05240 if (!type->defaultAtts) 05241 return 0; 05242 } 05243 else { 05244 DEFAULT_ATTRIBUTE *temp; 05245 int count = type->allocDefaultAtts * 2; 05246 temp = (DEFAULT_ATTRIBUTE *) 05247 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); 05248 if (temp == NULL) 05249 return 0; 05250 type->allocDefaultAtts = count; 05251 type->defaultAtts = temp; 05252 } 05253 } 05254 att = type->defaultAtts + type->nDefaultAtts; 05255 att->id = attId; 05256 att->value = value; 05257 att->isCdata = isCdata; 05258 if (!isCdata) 05259 attId->maybeTokenized = XML_TRUE; 05260 type->nDefaultAtts += 1; 05261 return 1; 05262 } 05263 05264 static int 05265 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) 05266 { 05267 DTD * const dtd = _dtd; /* save one level of indirection */ 05268 const XML_Char *name; 05269 for (name = elementType->name; *name; name++) { 05270 if (*name == XML_T(':')) { 05271 PREFIX *prefix; 05272 const XML_Char *s; 05273 for (s = elementType->name; s != name; s++) { 05274 if (!poolAppendChar(&dtd->pool, *s)) 05275 return 0; 05276 } 05277 if (!poolAppendChar(&dtd->pool, XML_T('\0'))) 05278 return 0; 05279 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), 05280 sizeof(PREFIX)); 05281 if (!prefix) 05282 return 0; 05283 if (prefix->name == poolStart(&dtd->pool)) 05284 poolFinish(&dtd->pool); 05285 else 05286 poolDiscard(&dtd->pool); 05287 elementType->prefix = prefix; 05288 05289 } 05290 } 05291 return 1; 05292 } 05293 05294 static ATTRIBUTE_ID * 05295 getAttributeId(XML_Parser parser, const ENCODING *enc, 05296 const char *start, const char *end) 05297 { 05298 DTD * const dtd = _dtd; /* save one level of indirection */ 05299 ATTRIBUTE_ID *id; 05300 const XML_Char *name; 05301 if (!poolAppendChar(&dtd->pool, XML_T('\0'))) 05302 return NULL; 05303 name = poolStoreString(&dtd->pool, enc, start, end); 05304 if (!name) 05305 return NULL; 05306 /* skip quotation mark - its storage will be re-used (like in name[-1]) */ 05307 ++name; 05308 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); 05309 if (!id) 05310 return NULL; 05311 if (id->name != name) 05312 poolDiscard(&dtd->pool); 05313 else { 05314 poolFinish(&dtd->pool); 05315 if (!ns) 05316 ; 05317 else if (name[0] == XML_T('x') 05318 && name[1] == XML_T('m') 05319 && name[2] == XML_T('l') 05320 && name[3] == XML_T('n') 05321 && name[4] == XML_T('s') 05322 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) { 05323 if (name[5] == XML_T('\0')) 05324 id->prefix = &dtd->defaultPrefix; 05325 else 05326 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX)); 05327 id->xmlns = XML_TRUE; 05328 } 05329 else { 05330 int i; 05331 for (i = 0; name[i]; i++) { 05332 /* attributes without prefix are *not* in the default namespace */ 05333 if (name[i] == XML_T(':')) { 05334 int j; 05335 for (j = 0; j < i; j++) { 05336 if (!poolAppendChar(&dtd->pool, name[j])) 05337 return NULL; 05338 } 05339 if (!poolAppendChar(&dtd->pool, XML_T('\0'))) 05340 return NULL; 05341 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), 05342 sizeof(PREFIX)); 05343 if (id->prefix->name == poolStart(&dtd->pool)) 05344 poolFinish(&dtd->pool); 05345 else 05346 poolDiscard(&dtd->pool); 05347 break; 05348 } 05349 } 05350 } 05351 } 05352 return id; 05353 } 05354 05355 #define CONTEXT_SEP XML_T('\f') 05356 05357 static const XML_Char * 05358 getContext(XML_Parser parser) 05359 { 05360 DTD * const dtd = _dtd; /* save one level of indirection */ 05361 HASH_TABLE_ITER iter; 05362 XML_Bool needSep = XML_FALSE; 05363 05364 if (dtd->defaultPrefix.binding) { 05365 int i; 05366 int len; 05367 if (!poolAppendChar(&tempPool, XML_T('='))) 05368 return NULL; 05369 len = dtd->defaultPrefix.binding->uriLen; 05370 if (namespaceSeparator) 05371 len--; 05372 for (i = 0; i < len; i++) 05373 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) 05374 return NULL; 05375 needSep = XML_TRUE; 05376 } 05377 05378 hashTableIterInit(&iter, &(dtd->prefixes)); 05379 for (;;) { 05380 int i; 05381 int len; 05382 const XML_Char *s; 05383 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); 05384 if (!prefix) 05385 break; 05386 if (!prefix->binding) 05387 continue; 05388 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) 05389 return NULL; 05390 for (s = prefix->name; *s; s++) 05391 if (!poolAppendChar(&tempPool, *s)) 05392 return NULL; 05393 if (!poolAppendChar(&tempPool, XML_T('='))) 05394 return NULL; 05395 len = prefix->binding->uriLen; 05396 if (namespaceSeparator) 05397 len--; 05398 for (i = 0; i < len; i++) 05399 if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) 05400 return NULL; 05401 needSep = XML_TRUE; 05402 } 05403 05404 05405 hashTableIterInit(&iter, &(dtd->generalEntities)); 05406 for (;;) { 05407 const XML_Char *s; 05408 ENTITY *e = (ENTITY *)hashTableIterNext(&iter); 05409 if (!e) 05410 break; 05411 if (!e->open) 05412 continue; 05413 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) 05414 return NULL; 05415 for (s = e->name; *s; s++) 05416 if (!poolAppendChar(&tempPool, *s)) 05417 return 0; 05418 needSep = XML_TRUE; 05419 } 05420 05421 if (!poolAppendChar(&tempPool, XML_T('\0'))) 05422 return NULL; 05423 return tempPool.start; 05424 } 05425 05426 static XML_Bool 05427 setContext(XML_Parser parser, const XML_Char *context) 05428 { 05429 DTD * const dtd = _dtd; /* save one level of indirection */ 05430 const XML_Char *s = context; 05431 05432 while (*context != XML_T('\0')) { 05433 if (*s == CONTEXT_SEP || *s == XML_T('\0')) { 05434 ENTITY *e; 05435 if (!poolAppendChar(&tempPool, XML_T('\0'))) 05436 return XML_FALSE; 05437 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0); 05438 if (e) 05439 e->open = XML_TRUE; 05440 if (*s != XML_T('\0')) 05441 s++; 05442 context = s; 05443 poolDiscard(&tempPool); 05444 } 05445 else if (*s == XML_T('=')) { 05446 PREFIX *prefix; 05447 if (poolLength(&tempPool) == 0) 05448 prefix = &dtd->defaultPrefix; 05449 else { 05450 if (!poolAppendChar(&tempPool, XML_T('\0'))) 05451 return XML_FALSE; 05452 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool), 05453 sizeof(PREFIX)); 05454 if (!prefix) 05455 return XML_FALSE; 05456 if (prefix->name == poolStart(&tempPool)) { 05457 prefix->name = poolCopyString(&dtd->pool, prefix->name); 05458 if (!prefix->name) 05459 return XML_FALSE; 05460 } 05461 poolDiscard(&tempPool); 05462 } 05463 for (context = s + 1; 05464 *context != CONTEXT_SEP && *context != XML_T('\0'); 05465 context++) 05466 if (!poolAppendChar(&tempPool, *context)) 05467 return XML_FALSE; 05468 if (!poolAppendChar(&tempPool, XML_T('\0'))) 05469 return XML_FALSE; 05470 if (addBinding(parser, prefix, NULL, poolStart(&tempPool), 05471 &inheritedBindings) != XML_ERROR_NONE) 05472 return XML_FALSE; 05473 poolDiscard(&tempPool); 05474 if (*context != XML_T('\0')) 05475 ++context; 05476 s = context; 05477 } 05478 else { 05479 if (!poolAppendChar(&tempPool, *s)) 05480 return XML_FALSE; 05481 s++; 05482 } 05483 } 05484 return XML_TRUE; 05485 } 05486 05487 static void FASTCALL 05488 normalizePublicId(XML_Char *publicId) 05489 { 05490 XML_Char *p = publicId; 05491 XML_Char *s; 05492 for (s = publicId; *s; s++) { 05493 switch (*s) { 05494 case 0x20: 05495 case 0xD: 05496 case 0xA: 05497 if (p != publicId && p[-1] != 0x20) 05498 *p++ = 0x20; 05499 break; 05500 default: 05501 *p++ = *s; 05502 } 05503 } 05504 if (p != publicId && p[-1] == 0x20) 05505 --p; 05506 *p = XML_T('\0'); 05507 } 05508 05509 static DTD * 05510 dtdCreate(const XML_Memory_Handling_Suite *ms) 05511 { 05512 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); 05513 if (p == NULL) 05514 return p; 05515 poolInit(&(p->pool), ms); 05516 poolInit(&(p->entityValuePool), ms); 05517 hashTableInit(&(p->generalEntities), ms); 05518 hashTableInit(&(p->elementTypes), ms); 05519 hashTableInit(&(p->attributeIds), ms); 05520 hashTableInit(&(p->prefixes), ms); 05521 #ifdef XML_DTD 05522 p->paramEntityRead = XML_FALSE; 05523 hashTableInit(&(p->paramEntities), ms); 05524 #endif /* XML_DTD */ 05525 p->defaultPrefix.name = NULL; 05526 p->defaultPrefix.binding = NULL; 05527 05528 p->in_eldecl = XML_FALSE; 05529 p->scaffIndex = NULL; 05530 p->scaffold = NULL; 05531 p->scaffLevel = 0; 05532 p->scaffSize = 0; 05533 p->scaffCount = 0; 05534 p->contentStringLen = 0; 05535 05536 p->keepProcessing = XML_TRUE; 05537 p->hasParamEntityRefs = XML_FALSE; 05538 p->standalone = XML_FALSE; 05539 return p; 05540 } 05541 05542 static void 05543 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) 05544 { 05545 HASH_TABLE_ITER iter; 05546 hashTableIterInit(&iter, &(p->elementTypes)); 05547 for (;;) { 05548 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); 05549 if (!e) 05550 break; 05551 if (e->allocDefaultAtts != 0) 05552 ms->free_fcn(e->defaultAtts); 05553 } 05554 hashTableClear(&(p->generalEntities)); 05555 #ifdef XML_DTD 05556 p->paramEntityRead = XML_FALSE; 05557 hashTableClear(&(p->paramEntities)); 05558 #endif /* XML_DTD */ 05559 hashTableClear(&(p->elementTypes)); 05560 hashTableClear(&(p->attributeIds)); 05561 hashTableClear(&(p->prefixes)); 05562 poolClear(&(p->pool)); 05563 poolClear(&(p->entityValuePool)); 05564 p->defaultPrefix.name = NULL; 05565 p->defaultPrefix.binding = NULL; 05566 05567 p->in_eldecl = XML_FALSE; 05568 05569 ms->free_fcn(p->scaffIndex); 05570 p->scaffIndex = NULL; 05571 ms->free_fcn(p->scaffold); 05572 p->scaffold = NULL; 05573 05574 p->scaffLevel = 0; 05575 p->scaffSize = 0; 05576 p->scaffCount = 0; 05577 p->contentStringLen = 0; 05578 05579 p->keepProcessing = XML_TRUE; 05580 p->hasParamEntityRefs = XML_FALSE; 05581 p->standalone = XML_FALSE; 05582 } 05583 05584 static void 05585 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) 05586 { 05587 HASH_TABLE_ITER iter; 05588 hashTableIterInit(&iter, &(p->elementTypes)); 05589 for (;;) { 05590 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); 05591 if (!e) 05592 break; 05593 if (e->allocDefaultAtts != 0) 05594 ms->free_fcn(e->defaultAtts); 05595 } 05596 hashTableDestroy(&(p->generalEntities)); 05597 #ifdef XML_DTD 05598 hashTableDestroy(&(p->paramEntities)); 05599 #endif /* XML_DTD */ 05600 hashTableDestroy(&(p->elementTypes)); 05601 hashTableDestroy(&(p->attributeIds)); 05602 hashTableDestroy(&(p->prefixes)); 05603 poolDestroy(&(p->pool)); 05604 poolDestroy(&(p->entityValuePool)); 05605 if (isDocEntity) { 05606 ms->free_fcn(p->scaffIndex); 05607 ms->free_fcn(p->scaffold); 05608 } 05609 ms->free_fcn(p); 05610 } 05611 05612 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. 05613 The new DTD has already been initialized. 05614 */ 05615 static int 05616 dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms) 05617 { 05618 HASH_TABLE_ITER iter; 05619 05620 /* Copy the prefix table. */ 05621 05622 hashTableIterInit(&iter, &(oldDtd->prefixes)); 05623 for (;;) { 05624 const XML_Char *name; 05625 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); 05626 if (!oldP) 05627 break; 05628 name = poolCopyString(&(newDtd->pool), oldP->name); 05629 if (!name) 05630 return 0; 05631 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX))) 05632 return 0; 05633 } 05634 05635 hashTableIterInit(&iter, &(oldDtd->attributeIds)); 05636 05637 /* Copy the attribute id table. */ 05638 05639 for (;;) { 05640 ATTRIBUTE_ID *newA; 05641 const XML_Char *name; 05642 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); 05643 05644 if (!oldA) 05645 break; 05646 /* Remember to allocate the scratch byte before the name. */ 05647 if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) 05648 return 0; 05649 name = poolCopyString(&(newDtd->pool), oldA->name); 05650 if (!name) 05651 return 0; 05652 ++name; 05653 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, 05654 sizeof(ATTRIBUTE_ID)); 05655 if (!newA) 05656 return 0; 05657 newA->maybeTokenized = oldA->maybeTokenized; 05658 if (oldA->prefix) { 05659 newA->xmlns = oldA->xmlns; 05660 if (oldA->prefix == &oldDtd->defaultPrefix) 05661 newA->prefix = &newDtd->defaultPrefix; 05662 else 05663 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), 05664 oldA->prefix->name, 0); 05665 } 05666 } 05667 05668 /* Copy the element type table. */ 05669 05670 hashTableIterInit(&iter, &(oldDtd->elementTypes)); 05671 05672 for (;;) { 05673 int i; 05674 ELEMENT_TYPE *newE; 05675 const XML_Char *name; 05676 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); 05677 if (!oldE) 05678 break; 05679 name = poolCopyString(&(newDtd->pool), oldE->name); 05680 if (!name) 05681 return 0; 05682 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, 05683 sizeof(ELEMENT_TYPE)); 05684 if (!newE) 05685 return 0; 05686 if (oldE->nDefaultAtts) { 05687 newE->defaultAtts = (DEFAULT_ATTRIBUTE *) 05688 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); 05689 if (!newE->defaultAtts) { 05690 ms->free_fcn(newE); 05691 return 0; 05692 } 05693 } 05694 if (oldE->idAtt) 05695 newE->idAtt = (ATTRIBUTE_ID *) 05696 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0); 05697 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; 05698 if (oldE->prefix) 05699 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), 05700 oldE->prefix->name, 0); 05701 for (i = 0; i < newE->nDefaultAtts; i++) { 05702 newE->defaultAtts[i].id = (ATTRIBUTE_ID *) 05703 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); 05704 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; 05705 if (oldE->defaultAtts[i].value) { 05706 newE->defaultAtts[i].value 05707 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); 05708 if (!newE->defaultAtts[i].value) 05709 return 0; 05710 } 05711 else 05712 newE->defaultAtts[i].value = NULL; 05713 } 05714 } 05715 05716 /* Copy the entity tables. */ 05717 if (!copyEntityTable(&(newDtd->generalEntities), 05718 &(newDtd->pool), 05719 &(oldDtd->generalEntities))) 05720 return 0; 05721 05722 #ifdef XML_DTD 05723 if (!copyEntityTable(&(newDtd->paramEntities), 05724 &(newDtd->pool), 05725 &(oldDtd->paramEntities))) 05726 return 0; 05727 newDtd->paramEntityRead = oldDtd->paramEntityRead; 05728 #endif /* XML_DTD */ 05729 05730 newDtd->keepProcessing = oldDtd->keepProcessing; 05731 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; 05732 newDtd->standalone = oldDtd->standalone; 05733 05734 /* Don't want deep copying for scaffolding */ 05735 newDtd->in_eldecl = oldDtd->in_eldecl; 05736 newDtd->scaffold = oldDtd->scaffold; 05737 newDtd->contentStringLen = oldDtd->contentStringLen; 05738 newDtd->scaffSize = oldDtd->scaffSize; 05739 newDtd->scaffLevel = oldDtd->scaffLevel; 05740 newDtd->scaffIndex = oldDtd->scaffIndex; 05741 05742 return 1; 05743 } /* End dtdCopy */ 05744 05745 static int 05746 copyEntityTable(HASH_TABLE *newTable, 05747 STRING_POOL *newPool, 05748 const HASH_TABLE *oldTable) 05749 { 05750 HASH_TABLE_ITER iter; 05751 const XML_Char *cachedOldBase = NULL; 05752 const XML_Char *cachedNewBase = NULL; 05753 05754 hashTableIterInit(&iter, oldTable); 05755 05756 for (;;) { 05757 ENTITY *newE; 05758 const XML_Char *name; 05759 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); 05760 if (!oldE) 05761 break; 05762 name = poolCopyString(newPool, oldE->name); 05763 if (!name) 05764 return 0; 05765 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY)); 05766 if (!newE) 05767 return 0; 05768 if (oldE->systemId) { 05769 const XML_Char *tem = poolCopyString(newPool, oldE->systemId); 05770 if (!tem) 05771 return 0; 05772 newE->systemId = tem; 05773 if (oldE->base) { 05774 if (oldE->base == cachedOldBase) 05775 newE->base = cachedNewBase; 05776 else { 05777 cachedOldBase = oldE->base; 05778 tem = poolCopyString(newPool, cachedOldBase); 05779 if (!tem) 05780 return 0; 05781 cachedNewBase = newE->base = tem; 05782 } 05783 } 05784 if (oldE->publicId) { 05785 tem = poolCopyString(newPool, oldE->publicId); 05786 if (!tem) 05787 return 0; 05788 newE->publicId = tem; 05789 } 05790 } 05791 else { 05792 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, 05793 oldE->textLen); 05794 if (!tem) 05795 return 0; 05796 newE->textPtr = tem; 05797 newE->textLen = oldE->textLen; 05798 } 05799 if (oldE->notation) { 05800 const XML_Char *tem = poolCopyString(newPool, oldE->notation); 05801 if (!tem) 05802 return 0; 05803 newE->notation = tem; 05804 } 05805 newE->is_param = oldE->is_param; 05806 newE->is_internal = oldE->is_internal; 05807 } 05808 return 1; 05809 } 05810 05811 #define INIT_POWER 6 05812 05813 static XML_Bool FASTCALL 05814 keyeq(KEY s1, KEY s2) 05815 { 05816 for (; *s1 == *s2; s1++, s2++) 05817 if (*s1 == 0) 05818 return XML_TRUE; 05819 return XML_FALSE; 05820 } 05821 05822 static unsigned long FASTCALL 05823 hash(KEY s) 05824 { 05825 unsigned long h = 0; 05826 while (*s) 05827 h = CHAR_HASH(h, *s++); 05828 return h; 05829 } 05830 05831 static NAMED * 05832 lookup(HASH_TABLE *table, KEY name, size_t createSize) 05833 { 05834 size_t i; 05835 if (table->size == 0) { 05836 size_t tsize; 05837 if (!createSize) 05838 return NULL; 05839 table->power = INIT_POWER; 05840 /* table->size is a power of 2 */ 05841 table->size = (size_t)1 << INIT_POWER; 05842 tsize = table->size * sizeof(NAMED *); 05843 table->v = (NAMED **)table->mem->malloc_fcn(tsize); 05844 if (!table->v) { 05845 table->size = 0; 05846 return NULL; 05847 } 05848 memset(table->v, 0, tsize); 05849 i = hash(name) & ((unsigned long)table->size - 1); 05850 } 05851 else { 05852 unsigned long h = hash(name); 05853 unsigned long mask = (unsigned long)table->size - 1; 05854 unsigned char step = 0; 05855 i = h & mask; 05856 while (table->v[i]) { 05857 if (keyeq(name, table->v[i]->name)) 05858 return table->v[i]; 05859 if (!step) 05860 step = PROBE_STEP(h, mask, table->power); 05861 i < step ? (i += table->size - step) : (i -= step); 05862 } 05863 if (!createSize) 05864 return NULL; 05865 05866 /* check for overflow (table is half full) */ 05867 if (table->used >> (table->power - 1)) { 05868 unsigned char newPower = table->power + 1; 05869 size_t newSize = (size_t)1 << newPower; 05870 unsigned long newMask = (unsigned long)newSize - 1; 05871 size_t tsize = newSize * sizeof(NAMED *); 05872 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); 05873 if (!newV) 05874 return NULL; 05875 memset(newV, 0, tsize); 05876 for (i = 0; i < table->size; i++) 05877 if (table->v[i]) { 05878 unsigned long newHash = hash(table->v[i]->name); 05879 size_t j = newHash & newMask; 05880 step = 0; 05881 while (newV[j]) { 05882 if (!step) 05883 step = PROBE_STEP(newHash, newMask, newPower); 05884 j < step ? (j += newSize - step) : (j -= step); 05885 } 05886 newV[j] = table->v[i]; 05887 } 05888 table->mem->free_fcn(table->v); 05889 table->v = newV; 05890 table->power = newPower; 05891 table->size = newSize; 05892 i = h & newMask; 05893 step = 0; 05894 while (table->v[i]) { 05895 if (!step) 05896 step = PROBE_STEP(h, newMask, newPower); 05897 i < step ? (i += newSize - step) : (i -= step); 05898 } 05899 } 05900 } 05901 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); 05902 if (!table->v[i]) 05903 return NULL; 05904 memset(table->v[i], 0, createSize); 05905 table->v[i]->name = name; 05906 (table->used)++; 05907 return table->v[i]; 05908 } 05909 05910 static void FASTCALL 05911 hashTableClear(HASH_TABLE *table) 05912 { 05913 size_t i; 05914 for (i = 0; i < table->size; i++) { 05915 table->mem->free_fcn(table->v[i]); 05916 table->v[i] = NULL; 05917 } 05918 table->used = 0; 05919 } 05920 05921 static void FASTCALL 05922 hashTableDestroy(HASH_TABLE *table) 05923 { 05924 size_t i; 05925 for (i = 0; i < table->size; i++) 05926 table->mem->free_fcn(table->v[i]); 05927 table->mem->free_fcn(table->v); 05928 } 05929 05930 static void FASTCALL 05931 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) 05932 { 05933 p->power = 0; 05934 p->size = 0; 05935 p->used = 0; 05936 p->v = NULL; 05937 p->mem = ms; 05938 } 05939 05940 static void FASTCALL 05941 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) 05942 { 05943 iter->p = table->v; 05944 iter->end = iter->p + table->size; 05945 } 05946 05947 static NAMED * FASTCALL 05948 hashTableIterNext(HASH_TABLE_ITER *iter) 05949 { 05950 while (iter->p != iter->end) { 05951 NAMED *tem = *(iter->p)++; 05952 if (tem) 05953 return tem; 05954 } 05955 return NULL; 05956 } 05957 05958 static void FASTCALL 05959 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) 05960 { 05961 pool->blocks = NULL; 05962 pool->freeBlocks = NULL; 05963 pool->start = NULL; 05964 pool->ptr = NULL; 05965 pool->end = NULL; 05966 pool->mem = ms; 05967 } 05968 05969 static void FASTCALL 05970 poolClear(STRING_POOL *pool) 05971 { 05972 if (!pool->freeBlocks) 05973 pool->freeBlocks = pool->blocks; 05974 else { 05975 BLOCK *p = pool->blocks; 05976 while (p) { 05977 BLOCK *tem = p->next; 05978 p->next = pool->freeBlocks; 05979 pool->freeBlocks = p; 05980 p = tem; 05981 } 05982 } 05983 pool->blocks = NULL; 05984 pool->start = NULL; 05985 pool->ptr = NULL; 05986 pool->end = NULL; 05987 } 05988 05989 static void FASTCALL 05990 poolDestroy(STRING_POOL *pool) 05991 { 05992 BLOCK *p = pool->blocks; 05993 while (p) { 05994 BLOCK *tem = p->next; 05995 pool->mem->free_fcn(p); 05996 p = tem; 05997 } 05998 p = pool->freeBlocks; 05999 while (p) { 06000 BLOCK *tem = p->next; 06001 pool->mem->free_fcn(p); 06002 p = tem; 06003 } 06004 } 06005 06006 static XML_Char * 06007 poolAppend(STRING_POOL *pool, const ENCODING *enc, 06008 const char *ptr, const char *end) 06009 { 06010 if (!pool->ptr && !poolGrow(pool)) 06011 return NULL; 06012 for (;;) { 06013 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); 06014 if (ptr == end) 06015 break; 06016 if (!poolGrow(pool)) 06017 return NULL; 06018 } 06019 return pool->start; 06020 } 06021 06022 static const XML_Char * FASTCALL 06023 poolCopyString(STRING_POOL *pool, const XML_Char *s) 06024 { 06025 do { 06026 if (!poolAppendChar(pool, *s)) 06027 return NULL; 06028 } while (*s++); 06029 s = pool->start; 06030 poolFinish(pool); 06031 return s; 06032 } 06033 06034 static const XML_Char * 06035 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) 06036 { 06037 if (!pool->ptr && !poolGrow(pool)) 06038 return NULL; 06039 for (; n > 0; --n, s++) { 06040 if (!poolAppendChar(pool, *s)) 06041 return NULL; 06042 } 06043 s = pool->start; 06044 poolFinish(pool); 06045 return s; 06046 } 06047 06048 static const XML_Char * FASTCALL 06049 poolAppendString(STRING_POOL *pool, const XML_Char *s) 06050 { 06051 while (*s) { 06052 if (!poolAppendChar(pool, *s)) 06053 return NULL; 06054 s++; 06055 } 06056 return pool->start; 06057 } 06058 06059 static XML_Char * 06060 poolStoreString(STRING_POOL *pool, const ENCODING *enc, 06061 const char *ptr, const char *end) 06062 { 06063 if (!poolAppend(pool, enc, ptr, end)) 06064 return NULL; 06065 if (pool->ptr == pool->end && !poolGrow(pool)) 06066 return NULL; 06067 *(pool->ptr)++ = 0; 06068 return pool->start; 06069 } 06070 06071 static XML_Bool FASTCALL 06072 poolGrow(STRING_POOL *pool) 06073 { 06074 if (pool->freeBlocks) { 06075 if (pool->start == 0) { 06076 pool->blocks = pool->freeBlocks; 06077 pool->freeBlocks = pool->freeBlocks->next; 06078 pool->blocks->next = NULL; 06079 pool->start = pool->blocks->s; 06080 pool->end = pool->start + pool->blocks->size; 06081 pool->ptr = pool->start; 06082 return XML_TRUE; 06083 } 06084 if (pool->end - pool->start < pool->freeBlocks->size) { 06085 BLOCK *tem = pool->freeBlocks->next; 06086 pool->freeBlocks->next = pool->blocks; 06087 pool->blocks = pool->freeBlocks; 06088 pool->freeBlocks = tem; 06089 memcpy(pool->blocks->s, pool->start, 06090 (pool->end - pool->start) * sizeof(XML_Char)); 06091 pool->ptr = pool->blocks->s + (pool->ptr - pool->start); 06092 pool->start = pool->blocks->s; 06093 pool->end = pool->start + pool->blocks->size; 06094 return XML_TRUE; 06095 } 06096 } 06097 if (pool->blocks && pool->start == pool->blocks->s) { 06098 int blockSize = (int)(pool->end - pool->start)*2; 06099 pool->blocks = (BLOCK *) 06100 pool->mem->realloc_fcn(pool->blocks, 06101 (offsetof(BLOCK, s) 06102 + blockSize * sizeof(XML_Char))); 06103 if (pool->blocks == NULL) 06104 return XML_FALSE; 06105 pool->blocks->size = blockSize; 06106 pool->ptr = pool->blocks->s + (pool->ptr - pool->start); 06107 pool->start = pool->blocks->s; 06108 pool->end = pool->start + blockSize; 06109 } 06110 else { 06111 BLOCK *tem; 06112 int blockSize = (int)(pool->end - pool->start); 06113 if (blockSize < INIT_BLOCK_SIZE) 06114 blockSize = INIT_BLOCK_SIZE; 06115 else 06116 blockSize *= 2; 06117 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) 06118 + blockSize * sizeof(XML_Char)); 06119 if (!tem) 06120 return XML_FALSE; 06121 tem->size = blockSize; 06122 tem->next = pool->blocks; 06123 pool->blocks = tem; 06124 if (pool->ptr != pool->start) 06125 memcpy(tem->s, pool->start, 06126 (pool->ptr - pool->start) * sizeof(XML_Char)); 06127 pool->ptr = tem->s + (pool->ptr - pool->start); 06128 pool->start = tem->s; 06129 pool->end = tem->s + blockSize; 06130 } 06131 return XML_TRUE; 06132 } 06133 06134 static int FASTCALL 06135 nextScaffoldPart(XML_Parser parser) 06136 { 06137 DTD * const dtd = _dtd; /* save one level of indirection */ 06138 CONTENT_SCAFFOLD * me; 06139 int next; 06140 06141 if (!dtd->scaffIndex) { 06142 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int)); 06143 if (!dtd->scaffIndex) 06144 return -1; 06145 dtd->scaffIndex[0] = 0; 06146 } 06147 06148 if (dtd->scaffCount >= dtd->scaffSize) { 06149 CONTENT_SCAFFOLD *temp; 06150 if (dtd->scaffold) { 06151 temp = (CONTENT_SCAFFOLD *) 06152 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); 06153 if (temp == NULL) 06154 return -1; 06155 dtd->scaffSize *= 2; 06156 } 06157 else { 06158 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS 06159 * sizeof(CONTENT_SCAFFOLD)); 06160 if (temp == NULL) 06161 return -1; 06162 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; 06163 } 06164 dtd->scaffold = temp; 06165 } 06166 next = dtd->scaffCount++; 06167 me = &dtd->scaffold[next]; 06168 if (dtd->scaffLevel) { 06169 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]]; 06170 if (parent->lastchild) { 06171 dtd->scaffold[parent->lastchild].nextsib = next; 06172 } 06173 if (!parent->childcnt) 06174 parent->firstchild = next; 06175 parent->lastchild = next; 06176 parent->childcnt++; 06177 } 06178 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; 06179 return next; 06180 } 06181 06182 static void 06183 build_node(XML_Parser parser, 06184 int src_node, 06185 XML_Content *dest, 06186 XML_Content **contpos, 06187 XML_Char **strpos) 06188 { 06189 DTD * const dtd = _dtd; /* save one level of indirection */ 06190 dest->type = dtd->scaffold[src_node].type; 06191 dest->quant = dtd->scaffold[src_node].quant; 06192 if (dest->type == XML_CTYPE_NAME) { 06193 const XML_Char *src; 06194 dest->name = *strpos; 06195 src = dtd->scaffold[src_node].name; 06196 for (;;) { 06197 *(*strpos)++ = *src; 06198 if (!*src) 06199 break; 06200 src++; 06201 } 06202 dest->numchildren = 0; 06203 dest->children = NULL; 06204 } 06205 else { 06206 unsigned int i; 06207 int cn; 06208 dest->numchildren = dtd->scaffold[src_node].childcnt; 06209 dest->children = *contpos; 06210 *contpos += dest->numchildren; 06211 for (i = 0, cn = dtd->scaffold[src_node].firstchild; 06212 i < dest->numchildren; 06213 i++, cn = dtd->scaffold[cn].nextsib) { 06214 build_node(parser, cn, &(dest->children[i]), contpos, strpos); 06215 } 06216 dest->name = NULL; 06217 } 06218 } 06219 06220 static XML_Content * 06221 build_model (XML_Parser parser) 06222 { 06223 DTD * const dtd = _dtd; /* save one level of indirection */ 06224 XML_Content *ret; 06225 XML_Content *cpos; 06226 XML_Char * str; 06227 int allocsize = (dtd->scaffCount * sizeof(XML_Content) 06228 + (dtd->contentStringLen * sizeof(XML_Char))); 06229 06230 ret = (XML_Content *)MALLOC(allocsize); 06231 if (!ret) 06232 return NULL; 06233 06234 str = (XML_Char *) (&ret[dtd->scaffCount]); 06235 cpos = &ret[1]; 06236 06237 build_node(parser, 0, ret, &cpos, &str); 06238 return ret; 06239 } 06240 06241 static ELEMENT_TYPE * 06242 getElementType(XML_Parser parser, 06243 const ENCODING *enc, 06244 const char *ptr, 06245 const char *end) 06246 { 06247 DTD * const dtd = _dtd; /* save one level of indirection */ 06248 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); 06249 ELEMENT_TYPE *ret; 06250 06251 if (!name) 06252 return NULL; 06253 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); 06254 if (!ret) 06255 return NULL; 06256 if (ret->name != name) 06257 poolDiscard(&dtd->pool); 06258 else { 06259 poolFinish(&dtd->pool); 06260 if (!setElementTypePrefix(parser, ret)) 06261 return NULL; 06262 } 06263 return ret; 06264 } Generated on Sat May 26 2012 04:32:24 for ReactOS by
1.7.6.1
|