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