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