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