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