1 /*
2 Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
3 See the file COPYING for copying permission.
4 */
5 
6 static char RCSId[]
7   = "$Header: /home/cvs/apr-util/xml/expat/lib/xmlparse.c,v 1.4 2001/08/30 05:44:18 wrowe Exp $";
8 
9 #ifdef COMPILED_FROM_DSP
10 #  include "winconfig.h"
11 #  define XMLPARSEAPI __declspec(dllexport)
12 #  include "expat.h"
13 #  undef XMLPARSEAPI
14 #else
15 #include <config.h>
16 
17 #ifndef HAVE_MEMMOVE
18 #ifdef HAVE_BCOPY
19 #define memmove(d,s,l) bcopy((s),(d),(l))
20 #else
21 #define memmove(d,s,l) ;punting on memmove;
22 #endif
23 #endif
24 
25 #ifdef HAVE_STRING_H
26 #  include <string.h>
27 #endif
28 
29 #ifndef __CYGWIN__
30 #ifdef __declspec
31 #  define XMLPARSEAPI __declspec(dllexport)
32 #endif
33 #endif
34 
35 #include "expat.h"
36 
37 #ifdef __declspec
38 #  undef XMLPARSEAPI
39 #endif
40 #endif /* ndef COMPILED_FROM_DSP */
41 
42 #include <stddef.h>
43 
44 #ifdef XML_UNICODE
45 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
46 #define XmlConvert XmlUtf16Convert
47 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
48 #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
49 #define XmlEncode XmlUtf16Encode
50 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
51 typedef unsigned short ICHAR;
52 #else
53 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
54 #define XmlConvert XmlUtf8Convert
55 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
56 #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
57 #define XmlEncode XmlUtf8Encode
58 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
59 typedef char ICHAR;
60 #endif
61 
62 
63 #ifndef XML_NS
64 
65 #define XmlInitEncodingNS XmlInitEncoding
66 #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
67 #undef XmlGetInternalEncodingNS
68 #define XmlGetInternalEncodingNS XmlGetInternalEncoding
69 #define XmlParseXmlDeclNS XmlParseXmlDecl
70 
71 #endif
72 
73 #ifdef XML_UNICODE_WCHAR_T
74 #define XML_T(x) L ## x
75 #else
76 #define XML_T(x) x
77 #endif
78 
79 /* Round up n to be a multiple of sz, where sz is a power of 2. */
80 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
81 
82 #include "xmltok.h"
83 #include "xmlrole.h"
84 
85 typedef const XML_Char *KEY;
86 
87 typedef struct {
88   KEY name;
89 } NAMED;
90 
91 typedef struct {
92   NAMED **v;
93   size_t size;
94   size_t used;
95   size_t usedLim;
96   XML_Memory_Handling_Suite *mem;
97 } HASH_TABLE;
98 
99 typedef struct {
100   NAMED **p;
101   NAMED **end;
102 } HASH_TABLE_ITER;
103 
104 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
105 #define INIT_DATA_BUF_SIZE 1024
106 #define INIT_ATTS_SIZE 16
107 #define INIT_BLOCK_SIZE 1024
108 #define INIT_BUFFER_SIZE 1024
109 
110 #define EXPAND_SPARE 24
111 
112 typedef struct binding {
113   struct prefix *prefix;
114   struct binding *nextTagBinding;
115   struct binding *prevPrefixBinding;
116   const struct attribute_id *attId;
117   XML_Char *uri;
118   int uriLen;
119   int uriAlloc;
120 } BINDING;
121 
122 typedef struct prefix {
123   const XML_Char *name;
124   BINDING *binding;
125 } PREFIX;
126 
127 typedef struct {
128   const XML_Char *str;
129   const XML_Char *localPart;
130   int uriLen;
131 } TAG_NAME;
132 
133 typedef struct tag {
134   struct tag *parent;
135   const char *rawName;
136   int rawNameLength;
137   TAG_NAME name;
138   char *buf;
139   char *bufEnd;
140   BINDING *bindings;
141 } TAG;
142 
143 typedef struct {
144   const XML_Char *name;
145   const XML_Char *textPtr;
146   int textLen;
147   const XML_Char *systemId;
148   const XML_Char *base;
149   const XML_Char *publicId;
150   const XML_Char *notation;
151   char open;
152   char is_param;
153 } ENTITY;
154 
155 typedef struct {
156   enum XML_Content_Type		type;
157   enum XML_Content_Quant	quant;
158   const XML_Char *		name;
159   int				firstchild;
160   int				lastchild;
161   int				childcnt;
162   int				nextsib;
163 } CONTENT_SCAFFOLD;
164 
165 typedef struct block {
166   struct block *next;
167   int size;
168   XML_Char s[1];
169 } BLOCK;
170 
171 typedef struct {
172   BLOCK *blocks;
173   BLOCK *freeBlocks;
174   const XML_Char *end;
175   XML_Char *ptr;
176   XML_Char *start;
177   XML_Memory_Handling_Suite *mem;
178 } STRING_POOL;
179 
180 /* The XML_Char before the name is used to determine whether
181 an attribute has been specified. */
182 typedef struct attribute_id {
183   XML_Char *name;
184   PREFIX *prefix;
185   char maybeTokenized;
186   char xmlns;
187 } ATTRIBUTE_ID;
188 
189 typedef struct {
190   const ATTRIBUTE_ID *id;
191   char isCdata;
192   const XML_Char *value;
193 } DEFAULT_ATTRIBUTE;
194 
195 typedef struct {
196   const XML_Char *name;
197   PREFIX *prefix;
198   const ATTRIBUTE_ID *idAtt;
199   int nDefaultAtts;
200   int allocDefaultAtts;
201   DEFAULT_ATTRIBUTE *defaultAtts;
202 } ELEMENT_TYPE;
203 
204 typedef struct {
205   HASH_TABLE generalEntities;
206   HASH_TABLE elementTypes;
207   HASH_TABLE attributeIds;
208   HASH_TABLE prefixes;
209   STRING_POOL pool;
210   int complete;
211   int standalone;
212 #ifdef XML_DTD
213   HASH_TABLE paramEntities;
214 #endif /* XML_DTD */
215   PREFIX defaultPrefix;
216   /* === scaffolding for building content model === */
217   int in_eldecl;
218   CONTENT_SCAFFOLD *scaffold;
219   unsigned contentStringLen;
220   unsigned scaffSize;
221   unsigned scaffCount;
222   int scaffLevel;
223   int *scaffIndex;
224 } DTD;
225 
226 typedef struct open_internal_entity {
227   const char *internalEventPtr;
228   const char *internalEventEndPtr;
229   struct open_internal_entity *next;
230   ENTITY *entity;
231 } OPEN_INTERNAL_ENTITY;
232 
233 typedef enum XML_Error Processor(XML_Parser parser,
234 				 const char *start,
235 				 const char *end,
236 				 const char **endPtr);
237 
238 static Processor prologProcessor;
239 static Processor prologInitProcessor;
240 static Processor contentProcessor;
241 static Processor cdataSectionProcessor;
242 #ifdef XML_DTD
243 static Processor ignoreSectionProcessor;
244 #endif /* XML_DTD */
245 static Processor epilogProcessor;
246 static Processor errorProcessor;
247 static Processor externalEntityInitProcessor;
248 static Processor externalEntityInitProcessor2;
249 static Processor externalEntityInitProcessor3;
250 static Processor externalEntityContentProcessor;
251 
252 static enum XML_Error
253 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
254 static enum XML_Error
255 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
256 static enum XML_Error
257 initializeEncoding(XML_Parser parser);
258 static enum XML_Error
259 doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
260 	 const char *end, int tok, const char *next, const char **nextPtr);
261 static enum XML_Error
262 processInternalParamEntity(XML_Parser parser, ENTITY *entity);
263 static enum XML_Error
264 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
265 	  const char *start, const char *end, const char **endPtr);
266 static enum XML_Error
267 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
268 #ifdef XML_DTD
269 static enum XML_Error
270 doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
271 #endif /* XML_DTD */
272 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
273 				TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
274 static
275 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
276 
277 static int
278 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
279 		int isCdata, int isId, const XML_Char *dfltValue,
280 		XML_Parser parser);
281 
282 static enum XML_Error
283 storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
284 		    STRING_POOL *);
285 static enum XML_Error
286 appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
287 		    STRING_POOL *);
288 static ATTRIBUTE_ID *
289 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
290 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
291 static enum XML_Error
292 storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
293 static int
294 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
295 static int
296 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
297 static void
298 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
299 
300 static const XML_Char *getContext(XML_Parser parser);
301 static int setContext(XML_Parser parser, const XML_Char *context);
302 static void normalizePublicId(XML_Char *s);
303 static int dtdInit(DTD *, XML_Parser parser);
304 
305 static void dtdDestroy(DTD *, XML_Parser parser);
306 
307 static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
308 
309 static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
310 			   XML_Parser parser);
311 
312 #ifdef XML_DTD
313 static void dtdSwap(DTD *, DTD *);
314 #endif /* XML_DTD */
315 
316 static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
317 
318 static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
319 
320 static void hashTableDestroy(HASH_TABLE *);
321 static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
322 static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
323 static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
324 static void poolClear(STRING_POOL *);
325 static void poolDestroy(STRING_POOL *);
326 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
327 			    const char *ptr, const char *end);
328 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
329 				  const char *ptr, const char *end);
330 
331 static int poolGrow(STRING_POOL *pool);
332 
333 static int nextScaffoldPart(XML_Parser parser);
334 static XML_Content *build_model(XML_Parser parser);
335 
336 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
337 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
338 static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
339 static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
340 				     const ENCODING *enc,
341 				     const char *ptr,
342 				     const char *end);
343 
344 #define poolStart(pool) ((pool)->start)
345 #define poolEnd(pool) ((pool)->ptr)
346 #define poolLength(pool) ((pool)->ptr - (pool)->start)
347 #define poolChop(pool) ((void)--(pool->ptr))
348 #define poolLastChar(pool) (((pool)->ptr)[-1])
349 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
350 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
351 #define poolAppendChar(pool, c) \
352   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
353    ? 0 \
354    : ((*((pool)->ptr)++ = c), 1))
355 
356 typedef struct {
357   /* The first member must be userData so that the XML_GetUserData macro works. */
358   void *m_userData;
359   void *m_handlerArg;
360   char *m_buffer;
361   XML_Memory_Handling_Suite m_mem;
362   /* first character to be parsed */
363   const char *m_bufferPtr;
364   /* past last character to be parsed */
365   char *m_bufferEnd;
366   /* allocated end of buffer */
367   const char *m_bufferLim;
368   long m_parseEndByteIndex;
369   const char *m_parseEndPtr;
370   XML_Char *m_dataBuf;
371   XML_Char *m_dataBufEnd;
372   XML_StartElementHandler m_startElementHandler;
373   XML_EndElementHandler m_endElementHandler;
374   XML_CharacterDataHandler m_characterDataHandler;
375   XML_ProcessingInstructionHandler m_processingInstructionHandler;
376   XML_CommentHandler m_commentHandler;
377   XML_StartCdataSectionHandler m_startCdataSectionHandler;
378   XML_EndCdataSectionHandler m_endCdataSectionHandler;
379   XML_DefaultHandler m_defaultHandler;
380   XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
381   XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
382   XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
383   XML_NotationDeclHandler m_notationDeclHandler;
384   XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
385   XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
386   XML_NotStandaloneHandler m_notStandaloneHandler;
387   XML_ExternalEntityRefHandler m_externalEntityRefHandler;
388   void *m_externalEntityRefHandlerArg;
389   XML_UnknownEncodingHandler m_unknownEncodingHandler;
390   XML_ElementDeclHandler m_elementDeclHandler;
391   XML_AttlistDeclHandler m_attlistDeclHandler;
392   XML_EntityDeclHandler m_entityDeclHandler;
393   XML_XmlDeclHandler m_xmlDeclHandler;
394   const ENCODING *m_encoding;
395   INIT_ENCODING m_initEncoding;
396   const ENCODING *m_internalEncoding;
397   const XML_Char *m_protocolEncodingName;
398   int m_ns;
399   int m_ns_triplets;
400   void *m_unknownEncodingMem;
401   void *m_unknownEncodingData;
402   void *m_unknownEncodingHandlerData;
403   void (*m_unknownEncodingRelease)(void *);
404   PROLOG_STATE m_prologState;
405   Processor *m_processor;
406   enum XML_Error m_errorCode;
407   const char *m_eventPtr;
408   const char *m_eventEndPtr;
409   const char *m_positionPtr;
410   OPEN_INTERNAL_ENTITY *m_openInternalEntities;
411   int m_defaultExpandInternalEntities;
412   int m_tagLevel;
413   ENTITY *m_declEntity;
414   const XML_Char *m_doctypeName;
415   const XML_Char *m_doctypeSysid;
416   const XML_Char *m_doctypePubid;
417   const XML_Char *m_declAttributeType;
418   const XML_Char *m_declNotationName;
419   const XML_Char *m_declNotationPublicId;
420   ELEMENT_TYPE *m_declElementType;
421   ATTRIBUTE_ID *m_declAttributeId;
422   char m_declAttributeIsCdata;
423   char m_declAttributeIsId;
424   DTD m_dtd;
425   const XML_Char *m_curBase;
426   TAG *m_tagStack;
427   TAG *m_freeTagList;
428   BINDING *m_inheritedBindings;
429   BINDING *m_freeBindingList;
430   int m_attsSize;
431   int m_nSpecifiedAtts;
432   int m_idAttIndex;
433   ATTRIBUTE *m_atts;
434   POSITION m_position;
435   STRING_POOL m_tempPool;
436   STRING_POOL m_temp2Pool;
437   char *m_groupConnector;
438   unsigned m_groupSize;
439   int m_hadExternalDoctype;
440   XML_Char m_namespaceSeparator;
441 #ifdef XML_DTD
442   enum XML_ParamEntityParsing m_paramEntityParsing;
443   XML_Parser m_parentParser;
444 #endif
445 } Parser;
446 
447 #define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
448 #define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
449 #define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
450 
451 #define userData (((Parser *)parser)->m_userData)
452 #define handlerArg (((Parser *)parser)->m_handlerArg)
453 #define startElementHandler (((Parser *)parser)->m_startElementHandler)
454 #define endElementHandler (((Parser *)parser)->m_endElementHandler)
455 #define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
456 #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
457 #define commentHandler (((Parser *)parser)->m_commentHandler)
458 #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
459 #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
460 #define defaultHandler (((Parser *)parser)->m_defaultHandler)
461 #define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
462 #define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
463 #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
464 #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
465 #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
466 #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
467 #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
468 #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
469 #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
470 #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
471 #define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
472 #define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
473 #define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
474 #define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
475 #define encoding (((Parser *)parser)->m_encoding)
476 #define initEncoding (((Parser *)parser)->m_initEncoding)
477 #define internalEncoding (((Parser *)parser)->m_internalEncoding)
478 #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
479 #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
480 #define unknownEncodingHandlerData \
481   (((Parser *)parser)->m_unknownEncodingHandlerData)
482 #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
483 #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
484 #define ns (((Parser *)parser)->m_ns)
485 #define ns_triplets (((Parser *)parser)->m_ns_triplets)
486 #define prologState (((Parser *)parser)->m_prologState)
487 #define processor (((Parser *)parser)->m_processor)
488 #define errorCode (((Parser *)parser)->m_errorCode)
489 #define eventPtr (((Parser *)parser)->m_eventPtr)
490 #define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
491 #define positionPtr (((Parser *)parser)->m_positionPtr)
492 #define position (((Parser *)parser)->m_position)
493 #define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
494 #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
495 #define tagLevel (((Parser *)parser)->m_tagLevel)
496 #define buffer (((Parser *)parser)->m_buffer)
497 #define bufferPtr (((Parser *)parser)->m_bufferPtr)
498 #define bufferEnd (((Parser *)parser)->m_bufferEnd)
499 #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
500 #define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
501 #define bufferLim (((Parser *)parser)->m_bufferLim)
502 #define dataBuf (((Parser *)parser)->m_dataBuf)
503 #define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
504 #define dtd (((Parser *)parser)->m_dtd)
505 #define curBase (((Parser *)parser)->m_curBase)
506 #define declEntity (((Parser *)parser)->m_declEntity)
507 #define doctypeName (((Parser *)parser)->m_doctypeName)
508 #define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
509 #define doctypePubid (((Parser *)parser)->m_doctypePubid)
510 #define declAttributeType (((Parser *)parser)->m_declAttributeType)
511 #define declNotationName (((Parser *)parser)->m_declNotationName)
512 #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
513 #define declElementType (((Parser *)parser)->m_declElementType)
514 #define declAttributeId (((Parser *)parser)->m_declAttributeId)
515 #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
516 #define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
517 #define freeTagList (((Parser *)parser)->m_freeTagList)
518 #define freeBindingList (((Parser *)parser)->m_freeBindingList)
519 #define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
520 #define tagStack (((Parser *)parser)->m_tagStack)
521 #define atts (((Parser *)parser)->m_atts)
522 #define attsSize (((Parser *)parser)->m_attsSize)
523 #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
524 #define idAttIndex (((Parser *)parser)->m_idAttIndex)
525 #define tempPool (((Parser *)parser)->m_tempPool)
526 #define temp2Pool (((Parser *)parser)->m_temp2Pool)
527 #define groupConnector (((Parser *)parser)->m_groupConnector)
528 #define groupSize (((Parser *)parser)->m_groupSize)
529 #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
530 #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
531 #ifdef XML_DTD
532 #define parentParser (((Parser *)parser)->m_parentParser)
533 #define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
534 #endif /* XML_DTD */
535 
536 #ifdef COMPILED_FROM_DSP
DllMain(HINSTANCE h,DWORD r,LPVOID p)537 BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
538   return TRUE;
539 }
540 #endif /* def COMPILED_FROM_DSP */
541 
542 #ifdef _MSC_VER
543 #ifdef _DEBUG
asParser(XML_Parser parser)544 Parser *asParser(XML_Parser parser)
545 {
546   return parser;
547 }
548 #endif
549 #endif
550 
XML_ParserCreate(const XML_Char * encodingName)551 XML_Parser XML_ParserCreate(const XML_Char *encodingName)
552 {
553   return XML_ParserCreate_MM(encodingName, NULL, NULL);
554 }
555 
XML_ParserCreateNS(const XML_Char * encodingName,XML_Char nsSep)556 XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
557 {
558   XML_Char tmp[2];
559   *tmp = nsSep;
560   return XML_ParserCreate_MM(encodingName, NULL, tmp);
561 }
562 
563 XML_Parser
XML_ParserCreate_MM(const XML_Char * encodingName,const XML_Memory_Handling_Suite * memsuite,const XML_Char * nameSep)564 XML_ParserCreate_MM(const XML_Char *encodingName,
565 		    const XML_Memory_Handling_Suite *memsuite,
566 		    const XML_Char *nameSep) {
567 
568   XML_Parser parser;
569   static
570   const XML_Char implicitContext[] = {
571     XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
572     XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
573     XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
574     XML_T('.'), XML_T('w'), XML_T('3'),
575     XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
576     XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
577     XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
578     XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
579     XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
580     XML_T('\0')
581   };
582 
583 
584   if (memsuite) {
585     XML_Memory_Handling_Suite *mtemp;
586     parser = memsuite->malloc_fcn(sizeof(Parser));
587     mtemp = &(((Parser *) parser)->m_mem);
588     mtemp->malloc_fcn = memsuite->malloc_fcn;
589     mtemp->realloc_fcn = memsuite->realloc_fcn;
590     mtemp->free_fcn = memsuite->free_fcn;
591   }
592   else {
593     XML_Memory_Handling_Suite *mtemp;
594     parser = malloc(sizeof(Parser));
595     mtemp = &(((Parser *) parser)->m_mem);
596     mtemp->malloc_fcn = malloc;
597     mtemp->realloc_fcn = realloc;
598     mtemp->free_fcn = free;
599   }
600 
601   if (!parser)
602     return parser;
603   processor = prologInitProcessor;
604   XmlPrologStateInit(&prologState);
605   userData = 0;
606   handlerArg = 0;
607   startElementHandler = 0;
608   endElementHandler = 0;
609   characterDataHandler = 0;
610   processingInstructionHandler = 0;
611   commentHandler = 0;
612   startCdataSectionHandler = 0;
613   endCdataSectionHandler = 0;
614   defaultHandler = 0;
615   startDoctypeDeclHandler = 0;
616   endDoctypeDeclHandler = 0;
617   unparsedEntityDeclHandler = 0;
618   notationDeclHandler = 0;
619   startNamespaceDeclHandler = 0;
620   endNamespaceDeclHandler = 0;
621   notStandaloneHandler = 0;
622   externalEntityRefHandler = 0;
623   externalEntityRefHandlerArg = parser;
624   unknownEncodingHandler = 0;
625   elementDeclHandler = 0;
626   attlistDeclHandler = 0;
627   entityDeclHandler = 0;
628   xmlDeclHandler = 0;
629   buffer = 0;
630   bufferPtr = 0;
631   bufferEnd = 0;
632   parseEndByteIndex = 0;
633   parseEndPtr = 0;
634   bufferLim = 0;
635   declElementType = 0;
636   declAttributeId = 0;
637   declEntity = 0;
638   doctypeName = 0;
639   doctypeSysid = 0;
640   doctypePubid = 0;
641   declAttributeType = 0;
642   declNotationName = 0;
643   declNotationPublicId = 0;
644   memset(&position, 0, sizeof(POSITION));
645   errorCode = XML_ERROR_NONE;
646   eventPtr = 0;
647   eventEndPtr = 0;
648   positionPtr = 0;
649   openInternalEntities = 0;
650   tagLevel = 0;
651   tagStack = 0;
652   freeTagList = 0;
653   freeBindingList = 0;
654   inheritedBindings = 0;
655   attsSize = INIT_ATTS_SIZE;
656   atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
657   nSpecifiedAtts = 0;
658   dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
659   groupSize = 0;
660   groupConnector = 0;
661   hadExternalDoctype = 0;
662   unknownEncodingMem = 0;
663   unknownEncodingRelease = 0;
664   unknownEncodingData = 0;
665   unknownEncodingHandlerData = 0;
666   namespaceSeparator = '!';
667 #ifdef XML_DTD
668   parentParser = 0;
669   paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
670 #endif
671   ns = 0;
672   ns_triplets = 0;
673   poolInit(&tempPool, &(((Parser *) parser)->m_mem));
674   poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
675   protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
676   curBase = 0;
677   if (!dtdInit(&dtd, parser) || !atts || !dataBuf
678       || (encodingName && !protocolEncodingName)) {
679     XML_ParserFree(parser);
680     return 0;
681   }
682   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
683 
684   if (nameSep) {
685     XmlInitEncodingNS(&initEncoding, &encoding, 0);
686     ns = 1;
687     internalEncoding = XmlGetInternalEncodingNS();
688     namespaceSeparator = *nameSep;
689 
690     if (! setContext(parser, implicitContext)) {
691       XML_ParserFree(parser);
692       return 0;
693     }
694   }
695   else {
696     XmlInitEncoding(&initEncoding, &encoding, 0);
697     internalEncoding = XmlGetInternalEncoding();
698   }
699 
700   return parser;
701 }  /* End XML_ParserCreate_MM */
702 
XML_SetEncoding(XML_Parser parser,const XML_Char * encodingName)703 int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
704 {
705   if (!encodingName)
706     protocolEncodingName = 0;
707   else {
708     protocolEncodingName = poolCopyString(&tempPool, encodingName);
709     if (!protocolEncodingName)
710       return 0;
711   }
712   return 1;
713 }
714 
XML_ExternalEntityParserCreate(XML_Parser oldParser,const XML_Char * context,const XML_Char * encodingName)715 XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
716 					  const XML_Char *context,
717 					  const XML_Char *encodingName)
718 {
719   XML_Parser parser = oldParser;
720   DTD *oldDtd = &dtd;
721   XML_StartElementHandler oldStartElementHandler = startElementHandler;
722   XML_EndElementHandler oldEndElementHandler = endElementHandler;
723   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
724   XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
725   XML_CommentHandler oldCommentHandler = commentHandler;
726   XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
727   XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
728   XML_DefaultHandler oldDefaultHandler = defaultHandler;
729   XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
730   XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
731   XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
732   XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
733   XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
734   XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
735   XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
736   XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
737   XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
738   XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
739   XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
740   ELEMENT_TYPE * oldDeclElementType = declElementType;
741 
742   void *oldUserData = userData;
743   void *oldHandlerArg = handlerArg;
744   int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
745   void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
746 #ifdef XML_DTD
747   int oldParamEntityParsing = paramEntityParsing;
748 #endif
749   int oldns_triplets = ns_triplets;
750 
751   if (ns) {
752     XML_Char tmp[2];
753 
754     *tmp = namespaceSeparator;
755     parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
756 				 tmp);
757   }
758   else {
759     parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
760 				 NULL);
761   }
762 
763   if (!parser)
764     return 0;
765 
766   startElementHandler = oldStartElementHandler;
767   endElementHandler = oldEndElementHandler;
768   characterDataHandler = oldCharacterDataHandler;
769   processingInstructionHandler = oldProcessingInstructionHandler;
770   commentHandler = oldCommentHandler;
771   startCdataSectionHandler = oldStartCdataSectionHandler;
772   endCdataSectionHandler = oldEndCdataSectionHandler;
773   defaultHandler = oldDefaultHandler;
774   unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
775   notationDeclHandler = oldNotationDeclHandler;
776   startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
777   endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
778   notStandaloneHandler = oldNotStandaloneHandler;
779   externalEntityRefHandler = oldExternalEntityRefHandler;
780   unknownEncodingHandler = oldUnknownEncodingHandler;
781   elementDeclHandler = oldElementDeclHandler;
782   attlistDeclHandler = oldAttlistDeclHandler;
783   entityDeclHandler = oldEntityDeclHandler;
784   xmlDeclHandler = oldXmlDeclHandler;
785   declElementType = oldDeclElementType;
786   userData = oldUserData;
787   if (oldUserData == oldHandlerArg)
788     handlerArg = userData;
789   else
790     handlerArg = parser;
791   if (oldExternalEntityRefHandlerArg != oldParser)
792     externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
793   defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
794   ns_triplets = oldns_triplets;
795 #ifdef XML_DTD
796   paramEntityParsing = oldParamEntityParsing;
797   if (context) {
798 #endif /* XML_DTD */
799     if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
800       XML_ParserFree(parser);
801       return 0;
802     }
803     processor = externalEntityInitProcessor;
804 #ifdef XML_DTD
805   }
806   else {
807     dtdSwap(&dtd, oldDtd);
808     parentParser = oldParser;
809     XmlPrologStateInitExternalEntity(&prologState);
810     dtd.complete = 1;
811     hadExternalDoctype = 1;
812   }
813 #endif /* XML_DTD */
814   return parser;
815 }
816 
817 static
destroyBindings(BINDING * bindings,XML_Parser parser)818 void destroyBindings(BINDING *bindings, XML_Parser parser)
819 {
820   for (;;) {
821     BINDING *b = bindings;
822     if (!b)
823       break;
824     bindings = b->nextTagBinding;
825     FREE(b->uri);
826     FREE(b);
827   }
828 }
829 
XML_ParserFree(XML_Parser parser)830 void XML_ParserFree(XML_Parser parser)
831 {
832   for (;;) {
833     TAG *p;
834     if (tagStack == 0) {
835       if (freeTagList == 0)
836 	break;
837       tagStack = freeTagList;
838       freeTagList = 0;
839     }
840     p = tagStack;
841     tagStack = tagStack->parent;
842     FREE(p->buf);
843     destroyBindings(p->bindings, parser);
844     FREE(p);
845   }
846   destroyBindings(freeBindingList, parser);
847   destroyBindings(inheritedBindings, parser);
848   poolDestroy(&tempPool);
849   poolDestroy(&temp2Pool);
850 #ifdef XML_DTD
851   if (parentParser) {
852     if (hadExternalDoctype)
853       dtd.complete = 0;
854     dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
855   }
856 #endif /* XML_DTD */
857   dtdDestroy(&dtd, parser);
858   FREE((void *)atts);
859   if (groupConnector)
860     FREE(groupConnector);
861   if (buffer)
862     FREE(buffer);
863   FREE(dataBuf);
864   if (unknownEncodingMem)
865     FREE(unknownEncodingMem);
866   if (unknownEncodingRelease)
867     unknownEncodingRelease(unknownEncodingData);
868   FREE(parser);
869 }
870 
XML_UseParserAsHandlerArg(XML_Parser parser)871 void XML_UseParserAsHandlerArg(XML_Parser parser)
872 {
873   handlerArg = parser;
874 }
875 
876 void
XML_SetReturnNSTriplet(XML_Parser parser,int do_nst)877 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
878   ns_triplets = do_nst;
879 }
880 
XML_SetUserData(XML_Parser parser,void * p)881 void XML_SetUserData(XML_Parser parser, void *p)
882 {
883   if (handlerArg == userData)
884     handlerArg = userData = p;
885   else
886     userData = p;
887 }
888 
XML_SetBase(XML_Parser parser,const XML_Char * p)889 int XML_SetBase(XML_Parser parser, const XML_Char *p)
890 {
891   if (p) {
892     p = poolCopyString(&dtd.pool, p);
893     if (!p)
894       return 0;
895     curBase = p;
896   }
897   else
898     curBase = 0;
899   return 1;
900 }
901 
XML_GetBase(XML_Parser parser)902 const XML_Char *XML_GetBase(XML_Parser parser)
903 {
904   return curBase;
905 }
906 
XML_GetSpecifiedAttributeCount(XML_Parser parser)907 int XML_GetSpecifiedAttributeCount(XML_Parser parser)
908 {
909   return nSpecifiedAtts;
910 }
911 
XML_GetIdAttributeIndex(XML_Parser parser)912 int XML_GetIdAttributeIndex(XML_Parser parser)
913 {
914   return idAttIndex;
915 }
916 
XML_SetElementHandler(XML_Parser parser,XML_StartElementHandler start,XML_EndElementHandler end)917 void XML_SetElementHandler(XML_Parser parser,
918 			   XML_StartElementHandler start,
919 			   XML_EndElementHandler end)
920 {
921   startElementHandler = start;
922   endElementHandler = end;
923 }
924 
XML_SetStartElementHandler(XML_Parser parser,XML_StartElementHandler start)925 void XML_SetStartElementHandler(XML_Parser parser,
926 				XML_StartElementHandler start) {
927   startElementHandler = start;
928 }
929 
XML_SetEndElementHandler(XML_Parser parser,XML_EndElementHandler end)930 void XML_SetEndElementHandler(XML_Parser parser,
931 			      XML_EndElementHandler end) {
932   endElementHandler = end;
933 }
934 
XML_SetCharacterDataHandler(XML_Parser parser,XML_CharacterDataHandler handler)935 void XML_SetCharacterDataHandler(XML_Parser parser,
936 				 XML_CharacterDataHandler handler)
937 {
938   characterDataHandler = handler;
939 }
940 
XML_SetProcessingInstructionHandler(XML_Parser parser,XML_ProcessingInstructionHandler handler)941 void XML_SetProcessingInstructionHandler(XML_Parser parser,
942 					 XML_ProcessingInstructionHandler handler)
943 {
944   processingInstructionHandler = handler;
945 }
946 
XML_SetCommentHandler(XML_Parser parser,XML_CommentHandler handler)947 void XML_SetCommentHandler(XML_Parser parser,
948 			   XML_CommentHandler handler)
949 {
950   commentHandler = handler;
951 }
952 
XML_SetCdataSectionHandler(XML_Parser parser,XML_StartCdataSectionHandler start,XML_EndCdataSectionHandler end)953 void XML_SetCdataSectionHandler(XML_Parser parser,
954 				XML_StartCdataSectionHandler start,
955 			        XML_EndCdataSectionHandler end)
956 {
957   startCdataSectionHandler = start;
958   endCdataSectionHandler = end;
959 }
960 
XML_SetStartCdataSectionHandler(XML_Parser parser,XML_StartCdataSectionHandler start)961 void XML_SetStartCdataSectionHandler(XML_Parser parser,
962                                      XML_StartCdataSectionHandler start) {
963   startCdataSectionHandler = start;
964 }
965 
XML_SetEndCdataSectionHandler(XML_Parser parser,XML_EndCdataSectionHandler end)966 void XML_SetEndCdataSectionHandler(XML_Parser parser,
967                                    XML_EndCdataSectionHandler end) {
968   endCdataSectionHandler = end;
969 }
970 
XML_SetDefaultHandler(XML_Parser parser,XML_DefaultHandler handler)971 void XML_SetDefaultHandler(XML_Parser parser,
972 			   XML_DefaultHandler handler)
973 {
974   defaultHandler = handler;
975   defaultExpandInternalEntities = 0;
976 }
977 
XML_SetDefaultHandlerExpand(XML_Parser parser,XML_DefaultHandler handler)978 void XML_SetDefaultHandlerExpand(XML_Parser parser,
979 				 XML_DefaultHandler handler)
980 {
981   defaultHandler = handler;
982   defaultExpandInternalEntities = 1;
983 }
984 
XML_SetDoctypeDeclHandler(XML_Parser parser,XML_StartDoctypeDeclHandler start,XML_EndDoctypeDeclHandler end)985 void XML_SetDoctypeDeclHandler(XML_Parser parser,
986 			       XML_StartDoctypeDeclHandler start,
987 			       XML_EndDoctypeDeclHandler end)
988 {
989   startDoctypeDeclHandler = start;
990   endDoctypeDeclHandler = end;
991 }
992 
XML_SetStartDoctypeDeclHandler(XML_Parser parser,XML_StartDoctypeDeclHandler start)993 void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
994 				    XML_StartDoctypeDeclHandler start) {
995   startDoctypeDeclHandler = start;
996 }
997 
XML_SetEndDoctypeDeclHandler(XML_Parser parser,XML_EndDoctypeDeclHandler end)998 void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
999 				  XML_EndDoctypeDeclHandler end) {
1000   endDoctypeDeclHandler = end;
1001 }
1002 
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,XML_UnparsedEntityDeclHandler handler)1003 void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1004 				      XML_UnparsedEntityDeclHandler handler)
1005 {
1006   unparsedEntityDeclHandler = handler;
1007 }
1008 
XML_SetNotationDeclHandler(XML_Parser parser,XML_NotationDeclHandler handler)1009 void XML_SetNotationDeclHandler(XML_Parser parser,
1010 				XML_NotationDeclHandler handler)
1011 {
1012   notationDeclHandler = handler;
1013 }
1014 
XML_SetNamespaceDeclHandler(XML_Parser parser,XML_StartNamespaceDeclHandler start,XML_EndNamespaceDeclHandler end)1015 void XML_SetNamespaceDeclHandler(XML_Parser parser,
1016 				 XML_StartNamespaceDeclHandler start,
1017 				 XML_EndNamespaceDeclHandler end)
1018 {
1019   startNamespaceDeclHandler = start;
1020   endNamespaceDeclHandler = end;
1021 }
1022 
XML_SetStartNamespaceDeclHandler(XML_Parser parser,XML_StartNamespaceDeclHandler start)1023 void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1024 				      XML_StartNamespaceDeclHandler start) {
1025   startNamespaceDeclHandler = start;
1026 }
1027 
XML_SetEndNamespaceDeclHandler(XML_Parser parser,XML_EndNamespaceDeclHandler end)1028 void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1029 				    XML_EndNamespaceDeclHandler end) {
1030   endNamespaceDeclHandler = end;
1031 }
1032 
1033 
XML_SetNotStandaloneHandler(XML_Parser parser,XML_NotStandaloneHandler handler)1034 void XML_SetNotStandaloneHandler(XML_Parser parser,
1035 				 XML_NotStandaloneHandler handler)
1036 {
1037   notStandaloneHandler = handler;
1038 }
1039 
XML_SetExternalEntityRefHandler(XML_Parser parser,XML_ExternalEntityRefHandler handler)1040 void XML_SetExternalEntityRefHandler(XML_Parser parser,
1041 				     XML_ExternalEntityRefHandler handler)
1042 {
1043   externalEntityRefHandler = handler;
1044 }
1045 
XML_SetExternalEntityRefHandlerArg(XML_Parser parser,void * arg)1046 void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1047 {
1048   if (arg)
1049     externalEntityRefHandlerArg = arg;
1050   else
1051     externalEntityRefHandlerArg = parser;
1052 }
1053 
XML_SetUnknownEncodingHandler(XML_Parser parser,XML_UnknownEncodingHandler handler,void * data)1054 void XML_SetUnknownEncodingHandler(XML_Parser parser,
1055 				   XML_UnknownEncodingHandler handler,
1056 				   void *data)
1057 {
1058   unknownEncodingHandler = handler;
1059   unknownEncodingHandlerData = data;
1060 }
1061 
XML_SetElementDeclHandler(XML_Parser parser,XML_ElementDeclHandler eldecl)1062 void XML_SetElementDeclHandler(XML_Parser parser,
1063 			       XML_ElementDeclHandler eldecl)
1064 {
1065   elementDeclHandler = eldecl;
1066 }
1067 
XML_SetAttlistDeclHandler(XML_Parser parser,XML_AttlistDeclHandler attdecl)1068 void XML_SetAttlistDeclHandler(XML_Parser parser,
1069 			       XML_AttlistDeclHandler attdecl)
1070 {
1071   attlistDeclHandler = attdecl;
1072 }
1073 
XML_SetEntityDeclHandler(XML_Parser parser,XML_EntityDeclHandler handler)1074 void XML_SetEntityDeclHandler(XML_Parser parser,
1075 			      XML_EntityDeclHandler handler)
1076 {
1077   entityDeclHandler = handler;
1078 }
1079 
XML_SetXmlDeclHandler(XML_Parser parser,XML_XmlDeclHandler handler)1080 void XML_SetXmlDeclHandler(XML_Parser parser,
1081 			   XML_XmlDeclHandler handler) {
1082   xmlDeclHandler = handler;
1083 }
1084 
XML_SetParamEntityParsing(XML_Parser parser,enum XML_ParamEntityParsing parsing)1085 int XML_SetParamEntityParsing(XML_Parser parser,
1086 			      enum XML_ParamEntityParsing parsing)
1087 {
1088 #ifdef XML_DTD
1089   paramEntityParsing = parsing;
1090   return 1;
1091 #else
1092   return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
1093 #endif
1094 }
1095 
XML_Parse(XML_Parser parser,const char * s,int len,int isFinal)1096 int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1097 {
1098   if (len == 0) {
1099     if (!isFinal)
1100       return 1;
1101     positionPtr = bufferPtr;
1102     errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
1103     if (errorCode == XML_ERROR_NONE)
1104       return 1;
1105     eventEndPtr = eventPtr;
1106     processor = errorProcessor;
1107     return 0;
1108   }
1109 #ifndef XML_CONTEXT_BYTES
1110   else if (bufferPtr == bufferEnd) {
1111     const char *end;
1112     int nLeftOver;
1113     parseEndByteIndex += len;
1114     positionPtr = s;
1115     if (isFinal) {
1116       errorCode = processor(parser, s, parseEndPtr = s + len, 0);
1117       if (errorCode == XML_ERROR_NONE)
1118 	return 1;
1119       eventEndPtr = eventPtr;
1120       processor = errorProcessor;
1121       return 0;
1122     }
1123     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1124     if (errorCode != XML_ERROR_NONE) {
1125       eventEndPtr = eventPtr;
1126       processor = errorProcessor;
1127       return 0;
1128     }
1129     XmlUpdatePosition(encoding, positionPtr, end, &position);
1130     nLeftOver = s + len - end;
1131     if (nLeftOver) {
1132       if (buffer == 0 || nLeftOver > bufferLim - buffer) {
1133 	/* FIXME avoid integer overflow */
1134 	buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
1135 	/* FIXME storage leak if realloc fails */
1136 	if (!buffer) {
1137 	  errorCode = XML_ERROR_NO_MEMORY;
1138 	  eventPtr = eventEndPtr = 0;
1139 	  processor = errorProcessor;
1140 	  return 0;
1141 	}
1142 	bufferLim = buffer + len * 2;
1143       }
1144       memcpy(buffer, end, nLeftOver);
1145       bufferPtr = buffer;
1146       bufferEnd = buffer + nLeftOver;
1147     }
1148     return 1;
1149   }
1150 #endif  /* not defined XML_CONTEXT_BYTES */
1151   else {
1152     memcpy(XML_GetBuffer(parser, len), s, len);
1153     return XML_ParseBuffer(parser, len, isFinal);
1154   }
1155 }
1156 
XML_ParseBuffer(XML_Parser parser,int len,int isFinal)1157 int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1158 {
1159   const char *start = bufferPtr;
1160   positionPtr = start;
1161   bufferEnd += len;
1162   parseEndByteIndex += len;
1163   errorCode = processor(parser, start, parseEndPtr = bufferEnd,
1164 			isFinal ? (const char **)0 : &bufferPtr);
1165   if (errorCode == XML_ERROR_NONE) {
1166     if (!isFinal)
1167       XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1168     return 1;
1169   }
1170   else {
1171     eventEndPtr = eventPtr;
1172     processor = errorProcessor;
1173     return 0;
1174   }
1175 }
1176 
XML_GetBuffer(XML_Parser parser,int len)1177 void *XML_GetBuffer(XML_Parser parser, int len)
1178 {
1179   if (len > bufferLim - bufferEnd) {
1180     /* FIXME avoid integer overflow */
1181     int neededSize = len + (bufferEnd - bufferPtr);
1182 #ifdef XML_CONTEXT_BYTES
1183     int keep = bufferPtr - buffer;
1184 
1185     if (keep > XML_CONTEXT_BYTES)
1186       keep = XML_CONTEXT_BYTES;
1187     neededSize += keep;
1188 #endif  /* defined XML_CONTEXT_BYTES */
1189     if (neededSize  <= bufferLim - buffer) {
1190 #ifdef XML_CONTEXT_BYTES
1191       if (keep < bufferPtr - buffer) {
1192 	int offset = (bufferPtr - buffer) - keep;
1193 	memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1194 	bufferEnd -= offset;
1195 	bufferPtr -= offset;
1196       }
1197 #else
1198       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1199       bufferEnd = buffer + (bufferEnd - bufferPtr);
1200       bufferPtr = buffer;
1201 #endif  /* not defined XML_CONTEXT_BYTES */
1202     }
1203     else {
1204       char *newBuf;
1205       int bufferSize = bufferLim - bufferPtr;
1206       if (bufferSize == 0)
1207 	bufferSize = INIT_BUFFER_SIZE;
1208       do {
1209 	bufferSize *= 2;
1210       } while (bufferSize < neededSize);
1211       newBuf = MALLOC(bufferSize);
1212       if (newBuf == 0) {
1213 	errorCode = XML_ERROR_NO_MEMORY;
1214 	return 0;
1215       }
1216       bufferLim = newBuf + bufferSize;
1217 #ifdef XML_CONTEXT_BYTES
1218       if (bufferPtr) {
1219 	int keep = bufferPtr - buffer;
1220 	if (keep > XML_CONTEXT_BYTES)
1221 	  keep = XML_CONTEXT_BYTES;
1222 	memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1223 	FREE(buffer);
1224 	buffer = newBuf;
1225 	bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1226 	bufferPtr = buffer + keep;
1227       }
1228       else {
1229 	bufferEnd = newBuf + (bufferEnd - bufferPtr);
1230 	bufferPtr = buffer = newBuf;
1231       }
1232 #else
1233       if (bufferPtr) {
1234 	memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1235 	FREE(buffer);
1236       }
1237       bufferEnd = newBuf + (bufferEnd - bufferPtr);
1238       bufferPtr = buffer = newBuf;
1239 #endif  /* not defined XML_CONTEXT_BYTES */
1240     }
1241   }
1242   return bufferEnd;
1243 }
1244 
XML_GetErrorCode(XML_Parser parser)1245 enum XML_Error XML_GetErrorCode(XML_Parser parser)
1246 {
1247   return errorCode;
1248 }
1249 
XML_GetCurrentByteIndex(XML_Parser parser)1250 long XML_GetCurrentByteIndex(XML_Parser parser)
1251 {
1252   if (eventPtr)
1253     return parseEndByteIndex - (parseEndPtr - eventPtr);
1254   return -1;
1255 }
1256 
XML_GetCurrentByteCount(XML_Parser parser)1257 int XML_GetCurrentByteCount(XML_Parser parser)
1258 {
1259   if (eventEndPtr && eventPtr)
1260     return eventEndPtr - eventPtr;
1261   return 0;
1262 }
1263 
XML_GetInputContext(XML_Parser parser,int * offset,int * size)1264 const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
1265 {
1266 #ifdef XML_CONTEXT_BYTES
1267   if (eventPtr && buffer) {
1268     *offset = eventPtr - buffer;
1269     *size   = bufferEnd - buffer;
1270     return buffer;
1271   }
1272 #endif /* defined XML_CONTEXT_BYTES */
1273   return (char *) 0;
1274 }
1275 
XML_GetCurrentLineNumber(XML_Parser parser)1276 int XML_GetCurrentLineNumber(XML_Parser parser)
1277 {
1278   if (eventPtr) {
1279     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1280     positionPtr = eventPtr;
1281   }
1282   return position.lineNumber + 1;
1283 }
1284 
XML_GetCurrentColumnNumber(XML_Parser parser)1285 int XML_GetCurrentColumnNumber(XML_Parser parser)
1286 {
1287   if (eventPtr) {
1288     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1289     positionPtr = eventPtr;
1290   }
1291   return position.columnNumber;
1292 }
1293 
XML_DefaultCurrent(XML_Parser parser)1294 void XML_DefaultCurrent(XML_Parser parser)
1295 {
1296   if (defaultHandler) {
1297     if (openInternalEntities)
1298       reportDefault(parser,
1299 	            internalEncoding,
1300 		    openInternalEntities->internalEventPtr,
1301 		    openInternalEntities->internalEventEndPtr);
1302     else
1303       reportDefault(parser, encoding, eventPtr, eventEndPtr);
1304   }
1305 }
1306 
XML_ErrorString(int code)1307 const XML_LChar *XML_ErrorString(int code)
1308 {
1309   static const XML_LChar *message[] = {
1310     0,
1311     XML_T("out of memory"),
1312     XML_T("syntax error"),
1313     XML_T("no element found"),
1314     XML_T("not well-formed (invalid token)"),
1315     XML_T("unclosed token"),
1316     XML_T("unclosed token"),
1317     XML_T("mismatched tag"),
1318     XML_T("duplicate attribute"),
1319     XML_T("junk after document element"),
1320     XML_T("illegal parameter entity reference"),
1321     XML_T("undefined entity"),
1322     XML_T("recursive entity reference"),
1323     XML_T("asynchronous entity"),
1324     XML_T("reference to invalid character number"),
1325     XML_T("reference to binary entity"),
1326     XML_T("reference to external entity in attribute"),
1327     XML_T("xml processing instruction not at start of external entity"),
1328     XML_T("unknown encoding"),
1329     XML_T("encoding specified in XML declaration is incorrect"),
1330     XML_T("unclosed CDATA section"),
1331     XML_T("error in processing external entity reference"),
1332     XML_T("document is not standalone"),
1333     XML_T("unexpected parser state - please send a bug report")
1334   };
1335   if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1336     return message[code];
1337   return 0;
1338 }
1339 
1340 const XML_LChar *
XML_ExpatVersion(void)1341 XML_ExpatVersion(void) {
1342   return VERSION;
1343 }
1344 
1345 XML_Expat_Version
XML_ExpatVersionInfo(void)1346 XML_ExpatVersionInfo(void) {
1347   XML_Expat_Version version;
1348 
1349   version.major = XML_MAJOR_VERSION;
1350   version.minor = XML_MINOR_VERSION;
1351   version.micro = XML_MICRO_VERSION;
1352 
1353   return version;
1354 }
1355 
1356 static
contentProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)1357 enum XML_Error contentProcessor(XML_Parser parser,
1358 				const char *start,
1359 				const char *end,
1360 				const char **endPtr)
1361 {
1362   return doContent(parser, 0, encoding, start, end, endPtr);
1363 }
1364 
1365 static
externalEntityInitProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)1366 enum XML_Error externalEntityInitProcessor(XML_Parser parser,
1367 					   const char *start,
1368 					   const char *end,
1369 					   const char **endPtr)
1370 {
1371   enum XML_Error result = initializeEncoding(parser);
1372   if (result != XML_ERROR_NONE)
1373     return result;
1374   processor = externalEntityInitProcessor2;
1375   return externalEntityInitProcessor2(parser, start, end, endPtr);
1376 }
1377 
1378 static
externalEntityInitProcessor2(XML_Parser parser,const char * start,const char * end,const char ** endPtr)1379 enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
1380 					    const char *start,
1381 					    const char *end,
1382 					    const char **endPtr)
1383 {
1384   const char *next;
1385   int tok = XmlContentTok(encoding, start, end, &next);
1386   switch (tok) {
1387   case XML_TOK_BOM:
1388     start = next;
1389     break;
1390   case XML_TOK_PARTIAL:
1391     if (endPtr) {
1392       *endPtr = start;
1393       return XML_ERROR_NONE;
1394     }
1395     eventPtr = start;
1396     return XML_ERROR_UNCLOSED_TOKEN;
1397   case XML_TOK_PARTIAL_CHAR:
1398     if (endPtr) {
1399       *endPtr = start;
1400       return XML_ERROR_NONE;
1401     }
1402     eventPtr = start;
1403     return XML_ERROR_PARTIAL_CHAR;
1404   }
1405   processor = externalEntityInitProcessor3;
1406   return externalEntityInitProcessor3(parser, start, end, endPtr);
1407 }
1408 
1409 static
externalEntityInitProcessor3(XML_Parser parser,const char * start,const char * end,const char ** endPtr)1410 enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
1411 					    const char *start,
1412 					    const char *end,
1413 					    const char **endPtr)
1414 {
1415   const char *next;
1416   int tok = XmlContentTok(encoding, start, end, &next);
1417   switch (tok) {
1418   case XML_TOK_XML_DECL:
1419     {
1420       enum XML_Error result = processXmlDecl(parser, 1, start, next);
1421       if (result != XML_ERROR_NONE)
1422 	return result;
1423       start = next;
1424     }
1425     break;
1426   case XML_TOK_PARTIAL:
1427     if (endPtr) {
1428       *endPtr = start;
1429       return XML_ERROR_NONE;
1430     }
1431     eventPtr = start;
1432     return XML_ERROR_UNCLOSED_TOKEN;
1433   case XML_TOK_PARTIAL_CHAR:
1434     if (endPtr) {
1435       *endPtr = start;
1436       return XML_ERROR_NONE;
1437     }
1438     eventPtr = start;
1439     return XML_ERROR_PARTIAL_CHAR;
1440   }
1441   processor = externalEntityContentProcessor;
1442   tagLevel = 1;
1443   return doContent(parser, 1, encoding, start, end, endPtr);
1444 }
1445 
1446 static
externalEntityContentProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)1447 enum XML_Error externalEntityContentProcessor(XML_Parser parser,
1448 					      const char *start,
1449 					      const char *end,
1450 					      const char **endPtr)
1451 {
1452   return doContent(parser, 1, encoding, start, end, endPtr);
1453 }
1454 
1455 static enum XML_Error
doContent(XML_Parser parser,int startTagLevel,const ENCODING * enc,const char * s,const char * end,const char ** nextPtr)1456 doContent(XML_Parser parser,
1457 	  int startTagLevel,
1458 	  const ENCODING *enc,
1459 	  const char *s,
1460 	  const char *end,
1461 	  const char **nextPtr)
1462 {
1463   const char **eventPP;
1464   const char **eventEndPP;
1465   if (enc == encoding) {
1466     eventPP = &eventPtr;
1467     eventEndPP = &eventEndPtr;
1468   }
1469   else {
1470     eventPP = &(openInternalEntities->internalEventPtr);
1471     eventEndPP = &(openInternalEntities->internalEventEndPtr);
1472   }
1473   *eventPP = s;
1474   for (;;) {
1475     const char *next = s; /* XmlContentTok doesn't always set the last arg */
1476     int tok = XmlContentTok(enc, s, end, &next);
1477     *eventEndPP = next;
1478     switch (tok) {
1479     case XML_TOK_TRAILING_CR:
1480       if (nextPtr) {
1481 	*nextPtr = s;
1482 	return XML_ERROR_NONE;
1483       }
1484       *eventEndPP = end;
1485       if (characterDataHandler) {
1486 	XML_Char c = 0xA;
1487 	characterDataHandler(handlerArg, &c, 1);
1488       }
1489       else if (defaultHandler)
1490 	reportDefault(parser, enc, s, end);
1491       if (startTagLevel == 0)
1492 	return XML_ERROR_NO_ELEMENTS;
1493       if (tagLevel != startTagLevel)
1494 	return XML_ERROR_ASYNC_ENTITY;
1495       return XML_ERROR_NONE;
1496     case XML_TOK_NONE:
1497       if (nextPtr) {
1498 	*nextPtr = s;
1499 	return XML_ERROR_NONE;
1500       }
1501       if (startTagLevel > 0) {
1502 	if (tagLevel != startTagLevel)
1503 	  return XML_ERROR_ASYNC_ENTITY;
1504 	return XML_ERROR_NONE;
1505       }
1506       return XML_ERROR_NO_ELEMENTS;
1507     case XML_TOK_INVALID:
1508       *eventPP = next;
1509       return XML_ERROR_INVALID_TOKEN;
1510     case XML_TOK_PARTIAL:
1511       if (nextPtr) {
1512 	*nextPtr = s;
1513 	return XML_ERROR_NONE;
1514       }
1515       return XML_ERROR_UNCLOSED_TOKEN;
1516     case XML_TOK_PARTIAL_CHAR:
1517       if (nextPtr) {
1518 	*nextPtr = s;
1519 	return XML_ERROR_NONE;
1520       }
1521       return XML_ERROR_PARTIAL_CHAR;
1522     case XML_TOK_ENTITY_REF:
1523       {
1524 	const XML_Char *name;
1525 	ENTITY *entity;
1526 	XML_Char ch = XmlPredefinedEntityName(enc,
1527 					      s + enc->minBytesPerChar,
1528 					      next - enc->minBytesPerChar);
1529 	if (ch) {
1530 	  if (characterDataHandler)
1531 	    characterDataHandler(handlerArg, &ch, 1);
1532 	  else if (defaultHandler)
1533 	    reportDefault(parser, enc, s, next);
1534 	  break;
1535 	}
1536 	name = poolStoreString(&dtd.pool, enc,
1537 				s + enc->minBytesPerChar,
1538 				next - enc->minBytesPerChar);
1539 	if (!name)
1540 	  return XML_ERROR_NO_MEMORY;
1541 	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
1542 	poolDiscard(&dtd.pool);
1543 	if (!entity) {
1544 	  if (dtd.complete || dtd.standalone)
1545 	    return XML_ERROR_UNDEFINED_ENTITY;
1546 	  if (defaultHandler)
1547 	    reportDefault(parser, enc, s, next);
1548 	  break;
1549 	}
1550 	if (entity->open)
1551 	  return XML_ERROR_RECURSIVE_ENTITY_REF;
1552 	if (entity->notation)
1553 	  return XML_ERROR_BINARY_ENTITY_REF;
1554 	if (entity) {
1555 	  if (entity->textPtr) {
1556 	    enum XML_Error result;
1557 	    OPEN_INTERNAL_ENTITY openEntity;
1558 	    if (defaultHandler && !defaultExpandInternalEntities) {
1559 	      reportDefault(parser, enc, s, next);
1560 	      break;
1561 	    }
1562 	    entity->open = 1;
1563 	    openEntity.next = openInternalEntities;
1564 	    openInternalEntities = &openEntity;
1565 	    openEntity.entity = entity;
1566 	    openEntity.internalEventPtr = 0;
1567 	    openEntity.internalEventEndPtr = 0;
1568 	    result = doContent(parser,
1569 			       tagLevel,
1570 			       internalEncoding,
1571 			       (char *)entity->textPtr,
1572 			       (char *)(entity->textPtr + entity->textLen),
1573 			       0);
1574 	    entity->open = 0;
1575 	    openInternalEntities = openEntity.next;
1576 	    if (result)
1577 	      return result;
1578 	  }
1579 	  else if (externalEntityRefHandler) {
1580 	    const XML_Char *context;
1581 	    entity->open = 1;
1582 	    context = getContext(parser);
1583 	    entity->open = 0;
1584 	    if (!context)
1585 	      return XML_ERROR_NO_MEMORY;
1586 	    if (!externalEntityRefHandler(externalEntityRefHandlerArg,
1587 				          context,
1588 					  entity->base,
1589 					  entity->systemId,
1590 					  entity->publicId))
1591 	      return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
1592 	    poolDiscard(&tempPool);
1593 	  }
1594 	  else if (defaultHandler)
1595 	    reportDefault(parser, enc, s, next);
1596 	}
1597 	break;
1598       }
1599     case XML_TOK_START_TAG_WITH_ATTS:
1600       if (!startElementHandler) {
1601 	enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1602 	if (result)
1603 	  return result;
1604       }
1605       /* fall through */
1606     case XML_TOK_START_TAG_NO_ATTS:
1607       {
1608 	TAG *tag;
1609 	if (freeTagList) {
1610 	  tag = freeTagList;
1611 	  freeTagList = freeTagList->parent;
1612 	}
1613 	else {
1614 	  tag = MALLOC(sizeof(TAG));
1615 	  if (!tag)
1616 	    return XML_ERROR_NO_MEMORY;
1617 	  tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
1618 	  if (!tag->buf)
1619 	    return XML_ERROR_NO_MEMORY;
1620 	  tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
1621 	}
1622 	tag->bindings = 0;
1623 	tag->parent = tagStack;
1624 	tagStack = tag;
1625 	tag->name.localPart = 0;
1626 	tag->rawName = s + enc->minBytesPerChar;
1627 	tag->rawNameLength = XmlNameLength(enc, tag->rawName);
1628 	if (nextPtr) {
1629 	  /* Need to guarantee that:
1630 	     tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
1631 	  if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
1632 	    int bufSize = tag->rawNameLength * 4;
1633 	    bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
1634 	    tag->buf = REALLOC(tag->buf, bufSize);
1635 	    if (!tag->buf)
1636 	      return XML_ERROR_NO_MEMORY;
1637 	    tag->bufEnd = tag->buf + bufSize;
1638 	  }
1639 	  memcpy(tag->buf, tag->rawName, tag->rawNameLength);
1640 	  tag->rawName = tag->buf;
1641 	}
1642 	++tagLevel;
1643 	if (startElementHandler) {
1644 	  enum XML_Error result;
1645 	  XML_Char *toPtr;
1646 	  for (;;) {
1647 	    const char *rawNameEnd = tag->rawName + tag->rawNameLength;
1648 	    const char *fromPtr = tag->rawName;
1649 	    int bufSize;
1650 	    if (nextPtr)
1651 	      toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
1652 	    else
1653 	      toPtr = (XML_Char *)tag->buf;
1654 	    tag->name.str = toPtr;
1655 	    XmlConvert(enc,
1656 		       &fromPtr, rawNameEnd,
1657 		       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
1658 	    if (fromPtr == rawNameEnd)
1659 	      break;
1660 	    bufSize = (tag->bufEnd - tag->buf) << 1;
1661 	    tag->buf = REALLOC(tag->buf, bufSize);
1662 	    if (!tag->buf)
1663 	      return XML_ERROR_NO_MEMORY;
1664 	    tag->bufEnd = tag->buf + bufSize;
1665 	    if (nextPtr)
1666 	      tag->rawName = tag->buf;
1667 	  }
1668 	  *toPtr = XML_T('\0');
1669 	  result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
1670 	  if (result)
1671 	    return result;
1672 	  startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
1673 	  poolClear(&tempPool);
1674 	}
1675 	else {
1676 	  tag->name.str = 0;
1677 	  if (defaultHandler)
1678 	    reportDefault(parser, enc, s, next);
1679 	}
1680 	break;
1681       }
1682     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
1683       if (!startElementHandler) {
1684 	enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
1685 	if (result)
1686 	  return result;
1687       }
1688       /* fall through */
1689     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
1690       if (startElementHandler || endElementHandler) {
1691 	const char *rawName = s + enc->minBytesPerChar;
1692 	enum XML_Error result;
1693 	BINDING *bindings = 0;
1694 	TAG_NAME name;
1695 	name.str = poolStoreString(&tempPool, enc, rawName,
1696 				   rawName + XmlNameLength(enc, rawName));
1697 	if (!name.str)
1698 	  return XML_ERROR_NO_MEMORY;
1699 	poolFinish(&tempPool);
1700 	result = storeAtts(parser, enc, s, &name, &bindings);
1701 	if (result)
1702 	  return result;
1703 	poolFinish(&tempPool);
1704 	if (startElementHandler)
1705 	  startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
1706 	if (endElementHandler) {
1707 	  if (startElementHandler)
1708 	    *eventPP = *eventEndPP;
1709 	  endElementHandler(handlerArg, name.str);
1710 	}
1711 	poolClear(&tempPool);
1712 	while (bindings) {
1713 	  BINDING *b = bindings;
1714 	  if (endNamespaceDeclHandler)
1715 	    endNamespaceDeclHandler(handlerArg, b->prefix->name);
1716 	  bindings = bindings->nextTagBinding;
1717 	  b->nextTagBinding = freeBindingList;
1718 	  freeBindingList = b;
1719 	  b->prefix->binding = b->prevPrefixBinding;
1720 	}
1721       }
1722       else if (defaultHandler)
1723 	reportDefault(parser, enc, s, next);
1724       if (tagLevel == 0)
1725 	return epilogProcessor(parser, next, end, nextPtr);
1726       break;
1727     case XML_TOK_END_TAG:
1728       if (tagLevel == startTagLevel)
1729         return XML_ERROR_ASYNC_ENTITY;
1730       else {
1731 	int len;
1732 	const char *rawName;
1733 	TAG *tag = tagStack;
1734 	tagStack = tag->parent;
1735 	tag->parent = freeTagList;
1736 	freeTagList = tag;
1737 	rawName = s + enc->minBytesPerChar*2;
1738 	len = XmlNameLength(enc, rawName);
1739 	if (len != tag->rawNameLength
1740 	    || memcmp(tag->rawName, rawName, len) != 0) {
1741 	  *eventPP = rawName;
1742 	  return XML_ERROR_TAG_MISMATCH;
1743 	}
1744 	--tagLevel;
1745 	if (endElementHandler && tag->name.str) {
1746 	  if (tag->name.localPart) {
1747 	    XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
1748 	    const XML_Char *from = tag->name.localPart;
1749 	    while ((*to++ = *from++) != 0)
1750 	      ;
1751 	  }
1752 	  endElementHandler(handlerArg, tag->name.str);
1753 	}
1754 	else if (defaultHandler)
1755 	  reportDefault(parser, enc, s, next);
1756 	while (tag->bindings) {
1757 	  BINDING *b = tag->bindings;
1758 	  if (endNamespaceDeclHandler)
1759 	    endNamespaceDeclHandler(handlerArg, b->prefix->name);
1760 	  tag->bindings = tag->bindings->nextTagBinding;
1761 	  b->nextTagBinding = freeBindingList;
1762 	  freeBindingList = b;
1763 	  b->prefix->binding = b->prevPrefixBinding;
1764 	}
1765 	if (tagLevel == 0)
1766 	  return epilogProcessor(parser, next, end, nextPtr);
1767       }
1768       break;
1769     case XML_TOK_CHAR_REF:
1770       {
1771 	int n = XmlCharRefNumber(enc, s);
1772 	if (n < 0)
1773 	  return XML_ERROR_BAD_CHAR_REF;
1774 	if (characterDataHandler) {
1775 	  XML_Char buf[XML_ENCODE_MAX];
1776 	  characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
1777 	}
1778 	else if (defaultHandler)
1779 	  reportDefault(parser, enc, s, next);
1780       }
1781       break;
1782     case XML_TOK_XML_DECL:
1783       return XML_ERROR_MISPLACED_XML_PI;
1784     case XML_TOK_DATA_NEWLINE:
1785       if (characterDataHandler) {
1786 	XML_Char c = 0xA;
1787 	characterDataHandler(handlerArg, &c, 1);
1788       }
1789       else if (defaultHandler)
1790 	reportDefault(parser, enc, s, next);
1791       break;
1792     case XML_TOK_CDATA_SECT_OPEN:
1793       {
1794 	enum XML_Error result;
1795 	if (startCdataSectionHandler)
1796   	  startCdataSectionHandler(handlerArg);
1797 #if 0
1798 	/* Suppose you doing a transformation on a document that involves
1799 	   changing only the character data.  You set up a defaultHandler
1800 	   and a characterDataHandler.  The defaultHandler simply copies
1801 	   characters through.  The characterDataHandler does the transformation
1802 	   and writes the characters out escaping them as necessary.  This case
1803 	   will fail to work if we leave out the following two lines (because &
1804 	   and < inside CDATA sections will be incorrectly escaped).
1805 
1806 	   However, now we have a start/endCdataSectionHandler, so it seems
1807 	   easier to let the user deal with this. */
1808 
1809 	else if (characterDataHandler)
1810   	  characterDataHandler(handlerArg, dataBuf, 0);
1811 #endif
1812 	else if (defaultHandler)
1813 	  reportDefault(parser, enc, s, next);
1814 	result = doCdataSection(parser, enc, &next, end, nextPtr);
1815 	if (!next) {
1816 	  processor = cdataSectionProcessor;
1817 	  return result;
1818 	}
1819       }
1820       break;
1821     case XML_TOK_TRAILING_RSQB:
1822       if (nextPtr) {
1823 	*nextPtr = s;
1824 	return XML_ERROR_NONE;
1825       }
1826       if (characterDataHandler) {
1827 	if (MUST_CONVERT(enc, s)) {
1828 	  ICHAR *dataPtr = (ICHAR *)dataBuf;
1829 	  XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
1830 	  characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1831 	}
1832 	else
1833 	  characterDataHandler(handlerArg,
1834 		  	       (XML_Char *)s,
1835 			       (XML_Char *)end - (XML_Char *)s);
1836       }
1837       else if (defaultHandler)
1838 	reportDefault(parser, enc, s, end);
1839       if (startTagLevel == 0) {
1840         *eventPP = end;
1841 	return XML_ERROR_NO_ELEMENTS;
1842       }
1843       if (tagLevel != startTagLevel) {
1844 	*eventPP = end;
1845 	return XML_ERROR_ASYNC_ENTITY;
1846       }
1847       return XML_ERROR_NONE;
1848     case XML_TOK_DATA_CHARS:
1849       if (characterDataHandler) {
1850 	if (MUST_CONVERT(enc, s)) {
1851 	  for (;;) {
1852 	    ICHAR *dataPtr = (ICHAR *)dataBuf;
1853 	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
1854 	    *eventEndPP = s;
1855 	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1856 	    if (s == next)
1857 	      break;
1858 	    *eventPP = s;
1859 	  }
1860 	}
1861 	else
1862 	  characterDataHandler(handlerArg,
1863 			       (XML_Char *)s,
1864 			       (XML_Char *)next - (XML_Char *)s);
1865       }
1866       else if (defaultHandler)
1867 	reportDefault(parser, enc, s, next);
1868       break;
1869     case XML_TOK_PI:
1870       if (!reportProcessingInstruction(parser, enc, s, next))
1871 	return XML_ERROR_NO_MEMORY;
1872       break;
1873     case XML_TOK_COMMENT:
1874       if (!reportComment(parser, enc, s, next))
1875 	return XML_ERROR_NO_MEMORY;
1876       break;
1877     default:
1878       if (defaultHandler)
1879 	reportDefault(parser, enc, s, next);
1880       break;
1881     }
1882     *eventPP = s = next;
1883   }
1884   /* not reached */
1885 }
1886 
1887 /* If tagNamePtr is non-null, build a real list of attributes,
1888 otherwise just check the attributes for well-formedness. */
1889 
storeAtts(XML_Parser parser,const ENCODING * enc,const char * attStr,TAG_NAME * tagNamePtr,BINDING ** bindingsPtr)1890 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
1891 				const char *attStr, TAG_NAME *tagNamePtr,
1892 				BINDING **bindingsPtr)
1893 {
1894   ELEMENT_TYPE *elementType = 0;
1895   int nDefaultAtts = 0;
1896   const XML_Char **appAtts;   /* the attribute list to pass to the application */
1897   int attIndex = 0;
1898   int i;
1899   int n;
1900   int nPrefixes = 0;
1901   BINDING *binding;
1902   const XML_Char *localPart;
1903 
1904   /* lookup the element type name */
1905   if (tagNamePtr) {
1906     elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
1907     if (!elementType) {
1908       tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
1909       if (!tagNamePtr->str)
1910 	return XML_ERROR_NO_MEMORY;
1911       elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
1912       if (!elementType)
1913         return XML_ERROR_NO_MEMORY;
1914       if (ns && !setElementTypePrefix(parser, elementType))
1915         return XML_ERROR_NO_MEMORY;
1916     }
1917     nDefaultAtts = elementType->nDefaultAtts;
1918   }
1919   /* get the attributes from the tokenizer */
1920   n = XmlGetAttributes(enc, attStr, attsSize, atts);
1921   if (n + nDefaultAtts > attsSize) {
1922     int oldAttsSize = attsSize;
1923     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
1924     atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
1925     if (!atts)
1926       return XML_ERROR_NO_MEMORY;
1927     if (n > oldAttsSize)
1928       XmlGetAttributes(enc, attStr, n, atts);
1929   }
1930   appAtts = (const XML_Char **)atts;
1931   for (i = 0; i < n; i++) {
1932     /* add the name and value to the attribute list */
1933     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
1934 					 atts[i].name
1935 					 + XmlNameLength(enc, atts[i].name));
1936     if (!attId)
1937       return XML_ERROR_NO_MEMORY;
1938     /* detect duplicate attributes */
1939     if ((attId->name)[-1]) {
1940       if (enc == encoding)
1941 	eventPtr = atts[i].name;
1942       return XML_ERROR_DUPLICATE_ATTRIBUTE;
1943     }
1944     (attId->name)[-1] = 1;
1945     appAtts[attIndex++] = attId->name;
1946     if (!atts[i].normalized) {
1947       enum XML_Error result;
1948       int isCdata = 1;
1949 
1950       /* figure out whether declared as other than CDATA */
1951       if (attId->maybeTokenized) {
1952 	int j;
1953 	for (j = 0; j < nDefaultAtts; j++) {
1954 	  if (attId == elementType->defaultAtts[j].id) {
1955 	    isCdata = elementType->defaultAtts[j].isCdata;
1956 	    break;
1957 	  }
1958 	}
1959       }
1960 
1961       /* normalize the attribute value */
1962       result = storeAttributeValue(parser, enc, isCdata,
1963 				   atts[i].valuePtr, atts[i].valueEnd,
1964 			           &tempPool);
1965       if (result)
1966 	return result;
1967       if (tagNamePtr) {
1968 	appAtts[attIndex] = poolStart(&tempPool);
1969 	poolFinish(&tempPool);
1970       }
1971       else
1972 	poolDiscard(&tempPool);
1973     }
1974     else if (tagNamePtr) {
1975       /* the value did not need normalizing */
1976       appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
1977       if (appAtts[attIndex] == 0)
1978 	return XML_ERROR_NO_MEMORY;
1979       poolFinish(&tempPool);
1980     }
1981     /* handle prefixed attribute names */
1982     if (attId->prefix && tagNamePtr) {
1983       if (attId->xmlns) {
1984 	/* deal with namespace declarations here */
1985         if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
1986           return XML_ERROR_NO_MEMORY;
1987         --attIndex;
1988       }
1989       else {
1990 	/* deal with other prefixed names later */
1991         attIndex++;
1992         nPrefixes++;
1993         (attId->name)[-1] = 2;
1994       }
1995     }
1996     else
1997       attIndex++;
1998   }
1999   if (tagNamePtr) {
2000     int j;
2001     nSpecifiedAtts = attIndex;
2002     if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2003       for (i = 0; i < attIndex; i += 2)
2004 	if (appAtts[i] == elementType->idAtt->name) {
2005 	  idAttIndex = i;
2006 	  break;
2007 	}
2008     }
2009     else
2010       idAttIndex = -1;
2011     /* do attribute defaulting */
2012     for (j = 0; j < nDefaultAtts; j++) {
2013       const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
2014       if (!(da->id->name)[-1] && da->value) {
2015         if (da->id->prefix) {
2016           if (da->id->xmlns) {
2017 	    if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
2018 	      return XML_ERROR_NO_MEMORY;
2019 	  }
2020           else {
2021 	    (da->id->name)[-1] = 2;
2022 	    nPrefixes++;
2023   	    appAtts[attIndex++] = da->id->name;
2024 	    appAtts[attIndex++] = da->value;
2025 	  }
2026 	}
2027 	else {
2028 	  (da->id->name)[-1] = 1;
2029 	  appAtts[attIndex++] = da->id->name;
2030 	  appAtts[attIndex++] = da->value;
2031 	}
2032       }
2033     }
2034     appAtts[attIndex] = 0;
2035   }
2036   i = 0;
2037   if (nPrefixes) {
2038     /* expand prefixed attribute names */
2039     for (; i < attIndex; i += 2) {
2040       if (appAtts[i][-1] == 2) {
2041         ATTRIBUTE_ID *id;
2042         ((XML_Char *)(appAtts[i]))[-1] = 0;
2043 	id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
2044 	if (id->prefix->binding) {
2045 	  int j;
2046 	  const BINDING *b = id->prefix->binding;
2047 	  const XML_Char *s = appAtts[i];
2048 	  for (j = 0; j < b->uriLen; j++) {
2049 	    if (!poolAppendChar(&tempPool, b->uri[j]))
2050 	      return XML_ERROR_NO_MEMORY;
2051 	  }
2052 	  while (*s++ != ':')
2053 	    ;
2054 	  do {
2055 	    if (!poolAppendChar(&tempPool, *s))
2056 	      return XML_ERROR_NO_MEMORY;
2057 	  } while (*s++);
2058 	  if (ns_triplets) {
2059 	    tempPool.ptr[-1] = namespaceSeparator;
2060 	    s = b->prefix->name;
2061 	    do {
2062 	      if (!poolAppendChar(&tempPool, *s))
2063 		return XML_ERROR_NO_MEMORY;
2064 	    } while (*s++);
2065 	  }
2066 
2067 	  appAtts[i] = poolStart(&tempPool);
2068 	  poolFinish(&tempPool);
2069 	}
2070 	if (!--nPrefixes)
2071 	  break;
2072       }
2073       else
2074 	((XML_Char *)(appAtts[i]))[-1] = 0;
2075     }
2076   }
2077   /* clear the flags that say whether attributes were specified */
2078   for (; i < attIndex; i += 2)
2079     ((XML_Char *)(appAtts[i]))[-1] = 0;
2080   if (!tagNamePtr)
2081     return XML_ERROR_NONE;
2082   for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2083     binding->attId->name[-1] = 0;
2084   /* expand the element type name */
2085   if (elementType->prefix) {
2086     binding = elementType->prefix->binding;
2087     if (!binding)
2088       return XML_ERROR_NONE;
2089     localPart = tagNamePtr->str;
2090     while (*localPart++ != XML_T(':'))
2091       ;
2092   }
2093   else if (dtd.defaultPrefix.binding) {
2094     binding = dtd.defaultPrefix.binding;
2095     localPart = tagNamePtr->str;
2096   }
2097   else
2098     return XML_ERROR_NONE;
2099   tagNamePtr->localPart = localPart;
2100   tagNamePtr->uriLen = binding->uriLen;
2101   for (i = 0; localPart[i++];)
2102     ;
2103   n = i + binding->uriLen;
2104   if (n > binding->uriAlloc) {
2105     TAG *p;
2106     XML_Char *uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
2107     if (!uri)
2108       return XML_ERROR_NO_MEMORY;
2109     binding->uriAlloc = n + EXPAND_SPARE;
2110     memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2111     for (p = tagStack; p; p = p->parent)
2112       if (p->name.str == binding->uri)
2113 	p->name.str = uri;
2114     FREE(binding->uri);
2115     binding->uri = uri;
2116   }
2117   memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
2118   tagNamePtr->str = binding->uri;
2119   return XML_ERROR_NONE;
2120 }
2121 
2122 static
addBinding(XML_Parser parser,PREFIX * prefix,const ATTRIBUTE_ID * attId,const XML_Char * uri,BINDING ** bindingsPtr)2123 int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
2124 {
2125   BINDING *b;
2126   int len;
2127   for (len = 0; uri[len]; len++)
2128     ;
2129   if (namespaceSeparator)
2130     len++;
2131   if (freeBindingList) {
2132     b = freeBindingList;
2133     if (len > b->uriAlloc) {
2134       b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
2135       if (!b->uri)
2136 	return 0;
2137       b->uriAlloc = len + EXPAND_SPARE;
2138     }
2139     freeBindingList = b->nextTagBinding;
2140   }
2141   else {
2142     b = MALLOC(sizeof(BINDING));
2143     if (!b)
2144       return 0;
2145     b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
2146     if (!b->uri) {
2147       FREE(b);
2148       return 0;
2149     }
2150     b->uriAlloc = len + EXPAND_SPARE;
2151   }
2152   b->uriLen = len;
2153   memcpy(b->uri, uri, len * sizeof(XML_Char));
2154   if (namespaceSeparator)
2155     b->uri[len - 1] = namespaceSeparator;
2156   b->prefix = prefix;
2157   b->attId = attId;
2158   b->prevPrefixBinding = prefix->binding;
2159   if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
2160     prefix->binding = 0;
2161   else
2162     prefix->binding = b;
2163   b->nextTagBinding = *bindingsPtr;
2164   *bindingsPtr = b;
2165   if (startNamespaceDeclHandler)
2166     startNamespaceDeclHandler(handlerArg, prefix->name,
2167 			      prefix->binding ? uri : 0);
2168   return 1;
2169 }
2170 
2171 /* The idea here is to avoid using stack for each CDATA section when
2172 the whole file is parsed with one call. */
2173 
2174 static
cdataSectionProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)2175 enum XML_Error cdataSectionProcessor(XML_Parser parser,
2176 				     const char *start,
2177 			    	     const char *end,
2178 				     const char **endPtr)
2179 {
2180   enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
2181   if (start) {
2182     processor = contentProcessor;
2183     return contentProcessor(parser, start, end, endPtr);
2184   }
2185   return result;
2186 }
2187 
2188 /* startPtr gets set to non-null is the section is closed, and to null if
2189 the section is not yet closed. */
2190 
2191 static
doCdataSection(XML_Parser parser,const ENCODING * enc,const char ** startPtr,const char * end,const char ** nextPtr)2192 enum XML_Error doCdataSection(XML_Parser parser,
2193 			      const ENCODING *enc,
2194 			      const char **startPtr,
2195 			      const char *end,
2196 			      const char **nextPtr)
2197 {
2198   const char *s = *startPtr;
2199   const char **eventPP;
2200   const char **eventEndPP;
2201   if (enc == encoding) {
2202     eventPP = &eventPtr;
2203     *eventPP = s;
2204     eventEndPP = &eventEndPtr;
2205   }
2206   else {
2207     eventPP = &(openInternalEntities->internalEventPtr);
2208     eventEndPP = &(openInternalEntities->internalEventEndPtr);
2209   }
2210   *eventPP = s;
2211   *startPtr = 0;
2212   for (;;) {
2213     const char *next;
2214     int tok = XmlCdataSectionTok(enc, s, end, &next);
2215     *eventEndPP = next;
2216     switch (tok) {
2217     case XML_TOK_CDATA_SECT_CLOSE:
2218       if (endCdataSectionHandler)
2219 	endCdataSectionHandler(handlerArg);
2220 #if 0
2221       /* see comment under XML_TOK_CDATA_SECT_OPEN */
2222       else if (characterDataHandler)
2223 	characterDataHandler(handlerArg, dataBuf, 0);
2224 #endif
2225       else if (defaultHandler)
2226 	reportDefault(parser, enc, s, next);
2227       *startPtr = next;
2228       return XML_ERROR_NONE;
2229     case XML_TOK_DATA_NEWLINE:
2230       if (characterDataHandler) {
2231 	XML_Char c = 0xA;
2232 	characterDataHandler(handlerArg, &c, 1);
2233       }
2234       else if (defaultHandler)
2235 	reportDefault(parser, enc, s, next);
2236       break;
2237     case XML_TOK_DATA_CHARS:
2238       if (characterDataHandler) {
2239 	if (MUST_CONVERT(enc, s)) {
2240 	  for (;;) {
2241   	    ICHAR *dataPtr = (ICHAR *)dataBuf;
2242 	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2243 	    *eventEndPP = next;
2244 	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
2245 	    if (s == next)
2246 	      break;
2247 	    *eventPP = s;
2248 	  }
2249 	}
2250 	else
2251 	  characterDataHandler(handlerArg,
2252 		  	       (XML_Char *)s,
2253 			       (XML_Char *)next - (XML_Char *)s);
2254       }
2255       else if (defaultHandler)
2256 	reportDefault(parser, enc, s, next);
2257       break;
2258     case XML_TOK_INVALID:
2259       *eventPP = next;
2260       return XML_ERROR_INVALID_TOKEN;
2261     case XML_TOK_PARTIAL_CHAR:
2262       if (nextPtr) {
2263 	*nextPtr = s;
2264 	return XML_ERROR_NONE;
2265       }
2266       return XML_ERROR_PARTIAL_CHAR;
2267     case XML_TOK_PARTIAL:
2268     case XML_TOK_NONE:
2269       if (nextPtr) {
2270 	*nextPtr = s;
2271 	return XML_ERROR_NONE;
2272       }
2273       return XML_ERROR_UNCLOSED_CDATA_SECTION;
2274     default:
2275       *eventPP = next;
2276       return XML_ERROR_UNEXPECTED_STATE;
2277     }
2278     *eventPP = s = next;
2279   }
2280   /* not reached */
2281 }
2282 
2283 #ifdef XML_DTD
2284 
2285 /* The idea here is to avoid using stack for each IGNORE section when
2286 the whole file is parsed with one call. */
2287 
2288 static
ignoreSectionProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)2289 enum XML_Error ignoreSectionProcessor(XML_Parser parser,
2290 				      const char *start,
2291 				      const char *end,
2292 				      const char **endPtr)
2293 {
2294   enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
2295   if (start) {
2296     processor = prologProcessor;
2297     return prologProcessor(parser, start, end, endPtr);
2298   }
2299   return result;
2300 }
2301 
2302 /* startPtr gets set to non-null is the section is closed, and to null if
2303 the section is not yet closed. */
2304 
2305 static
doIgnoreSection(XML_Parser parser,const ENCODING * enc,const char ** startPtr,const char * end,const char ** nextPtr)2306 enum XML_Error doIgnoreSection(XML_Parser parser,
2307 			       const ENCODING *enc,
2308 			       const char **startPtr,
2309 			       const char *end,
2310 			       const char **nextPtr)
2311 {
2312   const char *next;
2313   int tok;
2314   const char *s = *startPtr;
2315   const char **eventPP;
2316   const char **eventEndPP;
2317   if (enc == encoding) {
2318     eventPP = &eventPtr;
2319     *eventPP = s;
2320     eventEndPP = &eventEndPtr;
2321   }
2322   else {
2323     eventPP = &(openInternalEntities->internalEventPtr);
2324     eventEndPP = &(openInternalEntities->internalEventEndPtr);
2325   }
2326   *eventPP = s;
2327   *startPtr = 0;
2328   tok = XmlIgnoreSectionTok(enc, s, end, &next);
2329   *eventEndPP = next;
2330   switch (tok) {
2331   case XML_TOK_IGNORE_SECT:
2332     if (defaultHandler)
2333       reportDefault(parser, enc, s, next);
2334     *startPtr = next;
2335     return XML_ERROR_NONE;
2336   case XML_TOK_INVALID:
2337     *eventPP = next;
2338     return XML_ERROR_INVALID_TOKEN;
2339   case XML_TOK_PARTIAL_CHAR:
2340     if (nextPtr) {
2341       *nextPtr = s;
2342       return XML_ERROR_NONE;
2343     }
2344     return XML_ERROR_PARTIAL_CHAR;
2345   case XML_TOK_PARTIAL:
2346   case XML_TOK_NONE:
2347     if (nextPtr) {
2348       *nextPtr = s;
2349       return XML_ERROR_NONE;
2350     }
2351     return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
2352   default:
2353     *eventPP = next;
2354     return XML_ERROR_UNEXPECTED_STATE;
2355   }
2356   /* not reached */
2357 }
2358 
2359 #endif /* XML_DTD */
2360 
2361 static enum XML_Error
initializeEncoding(XML_Parser parser)2362 initializeEncoding(XML_Parser parser)
2363 {
2364   const char *s;
2365 #ifdef XML_UNICODE
2366   char encodingBuf[128];
2367   if (!protocolEncodingName)
2368     s = 0;
2369   else {
2370     int i;
2371     for (i = 0; protocolEncodingName[i]; i++) {
2372       if (i == sizeof(encodingBuf) - 1
2373 	  || (protocolEncodingName[i] & ~0x7f) != 0) {
2374 	encodingBuf[0] = '\0';
2375 	break;
2376       }
2377       encodingBuf[i] = (char)protocolEncodingName[i];
2378     }
2379     encodingBuf[i] = '\0';
2380     s = encodingBuf;
2381   }
2382 #else
2383   s = protocolEncodingName;
2384 #endif
2385   if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
2386     return XML_ERROR_NONE;
2387   return handleUnknownEncoding(parser, protocolEncodingName);
2388 }
2389 
2390 static enum XML_Error
processXmlDecl(XML_Parser parser,int isGeneralTextEntity,const char * s,const char * next)2391 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
2392 	       const char *s, const char *next)
2393 {
2394   const char *encodingName = 0;
2395   const char *storedEncName = 0;
2396   const ENCODING *newEncoding = 0;
2397   const char *version = 0;
2398   const char *versionend;
2399   const char *storedversion = 0;
2400   int standalone = -1;
2401   if (!(ns
2402         ? XmlParseXmlDeclNS
2403 	: XmlParseXmlDecl)(isGeneralTextEntity,
2404 		           encoding,
2405 		           s,
2406 		           next,
2407 		           &eventPtr,
2408 		           &version,
2409 			   &versionend,
2410 		           &encodingName,
2411 		           &newEncoding,
2412 		           &standalone))
2413     return XML_ERROR_SYNTAX;
2414   if (!isGeneralTextEntity && standalone == 1) {
2415     dtd.standalone = 1;
2416 #ifdef XML_DTD
2417     if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
2418       paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
2419 #endif /* XML_DTD */
2420   }
2421   if (xmlDeclHandler) {
2422     if (encodingName) {
2423       storedEncName = poolStoreString(&temp2Pool,
2424 				      encoding,
2425 				      encodingName,
2426 				      encodingName
2427 				      + XmlNameLength(encoding, encodingName));
2428       if (! storedEncName)
2429 	return XML_ERROR_NO_MEMORY;
2430       poolFinish(&temp2Pool);
2431     }
2432     if (version) {
2433       storedversion = poolStoreString(&temp2Pool,
2434 				      encoding,
2435 				      version,
2436 				      versionend - encoding->minBytesPerChar);
2437       if (! storedversion)
2438 	return XML_ERROR_NO_MEMORY;
2439     }
2440     xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
2441   }
2442   else if (defaultHandler)
2443     reportDefault(parser, encoding, s, next);
2444   if (!protocolEncodingName) {
2445     if (newEncoding) {
2446       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
2447 	eventPtr = encodingName;
2448 	return XML_ERROR_INCORRECT_ENCODING;
2449       }
2450       encoding = newEncoding;
2451     }
2452     else if (encodingName) {
2453       enum XML_Error result;
2454       if (! storedEncName) {
2455 	storedEncName = poolStoreString(&temp2Pool,
2456 					encoding,
2457 					encodingName,
2458 					encodingName
2459 					+ XmlNameLength(encoding, encodingName));
2460 	if (! storedEncName)
2461 	  return XML_ERROR_NO_MEMORY;
2462       }
2463       result = handleUnknownEncoding(parser, storedEncName);
2464       poolClear(&tempPool);
2465       if (result == XML_ERROR_UNKNOWN_ENCODING)
2466 	eventPtr = encodingName;
2467       return result;
2468     }
2469   }
2470 
2471   if (storedEncName || storedversion)
2472     poolClear(&temp2Pool);
2473 
2474   return XML_ERROR_NONE;
2475 }
2476 
2477 static enum XML_Error
handleUnknownEncoding(XML_Parser parser,const XML_Char * encodingName)2478 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
2479 {
2480   if (unknownEncodingHandler) {
2481     XML_Encoding info;
2482     int i;
2483     for (i = 0; i < 256; i++)
2484       info.map[i] = -1;
2485     info.convert = 0;
2486     info.data = 0;
2487     info.release = 0;
2488     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
2489       ENCODING *enc;
2490       unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
2491       if (!unknownEncodingMem) {
2492 	if (info.release)
2493 	  info.release(info.data);
2494 	return XML_ERROR_NO_MEMORY;
2495       }
2496       enc = (ns
2497 	     ? XmlInitUnknownEncodingNS
2498 	     : XmlInitUnknownEncoding)(unknownEncodingMem,
2499 				       info.map,
2500 				       info.convert,
2501 				       info.data);
2502       if (enc) {
2503 	unknownEncodingData = info.data;
2504 	unknownEncodingRelease = info.release;
2505 	encoding = enc;
2506 	return XML_ERROR_NONE;
2507       }
2508     }
2509     if (info.release)
2510       info.release(info.data);
2511   }
2512   return XML_ERROR_UNKNOWN_ENCODING;
2513 }
2514 
2515 static enum XML_Error
prologInitProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)2516 prologInitProcessor(XML_Parser parser,
2517 		    const char *s,
2518 		    const char *end,
2519 		    const char **nextPtr)
2520 {
2521   enum XML_Error result = initializeEncoding(parser);
2522   if (result != XML_ERROR_NONE)
2523     return result;
2524   processor = prologProcessor;
2525   return prologProcessor(parser, s, end, nextPtr);
2526 }
2527 
2528 static enum XML_Error
prologProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)2529 prologProcessor(XML_Parser parser,
2530 		const char *s,
2531 		const char *end,
2532 		const char **nextPtr)
2533 {
2534   const char *next;
2535   int tok = XmlPrologTok(encoding, s, end, &next);
2536   return doProlog(parser, encoding, s, end, tok, next, nextPtr);
2537 }
2538 
2539 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)2540 doProlog(XML_Parser parser,
2541 	 const ENCODING *enc,
2542 	 const char *s,
2543 	 const char *end,
2544 	 int tok,
2545 	 const char *next,
2546 	 const char **nextPtr)
2547 {
2548 #ifdef XML_DTD
2549   static const XML_Char externalSubsetName[] = { '#' , '\0' };
2550 #endif /* XML_DTD */
2551 
2552   const char **eventPP;
2553   const char **eventEndPP;
2554   enum XML_Content_Quant quant;
2555 
2556   if (enc == encoding) {
2557     eventPP = &eventPtr;
2558     eventEndPP = &eventEndPtr;
2559   }
2560   else {
2561     eventPP = &(openInternalEntities->internalEventPtr);
2562     eventEndPP = &(openInternalEntities->internalEventEndPtr);
2563   }
2564   for (;;) {
2565     int role;
2566     *eventPP = s;
2567     *eventEndPP = next;
2568     if (tok <= 0) {
2569       if (nextPtr != 0 && tok != XML_TOK_INVALID) {
2570 	*nextPtr = s;
2571 	return XML_ERROR_NONE;
2572       }
2573       switch (tok) {
2574       case XML_TOK_INVALID:
2575 	*eventPP = next;
2576 	return XML_ERROR_INVALID_TOKEN;
2577       case XML_TOK_PARTIAL:
2578 	return XML_ERROR_UNCLOSED_TOKEN;
2579       case XML_TOK_PARTIAL_CHAR:
2580 	return XML_ERROR_PARTIAL_CHAR;
2581       case XML_TOK_NONE:
2582 #ifdef XML_DTD
2583 	if (enc != encoding)
2584 	  return XML_ERROR_NONE;
2585 	if (parentParser) {
2586 	  if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
2587 	      == XML_ROLE_ERROR)
2588 	    return XML_ERROR_SYNTAX;
2589 	  hadExternalDoctype = 0;
2590 	  return XML_ERROR_NONE;
2591 	}
2592 #endif /* XML_DTD */
2593 	return XML_ERROR_NO_ELEMENTS;
2594       default:
2595 	tok = -tok;
2596 	next = end;
2597 	break;
2598       }
2599     }
2600     role = XmlTokenRole(&prologState, tok, s, next, enc);
2601     switch (role) {
2602     case XML_ROLE_XML_DECL:
2603       {
2604 	enum XML_Error result = processXmlDecl(parser, 0, s, next);
2605 	if (result != XML_ERROR_NONE)
2606 	  return result;
2607 	enc = encoding;
2608       }
2609       break;
2610     case XML_ROLE_DOCTYPE_NAME:
2611       if (startDoctypeDeclHandler) {
2612 	doctypeName = poolStoreString(&tempPool, enc, s, next);
2613 	if (! doctypeName)
2614 	  return XML_ERROR_NO_MEMORY;
2615 	poolFinish(&tempPool);
2616 	doctypeSysid = 0;
2617 	doctypePubid = 0;
2618       }
2619       break;
2620     case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
2621       if (startDoctypeDeclHandler) {
2622 	startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
2623 				doctypePubid, 1);
2624 	doctypeName = 0;
2625 	poolClear(&tempPool);
2626       }
2627       break;
2628 #ifdef XML_DTD
2629     case XML_ROLE_TEXT_DECL:
2630       {
2631 	enum XML_Error result = processXmlDecl(parser, 1, s, next);
2632 	if (result != XML_ERROR_NONE)
2633 	  return result;
2634 	enc = encoding;
2635       }
2636       break;
2637 #endif /* XML_DTD */
2638     case XML_ROLE_DOCTYPE_PUBLIC_ID:
2639       if (startDoctypeDeclHandler) {
2640 	doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
2641 	if (! doctypePubid)
2642 	  return XML_ERROR_NO_MEMORY;
2643 	poolFinish(&tempPool);
2644       }
2645 #ifdef XML_DTD
2646       declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2647 				    externalSubsetName,
2648 				    sizeof(ENTITY));
2649       if (!declEntity)
2650 	return XML_ERROR_NO_MEMORY;
2651 #endif /* XML_DTD */
2652       /* fall through */
2653     case XML_ROLE_ENTITY_PUBLIC_ID:
2654       if (!XmlIsPublicId(enc, s, next, eventPP))
2655 	return XML_ERROR_SYNTAX;
2656       if (declEntity) {
2657 	XML_Char *tem = poolStoreString(&dtd.pool,
2658 	                                enc,
2659 					s + enc->minBytesPerChar,
2660 	  				next - enc->minBytesPerChar);
2661 	if (!tem)
2662 	  return XML_ERROR_NO_MEMORY;
2663 	normalizePublicId(tem);
2664 	declEntity->publicId = tem;
2665 	poolFinish(&dtd.pool);
2666       }
2667       break;
2668     case XML_ROLE_DOCTYPE_CLOSE:
2669       if (doctypeName) {
2670 	startDoctypeDeclHandler(handlerArg, doctypeName,
2671 				doctypeSysid, doctypePubid, 0);
2672 	poolClear(&tempPool);
2673       }
2674       if (dtd.complete && hadExternalDoctype) {
2675 	dtd.complete = 0;
2676 #ifdef XML_DTD
2677 	if (paramEntityParsing && externalEntityRefHandler) {
2678 	  ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
2679 					    externalSubsetName,
2680 					    0);
2681 	  if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2682 					0,
2683 					entity->base,
2684 					entity->systemId,
2685 					entity->publicId))
2686 	   return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2687 	}
2688 #endif /* XML_DTD */
2689 	if (!dtd.complete
2690 	    && !dtd.standalone
2691 	    && notStandaloneHandler
2692 	    && !notStandaloneHandler(handlerArg))
2693 	  return XML_ERROR_NOT_STANDALONE;
2694       }
2695       if (endDoctypeDeclHandler)
2696 	endDoctypeDeclHandler(handlerArg);
2697       break;
2698     case XML_ROLE_INSTANCE_START:
2699       processor = contentProcessor;
2700       return contentProcessor(parser, s, end, nextPtr);
2701     case XML_ROLE_ATTLIST_ELEMENT_NAME:
2702       declElementType = getElementType(parser, enc, s, next);
2703       if (!declElementType)
2704 	return XML_ERROR_NO_MEMORY;
2705       break;
2706     case XML_ROLE_ATTRIBUTE_NAME:
2707       declAttributeId = getAttributeId(parser, enc, s, next);
2708       if (!declAttributeId)
2709 	return XML_ERROR_NO_MEMORY;
2710       declAttributeIsCdata = 0;
2711       declAttributeType = 0;
2712       declAttributeIsId = 0;
2713       break;
2714     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
2715       declAttributeIsCdata = 1;
2716       declAttributeType = "CDATA";
2717       break;
2718     case XML_ROLE_ATTRIBUTE_TYPE_ID:
2719       declAttributeIsId = 1;
2720       declAttributeType = "ID";
2721       break;
2722     case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
2723       declAttributeType = "IDREF";
2724       break;
2725     case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
2726       declAttributeType = "IDREFS";
2727       break;
2728     case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
2729       declAttributeType = "ENTITY";
2730       break;
2731     case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
2732       declAttributeType = "ENTITIES";
2733       break;
2734     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
2735       declAttributeType = "NMTOKEN";
2736       break;
2737     case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
2738       declAttributeType = "NMTOKENS";
2739       break;
2740 
2741     case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
2742     case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
2743       if (attlistDeclHandler)
2744       {
2745 	char *prefix;
2746 	if (declAttributeType) {
2747 	  prefix = "|";
2748 	}
2749 	else {
2750 	  prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
2751 		    ? "NOTATION("
2752 		    : "(");
2753 	}
2754 	if (! poolAppendString(&tempPool, prefix))
2755 	  return XML_ERROR_NO_MEMORY;
2756 	if (! poolAppend(&tempPool, enc, s, next))
2757 	  return XML_ERROR_NO_MEMORY;
2758 	declAttributeType = tempPool.start;
2759       }
2760       break;
2761     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
2762     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
2763       if (dtd.complete
2764 	  && !defineAttribute(declElementType, declAttributeId,
2765 			      declAttributeIsCdata, declAttributeIsId, 0,
2766 			      parser))
2767 	return XML_ERROR_NO_MEMORY;
2768       if (attlistDeclHandler && declAttributeType) {
2769 	if (*declAttributeType == '('
2770 	    || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
2771 	  /* Enumerated or Notation type */
2772 	  if (! poolAppendChar(&tempPool, ')')
2773 	      || ! poolAppendChar(&tempPool, '\0'))
2774 	    return XML_ERROR_NO_MEMORY;
2775 	  declAttributeType = tempPool.start;
2776 	  poolFinish(&tempPool);
2777 	}
2778 	*eventEndPP = s;
2779 	attlistDeclHandler(handlerArg, declElementType->name,
2780 			   declAttributeId->name, declAttributeType,
2781 			   0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
2782 	poolClear(&tempPool);
2783       }
2784       break;
2785     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
2786     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
2787       {
2788 	const XML_Char *attVal;
2789 	enum XML_Error result
2790 	  = storeAttributeValue(parser, enc, declAttributeIsCdata,
2791 				s + enc->minBytesPerChar,
2792 			        next - enc->minBytesPerChar,
2793 			        &dtd.pool);
2794 	if (result)
2795 	  return result;
2796 	attVal = poolStart(&dtd.pool);
2797 	poolFinish(&dtd.pool);
2798 	if (dtd.complete
2799 	    /* ID attributes aren't allowed to have a default */
2800 	    && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
2801 	  return XML_ERROR_NO_MEMORY;
2802 	if (attlistDeclHandler && declAttributeType) {
2803 	  if (*declAttributeType == '('
2804 	      || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
2805 	    /* Enumerated or Notation type */
2806 	    if (! poolAppendChar(&tempPool, ')')
2807 		|| ! poolAppendChar(&tempPool, '\0'))
2808 	      return XML_ERROR_NO_MEMORY;
2809 	    declAttributeType = tempPool.start;
2810 	    poolFinish(&tempPool);
2811 	  }
2812 	  *eventEndPP = s;
2813 	  attlistDeclHandler(handlerArg, declElementType->name,
2814 			     declAttributeId->name, declAttributeType,
2815 			     attVal,
2816 			     role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
2817 	  poolClear(&tempPool);
2818 	}
2819 	break;
2820       }
2821     case XML_ROLE_ENTITY_VALUE:
2822       {
2823 	enum XML_Error result = storeEntityValue(parser, enc,
2824 						 s + enc->minBytesPerChar,
2825 						 next - enc->minBytesPerChar);
2826 	if (declEntity) {
2827 	  declEntity->textPtr = poolStart(&dtd.pool);
2828 	  declEntity->textLen = poolLength(&dtd.pool);
2829 	  poolFinish(&dtd.pool);
2830 	  if (entityDeclHandler) {
2831 	    *eventEndPP = s;
2832 	    entityDeclHandler(handlerArg,
2833 			      declEntity->name,
2834 			      declEntity->is_param,
2835 			      declEntity->textPtr,
2836 			      declEntity->textLen,
2837 			      curBase, 0, 0, 0);
2838 	  }
2839 	}
2840 	else
2841 	  poolDiscard(&dtd.pool);
2842 	if (result != XML_ERROR_NONE)
2843 	  return result;
2844       }
2845       break;
2846     case XML_ROLE_DOCTYPE_SYSTEM_ID:
2847       if (startDoctypeDeclHandler) {
2848 	doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
2849 	if (! doctypeSysid)
2850 	  return XML_ERROR_NO_MEMORY;
2851 	poolFinish(&tempPool);
2852       }
2853       if (!dtd.standalone
2854 #ifdef XML_DTD
2855 	  && !paramEntityParsing
2856 #endif /* XML_DTD */
2857 	  && notStandaloneHandler
2858 	  && !notStandaloneHandler(handlerArg))
2859 	return XML_ERROR_NOT_STANDALONE;
2860       hadExternalDoctype = 1;
2861 #ifndef XML_DTD
2862       break;
2863 #else /* XML_DTD */
2864       if (!declEntity) {
2865 	declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2866 				      externalSubsetName,
2867 				      sizeof(ENTITY));
2868 	declEntity->publicId = 0;
2869 	if (!declEntity)
2870 	  return XML_ERROR_NO_MEMORY;
2871       }
2872       /* fall through */
2873 #endif /* XML_DTD */
2874     case XML_ROLE_ENTITY_SYSTEM_ID:
2875       if (declEntity) {
2876 	declEntity->systemId = poolStoreString(&dtd.pool, enc,
2877 	                                       s + enc->minBytesPerChar,
2878 	  				       next - enc->minBytesPerChar);
2879 	if (!declEntity->systemId)
2880 	  return XML_ERROR_NO_MEMORY;
2881 	declEntity->base = curBase;
2882 	poolFinish(&dtd.pool);
2883       }
2884       break;
2885     case XML_ROLE_ENTITY_COMPLETE:
2886       if (declEntity && entityDeclHandler) {
2887 	*eventEndPP = s;
2888 	entityDeclHandler(handlerArg,
2889 			  declEntity->name,
2890 			  0,0,0,
2891 			  declEntity->base,
2892 			  declEntity->systemId,
2893 			  declEntity->publicId,
2894 			  0);
2895       }
2896       break;
2897     case XML_ROLE_ENTITY_NOTATION_NAME:
2898       if (declEntity) {
2899 	declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
2900 	if (!declEntity->notation)
2901 	  return XML_ERROR_NO_MEMORY;
2902 	poolFinish(&dtd.pool);
2903 	if (unparsedEntityDeclHandler) {
2904 	  *eventEndPP = s;
2905 	  unparsedEntityDeclHandler(handlerArg,
2906 				    declEntity->name,
2907 				    declEntity->base,
2908 				    declEntity->systemId,
2909 				    declEntity->publicId,
2910 				    declEntity->notation);
2911 	}
2912 	else if (entityDeclHandler) {
2913 	  *eventEndPP = s;
2914 	  entityDeclHandler(handlerArg,
2915 			    declEntity->name,
2916 			    0,0,0,
2917 			    declEntity->base,
2918 			    declEntity->systemId,
2919 			    declEntity->publicId,
2920 			    declEntity->notation);
2921 	}
2922       }
2923       break;
2924     case XML_ROLE_GENERAL_ENTITY_NAME:
2925       {
2926 	const XML_Char *name;
2927 	if (XmlPredefinedEntityName(enc, s, next)) {
2928 	  declEntity = 0;
2929 	  break;
2930 	}
2931 	name = poolStoreString(&dtd.pool, enc, s, next);
2932 	if (!name)
2933 	  return XML_ERROR_NO_MEMORY;
2934 	if (dtd.complete) {
2935 	  declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
2936 	  if (!declEntity)
2937 	    return XML_ERROR_NO_MEMORY;
2938 	  if (declEntity->name != name) {
2939 	    poolDiscard(&dtd.pool);
2940 	    declEntity = 0;
2941 	  }
2942 	  else {
2943 	    poolFinish(&dtd.pool);
2944 	    declEntity->publicId = 0;
2945 	    declEntity->is_param = 0;
2946 	  }
2947 	}
2948 	else {
2949 	  poolDiscard(&dtd.pool);
2950 	  declEntity = 0;
2951 	}
2952       }
2953       break;
2954     case XML_ROLE_PARAM_ENTITY_NAME:
2955 #ifdef XML_DTD
2956       if (dtd.complete) {
2957 	const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
2958 	if (!name)
2959 	  return XML_ERROR_NO_MEMORY;
2960 	declEntity = (ENTITY *)lookup(&dtd.paramEntities,
2961 				      name, sizeof(ENTITY));
2962 	if (!declEntity)
2963 	  return XML_ERROR_NO_MEMORY;
2964 	if (declEntity->name != name) {
2965 	  poolDiscard(&dtd.pool);
2966 	  declEntity = 0;
2967 	}
2968 	else {
2969 	  poolFinish(&dtd.pool);
2970 	  declEntity->publicId = 0;
2971 	  declEntity->is_param = 1;
2972 	}
2973       }
2974 #else /* not XML_DTD */
2975       declEntity = 0;
2976 #endif /* not XML_DTD */
2977       break;
2978     case XML_ROLE_NOTATION_NAME:
2979       declNotationPublicId = 0;
2980       declNotationName = 0;
2981       if (notationDeclHandler) {
2982 	declNotationName = poolStoreString(&tempPool, enc, s, next);
2983 	if (!declNotationName)
2984 	  return XML_ERROR_NO_MEMORY;
2985 	poolFinish(&tempPool);
2986       }
2987       break;
2988     case XML_ROLE_NOTATION_PUBLIC_ID:
2989       if (!XmlIsPublicId(enc, s, next, eventPP))
2990 	return XML_ERROR_SYNTAX;
2991       if (declNotationName) {
2992 	XML_Char *tem = poolStoreString(&tempPool,
2993 	                                enc,
2994 					s + enc->minBytesPerChar,
2995 	  				next - enc->minBytesPerChar);
2996 	if (!tem)
2997 	  return XML_ERROR_NO_MEMORY;
2998 	normalizePublicId(tem);
2999 	declNotationPublicId = tem;
3000 	poolFinish(&tempPool);
3001       }
3002       break;
3003     case XML_ROLE_NOTATION_SYSTEM_ID:
3004       if (declNotationName && notationDeclHandler) {
3005 	const XML_Char *systemId
3006 	  = poolStoreString(&tempPool, enc,
3007 			    s + enc->minBytesPerChar,
3008 	  		    next - enc->minBytesPerChar);
3009 	if (!systemId)
3010 	  return XML_ERROR_NO_MEMORY;
3011 	*eventEndPP = s;
3012 	notationDeclHandler(handlerArg,
3013 			    declNotationName,
3014 			    curBase,
3015 			    systemId,
3016 			    declNotationPublicId);
3017       }
3018       poolClear(&tempPool);
3019       break;
3020     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
3021       if (declNotationPublicId && notationDeclHandler) {
3022 	*eventEndPP = s;
3023 	notationDeclHandler(handlerArg,
3024 			    declNotationName,
3025 			    curBase,
3026 			    0,
3027 			    declNotationPublicId);
3028       }
3029       poolClear(&tempPool);
3030       break;
3031     case XML_ROLE_ERROR:
3032       switch (tok) {
3033       case XML_TOK_PARAM_ENTITY_REF:
3034 	return XML_ERROR_PARAM_ENTITY_REF;
3035       case XML_TOK_XML_DECL:
3036 	return XML_ERROR_MISPLACED_XML_PI;
3037       default:
3038 	return XML_ERROR_SYNTAX;
3039       }
3040 #ifdef XML_DTD
3041     case XML_ROLE_IGNORE_SECT:
3042       {
3043 	enum XML_Error result;
3044 	if (defaultHandler)
3045 	  reportDefault(parser, enc, s, next);
3046 	result = doIgnoreSection(parser, enc, &next, end, nextPtr);
3047 	if (!next) {
3048 	  processor = ignoreSectionProcessor;
3049 	  return result;
3050 	}
3051       }
3052       break;
3053 #endif /* XML_DTD */
3054     case XML_ROLE_GROUP_OPEN:
3055       if (prologState.level >= groupSize) {
3056 	if (groupSize) {
3057 	  groupConnector = REALLOC(groupConnector, groupSize *= 2);
3058 	  if (dtd.scaffIndex)
3059 	    dtd.scaffIndex = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
3060 	}
3061 	else
3062 	  groupConnector = MALLOC(groupSize = 32);
3063 	if (!groupConnector)
3064 	  return XML_ERROR_NO_MEMORY;
3065       }
3066       groupConnector[prologState.level] = 0;
3067       if (dtd.in_eldecl) {
3068 	int myindex = nextScaffoldPart(parser);
3069 	if (myindex < 0)
3070 	  return XML_ERROR_NO_MEMORY;
3071 	dtd.scaffIndex[dtd.scaffLevel] = myindex;
3072 	dtd.scaffLevel++;
3073 	dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
3074       }
3075       break;
3076     case XML_ROLE_GROUP_SEQUENCE:
3077       if (groupConnector[prologState.level] == '|')
3078 	return XML_ERROR_SYNTAX;
3079       groupConnector[prologState.level] = ',';
3080       break;
3081     case XML_ROLE_GROUP_CHOICE:
3082       if (groupConnector[prologState.level] == ',')
3083 	return XML_ERROR_SYNTAX;
3084       if (dtd.in_eldecl
3085 	  && ! groupConnector[prologState.level]
3086 	  && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
3087 	  ) {
3088 	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
3089       }
3090       groupConnector[prologState.level] = '|';
3091       break;
3092     case XML_ROLE_PARAM_ENTITY_REF:
3093 #ifdef XML_DTD
3094     case XML_ROLE_INNER_PARAM_ENTITY_REF:
3095       if (paramEntityParsing
3096 	  && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
3097 	const XML_Char *name;
3098 	ENTITY *entity;
3099 	name = poolStoreString(&dtd.pool, enc,
3100 				s + enc->minBytesPerChar,
3101 				next - enc->minBytesPerChar);
3102 	if (!name)
3103 	  return XML_ERROR_NO_MEMORY;
3104 	entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
3105 	poolDiscard(&dtd.pool);
3106 	if (!entity) {
3107 	  /* FIXME what to do if !dtd.complete? */
3108 	  return XML_ERROR_UNDEFINED_ENTITY;
3109 	}
3110 	if (entity->open)
3111 	  return XML_ERROR_RECURSIVE_ENTITY_REF;
3112 	if (entity->textPtr) {
3113 	  enum XML_Error result;
3114 	  result = processInternalParamEntity(parser, entity);
3115 	  if (result != XML_ERROR_NONE)
3116 	    return result;
3117 	  break;
3118 	}
3119 	if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
3120 	  return XML_ERROR_PARAM_ENTITY_REF;
3121 	if (externalEntityRefHandler) {
3122 	  dtd.complete = 0;
3123 	  entity->open = 1;
3124 	  if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3125 					0,
3126 					entity->base,
3127 					entity->systemId,
3128 					entity->publicId)) {
3129 	    entity->open = 0;
3130 	    return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3131 	  }
3132 	  entity->open = 0;
3133 	  if (dtd.complete)
3134 	    break;
3135 	}
3136       }
3137 #endif /* XML_DTD */
3138       if (!dtd.standalone
3139 	  && notStandaloneHandler
3140 	  && !notStandaloneHandler(handlerArg))
3141 	return XML_ERROR_NOT_STANDALONE;
3142       dtd.complete = 0;
3143       if (defaultHandler)
3144 	reportDefault(parser, enc, s, next);
3145       break;
3146 
3147       /* Element declaration stuff */
3148 
3149     case XML_ROLE_ELEMENT_NAME:
3150       if (elementDeclHandler) {
3151 	declElementType = getElementType(parser, enc, s, next);
3152 	if (! declElementType)
3153 	  return XML_ERROR_NO_MEMORY;
3154 	dtd.scaffLevel = 0;
3155 	dtd.scaffCount = 0;
3156 	dtd.in_eldecl = 1;
3157       }
3158       break;
3159 
3160     case XML_ROLE_CONTENT_ANY:
3161     case XML_ROLE_CONTENT_EMPTY:
3162       if (dtd.in_eldecl) {
3163 	if (elementDeclHandler) {
3164 	  XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
3165 	  if (! content)
3166 	    return XML_ERROR_NO_MEMORY;
3167 	  content->quant = XML_CQUANT_NONE;
3168 	  content->name = 0;
3169 	  content->numchildren = 0;
3170 	  content->children = 0;
3171 	  content->type = ((role == XML_ROLE_CONTENT_ANY) ?
3172 			   XML_CTYPE_ANY :
3173 			   XML_CTYPE_EMPTY);
3174 	  *eventEndPP = s;
3175 	  elementDeclHandler(handlerArg, declElementType->name, content);
3176 	}
3177 	dtd.in_eldecl = 0;
3178       }
3179       break;
3180 
3181     case XML_ROLE_CONTENT_PCDATA:
3182       if (dtd.in_eldecl) {
3183 	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
3184       }
3185       break;
3186 
3187     case XML_ROLE_CONTENT_ELEMENT:
3188       quant = XML_CQUANT_NONE;
3189       goto elementContent;
3190     case XML_ROLE_CONTENT_ELEMENT_OPT:
3191       quant = XML_CQUANT_OPT;
3192       goto elementContent;
3193     case XML_ROLE_CONTENT_ELEMENT_REP:
3194       quant = XML_CQUANT_REP;
3195       goto elementContent;
3196     case XML_ROLE_CONTENT_ELEMENT_PLUS:
3197       quant = XML_CQUANT_PLUS;
3198     elementContent:
3199       if (dtd.in_eldecl)
3200 	{
3201 	  ELEMENT_TYPE *el;
3202 	  const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
3203 	  int myindex = nextScaffoldPart(parser);
3204 	  if (myindex < 0)
3205 	    return XML_ERROR_NO_MEMORY;
3206 	  dtd.scaffold[myindex].type = XML_CTYPE_NAME;
3207 	  dtd.scaffold[myindex].quant = quant;
3208 	  el = getElementType(parser, enc, s, nxt);
3209 	  if (! el)
3210 	    return XML_ERROR_NO_MEMORY;
3211 	  dtd.scaffold[myindex].name = el->name;
3212 	  dtd.contentStringLen +=  nxt - s + 1;
3213 	}
3214       break;
3215 
3216     case XML_ROLE_GROUP_CLOSE:
3217       quant = XML_CQUANT_NONE;
3218       goto closeGroup;
3219     case XML_ROLE_GROUP_CLOSE_OPT:
3220       quant = XML_CQUANT_OPT;
3221       goto closeGroup;
3222     case XML_ROLE_GROUP_CLOSE_REP:
3223       quant = XML_CQUANT_REP;
3224       goto closeGroup;
3225     case XML_ROLE_GROUP_CLOSE_PLUS:
3226       quant = XML_CQUANT_PLUS;
3227     closeGroup:
3228       if (dtd.in_eldecl) {
3229 	dtd.scaffLevel--;
3230 	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
3231 	if (dtd.scaffLevel == 0) {
3232 	  if (elementDeclHandler) {
3233 	    XML_Content *model = build_model(parser);
3234 	    if (! model)
3235 	      return XML_ERROR_NO_MEMORY;
3236 	    *eventEndPP = s;
3237 	    elementDeclHandler(handlerArg, declElementType->name, model);
3238 	  }
3239 	  dtd.in_eldecl = 0;
3240 	  dtd.contentStringLen = 0;
3241 	}
3242       }
3243       break;
3244       /* End element declaration stuff */
3245 
3246     case XML_ROLE_NONE:
3247       switch (tok) {
3248       case XML_TOK_PI:
3249 	if (!reportProcessingInstruction(parser, enc, s, next))
3250 	  return XML_ERROR_NO_MEMORY;
3251 	break;
3252       case XML_TOK_COMMENT:
3253 	if (!reportComment(parser, enc, s, next))
3254 	  return XML_ERROR_NO_MEMORY;
3255 	break;
3256       }
3257       break;
3258     }
3259     if (defaultHandler) {
3260       switch (tok) {
3261       case XML_TOK_PI:
3262       case XML_TOK_COMMENT:
3263       case XML_TOK_BOM:
3264       case XML_TOK_XML_DECL:
3265 #ifdef XML_DTD
3266       case XML_TOK_IGNORE_SECT:
3267 #endif /* XML_DTD */
3268       case XML_TOK_PARAM_ENTITY_REF:
3269 	break;
3270       default:
3271 #ifdef XML_DTD
3272 	if (role != XML_ROLE_IGNORE_SECT)
3273 #endif /* XML_DTD */
3274 	  reportDefault(parser, enc, s, next);
3275       }
3276     }
3277     s = next;
3278     tok = XmlPrologTok(enc, s, end, &next);
3279   }
3280   /* not reached */
3281 }
3282 
3283 static
epilogProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)3284 enum XML_Error epilogProcessor(XML_Parser parser,
3285 			       const char *s,
3286 			       const char *end,
3287 			       const char **nextPtr)
3288 {
3289   processor = epilogProcessor;
3290   eventPtr = s;
3291   for (;;) {
3292     const char *next;
3293     int tok = XmlPrologTok(encoding, s, end, &next);
3294     eventEndPtr = next;
3295     switch (tok) {
3296     case -XML_TOK_PROLOG_S:
3297       if (defaultHandler) {
3298 	eventEndPtr = end;
3299 	reportDefault(parser, encoding, s, end);
3300       }
3301       /* fall through */
3302     case XML_TOK_NONE:
3303       if (nextPtr)
3304 	*nextPtr = end;
3305       return XML_ERROR_NONE;
3306     case XML_TOK_PROLOG_S:
3307       if (defaultHandler)
3308 	reportDefault(parser, encoding, s, next);
3309       break;
3310     case XML_TOK_PI:
3311       if (!reportProcessingInstruction(parser, encoding, s, next))
3312 	return XML_ERROR_NO_MEMORY;
3313       break;
3314     case XML_TOK_COMMENT:
3315       if (!reportComment(parser, encoding, s, next))
3316 	return XML_ERROR_NO_MEMORY;
3317       break;
3318     case XML_TOK_INVALID:
3319       eventPtr = next;
3320       return XML_ERROR_INVALID_TOKEN;
3321     case XML_TOK_PARTIAL:
3322       if (nextPtr) {
3323 	*nextPtr = s;
3324 	return XML_ERROR_NONE;
3325       }
3326       return XML_ERROR_UNCLOSED_TOKEN;
3327     case XML_TOK_PARTIAL_CHAR:
3328       if (nextPtr) {
3329 	*nextPtr = s;
3330 	return XML_ERROR_NONE;
3331       }
3332       return XML_ERROR_PARTIAL_CHAR;
3333     default:
3334       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
3335     }
3336     eventPtr = s = next;
3337   }
3338 }
3339 
3340 #ifdef XML_DTD
3341 
3342 static enum XML_Error
processInternalParamEntity(XML_Parser parser,ENTITY * entity)3343 processInternalParamEntity(XML_Parser parser, ENTITY *entity)
3344 {
3345   const char *s, *end, *next;
3346   int tok;
3347   enum XML_Error result;
3348   OPEN_INTERNAL_ENTITY openEntity;
3349   entity->open = 1;
3350   openEntity.next = openInternalEntities;
3351   openInternalEntities = &openEntity;
3352   openEntity.entity = entity;
3353   openEntity.internalEventPtr = 0;
3354   openEntity.internalEventEndPtr = 0;
3355   s = (char *)entity->textPtr;
3356   end = (char *)(entity->textPtr + entity->textLen);
3357   tok = XmlPrologTok(internalEncoding, s, end, &next);
3358   result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
3359   entity->open = 0;
3360   openInternalEntities = openEntity.next;
3361   return result;
3362 }
3363 
3364 #endif /* XML_DTD */
3365 
3366 static
errorProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)3367 enum XML_Error errorProcessor(XML_Parser parser,
3368 			      const char *s,
3369 			      const char *end,
3370 			      const char **nextPtr)
3371 {
3372   return errorCode;
3373 }
3374 
3375 static enum XML_Error
storeAttributeValue(XML_Parser parser,const ENCODING * enc,int isCdata,const char * ptr,const char * end,STRING_POOL * pool)3376 storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
3377 		    const char *ptr, const char *end,
3378 		    STRING_POOL *pool)
3379 {
3380   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
3381   if (result)
3382     return result;
3383   if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
3384     poolChop(pool);
3385   if (!poolAppendChar(pool, XML_T('\0')))
3386     return XML_ERROR_NO_MEMORY;
3387   return XML_ERROR_NONE;
3388 }
3389 
3390 static enum XML_Error
appendAttributeValue(XML_Parser parser,const ENCODING * enc,int isCdata,const char * ptr,const char * end,STRING_POOL * pool)3391 appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
3392 		     const char *ptr, const char *end,
3393 		     STRING_POOL *pool)
3394 {
3395   for (;;) {
3396     const char *next;
3397     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
3398     switch (tok) {
3399     case XML_TOK_NONE:
3400       return XML_ERROR_NONE;
3401     case XML_TOK_INVALID:
3402       if (enc == encoding)
3403 	eventPtr = next;
3404       return XML_ERROR_INVALID_TOKEN;
3405     case XML_TOK_PARTIAL:
3406       if (enc == encoding)
3407 	eventPtr = ptr;
3408       return XML_ERROR_INVALID_TOKEN;
3409     case XML_TOK_CHAR_REF:
3410       {
3411 	XML_Char buf[XML_ENCODE_MAX];
3412 	int i;
3413 	int n = XmlCharRefNumber(enc, ptr);
3414 	if (n < 0) {
3415 	  if (enc == encoding)
3416 	    eventPtr = ptr;
3417       	  return XML_ERROR_BAD_CHAR_REF;
3418 	}
3419 	if (!isCdata
3420 	    && n == 0x20 /* space */
3421 	    && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
3422 	  break;
3423 	n = XmlEncode(n, (ICHAR *)buf);
3424 	if (!n) {
3425 	  if (enc == encoding)
3426 	    eventPtr = ptr;
3427 	  return XML_ERROR_BAD_CHAR_REF;
3428 	}
3429 	for (i = 0; i < n; i++) {
3430 	  if (!poolAppendChar(pool, buf[i]))
3431 	    return XML_ERROR_NO_MEMORY;
3432 	}
3433       }
3434       break;
3435     case XML_TOK_DATA_CHARS:
3436       if (!poolAppend(pool, enc, ptr, next))
3437 	return XML_ERROR_NO_MEMORY;
3438       break;
3439       break;
3440     case XML_TOK_TRAILING_CR:
3441       next = ptr + enc->minBytesPerChar;
3442       /* fall through */
3443     case XML_TOK_ATTRIBUTE_VALUE_S:
3444     case XML_TOK_DATA_NEWLINE:
3445       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
3446 	break;
3447       if (!poolAppendChar(pool, 0x20))
3448 	return XML_ERROR_NO_MEMORY;
3449       break;
3450     case XML_TOK_ENTITY_REF:
3451       {
3452 	const XML_Char *name;
3453 	ENTITY *entity;
3454 	XML_Char ch = XmlPredefinedEntityName(enc,
3455 					      ptr + enc->minBytesPerChar,
3456 					      next - enc->minBytesPerChar);
3457 	if (ch) {
3458 	  if (!poolAppendChar(pool, ch))
3459   	    return XML_ERROR_NO_MEMORY;
3460 	  break;
3461 	}
3462 	name = poolStoreString(&temp2Pool, enc,
3463 			       ptr + enc->minBytesPerChar,
3464 			       next - enc->minBytesPerChar);
3465 	if (!name)
3466 	  return XML_ERROR_NO_MEMORY;
3467 	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
3468 	poolDiscard(&temp2Pool);
3469 	if (!entity) {
3470 	  if (dtd.complete) {
3471 	    if (enc == encoding)
3472 	      eventPtr = ptr;
3473 	    return XML_ERROR_UNDEFINED_ENTITY;
3474 	  }
3475 	}
3476 	else if (entity->open) {
3477 	  if (enc == encoding)
3478 	    eventPtr = ptr;
3479 	  return XML_ERROR_RECURSIVE_ENTITY_REF;
3480 	}
3481 	else if (entity->notation) {
3482 	  if (enc == encoding)
3483 	    eventPtr = ptr;
3484 	  return XML_ERROR_BINARY_ENTITY_REF;
3485 	}
3486 	else if (!entity->textPtr) {
3487 	  if (enc == encoding)
3488 	    eventPtr = ptr;
3489   	  return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
3490 	}
3491 	else {
3492 	  enum XML_Error result;
3493 	  const XML_Char *textEnd = entity->textPtr + entity->textLen;
3494 	  entity->open = 1;
3495 	  result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
3496 	  entity->open = 0;
3497 	  if (result)
3498 	    return result;
3499 	}
3500       }
3501       break;
3502     default:
3503       if (enc == encoding)
3504 	eventPtr = ptr;
3505       return XML_ERROR_UNEXPECTED_STATE;
3506     }
3507     ptr = next;
3508   }
3509   /* not reached */
3510 }
3511 
3512 static
storeEntityValue(XML_Parser parser,const ENCODING * enc,const char * entityTextPtr,const char * entityTextEnd)3513 enum XML_Error storeEntityValue(XML_Parser parser,
3514 				const ENCODING *enc,
3515 				const char *entityTextPtr,
3516 				const char *entityTextEnd)
3517 {
3518   STRING_POOL *pool = &(dtd.pool);
3519   for (;;) {
3520     const char *next;
3521     int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
3522     switch (tok) {
3523     case XML_TOK_PARAM_ENTITY_REF:
3524 #ifdef XML_DTD
3525       if (parentParser || enc != encoding) {
3526 	enum XML_Error result;
3527 	const XML_Char *name;
3528 	ENTITY *entity;
3529 	name = poolStoreString(&tempPool, enc,
3530 			       entityTextPtr + enc->minBytesPerChar,
3531 			       next - enc->minBytesPerChar);
3532 	if (!name)
3533 	  return XML_ERROR_NO_MEMORY;
3534 	entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
3535 	poolDiscard(&tempPool);
3536 	if (!entity) {
3537 	  if (enc == encoding)
3538 	    eventPtr = entityTextPtr;
3539 	  return XML_ERROR_UNDEFINED_ENTITY;
3540 	}
3541 	if (entity->open) {
3542 	  if (enc == encoding)
3543 	    eventPtr = entityTextPtr;
3544 	  return XML_ERROR_RECURSIVE_ENTITY_REF;
3545 	}
3546 	if (entity->systemId) {
3547 	  if (enc == encoding)
3548 	    eventPtr = entityTextPtr;
3549 	  return XML_ERROR_PARAM_ENTITY_REF;
3550 	}
3551 	entity->open = 1;
3552 	result = storeEntityValue(parser,
3553 				  internalEncoding,
3554 				  (char *)entity->textPtr,
3555 				  (char *)(entity->textPtr + entity->textLen));
3556 	entity->open = 0;
3557 	if (result)
3558 	  return result;
3559 	break;
3560       }
3561 #endif /* XML_DTD */
3562       eventPtr = entityTextPtr;
3563       return XML_ERROR_SYNTAX;
3564     case XML_TOK_NONE:
3565       return XML_ERROR_NONE;
3566     case XML_TOK_ENTITY_REF:
3567     case XML_TOK_DATA_CHARS:
3568       if (!poolAppend(pool, enc, entityTextPtr, next))
3569 	return XML_ERROR_NO_MEMORY;
3570       break;
3571     case XML_TOK_TRAILING_CR:
3572       next = entityTextPtr + enc->minBytesPerChar;
3573       /* fall through */
3574     case XML_TOK_DATA_NEWLINE:
3575       if (pool->end == pool->ptr && !poolGrow(pool))
3576 	return XML_ERROR_NO_MEMORY;
3577       *(pool->ptr)++ = 0xA;
3578       break;
3579     case XML_TOK_CHAR_REF:
3580       {
3581 	XML_Char buf[XML_ENCODE_MAX];
3582 	int i;
3583 	int n = XmlCharRefNumber(enc, entityTextPtr);
3584 	if (n < 0) {
3585 	  if (enc == encoding)
3586 	    eventPtr = entityTextPtr;
3587 	  return XML_ERROR_BAD_CHAR_REF;
3588 	}
3589 	n = XmlEncode(n, (ICHAR *)buf);
3590 	if (!n) {
3591 	  if (enc == encoding)
3592 	    eventPtr = entityTextPtr;
3593 	  return XML_ERROR_BAD_CHAR_REF;
3594 	}
3595 	for (i = 0; i < n; i++) {
3596 	  if (pool->end == pool->ptr && !poolGrow(pool))
3597 	    return XML_ERROR_NO_MEMORY;
3598 	  *(pool->ptr)++ = buf[i];
3599 	}
3600       }
3601       break;
3602     case XML_TOK_PARTIAL:
3603       if (enc == encoding)
3604 	eventPtr = entityTextPtr;
3605       return XML_ERROR_INVALID_TOKEN;
3606     case XML_TOK_INVALID:
3607       if (enc == encoding)
3608 	eventPtr = next;
3609       return XML_ERROR_INVALID_TOKEN;
3610     default:
3611       if (enc == encoding)
3612 	eventPtr = entityTextPtr;
3613       return XML_ERROR_UNEXPECTED_STATE;
3614     }
3615     entityTextPtr = next;
3616   }
3617   /* not reached */
3618 }
3619 
3620 static void
normalizeLines(XML_Char * s)3621 normalizeLines(XML_Char *s)
3622 {
3623   XML_Char *p;
3624   for (;; s++) {
3625     if (*s == XML_T('\0'))
3626       return;
3627     if (*s == 0xD)
3628       break;
3629   }
3630   p = s;
3631   do {
3632     if (*s == 0xD) {
3633       *p++ = 0xA;
3634       if (*++s == 0xA)
3635         s++;
3636     }
3637     else
3638       *p++ = *s++;
3639   } while (*s);
3640   *p = XML_T('\0');
3641 }
3642 
3643 static int
reportProcessingInstruction(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)3644 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3645 {
3646   const XML_Char *target;
3647   XML_Char *data;
3648   const char *tem;
3649   if (!processingInstructionHandler) {
3650     if (defaultHandler)
3651       reportDefault(parser, enc, start, end);
3652     return 1;
3653   }
3654   start += enc->minBytesPerChar * 2;
3655   tem = start + XmlNameLength(enc, start);
3656   target = poolStoreString(&tempPool, enc, start, tem);
3657   if (!target)
3658     return 0;
3659   poolFinish(&tempPool);
3660   data = poolStoreString(&tempPool, enc,
3661 			XmlSkipS(enc, tem),
3662 			end - enc->minBytesPerChar*2);
3663   if (!data)
3664     return 0;
3665   normalizeLines(data);
3666   processingInstructionHandler(handlerArg, target, data);
3667   poolClear(&tempPool);
3668   return 1;
3669 }
3670 
3671 static int
reportComment(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)3672 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3673 {
3674   XML_Char *data;
3675   if (!commentHandler) {
3676     if (defaultHandler)
3677       reportDefault(parser, enc, start, end);
3678     return 1;
3679   }
3680   data = poolStoreString(&tempPool,
3681                          enc,
3682                          start + enc->minBytesPerChar * 4,
3683 			 end - enc->minBytesPerChar * 3);
3684   if (!data)
3685     return 0;
3686   normalizeLines(data);
3687   commentHandler(handlerArg, data);
3688   poolClear(&tempPool);
3689   return 1;
3690 }
3691 
3692 static void
reportDefault(XML_Parser parser,const ENCODING * enc,const char * s,const char * end)3693 reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
3694 {
3695   if (MUST_CONVERT(enc, s)) {
3696     const char **eventPP;
3697     const char **eventEndPP;
3698     if (enc == encoding) {
3699       eventPP = &eventPtr;
3700       eventEndPP = &eventEndPtr;
3701     }
3702     else {
3703       eventPP = &(openInternalEntities->internalEventPtr);
3704       eventEndPP = &(openInternalEntities->internalEventEndPtr);
3705     }
3706     do {
3707       ICHAR *dataPtr = (ICHAR *)dataBuf;
3708       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
3709       *eventEndPP = s;
3710       defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
3711       *eventPP = s;
3712     } while (s != end);
3713   }
3714   else
3715     defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
3716 }
3717 
3718 
3719 static int
defineAttribute(ELEMENT_TYPE * type,ATTRIBUTE_ID * attId,int isCdata,int isId,const XML_Char * value,XML_Parser parser)3720 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata,
3721 		int isId, const XML_Char *value, XML_Parser parser)
3722 {
3723   DEFAULT_ATTRIBUTE *att;
3724   if (value || isId) {
3725     /* The handling of default attributes gets messed up if we have
3726        a default which duplicates a non-default. */
3727     int i;
3728     for (i = 0; i < type->nDefaultAtts; i++)
3729       if (attId == type->defaultAtts[i].id)
3730 	return 1;
3731     if (isId && !type->idAtt && !attId->xmlns)
3732       type->idAtt = attId;
3733   }
3734   if (type->nDefaultAtts == type->allocDefaultAtts) {
3735     if (type->allocDefaultAtts == 0) {
3736       type->allocDefaultAtts = 8;
3737       type->defaultAtts = MALLOC(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
3738     }
3739     else {
3740       type->allocDefaultAtts *= 2;
3741       type->defaultAtts = REALLOC(type->defaultAtts,
3742 				  type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
3743     }
3744     if (!type->defaultAtts)
3745       return 0;
3746   }
3747   att = type->defaultAtts + type->nDefaultAtts;
3748   att->id = attId;
3749   att->value = value;
3750   att->isCdata = isCdata;
3751   if (!isCdata)
3752     attId->maybeTokenized = 1;
3753   type->nDefaultAtts += 1;
3754   return 1;
3755 }
3756 
setElementTypePrefix(XML_Parser parser,ELEMENT_TYPE * elementType)3757 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
3758 {
3759   const XML_Char *name;
3760   for (name = elementType->name; *name; name++) {
3761     if (*name == XML_T(':')) {
3762       PREFIX *prefix;
3763       const XML_Char *s;
3764       for (s = elementType->name; s != name; s++) {
3765 	if (!poolAppendChar(&dtd.pool, *s))
3766 	  return 0;
3767       }
3768       if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3769 	return 0;
3770       prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
3771       if (!prefix)
3772 	return 0;
3773       if (prefix->name == poolStart(&dtd.pool))
3774 	poolFinish(&dtd.pool);
3775       else
3776 	poolDiscard(&dtd.pool);
3777       elementType->prefix = prefix;
3778 
3779     }
3780   }
3781   return 1;
3782 }
3783 
3784 static ATTRIBUTE_ID *
getAttributeId(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)3785 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
3786 {
3787   ATTRIBUTE_ID *id;
3788   const XML_Char *name;
3789   if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3790     return 0;
3791   name = poolStoreString(&dtd.pool, enc, start, end);
3792   if (!name)
3793     return 0;
3794   ++name;
3795   id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
3796   if (!id)
3797     return 0;
3798   if (id->name != name)
3799     poolDiscard(&dtd.pool);
3800   else {
3801     poolFinish(&dtd.pool);
3802     if (!ns)
3803       ;
3804     else if (name[0] == 'x'
3805 	&& name[1] == 'm'
3806 	&& name[2] == 'l'
3807 	&& name[3] == 'n'
3808 	&& name[4] == 's'
3809 	&& (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
3810       if (name[5] == '\0')
3811 	id->prefix = &dtd.defaultPrefix;
3812       else
3813 	id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
3814       id->xmlns = 1;
3815     }
3816     else {
3817       int i;
3818       for (i = 0; name[i]; i++) {
3819 	if (name[i] == XML_T(':')) {
3820 	  int j;
3821 	  for (j = 0; j < i; j++) {
3822 	    if (!poolAppendChar(&dtd.pool, name[j]))
3823 	      return 0;
3824 	  }
3825 	  if (!poolAppendChar(&dtd.pool, XML_T('\0')))
3826 	    return 0;
3827 	  id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
3828 	  if (id->prefix->name == poolStart(&dtd.pool))
3829 	    poolFinish(&dtd.pool);
3830 	  else
3831 	    poolDiscard(&dtd.pool);
3832 	  break;
3833 	}
3834       }
3835     }
3836   }
3837   return id;
3838 }
3839 
3840 #define CONTEXT_SEP XML_T('\f')
3841 
3842 static
getContext(XML_Parser parser)3843 const XML_Char *getContext(XML_Parser parser)
3844 {
3845   HASH_TABLE_ITER iter;
3846   int needSep = 0;
3847 
3848   if (dtd.defaultPrefix.binding) {
3849     int i;
3850     int len;
3851     if (!poolAppendChar(&tempPool, XML_T('=')))
3852       return 0;
3853     len = dtd.defaultPrefix.binding->uriLen;
3854     if (namespaceSeparator != XML_T('\0'))
3855       len--;
3856     for (i = 0; i < len; i++)
3857       if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
3858   	return 0;
3859     needSep = 1;
3860   }
3861 
3862   hashTableIterInit(&iter, &(dtd.prefixes));
3863   for (;;) {
3864     int i;
3865     int len;
3866     const XML_Char *s;
3867     PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
3868     if (!prefix)
3869       break;
3870     if (!prefix->binding)
3871       continue;
3872     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
3873       return 0;
3874     for (s = prefix->name; *s; s++)
3875       if (!poolAppendChar(&tempPool, *s))
3876         return 0;
3877     if (!poolAppendChar(&tempPool, XML_T('=')))
3878       return 0;
3879     len = prefix->binding->uriLen;
3880     if (namespaceSeparator != XML_T('\0'))
3881       len--;
3882     for (i = 0; i < len; i++)
3883       if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
3884         return 0;
3885     needSep = 1;
3886   }
3887 
3888 
3889   hashTableIterInit(&iter, &(dtd.generalEntities));
3890   for (;;) {
3891     const XML_Char *s;
3892     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
3893     if (!e)
3894       break;
3895     if (!e->open)
3896       continue;
3897     if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
3898       return 0;
3899     for (s = e->name; *s; s++)
3900       if (!poolAppendChar(&tempPool, *s))
3901         return 0;
3902     needSep = 1;
3903   }
3904 
3905   if (!poolAppendChar(&tempPool, XML_T('\0')))
3906     return 0;
3907   return tempPool.start;
3908 }
3909 
3910 static
setContext(XML_Parser parser,const XML_Char * context)3911 int setContext(XML_Parser parser, const XML_Char *context)
3912 {
3913   const XML_Char *s = context;
3914 
3915   while (*context != XML_T('\0')) {
3916     if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
3917       ENTITY *e;
3918       if (!poolAppendChar(&tempPool, XML_T('\0')))
3919 	return 0;
3920       e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
3921       if (e)
3922 	e->open = 1;
3923       if (*s != XML_T('\0'))
3924 	s++;
3925       context = s;
3926       poolDiscard(&tempPool);
3927     }
3928     else if (*s == '=') {
3929       PREFIX *prefix;
3930       if (poolLength(&tempPool) == 0)
3931 	prefix = &dtd.defaultPrefix;
3932       else {
3933 	if (!poolAppendChar(&tempPool, XML_T('\0')))
3934 	  return 0;
3935 	prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
3936 	if (!prefix)
3937 	  return 0;
3938         if (prefix->name == poolStart(&tempPool)) {
3939 	  prefix->name = poolCopyString(&dtd.pool, prefix->name);
3940 	  if (!prefix->name)
3941 	    return 0;
3942 	}
3943 	poolDiscard(&tempPool);
3944       }
3945       for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
3946         if (!poolAppendChar(&tempPool, *context))
3947           return 0;
3948       if (!poolAppendChar(&tempPool, XML_T('\0')))
3949 	return 0;
3950       if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
3951 	return 0;
3952       poolDiscard(&tempPool);
3953       if (*context != XML_T('\0'))
3954 	++context;
3955       s = context;
3956     }
3957     else {
3958       if (!poolAppendChar(&tempPool, *s))
3959 	return 0;
3960       s++;
3961     }
3962   }
3963   return 1;
3964 }
3965 
3966 
3967 static
normalizePublicId(XML_Char * publicId)3968 void normalizePublicId(XML_Char *publicId)
3969 {
3970   XML_Char *p = publicId;
3971   XML_Char *s;
3972   for (s = publicId; *s; s++) {
3973     switch (*s) {
3974     case 0x20:
3975     case 0xD:
3976     case 0xA:
3977       if (p != publicId && p[-1] != 0x20)
3978 	*p++ = 0x20;
3979       break;
3980     default:
3981       *p++ = *s;
3982     }
3983   }
3984   if (p != publicId && p[-1] == 0x20)
3985     --p;
3986   *p = XML_T('\0');
3987 }
3988 
dtdInit(DTD * p,XML_Parser parser)3989 static int dtdInit(DTD *p, XML_Parser parser)
3990 {
3991   XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem;
3992   poolInit(&(p->pool), ms);
3993   hashTableInit(&(p->generalEntities), ms);
3994   hashTableInit(&(p->elementTypes), ms);
3995   hashTableInit(&(p->attributeIds), ms);
3996   hashTableInit(&(p->prefixes), ms);
3997   p->complete = 1;
3998   p->standalone = 0;
3999 #ifdef XML_DTD
4000   hashTableInit(&(p->paramEntities), ms);
4001 #endif /* XML_DTD */
4002   p->defaultPrefix.name = 0;
4003   p->defaultPrefix.binding = 0;
4004 
4005   p->in_eldecl = 0;
4006   p->scaffIndex = 0;
4007   p->scaffLevel = 0;
4008   p->scaffold = 0;
4009   p->contentStringLen = 0;
4010   p->scaffSize = 0;
4011   p->scaffCount = 0;
4012 
4013   return 1;
4014 }
4015 
4016 #ifdef XML_DTD
4017 
dtdSwap(DTD * p1,DTD * p2)4018 static void dtdSwap(DTD *p1, DTD *p2)
4019 {
4020   DTD tem;
4021   memcpy(&tem, p1, sizeof(DTD));
4022   memcpy(p1, p2, sizeof(DTD));
4023   memcpy(p2, &tem, sizeof(DTD));
4024 }
4025 
4026 #endif /* XML_DTD */
4027 
dtdDestroy(DTD * p,XML_Parser parser)4028 static void dtdDestroy(DTD *p, XML_Parser parser)
4029 {
4030   HASH_TABLE_ITER iter;
4031   hashTableIterInit(&iter, &(p->elementTypes));
4032   for (;;) {
4033     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4034     if (!e)
4035       break;
4036     if (e->allocDefaultAtts != 0)
4037       FREE(e->defaultAtts);
4038   }
4039   hashTableDestroy(&(p->generalEntities));
4040 #ifdef XML_DTD
4041   hashTableDestroy(&(p->paramEntities));
4042 #endif /* XML_DTD */
4043   hashTableDestroy(&(p->elementTypes));
4044   hashTableDestroy(&(p->attributeIds));
4045   hashTableDestroy(&(p->prefixes));
4046   poolDestroy(&(p->pool));
4047   if (p->scaffIndex)
4048     FREE(p->scaffIndex);
4049   if (p->scaffold)
4050     FREE(p->scaffold);
4051 }
4052 
4053 /* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
4054 The new DTD has already been initialized. */
4055 
dtdCopy(DTD * newDtd,const DTD * oldDtd,XML_Parser parser)4056 static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
4057 {
4058   HASH_TABLE_ITER iter;
4059 
4060   /* Copy the prefix table. */
4061 
4062   hashTableIterInit(&iter, &(oldDtd->prefixes));
4063   for (;;) {
4064     const XML_Char *name;
4065     const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
4066     if (!oldP)
4067       break;
4068     name = poolCopyString(&(newDtd->pool), oldP->name);
4069     if (!name)
4070       return 0;
4071     if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
4072       return 0;
4073   }
4074 
4075   hashTableIterInit(&iter, &(oldDtd->attributeIds));
4076 
4077   /* Copy the attribute id table. */
4078 
4079   for (;;) {
4080     ATTRIBUTE_ID *newA;
4081     const XML_Char *name;
4082     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
4083 
4084     if (!oldA)
4085       break;
4086     /* Remember to allocate the scratch byte before the name. */
4087     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
4088       return 0;
4089     name = poolCopyString(&(newDtd->pool), oldA->name);
4090     if (!name)
4091       return 0;
4092     ++name;
4093     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
4094     if (!newA)
4095       return 0;
4096     newA->maybeTokenized = oldA->maybeTokenized;
4097     if (oldA->prefix) {
4098       newA->xmlns = oldA->xmlns;
4099       if (oldA->prefix == &oldDtd->defaultPrefix)
4100 	newA->prefix = &newDtd->defaultPrefix;
4101       else
4102 	newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
4103     }
4104   }
4105 
4106   /* Copy the element type table. */
4107 
4108   hashTableIterInit(&iter, &(oldDtd->elementTypes));
4109 
4110   for (;;) {
4111     int i;
4112     ELEMENT_TYPE *newE;
4113     const XML_Char *name;
4114     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
4115     if (!oldE)
4116       break;
4117     name = poolCopyString(&(newDtd->pool), oldE->name);
4118     if (!name)
4119       return 0;
4120     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
4121     if (!newE)
4122       return 0;
4123     if (oldE->nDefaultAtts) {
4124       newE->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
4125       if (!newE->defaultAtts)
4126 	return 0;
4127     }
4128     if (oldE->idAtt)
4129       newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
4130     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
4131     if (oldE->prefix)
4132       newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
4133     for (i = 0; i < newE->nDefaultAtts; i++) {
4134       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
4135       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
4136       if (oldE->defaultAtts[i].value) {
4137 	newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
4138 	if (!newE->defaultAtts[i].value)
4139   	  return 0;
4140       }
4141       else
4142 	newE->defaultAtts[i].value = 0;
4143     }
4144   }
4145 
4146   /* Copy the entity tables. */
4147   if (!copyEntityTable(&(newDtd->generalEntities),
4148 		       &(newDtd->pool),
4149 		       &(oldDtd->generalEntities), parser))
4150       return 0;
4151 
4152 #ifdef XML_DTD
4153   if (!copyEntityTable(&(newDtd->paramEntities),
4154 		       &(newDtd->pool),
4155 		       &(oldDtd->paramEntities), parser))
4156       return 0;
4157 #endif /* XML_DTD */
4158 
4159   newDtd->complete = oldDtd->complete;
4160   newDtd->standalone = oldDtd->standalone;
4161 
4162   /* Don't want deep copying for scaffolding */
4163   newDtd->in_eldecl = oldDtd->in_eldecl;
4164   newDtd->scaffold = oldDtd->scaffold;
4165   newDtd->contentStringLen = oldDtd->contentStringLen;
4166   newDtd->scaffSize = oldDtd->scaffSize;
4167   newDtd->scaffLevel = oldDtd->scaffLevel;
4168   newDtd->scaffIndex = oldDtd->scaffIndex;
4169 
4170   return 1;
4171 }  /* End dtdCopy */
4172 
copyEntityTable(HASH_TABLE * newTable,STRING_POOL * newPool,const HASH_TABLE * oldTable,XML_Parser parser)4173 static int copyEntityTable(HASH_TABLE *newTable,
4174 			   STRING_POOL *newPool,
4175 			   const HASH_TABLE *oldTable,
4176 			   XML_Parser parser)
4177 {
4178   HASH_TABLE_ITER iter;
4179   const XML_Char *cachedOldBase = 0;
4180   const XML_Char *cachedNewBase = 0;
4181 
4182   hashTableIterInit(&iter, oldTable);
4183 
4184   for (;;) {
4185     ENTITY *newE;
4186     const XML_Char *name;
4187     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
4188     if (!oldE)
4189       break;
4190     name = poolCopyString(newPool, oldE->name);
4191     if (!name)
4192       return 0;
4193     newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
4194     if (!newE)
4195       return 0;
4196     if (oldE->systemId) {
4197       const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
4198       if (!tem)
4199 	return 0;
4200       newE->systemId = tem;
4201       if (oldE->base) {
4202 	if (oldE->base == cachedOldBase)
4203 	  newE->base = cachedNewBase;
4204 	else {
4205 	  cachedOldBase = oldE->base;
4206 	  tem = poolCopyString(newPool, cachedOldBase);
4207 	  if (!tem)
4208 	    return 0;
4209 	  cachedNewBase = newE->base = tem;
4210 	}
4211       }
4212     }
4213     else {
4214       const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
4215       if (!tem)
4216 	return 0;
4217       newE->textPtr = tem;
4218       newE->textLen = oldE->textLen;
4219     }
4220     if (oldE->notation) {
4221       const XML_Char *tem = poolCopyString(newPool, oldE->notation);
4222       if (!tem)
4223 	return 0;
4224       newE->notation = tem;
4225     }
4226   }
4227   return 1;
4228 }
4229 
4230 #define INIT_SIZE 64
4231 
4232 static
keyeq(KEY s1,KEY s2)4233 int keyeq(KEY s1, KEY s2)
4234 {
4235   for (; *s1 == *s2; s1++, s2++)
4236     if (*s1 == 0)
4237       return 1;
4238   return 0;
4239 }
4240 
4241 static
hash(KEY s)4242 unsigned long hash(KEY s)
4243 {
4244   unsigned long h = 0;
4245   while (*s)
4246     h = (h << 5) + h + (unsigned char)*s++;
4247   return h;
4248 }
4249 
4250 static
lookup(HASH_TABLE * table,KEY name,size_t createSize)4251 NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
4252 {
4253   size_t i;
4254   if (table->size == 0) {
4255     size_t tsize;
4256 
4257     if (!createSize)
4258       return 0;
4259     tsize = INIT_SIZE * sizeof(NAMED *);
4260     table->v = table->mem->malloc_fcn(tsize);
4261     if (!table->v)
4262       return 0;
4263     memset(table->v, 0, tsize);
4264     table->size = INIT_SIZE;
4265     table->usedLim = INIT_SIZE / 2;
4266     i = hash(name) & (table->size - 1);
4267   }
4268   else {
4269     unsigned long h = hash(name);
4270     for (i = h & (table->size - 1);
4271          table->v[i];
4272          i == 0 ? i = table->size - 1 : --i) {
4273       if (keyeq(name, table->v[i]->name))
4274 	return table->v[i];
4275     }
4276     if (!createSize)
4277       return 0;
4278     if (table->used == table->usedLim) {
4279       /* check for overflow */
4280       size_t newSize = table->size * 2;
4281       size_t tsize = newSize * sizeof(NAMED *);
4282       NAMED **newV = table->mem->malloc_fcn(tsize);
4283       if (!newV)
4284 	return 0;
4285       memset(newV, 0, tsize);
4286       for (i = 0; i < table->size; i++)
4287 	if (table->v[i]) {
4288 	  size_t j;
4289 	  for (j = hash(table->v[i]->name) & (newSize - 1);
4290 	       newV[j];
4291 	       j == 0 ? j = newSize - 1 : --j)
4292 	    ;
4293 	  newV[j] = table->v[i];
4294 	}
4295       table->mem->free_fcn(table->v);
4296       table->v = newV;
4297       table->size = newSize;
4298       table->usedLim = newSize/2;
4299       for (i = h & (table->size - 1);
4300 	   table->v[i];
4301 	   i == 0 ? i = table->size - 1 : --i)
4302 	;
4303     }
4304   }
4305   table->v[i] = table->mem->malloc_fcn(createSize);
4306   if (!table->v[i])
4307     return 0;
4308   memset(table->v[i], 0, createSize);
4309   table->v[i]->name = name;
4310   (table->used)++;
4311   return table->v[i];
4312 }
4313 
4314 static
hashTableDestroy(HASH_TABLE * table)4315 void hashTableDestroy(HASH_TABLE *table)
4316 {
4317   size_t i;
4318   for (i = 0; i < table->size; i++) {
4319     NAMED *p = table->v[i];
4320     if (p)
4321       table->mem->free_fcn(p);
4322   }
4323   if (table->v)
4324     table->mem->free_fcn(table->v);
4325 }
4326 
4327 static
hashTableInit(HASH_TABLE * p,XML_Memory_Handling_Suite * ms)4328 void hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
4329 {
4330   p->size = 0;
4331   p->usedLim = 0;
4332   p->used = 0;
4333   p->v = 0;
4334   p->mem = ms;
4335 }
4336 
4337 static
hashTableIterInit(HASH_TABLE_ITER * iter,const HASH_TABLE * table)4338 void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
4339 {
4340   iter->p = table->v;
4341   iter->end = iter->p + table->size;
4342 }
4343 
4344 static
hashTableIterNext(HASH_TABLE_ITER * iter)4345 NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
4346 {
4347   while (iter->p != iter->end) {
4348     NAMED *tem = *(iter->p)++;
4349     if (tem)
4350       return tem;
4351   }
4352   return 0;
4353 }
4354 
4355 
4356 static
poolInit(STRING_POOL * pool,XML_Memory_Handling_Suite * ms)4357 void poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
4358 {
4359   pool->blocks = 0;
4360   pool->freeBlocks = 0;
4361   pool->start = 0;
4362   pool->ptr = 0;
4363   pool->end = 0;
4364   pool->mem = ms;
4365 }
4366 
4367 static
poolClear(STRING_POOL * pool)4368 void poolClear(STRING_POOL *pool)
4369 {
4370   if (!pool->freeBlocks)
4371     pool->freeBlocks = pool->blocks;
4372   else {
4373     BLOCK *p = pool->blocks;
4374     while (p) {
4375       BLOCK *tem = p->next;
4376       p->next = pool->freeBlocks;
4377       pool->freeBlocks = p;
4378       p = tem;
4379     }
4380   }
4381   pool->blocks = 0;
4382   pool->start = 0;
4383   pool->ptr = 0;
4384   pool->end = 0;
4385 }
4386 
4387 static
poolDestroy(STRING_POOL * pool)4388 void poolDestroy(STRING_POOL *pool)
4389 {
4390   BLOCK *p = pool->blocks;
4391   while (p) {
4392     BLOCK *tem = p->next;
4393     pool->mem->free_fcn(p);
4394     p = tem;
4395   }
4396   pool->blocks = 0;
4397   p = pool->freeBlocks;
4398   while (p) {
4399     BLOCK *tem = p->next;
4400     pool->mem->free_fcn(p);
4401     p = tem;
4402   }
4403   pool->freeBlocks = 0;
4404   pool->ptr = 0;
4405   pool->start = 0;
4406   pool->end = 0;
4407 }
4408 
4409 static
poolAppend(STRING_POOL * pool,const ENCODING * enc,const char * ptr,const char * end)4410 XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
4411 		     const char *ptr, const char *end)
4412 {
4413   if (!pool->ptr && !poolGrow(pool))
4414     return 0;
4415   for (;;) {
4416     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
4417     if (ptr == end)
4418       break;
4419     if (!poolGrow(pool))
4420       return 0;
4421   }
4422   return pool->start;
4423 }
4424 
poolCopyString(STRING_POOL * pool,const XML_Char * s)4425 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
4426 {
4427   do {
4428     if (!poolAppendChar(pool, *s))
4429       return 0;
4430   } while (*s++);
4431   s = pool->start;
4432   poolFinish(pool);
4433   return s;
4434 }
4435 
poolCopyStringN(STRING_POOL * pool,const XML_Char * s,int n)4436 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
4437 {
4438   if (!pool->ptr && !poolGrow(pool))
4439     return 0;
4440   for (; n > 0; --n, s++) {
4441     if (!poolAppendChar(pool, *s))
4442       return 0;
4443 
4444   }
4445   s = pool->start;
4446   poolFinish(pool);
4447   return s;
4448 }
4449 
4450 static
poolAppendString(STRING_POOL * pool,const XML_Char * s)4451 const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s)
4452 {
4453   while (*s) {
4454     if (!poolAppendChar(pool, *s))
4455       return 0;
4456     s++;
4457   }
4458   return pool->start;
4459 }  /* End poolAppendString */
4460 
4461 static
poolStoreString(STRING_POOL * pool,const ENCODING * enc,const char * ptr,const char * end)4462 XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
4463 			  const char *ptr, const char *end)
4464 {
4465   if (!poolAppend(pool, enc, ptr, end))
4466     return 0;
4467   if (pool->ptr == pool->end && !poolGrow(pool))
4468     return 0;
4469   *(pool->ptr)++ = 0;
4470   return pool->start;
4471 }
4472 
4473 static
poolGrow(STRING_POOL * pool)4474 int poolGrow(STRING_POOL *pool)
4475 {
4476   if (pool->freeBlocks) {
4477     if (pool->start == 0) {
4478       pool->blocks = pool->freeBlocks;
4479       pool->freeBlocks = pool->freeBlocks->next;
4480       pool->blocks->next = 0;
4481       pool->start = pool->blocks->s;
4482       pool->end = pool->start + pool->blocks->size;
4483       pool->ptr = pool->start;
4484       return 1;
4485     }
4486     if (pool->end - pool->start < pool->freeBlocks->size) {
4487       BLOCK *tem = pool->freeBlocks->next;
4488       pool->freeBlocks->next = pool->blocks;
4489       pool->blocks = pool->freeBlocks;
4490       pool->freeBlocks = tem;
4491       memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
4492       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
4493       pool->start = pool->blocks->s;
4494       pool->end = pool->start + pool->blocks->size;
4495       return 1;
4496     }
4497   }
4498   if (pool->blocks && pool->start == pool->blocks->s) {
4499     int blockSize = (pool->end - pool->start)*2;
4500     pool->blocks = pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
4501     if (!pool->blocks)
4502       return 0;
4503     pool->blocks->size = blockSize;
4504     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
4505     pool->start = pool->blocks->s;
4506     pool->end = pool->start + blockSize;
4507   }
4508   else {
4509     BLOCK *tem;
4510     int blockSize = pool->end - pool->start;
4511     if (blockSize < INIT_BLOCK_SIZE)
4512       blockSize = INIT_BLOCK_SIZE;
4513     else
4514       blockSize *= 2;
4515     tem = pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
4516     if (!tem)
4517       return 0;
4518     tem->size = blockSize;
4519     tem->next = pool->blocks;
4520     pool->blocks = tem;
4521     if (pool->ptr != pool->start)
4522       memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
4523     pool->ptr = tem->s + (pool->ptr - pool->start);
4524     pool->start = tem->s;
4525     pool->end = tem->s + blockSize;
4526   }
4527   return 1;
4528 }
4529 
4530 static int
nextScaffoldPart(XML_Parser parser)4531 nextScaffoldPart(XML_Parser parser)
4532 {
4533   CONTENT_SCAFFOLD * me;
4534   int next;
4535 
4536   if (! dtd.scaffIndex) {
4537     dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
4538     if (! dtd.scaffIndex)
4539       return -1;
4540     dtd.scaffIndex[0] = 0;
4541   }
4542 
4543   if (dtd.scaffCount >= dtd.scaffSize) {
4544     if (dtd.scaffold) {
4545       dtd.scaffSize *= 2;
4546       dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
4547 					      dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
4548     }
4549     else {
4550       dtd.scaffSize = 32;
4551       dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
4552     }
4553     if (! dtd.scaffold)
4554       return -1;
4555   }
4556   next = dtd.scaffCount++;
4557   me = &dtd.scaffold[next];
4558   if (dtd.scaffLevel) {
4559     CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
4560     if (parent->lastchild) {
4561       dtd.scaffold[parent->lastchild].nextsib = next;
4562     }
4563     if (! parent->childcnt)
4564       parent->firstchild = next;
4565     parent->lastchild = next;
4566     parent->childcnt++;
4567   }
4568   me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
4569   return next;
4570 }  /* End nextScaffoldPart */
4571 
4572 static void
build_node(XML_Parser parser,int src_node,XML_Content * dest,XML_Content ** contpos,char ** strpos)4573 build_node (XML_Parser parser,
4574 	    int src_node,
4575 	    XML_Content *dest,
4576 	    XML_Content **contpos,
4577 	    char **strpos)
4578 {
4579   dest->type = dtd.scaffold[src_node].type;
4580   dest->quant = dtd.scaffold[src_node].quant;
4581   if (dest->type == XML_CTYPE_NAME) {
4582     const char *src;
4583     dest->name = *strpos;
4584     src = dtd.scaffold[src_node].name;
4585     for (;;) {
4586       *(*strpos)++ = *src;
4587       if (! *src)
4588 	break;
4589       src++;
4590     }
4591     dest->numchildren = 0;
4592     dest->children = 0;
4593   }
4594   else {
4595     unsigned int i;
4596     int cn;
4597     dest->numchildren = dtd.scaffold[src_node].childcnt;
4598     dest->children = *contpos;
4599     *contpos += dest->numchildren;
4600     for (i = 0, cn = dtd.scaffold[src_node].firstchild;
4601 	 i < dest->numchildren;
4602 	 i++, cn = dtd.scaffold[cn].nextsib) {
4603       build_node(parser, cn, &(dest->children[i]), contpos, strpos);
4604     }
4605     dest->name = 0;
4606   }
4607 }  /* End build_node */
4608 
4609 static XML_Content *
build_model(XML_Parser parser)4610 build_model (XML_Parser parser)
4611 {
4612   XML_Content *ret;
4613   XML_Content *cpos;
4614   char * str;
4615   int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
4616 
4617   ret = MALLOC(allocsize);
4618   if (! ret)
4619     return 0;
4620 
4621   str =  (char *) (&ret[dtd.scaffCount]);
4622   cpos = &ret[1];
4623 
4624   build_node(parser, 0, ret, &cpos, &str);
4625   return ret;
4626 }  /* End build_model */
4627 
4628 static ELEMENT_TYPE *
getElementType(XML_Parser parser,const ENCODING * enc,const char * ptr,const char * end)4629 getElementType(XML_Parser parser,
4630 	       const ENCODING *enc,
4631 	       const char *ptr,
4632 	       const char *end)
4633 {
4634   const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
4635   ELEMENT_TYPE *ret;
4636 
4637   if (! name)
4638     return 0;
4639   ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
4640   if (! ret)
4641     return 0;
4642   if (ret->name != name)
4643     poolDiscard(&dtd.pool);
4644   else {
4645     poolFinish(&dtd.pool);
4646     if (!setElementTypePrefix(parser, ret))
4647       return 0;
4648   }
4649   return ret;
4650 }  /* End getElementType */
4651