1 /*
2 The contents of this file are subject to the Mozilla Public License
3 Version 1.0 (the "License"); you may not use this file except in
4 compliance with the License. You may obtain a copy of the License at
5 http://www.mozilla.org/MPL/
6 
7 Software distributed under the License is distributed on an "AS IS"
8 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
9 License for the specific language governing rights and limitations
10 under the License.
11 
12 The Original Code is expat.
13 
14 The Initial Developer of the Original Code is James Clark.
15 Portions created by James Clark are Copyright (C) 1998
16 James Clark. All Rights Reserved.
17 
18 Contributor(s):
19 $Id: xmlparse.c,v 1.5 2003/03/08 17:58:32 torcs Exp $
20 */
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stddef.h>
25 
26 #include "xmldef.h"
27 
28 #ifdef XML_UNICODE
29 #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
30 #define XmlConvert XmlUtf16Convert
31 #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
32 #define XmlEncode XmlUtf16Encode
33 #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
34 typedef unsigned short ICHAR;
35 #else
36 #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
37 #define XmlConvert XmlUtf8Convert
38 #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
39 #define XmlEncode XmlUtf8Encode
40 #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
41 typedef char ICHAR;
42 #endif
43 
44 #ifdef XML_UNICODE_WCHAR_T
45 #define XML_T(x) L ## x
46 #else
47 #define XML_T(x) x
48 #endif
49 
50 /* Round up n to be a multiple of sz, where sz is a power of 2. */
51 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
52 
53 #include "xmlparse.h"
54 #include "xmltok.h"
55 #include "xmlrole.h"
56 #include "hashtable.h"
57 
58 #define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
59 #define INIT_DATA_BUF_SIZE 1024
60 #define INIT_ATTS_SIZE 16
61 #define INIT_BLOCK_SIZE 1024
62 #define INIT_BUFFER_SIZE 1024
63 
64 typedef struct tag {
65   struct tag *parent;
66   const char *rawName;
67   int rawNameLength;
68   const XML_Char *name;
69   char *buf;
70   char *bufEnd;
71 } TAG;
72 
73 typedef struct {
74   const XML_Char *name;
75   const XML_Char *textPtr;
76   int textLen;
77   const XML_Char *systemId;
78   const XML_Char *base;
79   const XML_Char *publicId;
80   const XML_Char *notation;
81   char open;
82 } ENTITY;
83 
84 typedef struct block {
85   struct block *next;
86   int size;
87   XML_Char s[1];
88 } BLOCK;
89 
90 typedef struct {
91   BLOCK *blocks;
92   BLOCK *freeBlocks;
93   const XML_Char *end;
94   XML_Char *ptr;
95   XML_Char *start;
96 } STRING_POOL;
97 
98 /* The XML_Char before the name is used to determine whether
99 an attribute has been specified. */
100 typedef struct {
101   XML_Char *name;
102   char maybeTokenized;
103 } ATTRIBUTE_ID;
104 
105 typedef struct {
106   const ATTRIBUTE_ID *id;
107   char isCdata;
108   const XML_Char *value;
109 } DEFAULT_ATTRIBUTE;
110 
111 typedef struct {
112   const XML_Char *name;
113   int nDefaultAtts;
114   int allocDefaultAtts;
115   DEFAULT_ATTRIBUTE *defaultAtts;
116 } ELEMENT_TYPE;
117 
118 typedef struct {
119   HASH_TABLE generalEntities;
120   HASH_TABLE elementTypes;
121   HASH_TABLE attributeIds;
122   STRING_POOL pool;
123   int complete;
124   int standalone;
125   const XML_Char *base;
126 } DTD;
127 
128 typedef enum XML_Error Processor(XML_Parser parser,
129 				 const char *start,
130 				 const char *end,
131 				 const char **endPtr);
132 
133 static Processor prologProcessor;
134 static Processor prologInitProcessor;
135 static Processor contentProcessor;
136 static Processor cdataSectionProcessor;
137 static Processor epilogProcessor;
138 /* static Processor errorProcessor; */
139 static Processor externalEntityInitProcessor;
140 static Processor externalEntityInitProcessor2;
141 static Processor externalEntityInitProcessor3;
142 static Processor externalEntityContentProcessor;
143 
144 static enum XML_Error
145 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
146 static enum XML_Error
147 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
148 static enum XML_Error
149 initializeEncoding(XML_Parser parser);
150 static enum XML_Error
151 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
152 	  const char *start, const char *end, const char **endPtr);
153 static enum XML_Error
154 doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
155 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const XML_Char *tagName, const char *s);
156 static int
157 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue);
158 static enum XML_Error
159 storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
160 		    STRING_POOL *);
161 static enum XML_Error
162 appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
163 		    STRING_POOL *);
164 static ATTRIBUTE_ID *
165 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
166 static enum XML_Error
167 storeEntityValue(XML_Parser parser, const char *start, const char *end);
168 static int
169 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
170 static void
171 reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
172 
173 static const XML_Char *getOpenEntityNames(XML_Parser parser);
174 static int setOpenEntityNames(XML_Parser parser, const XML_Char *openEntityNames);
175 static void normalizePublicId(XML_Char *s);
176 static int dtdInit(DTD *);
177 static void dtdDestroy(DTD *);
178 static int dtdCopy(DTD *newDtd, const DTD *oldDtd);
179 static void poolInit(STRING_POOL *);
180 static void poolClear(STRING_POOL *);
181 static void poolDestroy(STRING_POOL *);
182 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
183 			    const char *ptr, const char *end);
184 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
185 				  const char *ptr, const char *end);
186 static int poolGrow(STRING_POOL *pool);
187 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
188 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
189 
190 #define poolStart(pool) ((pool)->start)
191 #define poolEnd(pool) ((pool)->ptr)
192 #define poolLength(pool) ((pool)->ptr - (pool)->start)
193 #define poolChop(pool) ((void)--(pool->ptr))
194 #define poolLastChar(pool) (((pool)->ptr)[-1])
195 #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
196 #define poolFinish(pool) ((pool)->start = (pool)->ptr)
197 #define poolAppendChar(pool, c) \
198   (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
199    ? 0 \
200    : ((*((pool)->ptr)++ = c), 1))
201 
202 typedef struct {
203   /* The first member must be userData so that the XML_GetUserData macro works. */
204   void *userData;
205   void *handlerArg;
206   char *buffer;
207   /* first character to be parsed */
208   const char *bufferPtr;
209   /* past last character to be parsed */
210   char *bufferEnd;
211   /* allocated end of buffer */
212   const char *bufferLim;
213   long parseEndByteIndex;
214   const char *parseEndPtr;
215   XML_Char *dataBuf;
216   XML_Char *dataBufEnd;
217   XML_StartElementHandler startElementHandler;
218   XML_EndElementHandler endElementHandler;
219   XML_CharacterDataHandler characterDataHandler;
220   XML_ProcessingInstructionHandler processingInstructionHandler;
221   XML_DefaultHandler defaultHandler;
222   XML_UnparsedEntityDeclHandler unparsedEntityDeclHandler;
223   XML_NotationDeclHandler notationDeclHandler;
224   XML_ExternalEntityRefHandler externalEntityRefHandler;
225   XML_UnknownEncodingHandler unknownEncodingHandler;
226   const ENCODING *encoding;
227   INIT_ENCODING initEncoding;
228   const XML_Char *protocolEncodingName;
229   void *unknownEncodingMem;
230   void *unknownEncodingData;
231   void *unknownEncodingHandlerData;
232   void (*unknownEncodingRelease)(void *);
233   PROLOG_STATE prologState;
234   Processor *processor;
235   enum XML_Error errorCode;
236   const char *eventPtr;
237   const char *eventEndPtr;
238   const char *positionPtr;
239   int tagLevel;
240   ENTITY *declEntity;
241   const XML_Char *declNotationName;
242   const XML_Char *declNotationPublicId;
243   ELEMENT_TYPE *declElementType;
244   ATTRIBUTE_ID *declAttributeId;
245   char declAttributeIsCdata;
246   DTD dtd;
247   TAG *tagStack;
248   TAG *freeTagList;
249   int attsSize;
250   ATTRIBUTE *atts;
251   POSITION position;
252   STRING_POOL tempPool;
253   STRING_POOL temp2Pool;
254   char *groupConnector;
255   unsigned groupSize;
256   int hadExternalDoctype;
257 } Parser;
258 
259 #define userData (((Parser *)parser)->userData)
260 #define handlerArg (((Parser *)parser)->handlerArg)
261 #define startElementHandler (((Parser *)parser)->startElementHandler)
262 #define endElementHandler (((Parser *)parser)->endElementHandler)
263 #define characterDataHandler (((Parser *)parser)->characterDataHandler)
264 #define processingInstructionHandler (((Parser *)parser)->processingInstructionHandler)
265 #define defaultHandler (((Parser *)parser)->defaultHandler)
266 #define unparsedEntityDeclHandler (((Parser *)parser)->unparsedEntityDeclHandler)
267 #define notationDeclHandler (((Parser *)parser)->notationDeclHandler)
268 #define externalEntityRefHandler (((Parser *)parser)->externalEntityRefHandler)
269 #define unknownEncodingHandler (((Parser *)parser)->unknownEncodingHandler)
270 #define encoding (((Parser *)parser)->encoding)
271 #define initEncoding (((Parser *)parser)->initEncoding)
272 #define unknownEncodingMem (((Parser *)parser)->unknownEncodingMem)
273 #define unknownEncodingData (((Parser *)parser)->unknownEncodingData)
274 #define unknownEncodingHandlerData \
275   (((Parser *)parser)->unknownEncodingHandlerData)
276 #define unknownEncodingRelease (((Parser *)parser)->unknownEncodingRelease)
277 #define protocolEncodingName (((Parser *)parser)->protocolEncodingName)
278 #define prologState (((Parser *)parser)->prologState)
279 #define processor (((Parser *)parser)->processor)
280 #define errorCode (((Parser *)parser)->errorCode)
281 #define eventPtr (((Parser *)parser)->eventPtr)
282 #define eventEndPtr (((Parser *)parser)->eventEndPtr)
283 #define positionPtr (((Parser *)parser)->positionPtr)
284 #define position (((Parser *)parser)->position)
285 #define tagLevel (((Parser *)parser)->tagLevel)
286 #define buffer (((Parser *)parser)->buffer)
287 #define bufferPtr (((Parser *)parser)->bufferPtr)
288 #define bufferEnd (((Parser *)parser)->bufferEnd)
289 #define parseEndByteIndex (((Parser *)parser)->parseEndByteIndex)
290 #define parseEndPtr (((Parser *)parser)->parseEndPtr)
291 #define bufferLim (((Parser *)parser)->bufferLim)
292 #define dataBuf (((Parser *)parser)->dataBuf)
293 #define dataBufEnd (((Parser *)parser)->dataBufEnd)
294 #define dtd (((Parser *)parser)->dtd)
295 #define declEntity (((Parser *)parser)->declEntity)
296 #define declNotationName (((Parser *)parser)->declNotationName)
297 #define declNotationPublicId (((Parser *)parser)->declNotationPublicId)
298 #define declElementType (((Parser *)parser)->declElementType)
299 #define declAttributeId (((Parser *)parser)->declAttributeId)
300 #define declAttributeIsCdata (((Parser *)parser)->declAttributeIsCdata)
301 #define freeTagList (((Parser *)parser)->freeTagList)
302 #define tagStack (((Parser *)parser)->tagStack)
303 #define atts (((Parser *)parser)->atts)
304 #define attsSize (((Parser *)parser)->attsSize)
305 #define tempPool (((Parser *)parser)->tempPool)
306 #define temp2Pool (((Parser *)parser)->temp2Pool)
307 #define groupConnector (((Parser *)parser)->groupConnector)
308 #define groupSize (((Parser *)parser)->groupSize)
309 #define hadExternalDoctype (((Parser *)parser)->hadExternalDoctype)
310 
XML_ParserCreate(const XML_Char * encodingName)311 XML_Parser XML_ParserCreate(const XML_Char *encodingName)
312 {
313   XML_Parser parser = malloc(sizeof(Parser));
314   if (!parser)
315     return parser;
316   processor = prologInitProcessor;
317   XmlPrologStateInit(&prologState);
318   userData = 0;
319   handlerArg = 0;
320   startElementHandler = 0;
321   endElementHandler = 0;
322   characterDataHandler = 0;
323   processingInstructionHandler = 0;
324   defaultHandler = 0;
325   unparsedEntityDeclHandler = 0;
326   notationDeclHandler = 0;
327   externalEntityRefHandler = 0;
328   unknownEncodingHandler = 0;
329   buffer = 0;
330   bufferPtr = 0;
331   bufferEnd = 0;
332   parseEndByteIndex = 0;
333   parseEndPtr = 0;
334   bufferLim = 0;
335   declElementType = 0;
336   declAttributeId = 0;
337   declEntity = 0;
338   declNotationName = 0;
339   declNotationPublicId = 0;
340   memset(&position, 0, sizeof(POSITION));
341   errorCode = XML_ERROR_NONE;
342   eventPtr = 0;
343   eventEndPtr = 0;
344   positionPtr = 0;
345   tagLevel = 0;
346   tagStack = 0;
347   freeTagList = 0;
348   attsSize = INIT_ATTS_SIZE;
349   atts = (ATTRIBUTE*)malloc(attsSize * sizeof(ATTRIBUTE));
350   dataBuf = (XML_Char*)malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
351   groupSize = 0;
352   groupConnector = 0;
353   hadExternalDoctype = 0;
354   unknownEncodingMem = 0;
355   unknownEncodingRelease = 0;
356   unknownEncodingData = 0;
357   unknownEncodingHandlerData = 0;
358   poolInit(&tempPool);
359   poolInit(&temp2Pool);
360   protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
361   if (!dtdInit(&dtd) || !atts || !dataBuf
362       || (encodingName && !protocolEncodingName)) {
363     XML_ParserFree(parser);
364     return 0;
365   }
366   dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
367   XmlInitEncoding(&initEncoding, &encoding, 0);
368   return parser;
369 }
370 
XML_ExternalEntityParserCreate(XML_Parser oldParser,const XML_Char * openEntityNames,const XML_Char * encodingName)371 XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
372 					  const XML_Char *openEntityNames,
373 					  const XML_Char *encodingName)
374 {
375   XML_Parser parser = oldParser;
376   DTD *oldDtd = &dtd;
377   XML_StartElementHandler oldStartElementHandler = startElementHandler;
378   XML_EndElementHandler oldEndElementHandler = endElementHandler;
379   XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
380   XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
381   XML_DefaultHandler oldDefaultHandler = defaultHandler;
382   XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
383   XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
384   void *oldUserData = userData;
385   void *oldHandlerArg = handlerArg;
386 
387   parser = XML_ParserCreate(encodingName);
388   if (!parser)
389     return 0;
390   startElementHandler = oldStartElementHandler;
391   endElementHandler = oldEndElementHandler;
392   characterDataHandler = oldCharacterDataHandler;
393   processingInstructionHandler = oldProcessingInstructionHandler;
394   defaultHandler = oldDefaultHandler;
395   externalEntityRefHandler = oldExternalEntityRefHandler;
396   unknownEncodingHandler = oldUnknownEncodingHandler;
397   userData = oldUserData;
398   if (oldUserData == oldHandlerArg)
399     handlerArg = userData;
400   else
401     handlerArg = parser;
402   if (!dtdCopy(&dtd, oldDtd) || !setOpenEntityNames(parser, openEntityNames)) {
403     XML_ParserFree(parser);
404     return 0;
405   }
406   processor = externalEntityInitProcessor;
407   return parser;
408 }
409 
XML_ParserFree(XML_Parser parser)410 void XML_ParserFree(XML_Parser parser)
411 {
412   for (;;) {
413     TAG *p;
414     if (tagStack == 0) {
415       if (freeTagList == 0)
416 	break;
417       tagStack = freeTagList;
418       freeTagList = 0;
419     }
420     p = tagStack;
421     tagStack = tagStack->parent;
422     free(p->buf);
423     free(p);
424   }
425   poolDestroy(&tempPool);
426   poolDestroy(&temp2Pool);
427   dtdDestroy(&dtd);
428   free((void *)atts);
429   free(groupConnector);
430   free(buffer);
431   free(dataBuf);
432   free(unknownEncodingMem);
433   if (unknownEncodingRelease)
434     unknownEncodingRelease(unknownEncodingData);
435   free(parser);
436 }
437 
XML_UseParserAsHandlerArg(XML_Parser parser)438 void XML_UseParserAsHandlerArg(XML_Parser parser)
439 {
440   handlerArg = parser;
441 }
442 
XML_SetUserData(XML_Parser parser,void * p)443 void XML_SetUserData(XML_Parser parser, void *p)
444 {
445   if (handlerArg == userData)
446     handlerArg = userData = p;
447   else
448     userData = p;
449 }
450 
XML_SetBase(XML_Parser parser,const XML_Char * p)451 int XML_SetBase(XML_Parser parser, const XML_Char *p)
452 {
453   if (p) {
454     p = poolCopyString(&dtd.pool, p);
455     if (!p)
456       return 0;
457     dtd.base = p;
458   }
459   else
460     dtd.base = 0;
461   return 1;
462 }
463 
XML_GetBase(XML_Parser parser)464 const XML_Char *XML_GetBase(XML_Parser parser)
465 {
466   return dtd.base;
467 }
468 
XML_SetElementHandler(XML_Parser parser,XML_StartElementHandler start,XML_EndElementHandler end)469 void XML_SetElementHandler(XML_Parser parser,
470 			   XML_StartElementHandler start,
471 			   XML_EndElementHandler end)
472 {
473   startElementHandler = start;
474   endElementHandler = end;
475 }
476 
XML_SetCharacterDataHandler(XML_Parser parser,XML_CharacterDataHandler handler)477 void XML_SetCharacterDataHandler(XML_Parser parser,
478 				 XML_CharacterDataHandler handler)
479 {
480   characterDataHandler = handler;
481 }
482 
XML_SetProcessingInstructionHandler(XML_Parser parser,XML_ProcessingInstructionHandler handler)483 void XML_SetProcessingInstructionHandler(XML_Parser parser,
484 					 XML_ProcessingInstructionHandler handler)
485 {
486   processingInstructionHandler = handler;
487 }
488 
XML_SetDefaultHandler(XML_Parser parser,XML_DefaultHandler handler)489 void XML_SetDefaultHandler(XML_Parser parser,
490 			   XML_DefaultHandler handler)
491 {
492   defaultHandler = handler;
493 }
494 
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,XML_UnparsedEntityDeclHandler handler)495 void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
496 				      XML_UnparsedEntityDeclHandler handler)
497 {
498   unparsedEntityDeclHandler = handler;
499 }
500 
XML_SetNotationDeclHandler(XML_Parser parser,XML_NotationDeclHandler handler)501 void XML_SetNotationDeclHandler(XML_Parser parser,
502 				XML_NotationDeclHandler handler)
503 {
504   notationDeclHandler = handler;
505 }
506 
XML_SetExternalEntityRefHandler(XML_Parser parser,XML_ExternalEntityRefHandler handler)507 void XML_SetExternalEntityRefHandler(XML_Parser parser,
508 				     XML_ExternalEntityRefHandler handler)
509 {
510   externalEntityRefHandler = handler;
511 }
512 
XML_SetUnknownEncodingHandler(XML_Parser parser,XML_UnknownEncodingHandler handler,void * data)513 void XML_SetUnknownEncodingHandler(XML_Parser parser,
514 				   XML_UnknownEncodingHandler handler,
515 				   void *data)
516 {
517   unknownEncodingHandler = handler;
518   unknownEncodingHandlerData = data;
519 }
520 
XML_Parse(XML_Parser parser,const char * s,int len,int isFinal)521 int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
522 {
523   if (len == 0) {
524     if (!isFinal)
525       return 1;
526     errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
527     if (errorCode == XML_ERROR_NONE)
528       return 1;
529     eventEndPtr = eventPtr;
530     return 0;
531   }
532   else if (bufferPtr == bufferEnd) {
533     const char *end;
534     int nLeftOver;
535     parseEndByteIndex += len;
536     positionPtr = s;
537     if (isFinal) {
538       errorCode = processor(parser, s, parseEndPtr = s + len, 0);
539       if (errorCode == XML_ERROR_NONE)
540 	return 1;
541       eventEndPtr = eventPtr;
542       return 0;
543     }
544     errorCode = processor(parser, s, parseEndPtr = s + len, &end);
545     if (errorCode != XML_ERROR_NONE) {
546       eventEndPtr = eventPtr;
547       return 0;
548     }
549     XmlUpdatePosition(encoding, positionPtr, end, &position);
550     nLeftOver = s + len - end;
551     if (nLeftOver) {
552       if (buffer == 0 || nLeftOver > bufferLim - buffer) {
553 	/* FIXME avoid integer overflow */
554 	buffer = buffer == 0 ? (char*)malloc(len * 2) : (char*)realloc(buffer, len * 2);
555 	if (!buffer) {
556 	  errorCode = XML_ERROR_NO_MEMORY;
557 	  eventPtr = eventEndPtr = 0;
558 	  return 0;
559 	}
560 	bufferLim = buffer + len * 2;
561       }
562       memcpy(buffer, end, nLeftOver);
563       bufferPtr = buffer;
564       bufferEnd = buffer + nLeftOver;
565     }
566     return 1;
567   }
568   else {
569     memcpy(XML_GetBuffer(parser, len), s, len);
570     return XML_ParseBuffer(parser, len, isFinal);
571   }
572 }
573 
XML_ParseBuffer(XML_Parser parser,int len,int isFinal)574 int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
575 {
576   const char *start = bufferPtr;
577   positionPtr = start;
578   bufferEnd += len;
579   parseEndByteIndex += len;
580   errorCode = processor(parser, start, parseEndPtr = bufferEnd,
581 			isFinal ? (const char **)0 : &bufferPtr);
582   if (errorCode == XML_ERROR_NONE) {
583     if (!isFinal)
584       XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
585     return 1;
586   }
587   else {
588     eventEndPtr = eventPtr;
589     return 0;
590   }
591 }
592 
XML_GetBuffer(XML_Parser parser,int len)593 void *XML_GetBuffer(XML_Parser parser, int len)
594 {
595   if (len > bufferLim - bufferEnd) {
596     /* FIXME avoid integer overflow */
597     int neededSize = len + (bufferEnd - bufferPtr);
598     if (neededSize  <= bufferLim - buffer) {
599       memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
600       bufferEnd = buffer + (bufferEnd - bufferPtr);
601       bufferPtr = buffer;
602     }
603     else {
604       char *newBuf;
605       int bufferSize = bufferLim - bufferPtr;
606       if (bufferSize == 0)
607 	bufferSize = INIT_BUFFER_SIZE;
608       do {
609 	bufferSize *= 2;
610       } while (bufferSize < neededSize);
611       newBuf = (char*)malloc(bufferSize);
612       if (newBuf == 0) {
613 	errorCode = XML_ERROR_NO_MEMORY;
614 	return 0;
615       }
616       bufferLim = newBuf + bufferSize;
617       if (bufferPtr) {
618 	memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
619 	free(buffer);
620       }
621       bufferEnd = newBuf + (bufferEnd - bufferPtr);
622       bufferPtr = buffer = newBuf;
623     }
624   }
625   return bufferEnd;
626 }
627 
XML_GetErrorCode(XML_Parser parser)628 enum XML_Error XML_GetErrorCode(XML_Parser parser)
629 {
630   return errorCode;
631 }
632 
XML_GetCurrentByteIndex(XML_Parser parser)633 long XML_GetCurrentByteIndex(XML_Parser parser)
634 {
635   if (eventPtr)
636     return parseEndByteIndex - (parseEndPtr - eventPtr);
637   return -1;
638 }
639 
XML_GetCurrentLineNumber(XML_Parser parser)640 int XML_GetCurrentLineNumber(XML_Parser parser)
641 {
642   if (eventPtr) {
643     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
644     positionPtr = eventPtr;
645   }
646   return position.lineNumber + 1;
647 }
648 
XML_GetCurrentColumnNumber(XML_Parser parser)649 int XML_GetCurrentColumnNumber(XML_Parser parser)
650 {
651   if (eventPtr) {
652     XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
653     positionPtr = eventPtr;
654   }
655   return position.columnNumber;
656 }
657 
XML_DefaultCurrent(XML_Parser parser)658 void XML_DefaultCurrent(XML_Parser parser)
659 {
660   if (defaultHandler)
661     reportDefault(parser, encoding, eventPtr, eventEndPtr);
662 }
663 
XML_ErrorString(int code)664 const XML_LChar *XML_ErrorString(int code)
665 {
666   static const XML_LChar *message[] = {
667     0,
668     XML_T("out of memory"),
669     XML_T("syntax error"),
670     XML_T("no element found"),
671     XML_T("not well-formed"),
672     XML_T("unclosed token"),
673     XML_T("unclosed token"),
674     XML_T("mismatched tag"),
675     XML_T("duplicate attribute"),
676     XML_T("junk after document element"),
677     XML_T("illegal parameter entity reference"),
678     XML_T("undefined entity"),
679     XML_T("recursive entity reference"),
680     XML_T("asynchronous entity"),
681     XML_T("reference to invalid character number"),
682     XML_T("reference to binary entity"),
683     XML_T("reference to external entity in attribute"),
684     XML_T("xml processing instruction not at start of external entity"),
685     XML_T("unknown encoding"),
686     XML_T("encoding specified in XML declaration is incorrect"),
687     XML_T("unclosed CDATA section"),
688     XML_T("error in processing external entity reference")
689   };
690   if (code > 0 && code < (int)(sizeof(message)/sizeof(message[0])))
691     return message[code];
692   return 0;
693 }
694 
695 static
contentProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)696 enum XML_Error contentProcessor(XML_Parser parser,
697 				const char *start,
698 				const char *end,
699 				const char **endPtr)
700 {
701   return doContent(parser, 0, encoding, start, end, endPtr);
702 }
703 
704 static
externalEntityInitProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)705 enum XML_Error externalEntityInitProcessor(XML_Parser parser,
706 					   const char *start,
707 					   const char *end,
708 					   const char **endPtr)
709 {
710   enum XML_Error result = initializeEncoding(parser);
711   if (result != XML_ERROR_NONE)
712     return result;
713   processor = externalEntityInitProcessor2;
714   return externalEntityInitProcessor2(parser, start, end, endPtr);
715 }
716 
717 static
externalEntityInitProcessor2(XML_Parser parser,const char * start,const char * end,const char ** endPtr)718 enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
719 					    const char *start,
720 					    const char *end,
721 					    const char **endPtr)
722 {
723   const char *next;
724   int tok = XmlContentTok(encoding, start, end, &next);
725   switch (tok) {
726   case XML_TOK_BOM:
727     start = next;
728     break;
729   case XML_TOK_PARTIAL:
730     if (endPtr) {
731       *endPtr = start;
732       return XML_ERROR_NONE;
733     }
734     eventPtr = start;
735     return XML_ERROR_UNCLOSED_TOKEN;
736   case XML_TOK_PARTIAL_CHAR:
737     if (endPtr) {
738       *endPtr = start;
739       return XML_ERROR_NONE;
740     }
741     eventPtr = start;
742     return XML_ERROR_PARTIAL_CHAR;
743   }
744   processor = externalEntityInitProcessor3;
745   return externalEntityInitProcessor3(parser, start, end, endPtr);
746 }
747 
748 static
externalEntityInitProcessor3(XML_Parser parser,const char * start,const char * end,const char ** endPtr)749 enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
750 					    const char *start,
751 					    const char *end,
752 					    const char **endPtr)
753 {
754   const char *next;
755   int tok = XmlContentTok(encoding, start, end, &next);
756   switch (tok) {
757   case XML_TOK_XML_DECL:
758     {
759       enum XML_Error result = processXmlDecl(parser, 1, start, next);
760       if (result != XML_ERROR_NONE)
761 	return result;
762       start = next;
763     }
764     break;
765   case XML_TOK_PARTIAL:
766     if (endPtr) {
767       *endPtr = start;
768       return XML_ERROR_NONE;
769     }
770     eventPtr = start;
771     return XML_ERROR_UNCLOSED_TOKEN;
772   case XML_TOK_PARTIAL_CHAR:
773     if (endPtr) {
774       *endPtr = start;
775       return XML_ERROR_NONE;
776     }
777     eventPtr = start;
778     return XML_ERROR_PARTIAL_CHAR;
779   }
780   processor = externalEntityContentProcessor;
781   tagLevel = 1;
782   return doContent(parser, 1, encoding, start, end, endPtr);
783 }
784 
785 static
externalEntityContentProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)786 enum XML_Error externalEntityContentProcessor(XML_Parser parser,
787 					      const char *start,
788 					      const char *end,
789 					      const char **endPtr)
790 {
791   return doContent(parser, 1, encoding, start, end, endPtr);
792 }
793 
794 static enum XML_Error
doContent(XML_Parser parser,int startTagLevel,const ENCODING * enc,const char * s,const char * end,const char ** nextPtr)795 doContent(XML_Parser parser,
796 	  int startTagLevel,
797 	  const ENCODING *enc,
798 	  const char *s,
799 	  const char *end,
800 	  const char **nextPtr)
801 {
802   const ENCODING *internalEnc = XmlGetInternalEncoding();
803   const char *dummy;
804   const char **eventPP;
805   const char **eventEndPP;
806   if (enc == encoding) {
807     eventPP = &eventPtr;
808     *eventPP = s;
809     eventEndPP = &eventEndPtr;
810   }
811   else
812     eventPP = eventEndPP = &dummy;
813   for (;;) {
814     const char *next;
815     int tok = XmlContentTok(enc, s, end, &next);
816     *eventEndPP = next;
817     switch (tok) {
818     case XML_TOK_TRAILING_CR:
819       if (nextPtr) {
820 	*nextPtr = s;
821 	return XML_ERROR_NONE;
822       }
823       *eventEndPP = end;
824       if (characterDataHandler) {
825 	XML_Char c = XML_T('\n');
826 	characterDataHandler(handlerArg, &c, 1);
827       }
828       else if (defaultHandler)
829 	reportDefault(parser, enc, s, end);
830       if (startTagLevel == 0)
831 	return XML_ERROR_NO_ELEMENTS;
832       if (tagLevel != startTagLevel)
833 	return XML_ERROR_ASYNC_ENTITY;
834       return XML_ERROR_NONE;
835     case XML_TOK_NONE:
836       if (nextPtr) {
837 	*nextPtr = s;
838 	return XML_ERROR_NONE;
839       }
840       if (startTagLevel > 0) {
841 	if (tagLevel != startTagLevel)
842 	  return XML_ERROR_ASYNC_ENTITY;
843 	return XML_ERROR_NONE;
844       }
845       return XML_ERROR_NO_ELEMENTS;
846     case XML_TOK_INVALID:
847       *eventPP = next;
848       return XML_ERROR_INVALID_TOKEN;
849     case XML_TOK_PARTIAL:
850       if (nextPtr) {
851 	*nextPtr = s;
852 	return XML_ERROR_NONE;
853       }
854       return XML_ERROR_UNCLOSED_TOKEN;
855     case XML_TOK_PARTIAL_CHAR:
856       if (nextPtr) {
857 	*nextPtr = s;
858 	return XML_ERROR_NONE;
859       }
860       return XML_ERROR_PARTIAL_CHAR;
861     case XML_TOK_ENTITY_REF:
862       {
863 	const XML_Char *name;
864 	ENTITY *entity;
865 	XML_Char ch = XmlPredefinedEntityName(enc,
866 					      s + enc->minBytesPerChar,
867 					      next - enc->minBytesPerChar);
868 	if (ch) {
869 	  if (characterDataHandler)
870 	    characterDataHandler(handlerArg, &ch, 1);
871 	  else if (defaultHandler)
872 	    reportDefault(parser, enc, s, next);
873 	  break;
874 	}
875 	name = poolStoreString(&dtd.pool, enc,
876 				s + enc->minBytesPerChar,
877 				next - enc->minBytesPerChar);
878 	if (!name)
879 	  return XML_ERROR_NO_MEMORY;
880 	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
881 	poolDiscard(&dtd.pool);
882 	if (!entity) {
883 	  if (dtd.complete || dtd.standalone)
884 	    return XML_ERROR_UNDEFINED_ENTITY;
885 	  if (defaultHandler)
886 	    reportDefault(parser, enc, s, next);
887 	  break;
888 	}
889 	if (entity->open)
890 	  return XML_ERROR_RECURSIVE_ENTITY_REF;
891 	if (entity->notation)
892 	  return XML_ERROR_BINARY_ENTITY_REF;
893 	if (entity) {
894 	  if (entity->textPtr) {
895 	    enum XML_Error result;
896 	    if (defaultHandler) {
897 	      reportDefault(parser, enc, s, next);
898 	      break;
899 	    }
900 	    /* Protect against the possibility that somebody sets
901 	       the defaultHandler from inside another handler. */
902 	    *eventEndPP = *eventPP;
903 	    entity->open = 1;
904 	    result = doContent(parser,
905 			       tagLevel,
906 			       internalEnc,
907 			       (char *)entity->textPtr,
908 			       (char *)(entity->textPtr + entity->textLen),
909 			       0);
910 	    entity->open = 0;
911 	    if (result)
912 	      return result;
913 	  }
914 	  else if (externalEntityRefHandler) {
915 	    const XML_Char *openEntityNames;
916 	    entity->open = 1;
917 	    openEntityNames = getOpenEntityNames(parser);
918 	    entity->open = 0;
919 	    if (!openEntityNames)
920 	      return XML_ERROR_NO_MEMORY;
921 	    if (!externalEntityRefHandler(parser, openEntityNames, dtd.base, entity->systemId, entity->publicId))
922 	      return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
923 	    poolDiscard(&tempPool);
924 	  }
925 	  else if (defaultHandler)
926 	    reportDefault(parser, enc, s, next);
927 	}
928 	break;
929       }
930     case XML_TOK_START_TAG_WITH_ATTS:
931       if (!startElementHandler) {
932 	enum XML_Error result = storeAtts(parser, enc, 0, s);
933 	if (result)
934 	  return result;
935       }
936       /* fall through */
937     case XML_TOK_START_TAG_NO_ATTS:
938       {
939 	TAG *tag;
940 	if (freeTagList) {
941 	  tag = freeTagList;
942 	  freeTagList = freeTagList->parent;
943 	}
944 	else {
945 	  tag = (TAG*)malloc(sizeof(TAG));
946 	  if (!tag)
947 	    return XML_ERROR_NO_MEMORY;
948 	  tag->buf = (char*)malloc(INIT_TAG_BUF_SIZE);
949 	  if (!tag->buf)
950 	    return XML_ERROR_NO_MEMORY;
951 	  tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
952 	}
953 	tag->parent = tagStack;
954 	tagStack = tag;
955 	tag->rawName = s + enc->minBytesPerChar;
956 	tag->rawNameLength = XmlNameLength(enc, tag->rawName);
957 	if (nextPtr) {
958 	  if (tag->rawNameLength > tag->bufEnd - tag->buf) {
959 	    int bufSize = tag->rawNameLength * 4;
960 	    bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
961 	    tag->buf = (char*)realloc(tag->buf, bufSize);
962 	    if (!tag->buf)
963 	      return XML_ERROR_NO_MEMORY;
964 	    tag->bufEnd = tag->buf + bufSize;
965 	  }
966 	  memcpy(tag->buf, tag->rawName, tag->rawNameLength);
967 	  tag->rawName = tag->buf;
968 	}
969 	++tagLevel;
970 	if (startElementHandler) {
971 	  enum XML_Error result;
972 	  XML_Char *toPtr;
973 	  for (;;) {
974 	    const char *rawNameEnd = tag->rawName + tag->rawNameLength;
975 	    const char *fromPtr = tag->rawName;
976 	    int bufSize;
977 	    if (nextPtr)
978 	      toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
979 	    else
980 	      toPtr = (XML_Char *)tag->buf;
981 	    tag->name = toPtr;
982 	    XmlConvert(enc,
983 		       &fromPtr, rawNameEnd,
984 		       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
985 	    if (fromPtr == rawNameEnd)
986 	      break;
987 	    bufSize = (tag->bufEnd - tag->buf) << 1;
988 	    tag->buf = (char*)realloc(tag->buf, bufSize);
989 	    if (!tag->buf)
990 	      return XML_ERROR_NO_MEMORY;
991 	    tag->bufEnd = tag->buf + bufSize;
992 	    if (nextPtr)
993 	      tag->rawName = tag->buf;
994 	  }
995 	  *toPtr = XML_T('\0');
996 	  result = storeAtts(parser, enc, tag->name, s);
997 	  if (result)
998 	    return result;
999 	  startElementHandler(handlerArg, tag->name, (const XML_Char **)atts);
1000 	  poolClear(&tempPool);
1001 	}
1002 	else {
1003 	  tag->name = 0;
1004 	  if (defaultHandler)
1005 	    reportDefault(parser, enc, s, next);
1006 	}
1007 	break;
1008       }
1009     case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
1010       if (!startElementHandler) {
1011 	enum XML_Error result = storeAtts(parser, enc, 0, s);
1012 	if (result)
1013 	  return result;
1014       }
1015       /* fall through */
1016     case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
1017       if (startElementHandler || endElementHandler) {
1018 	const char *rawName = s + enc->minBytesPerChar;
1019 	const XML_Char *name = poolStoreString(&tempPool, enc, rawName,
1020 					       rawName
1021 					       + XmlNameLength(enc, rawName));
1022 	if (!name)
1023 	  return XML_ERROR_NO_MEMORY;
1024 	poolFinish(&tempPool);
1025 	if (startElementHandler) {
1026 	  enum XML_Error result = storeAtts(parser, enc, name, s);
1027 	  if (result)
1028 	    return result;
1029 	  startElementHandler(handlerArg, name, (const XML_Char **)atts);
1030 	}
1031 	if (endElementHandler) {
1032 	  if (startElementHandler)
1033 	    *eventPP = *eventEndPP;
1034 	  endElementHandler(handlerArg, name);
1035 	}
1036 	poolClear(&tempPool);
1037       }
1038       else if (defaultHandler)
1039 	reportDefault(parser, enc, s, next);
1040       if (tagLevel == 0)
1041 	return epilogProcessor(parser, next, end, nextPtr);
1042       break;
1043     case XML_TOK_END_TAG:
1044       if (tagLevel == startTagLevel)
1045         return XML_ERROR_ASYNC_ENTITY;
1046       else {
1047 	int len;
1048 	const char *rawName;
1049 	TAG *tag = tagStack;
1050 	tagStack = tag->parent;
1051 	tag->parent = freeTagList;
1052 	freeTagList = tag;
1053 	rawName = s + enc->minBytesPerChar*2;
1054 	len = XmlNameLength(enc, rawName);
1055 	if (len != tag->rawNameLength
1056 	    || memcmp(tag->rawName, rawName, len) != 0) {
1057 	  *eventPP = rawName;
1058 	  return XML_ERROR_TAG_MISMATCH;
1059 	}
1060 	--tagLevel;
1061 	if (endElementHandler) {
1062 	  if (tag->name)
1063 	    endElementHandler(handlerArg, tag->name);
1064 	  else {
1065 	    const XML_Char *name = poolStoreString(&tempPool, enc, rawName,
1066 	                                           rawName + len);
1067 	    if (!name)
1068 	      return XML_ERROR_NO_MEMORY;
1069 	    endElementHandler(handlerArg, name);
1070 	    poolClear(&tempPool);
1071 	  }
1072 	}
1073 	else if (defaultHandler)
1074 	  reportDefault(parser, enc, s, next);
1075 	if (tagLevel == 0)
1076 	  return epilogProcessor(parser, next, end, nextPtr);
1077       }
1078       break;
1079     case XML_TOK_CHAR_REF:
1080       {
1081 	int n = XmlCharRefNumber(enc, s);
1082 	if (n < 0)
1083 	  return XML_ERROR_BAD_CHAR_REF;
1084 	if (characterDataHandler) {
1085 	  XML_Char buf[XML_ENCODE_MAX];
1086 	  characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
1087 	}
1088 	else if (defaultHandler)
1089 	  reportDefault(parser, enc, s, next);
1090       }
1091       break;
1092     case XML_TOK_XML_DECL:
1093       return XML_ERROR_MISPLACED_XML_PI;
1094     case XML_TOK_DATA_NEWLINE:
1095       if (characterDataHandler) {
1096 	XML_Char c = XML_T('\n');
1097 	characterDataHandler(handlerArg, &c, 1);
1098       }
1099       else if (defaultHandler)
1100 	reportDefault(parser, enc, s, next);
1101       break;
1102     case XML_TOK_CDATA_SECT_OPEN:
1103       {
1104 	enum XML_Error result;
1105 	if (characterDataHandler)
1106   	  characterDataHandler(handlerArg, dataBuf, 0);
1107 	else if (defaultHandler)
1108 	  reportDefault(parser, enc, s, next);
1109 	result = doCdataSection(parser, enc, &next, end, nextPtr);
1110 	if (!next) {
1111 	  processor = cdataSectionProcessor;
1112 	  return result;
1113 	}
1114       }
1115       break;
1116     case XML_TOK_TRAILING_RSQB:
1117       if (nextPtr) {
1118 	*nextPtr = s;
1119 	return XML_ERROR_NONE;
1120       }
1121       if (characterDataHandler) {
1122 	if (MUST_CONVERT(enc, s)) {
1123 	  ICHAR *dataPtr = (ICHAR *)dataBuf;
1124 	  XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
1125 	  characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1126 	}
1127 	else
1128 	  characterDataHandler(handlerArg,
1129 		  	       (XML_Char *)s,
1130 			       (XML_Char *)end - (XML_Char *)s);
1131       }
1132       else if (defaultHandler)
1133 	reportDefault(parser, enc, s, end);
1134       if (startTagLevel == 0) {
1135         *eventPP = end;
1136 	return XML_ERROR_NO_ELEMENTS;
1137       }
1138       if (tagLevel != startTagLevel) {
1139 	*eventPP = end;
1140 	return XML_ERROR_ASYNC_ENTITY;
1141       }
1142       return XML_ERROR_NONE;
1143     case XML_TOK_DATA_CHARS:
1144       if (characterDataHandler) {
1145 	if (MUST_CONVERT(enc, s)) {
1146 	  for (;;) {
1147 	    ICHAR *dataPtr = (ICHAR *)dataBuf;
1148 	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
1149 	    *eventEndPP = s;
1150 	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1151 	    if (s == next)
1152 	      break;
1153 	    *eventPP = s;
1154 	  }
1155 	}
1156 	else
1157 	  characterDataHandler(handlerArg,
1158 			       (XML_Char *)s,
1159 			       (XML_Char *)next - (XML_Char *)s);
1160       }
1161       else if (defaultHandler)
1162 	reportDefault(parser, enc, s, next);
1163       break;
1164     case XML_TOK_PI:
1165       if (!reportProcessingInstruction(parser, enc, s, next))
1166 	return XML_ERROR_NO_MEMORY;
1167       break;
1168     default:
1169       if (defaultHandler)
1170 	reportDefault(parser, enc, s, next);
1171       break;
1172     }
1173     *eventPP = s = next;
1174   }
1175   /* not reached */
1176 }
1177 
1178 /* If tagName is non-null, build a real list of attributes,
1179 otherwise just check the attributes for well-formedness. */
1180 
storeAtts(XML_Parser parser,const ENCODING * enc,const XML_Char * tagName,const char * s)1181 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
1182 				const XML_Char *tagName, const char *s)
1183 {
1184   ELEMENT_TYPE *elementType = 0;
1185   int nDefaultAtts = 0;
1186   const XML_Char **appAtts;
1187   int i;
1188   int n;
1189 
1190   if (tagName) {
1191     elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagName, 0);
1192     if (elementType)
1193       nDefaultAtts = elementType->nDefaultAtts;
1194   }
1195 
1196   n = XmlGetAttributes(enc, s, attsSize, atts);
1197   if (n + nDefaultAtts > attsSize) {
1198     int oldAttsSize = attsSize;
1199     attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
1200     atts = (ATTRIBUTE*)realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
1201     if (!atts)
1202       return XML_ERROR_NO_MEMORY;
1203     if (n > oldAttsSize)
1204       XmlGetAttributes(enc, s, n, atts);
1205   }
1206   appAtts = (const XML_Char **)atts;
1207   for (i = 0; i < n; i++) {
1208     ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
1209 					  atts[i].name
1210 					  + XmlNameLength(enc, atts[i].name));
1211     if (!attId)
1212       return XML_ERROR_NO_MEMORY;
1213     if ((attId->name)[-1]) {
1214       if (enc == encoding)
1215 	eventPtr = atts[i].name;
1216       return XML_ERROR_DUPLICATE_ATTRIBUTE;
1217     }
1218     (attId->name)[-1] = 1;
1219     appAtts[i << 1] = attId->name;
1220     if (!atts[i].normalized) {
1221       enum XML_Error result;
1222       int isCdata = 1;
1223 
1224       if (attId->maybeTokenized) {
1225 	int j;
1226 	for (j = 0; j < nDefaultAtts; j++) {
1227 	  if (attId == elementType->defaultAtts[j].id) {
1228 	    isCdata = elementType->defaultAtts[j].isCdata;
1229 	    break;
1230 	  }
1231 	}
1232       }
1233 
1234       result = storeAttributeValue(parser, enc, isCdata,
1235 				   atts[i].valuePtr, atts[i].valueEnd,
1236 			           &tempPool);
1237       if (result)
1238 	return result;
1239       if (tagName) {
1240 	appAtts[(i << 1) + 1] = poolStart(&tempPool);
1241 	poolFinish(&tempPool);
1242       }
1243       else
1244 	poolDiscard(&tempPool);
1245     }
1246     else if (tagName) {
1247       appAtts[(i << 1) + 1] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
1248       if (appAtts[(i << 1) + 1] == 0)
1249 	return XML_ERROR_NO_MEMORY;
1250       poolFinish(&tempPool);
1251     }
1252   }
1253   if (tagName) {
1254     int j;
1255     for (j = 0; j < nDefaultAtts; j++) {
1256       const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
1257       if (!(da->id->name)[-1] && da->value) {
1258 	(da->id->name)[-1] = 1;
1259 	appAtts[i << 1] = da->id->name;
1260 	appAtts[(i << 1) + 1] = da->value;
1261 	i++;
1262       }
1263     }
1264     appAtts[i << 1] = 0;
1265   }
1266   while (i-- > 0)
1267     ((XML_Char *)appAtts[i << 1])[-1] = 0;
1268   return XML_ERROR_NONE;
1269 }
1270 
1271 /* The idea here is to avoid using stack for each CDATA section when
1272 the whole file is parsed with one call. */
1273 
1274 static
cdataSectionProcessor(XML_Parser parser,const char * start,const char * end,const char ** endPtr)1275 enum XML_Error cdataSectionProcessor(XML_Parser parser,
1276 				     const char *start,
1277 			    	     const char *end,
1278 				     const char **endPtr)
1279 {
1280   enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
1281   if (start) {
1282     processor = contentProcessor;
1283     return contentProcessor(parser, start, end, endPtr);
1284   }
1285   return result;
1286 }
1287 
1288 /* startPtr gets set to non-null is the section is closed, and to null if
1289 the section is not yet closed. */
1290 
1291 static
doCdataSection(XML_Parser parser,const ENCODING * enc,const char ** startPtr,const char * end,const char ** nextPtr)1292 enum XML_Error doCdataSection(XML_Parser parser,
1293 			      const ENCODING *enc,
1294 			      const char **startPtr,
1295 			      const char *end,
1296 			      const char **nextPtr)
1297 {
1298   const char *s = *startPtr;
1299   const char *dummy;
1300   const char **eventPP;
1301   const char **eventEndPP;
1302   if (enc == encoding) {
1303     eventPP = &eventPtr;
1304     *eventPP = s;
1305     eventEndPP = &eventEndPtr;
1306   }
1307   else
1308     eventPP = eventEndPP = &dummy;
1309   *startPtr = 0;
1310   for (;;) {
1311     const char *next;
1312     int tok = XmlCdataSectionTok(enc, s, end, &next);
1313     *eventEndPP = next;
1314     switch (tok) {
1315     case XML_TOK_CDATA_SECT_CLOSE:
1316       if (characterDataHandler)
1317 	characterDataHandler(handlerArg, dataBuf, 0);
1318       else if (defaultHandler)
1319 	reportDefault(parser, enc, s, next);
1320       *startPtr = next;
1321       return XML_ERROR_NONE;
1322     case XML_TOK_DATA_NEWLINE:
1323       if (characterDataHandler) {
1324 	XML_Char c = XML_T('\n');
1325 	characterDataHandler(handlerArg, &c, 1);
1326       }
1327       else if (defaultHandler)
1328 	reportDefault(parser, enc, s, next);
1329       break;
1330     case XML_TOK_DATA_CHARS:
1331       if (characterDataHandler) {
1332 	if (MUST_CONVERT(enc, s)) {
1333 	  for (;;) {
1334   	    ICHAR *dataPtr = (ICHAR *)dataBuf;
1335 	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
1336 	    *eventEndPP = next;
1337 	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
1338 	    if (s == next)
1339 	      break;
1340 	    *eventPP = s;
1341 	  }
1342 	}
1343 	else
1344 	  characterDataHandler(handlerArg,
1345 		  	       (XML_Char *)s,
1346 			       (XML_Char *)next - (XML_Char *)s);
1347       }
1348       else if (defaultHandler)
1349 	reportDefault(parser, enc, s, next);
1350       break;
1351     case XML_TOK_INVALID:
1352       *eventPP = next;
1353       return XML_ERROR_INVALID_TOKEN;
1354     case XML_TOK_PARTIAL_CHAR:
1355       if (nextPtr) {
1356 	*nextPtr = s;
1357 	return XML_ERROR_NONE;
1358       }
1359       return XML_ERROR_PARTIAL_CHAR;
1360     case XML_TOK_PARTIAL:
1361     case XML_TOK_NONE:
1362       if (nextPtr) {
1363 	*nextPtr = s;
1364 	return XML_ERROR_NONE;
1365       }
1366       return XML_ERROR_UNCLOSED_CDATA_SECTION;
1367     default:
1368       abort();
1369     }
1370     *eventPP = s = next;
1371   }
1372   /* not reached */
1373 }
1374 
1375 static enum XML_Error
initializeEncoding(XML_Parser parser)1376 initializeEncoding(XML_Parser parser)
1377 {
1378   const char *s;
1379 #ifdef XML_UNICODE
1380   char encodingBuf[128];
1381   if (!protocolEncodingName)
1382     s = 0;
1383   else {
1384     int i;
1385     for (i = 0; protocolEncodingName[i]; i++) {
1386       if (i == sizeof(encodingBuf) - 1
1387 	  || protocolEncodingName[i] >= 0x80
1388 	  || protocolEncodingName[i] < 0) {
1389 	encodingBuf[0] = '\0';
1390 	break;
1391       }
1392       encodingBuf[i] = (char)protocolEncodingName[i];
1393     }
1394     encodingBuf[i] = '\0';
1395     s = encodingBuf;
1396   }
1397 #else
1398   s = protocolEncodingName;
1399 #endif
1400   if (XmlInitEncoding(&initEncoding, &encoding, s))
1401     return XML_ERROR_NONE;
1402   return handleUnknownEncoding(parser, protocolEncodingName);
1403 }
1404 
1405 static enum XML_Error
processXmlDecl(XML_Parser parser,int isGeneralTextEntity,const char * s,const char * next)1406 processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
1407 	       const char *s, const char *next)
1408 {
1409   const char *encodingName = 0;
1410   const ENCODING *newEncoding = 0;
1411   const char *version;
1412   int standalone = -1;
1413   if (!XmlParseXmlDecl(isGeneralTextEntity,
1414 		       encoding,
1415 		       s,
1416 		       next,
1417 		       &eventPtr,
1418 		       &version,
1419 		       &encodingName,
1420 		       &newEncoding,
1421 		       &standalone))
1422     return XML_ERROR_SYNTAX;
1423   if (!isGeneralTextEntity && standalone == 1)
1424     dtd.standalone = 1;
1425   if (defaultHandler)
1426     reportDefault(parser, encoding, s, next);
1427   if (!protocolEncodingName) {
1428     if (newEncoding) {
1429       if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
1430 	eventPtr = encodingName;
1431 	return XML_ERROR_INCORRECT_ENCODING;
1432       }
1433       encoding = newEncoding;
1434     }
1435     else if (encodingName) {
1436       enum XML_Error result;
1437       const XML_Char *s = poolStoreString(&tempPool,
1438 					  encoding,
1439 					  encodingName,
1440 					  encodingName
1441 					  + XmlNameLength(encoding, encodingName));
1442       if (!s)
1443 	return XML_ERROR_NO_MEMORY;
1444       result = handleUnknownEncoding(parser, s);
1445       poolDiscard(&tempPool);
1446       if (result == XML_ERROR_UNKNOWN_ENCODING)
1447 	eventPtr = encodingName;
1448       return result;
1449     }
1450   }
1451   return XML_ERROR_NONE;
1452 }
1453 
1454 static enum XML_Error
handleUnknownEncoding(XML_Parser parser,const XML_Char * encodingName)1455 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
1456 {
1457   if (unknownEncodingHandler) {
1458     XML_Encoding info;
1459     int i;
1460     for (i = 0; i < 256; i++)
1461       info.map[i] = -1;
1462     info.convert = 0;
1463     info.data = 0;
1464     info.release = 0;
1465     if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
1466       ENCODING *enc;
1467       unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
1468       if (!unknownEncodingMem) {
1469 	if (info.release)
1470 	  info.release(info.data);
1471 	return XML_ERROR_NO_MEMORY;
1472       }
1473       enc = XmlInitUnknownEncoding(unknownEncodingMem,
1474 				   info.map,
1475 				   info.convert,
1476 				   info.data);
1477       if (enc) {
1478 	unknownEncodingData = info.data;
1479 	unknownEncodingRelease = info.release;
1480 	encoding = enc;
1481 	return XML_ERROR_NONE;
1482       }
1483     }
1484     if (info.release)
1485       info.release(info.data);
1486   }
1487   return XML_ERROR_UNKNOWN_ENCODING;
1488 }
1489 
1490 static enum XML_Error
prologInitProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)1491 prologInitProcessor(XML_Parser parser,
1492 		    const char *s,
1493 		    const char *end,
1494 		    const char **nextPtr)
1495 {
1496   enum XML_Error result = initializeEncoding(parser);
1497   if (result != XML_ERROR_NONE)
1498     return result;
1499   processor = prologProcessor;
1500   return prologProcessor(parser, s, end, nextPtr);
1501 }
1502 
1503 static enum XML_Error
prologProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)1504 prologProcessor(XML_Parser parser,
1505 		const char *s,
1506 		const char *end,
1507 		const char **nextPtr)
1508 {
1509   for (;;) {
1510     const char *next;
1511     int tok = XmlPrologTok(encoding, s, end, &next);
1512     if (tok <= 0) {
1513       if (nextPtr != 0 && tok != XML_TOK_INVALID) {
1514 	*nextPtr = s;
1515 	return XML_ERROR_NONE;
1516       }
1517       switch (tok) {
1518       case XML_TOK_INVALID:
1519 	eventPtr = next;
1520 	return XML_ERROR_INVALID_TOKEN;
1521       case XML_TOK_NONE:
1522 	return XML_ERROR_NO_ELEMENTS;
1523       case XML_TOK_PARTIAL:
1524 	return XML_ERROR_UNCLOSED_TOKEN;
1525       case XML_TOK_PARTIAL_CHAR:
1526 	return XML_ERROR_PARTIAL_CHAR;
1527       case XML_TOK_TRAILING_CR:
1528 	eventPtr = s + encoding->minBytesPerChar;
1529 	return XML_ERROR_NO_ELEMENTS;
1530       default:
1531 	abort();
1532       }
1533     }
1534     switch (XmlTokenRole(&prologState, tok, s, next, encoding)) {
1535     case XML_ROLE_XML_DECL:
1536       {
1537 	enum XML_Error result = processXmlDecl(parser, 0, s, next);
1538 	if (result != XML_ERROR_NONE)
1539 	  return result;
1540       }
1541       break;
1542     case XML_ROLE_DOCTYPE_SYSTEM_ID:
1543       hadExternalDoctype = 1;
1544       break;
1545     case XML_ROLE_DOCTYPE_PUBLIC_ID:
1546     case XML_ROLE_ENTITY_PUBLIC_ID:
1547       if (!XmlIsPublicId(encoding, s, next, &eventPtr))
1548 	return XML_ERROR_SYNTAX;
1549       if (declEntity) {
1550 	XML_Char *tem = poolStoreString(&dtd.pool,
1551 	                                encoding,
1552 					s + encoding->minBytesPerChar,
1553 	  				next - encoding->minBytesPerChar);
1554 	if (!tem)
1555 	  return XML_ERROR_NO_MEMORY;
1556 	normalizePublicId(tem);
1557 	declEntity->publicId = tem;
1558 	poolFinish(&dtd.pool);
1559       }
1560       break;
1561     case XML_ROLE_INSTANCE_START:
1562       processor = contentProcessor;
1563       if (hadExternalDoctype)
1564 	dtd.complete = 0;
1565       return contentProcessor(parser, s, end, nextPtr);
1566     case XML_ROLE_ATTLIST_ELEMENT_NAME:
1567       {
1568 	const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next);
1569 	if (!name)
1570 	  return XML_ERROR_NO_MEMORY;
1571 	declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
1572 	if (!declElementType)
1573 	  return XML_ERROR_NO_MEMORY;
1574 	if (declElementType->name != name)
1575 	  poolDiscard(&dtd.pool);
1576 	else
1577 	  poolFinish(&dtd.pool);
1578 	break;
1579       }
1580     case XML_ROLE_ATTRIBUTE_NAME:
1581       declAttributeId = getAttributeId(parser, encoding, s, next);
1582       if (!declAttributeId)
1583 	return XML_ERROR_NO_MEMORY;
1584       declAttributeIsCdata = 0;
1585       break;
1586     case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
1587       declAttributeIsCdata = 1;
1588       break;
1589     case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
1590     case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
1591       if (dtd.complete
1592 	  && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
1593 	return XML_ERROR_NO_MEMORY;
1594       break;
1595     case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
1596     case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
1597       {
1598 	const XML_Char *attVal;
1599 	enum XML_Error result
1600 	  = storeAttributeValue(parser, encoding, declAttributeIsCdata,
1601 				s + encoding->minBytesPerChar,
1602 			        next - encoding->minBytesPerChar,
1603 			        &dtd.pool);
1604 	if (result)
1605 	  return result;
1606 	attVal = poolStart(&dtd.pool);
1607 	poolFinish(&dtd.pool);
1608 	if (dtd.complete
1609 	    && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
1610 	  return XML_ERROR_NO_MEMORY;
1611 	break;
1612       }
1613     case XML_ROLE_ENTITY_VALUE:
1614       {
1615 	enum XML_Error result = storeEntityValue(parser, s, next);
1616 	if (result != XML_ERROR_NONE)
1617 	  return result;
1618       }
1619       break;
1620     case XML_ROLE_ENTITY_SYSTEM_ID:
1621       if (declEntity) {
1622 	declEntity->systemId = poolStoreString(&dtd.pool, encoding,
1623 	                                       s + encoding->minBytesPerChar,
1624 	  				       next - encoding->minBytesPerChar);
1625 	if (!declEntity->systemId)
1626 	  return XML_ERROR_NO_MEMORY;
1627 	declEntity->base = dtd.base;
1628 	poolFinish(&dtd.pool);
1629       }
1630       break;
1631     case XML_ROLE_ENTITY_NOTATION_NAME:
1632       if (declEntity) {
1633 	declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next);
1634 	if (!declEntity->notation)
1635 	  return XML_ERROR_NO_MEMORY;
1636 	poolFinish(&dtd.pool);
1637 	if (unparsedEntityDeclHandler) {
1638 	  eventPtr = eventEndPtr = s;
1639 	  unparsedEntityDeclHandler(handlerArg,
1640 				    declEntity->name,
1641 				    declEntity->base,
1642 				    declEntity->systemId,
1643 				    declEntity->publicId,
1644 				    declEntity->notation);
1645 	}
1646 
1647       }
1648       break;
1649     case XML_ROLE_GENERAL_ENTITY_NAME:
1650       {
1651 	const XML_Char *name;
1652 	if (XmlPredefinedEntityName(encoding, s, next)) {
1653 	  declEntity = 0;
1654 	  break;
1655 	}
1656 	name = poolStoreString(&dtd.pool, encoding, s, next);
1657 	if (!name)
1658 	  return XML_ERROR_NO_MEMORY;
1659 	if (dtd.complete) {
1660 	  declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
1661 	  if (!declEntity)
1662 	    return XML_ERROR_NO_MEMORY;
1663 	  if (declEntity->name != name) {
1664 	    poolDiscard(&dtd.pool);
1665 	    declEntity = 0;
1666 	  }
1667 	  else
1668 	    poolFinish(&dtd.pool);
1669 	}
1670 	else {
1671 	  poolDiscard(&dtd.pool);
1672 	  declEntity = 0;
1673 	}
1674       }
1675       break;
1676     case XML_ROLE_PARAM_ENTITY_NAME:
1677       declEntity = 0;
1678       break;
1679     case XML_ROLE_NOTATION_NAME:
1680       declNotationPublicId = 0;
1681       declNotationName = 0;
1682       if (notationDeclHandler) {
1683 	declNotationName = poolStoreString(&tempPool, encoding, s, next);
1684 	if (!declNotationName)
1685 	  return XML_ERROR_NO_MEMORY;
1686 	poolFinish(&tempPool);
1687       }
1688       break;
1689     case XML_ROLE_NOTATION_PUBLIC_ID:
1690       if (!XmlIsPublicId(encoding, s, next, &eventPtr))
1691 	return XML_ERROR_SYNTAX;
1692       if (declNotationName) {
1693 	XML_Char *tem = poolStoreString(&tempPool,
1694 	                                encoding,
1695 					s + encoding->minBytesPerChar,
1696 	  				next - encoding->minBytesPerChar);
1697 	if (!tem)
1698 	  return XML_ERROR_NO_MEMORY;
1699 	normalizePublicId(tem);
1700 	declNotationPublicId = tem;
1701 	poolFinish(&tempPool);
1702       }
1703       break;
1704     case XML_ROLE_NOTATION_SYSTEM_ID:
1705       if (declNotationName && notationDeclHandler) {
1706 	const XML_Char *systemId
1707 	  = poolStoreString(&tempPool, encoding,
1708 			    s + encoding->minBytesPerChar,
1709 	  		    next - encoding->minBytesPerChar);
1710 	if (!systemId)
1711 	  return XML_ERROR_NO_MEMORY;
1712 	eventPtr = eventEndPtr = s;
1713 	notationDeclHandler(handlerArg,
1714 			    declNotationName,
1715 			    dtd.base,
1716 			    systemId,
1717 			    declNotationPublicId);
1718       }
1719       poolClear(&tempPool);
1720       break;
1721     case XML_ROLE_NOTATION_NO_SYSTEM_ID:
1722       if (declNotationPublicId && notationDeclHandler) {
1723 	eventPtr = eventEndPtr = s;
1724 	notationDeclHandler(handlerArg,
1725 			    declNotationName,
1726 			    dtd.base,
1727 			    0,
1728 			    declNotationPublicId);
1729       }
1730       poolClear(&tempPool);
1731       break;
1732     case XML_ROLE_ERROR:
1733       eventPtr = s;
1734       switch (tok) {
1735       case XML_TOK_PARAM_ENTITY_REF:
1736 	return XML_ERROR_PARAM_ENTITY_REF;
1737       case XML_TOK_XML_DECL:
1738 	return XML_ERROR_MISPLACED_XML_PI;
1739       default:
1740 	return XML_ERROR_SYNTAX;
1741       }
1742     case XML_ROLE_GROUP_OPEN:
1743       if (prologState.level >= groupSize) {
1744 	if (groupSize)
1745 	  groupConnector = (char*)realloc(groupConnector, groupSize *= 2);
1746 	else
1747 	  groupConnector = (char*)malloc(groupSize = 32);
1748 	if (!groupConnector)
1749 	  return XML_ERROR_NO_MEMORY;
1750       }
1751       groupConnector[prologState.level] = 0;
1752       break;
1753     case XML_ROLE_GROUP_SEQUENCE:
1754       if (groupConnector[prologState.level] == '|') {
1755 	eventPtr = s;
1756 	return XML_ERROR_SYNTAX;
1757       }
1758       groupConnector[prologState.level] = ',';
1759       break;
1760     case XML_ROLE_GROUP_CHOICE:
1761       if (groupConnector[prologState.level] == ',') {
1762 	eventPtr = s;
1763 	return XML_ERROR_SYNTAX;
1764       }
1765       groupConnector[prologState.level] = '|';
1766       break;
1767     case XML_ROLE_PARAM_ENTITY_REF:
1768       dtd.complete = 0;
1769       break;
1770     case XML_ROLE_NONE:
1771       switch (tok) {
1772       case XML_TOK_PI:
1773 	eventPtr = s;
1774 	eventEndPtr = next;
1775 	if (!reportProcessingInstruction(parser, encoding, s, next))
1776 	  return XML_ERROR_NO_MEMORY;
1777 	break;
1778       }
1779       break;
1780     }
1781     if (defaultHandler) {
1782       switch (tok) {
1783       case XML_TOK_PI:
1784       case XML_TOK_BOM:
1785       case XML_TOK_XML_DECL:
1786 	break;
1787       default:
1788 	eventPtr = s;
1789 	eventEndPtr = next;
1790 	reportDefault(parser, encoding, s, next);
1791       }
1792     }
1793     s = next;
1794   }
1795   /* not reached */
1796 }
1797 
1798 static
epilogProcessor(XML_Parser parser,const char * s,const char * end,const char ** nextPtr)1799 enum XML_Error epilogProcessor(XML_Parser parser,
1800 			       const char *s,
1801 			       const char *end,
1802 			       const char **nextPtr)
1803 {
1804   processor = epilogProcessor;
1805   eventPtr = s;
1806   for (;;) {
1807     const char *next;
1808     int tok = XmlPrologTok(encoding, s, end, &next);
1809     eventEndPtr = next;
1810     switch (tok) {
1811     case XML_TOK_TRAILING_CR:
1812       if (defaultHandler) {
1813 	eventEndPtr = end;
1814 	reportDefault(parser, encoding, s, end);
1815       }
1816       /* fall through */
1817     case XML_TOK_NONE:
1818       if (nextPtr)
1819 	*nextPtr = end;
1820       return XML_ERROR_NONE;
1821     case XML_TOK_PROLOG_S:
1822     case XML_TOK_COMMENT:
1823       if (defaultHandler)
1824 	reportDefault(parser, encoding, s, next);
1825       break;
1826     case XML_TOK_PI:
1827       if (!reportProcessingInstruction(parser, encoding, s, next))
1828 	return XML_ERROR_NO_MEMORY;
1829       break;
1830     case XML_TOK_INVALID:
1831       eventPtr = next;
1832       return XML_ERROR_INVALID_TOKEN;
1833     case XML_TOK_PARTIAL:
1834       if (nextPtr) {
1835 	*nextPtr = s;
1836 	return XML_ERROR_NONE;
1837       }
1838       return XML_ERROR_UNCLOSED_TOKEN;
1839     case XML_TOK_PARTIAL_CHAR:
1840       if (nextPtr) {
1841 	*nextPtr = s;
1842 	return XML_ERROR_NONE;
1843       }
1844       return XML_ERROR_PARTIAL_CHAR;
1845     default:
1846       return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
1847     }
1848     eventPtr = s = next;
1849   }
1850 }
1851 
1852 /* static */
1853 /* enum XML_Error errorProcessor(XML_Parser parser, */
1854 /* 			      const char *s, */
1855 /* 			      const char *end, */
1856 /* 			      const char **nextPtr) */
1857 /* { */
1858 /*   return errorCode; */
1859 /* } */
1860 
1861 static enum XML_Error
storeAttributeValue(XML_Parser parser,const ENCODING * enc,int isCdata,const char * ptr,const char * end,STRING_POOL * pool)1862 storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
1863 		    const char *ptr, const char *end,
1864 		    STRING_POOL *pool)
1865 {
1866   enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
1867   if (result)
1868     return result;
1869   if (!isCdata && poolLength(pool) && poolLastChar(pool) == XML_T(' '))
1870     poolChop(pool);
1871   if (!poolAppendChar(pool, XML_T('\0')))
1872     return XML_ERROR_NO_MEMORY;
1873   return XML_ERROR_NONE;
1874 }
1875 
1876 static enum XML_Error
appendAttributeValue(XML_Parser parser,const ENCODING * enc,int isCdata,const char * ptr,const char * end,STRING_POOL * pool)1877 appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
1878 		     const char *ptr, const char *end,
1879 		     STRING_POOL *pool)
1880 {
1881   const ENCODING *internalEnc = XmlGetInternalEncoding();
1882   for (;;) {
1883     const char *next;
1884     int tok = XmlAttributeValueTok(enc, ptr, end, &next);
1885     switch (tok) {
1886     case XML_TOK_NONE:
1887       return XML_ERROR_NONE;
1888     case XML_TOK_INVALID:
1889       if (enc == encoding)
1890 	eventPtr = next;
1891       return XML_ERROR_INVALID_TOKEN;
1892     case XML_TOK_PARTIAL:
1893       if (enc == encoding)
1894 	eventPtr = ptr;
1895       return XML_ERROR_INVALID_TOKEN;
1896     case XML_TOK_CHAR_REF:
1897       {
1898 	XML_Char buf[XML_ENCODE_MAX];
1899 	int i;
1900 	int n = XmlCharRefNumber(enc, ptr);
1901 	if (n < 0) {
1902 	  if (enc == encoding)
1903 	    eventPtr = ptr;
1904       	  return XML_ERROR_BAD_CHAR_REF;
1905 	}
1906 	if (!isCdata
1907 	    && n == 0x20 /* space */
1908 	    && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' ')))
1909 	  break;
1910 	n = XmlEncode(n, (ICHAR *)buf);
1911 	if (!n) {
1912 	  if (enc == encoding)
1913 	    eventPtr = ptr;
1914 	  return XML_ERROR_BAD_CHAR_REF;
1915 	}
1916 	for (i = 0; i < n; i++) {
1917 	  if (!poolAppendChar(pool, buf[i]))
1918 	    return XML_ERROR_NO_MEMORY;
1919 	}
1920       }
1921       break;
1922     case XML_TOK_DATA_CHARS:
1923       if (!poolAppend(pool, enc, ptr, next))
1924 	return XML_ERROR_NO_MEMORY;
1925       break;
1926       break;
1927     case XML_TOK_TRAILING_CR:
1928       next = ptr + enc->minBytesPerChar;
1929       /* fall through */
1930     case XML_TOK_ATTRIBUTE_VALUE_S:
1931     case XML_TOK_DATA_NEWLINE:
1932       if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' ')))
1933 	break;
1934       if (!poolAppendChar(pool, XML_T(' ')))
1935 	return XML_ERROR_NO_MEMORY;
1936       break;
1937     case XML_TOK_ENTITY_REF:
1938       {
1939 	const XML_Char *name;
1940 	ENTITY *entity;
1941 	XML_Char ch = XmlPredefinedEntityName(enc,
1942 					      ptr + enc->minBytesPerChar,
1943 					      next - enc->minBytesPerChar);
1944 	if (ch) {
1945 	  if (!poolAppendChar(pool, ch))
1946   	    return XML_ERROR_NO_MEMORY;
1947 	  break;
1948 	}
1949 	name = poolStoreString(&temp2Pool, enc,
1950 			       ptr + enc->minBytesPerChar,
1951 			       next - enc->minBytesPerChar);
1952 	if (!name)
1953 	  return XML_ERROR_NO_MEMORY;
1954 	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
1955 	poolDiscard(&temp2Pool);
1956 	if (!entity) {
1957 	  if (dtd.complete) {
1958 	    if (enc == encoding)
1959 	      eventPtr = ptr;
1960 	    return XML_ERROR_UNDEFINED_ENTITY;
1961 	  }
1962 	}
1963 	else if (entity->open) {
1964 	  if (enc == encoding)
1965 	    eventPtr = ptr;
1966 	  return XML_ERROR_RECURSIVE_ENTITY_REF;
1967 	}
1968 	else if (entity->notation) {
1969 	  if (enc == encoding)
1970 	    eventPtr = ptr;
1971 	  return XML_ERROR_BINARY_ENTITY_REF;
1972 	}
1973 	else if (!entity->textPtr) {
1974 	  if (enc == encoding)
1975 	    eventPtr = ptr;
1976   	  return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
1977 	}
1978 	else {
1979 	  enum XML_Error result;
1980 	  const XML_Char *textEnd = entity->textPtr + entity->textLen;
1981 	  entity->open = 1;
1982 	  result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
1983 	  entity->open = 0;
1984 	  if (result)
1985 	    return result;
1986 	}
1987       }
1988       break;
1989     default:
1990       abort();
1991     }
1992     ptr = next;
1993   }
1994   /* not reached */
1995 }
1996 
1997 static
storeEntityValue(XML_Parser parser,const char * entityTextPtr,const char * entityTextEnd)1998 enum XML_Error storeEntityValue(XML_Parser parser,
1999 				const char *entityTextPtr,
2000 				const char *entityTextEnd)
2001 {
2002 /*   const ENCODING *internalEnc = XmlGetInternalEncoding(); */
2003   STRING_POOL *pool = &(dtd.pool);
2004   entityTextPtr += encoding->minBytesPerChar;
2005   entityTextEnd -= encoding->minBytesPerChar;
2006   for (;;) {
2007     const char *next;
2008     int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next);
2009     switch (tok) {
2010     case XML_TOK_PARAM_ENTITY_REF:
2011       eventPtr = entityTextPtr;
2012       return XML_ERROR_SYNTAX;
2013     case XML_TOK_NONE:
2014       if (declEntity) {
2015 	declEntity->textPtr = pool->start;
2016 	declEntity->textLen = pool->ptr - pool->start;
2017 	poolFinish(pool);
2018       }
2019       else
2020 	poolDiscard(pool);
2021       return XML_ERROR_NONE;
2022     case XML_TOK_ENTITY_REF:
2023     case XML_TOK_DATA_CHARS:
2024       if (!poolAppend(pool, encoding, entityTextPtr, next))
2025 	return XML_ERROR_NO_MEMORY;
2026       break;
2027     case XML_TOK_TRAILING_CR:
2028       next = entityTextPtr + encoding->minBytesPerChar;
2029       /* fall through */
2030     case XML_TOK_DATA_NEWLINE:
2031       if (pool->end == pool->ptr && !poolGrow(pool))
2032 	return XML_ERROR_NO_MEMORY;
2033       *(pool->ptr)++ = XML_T('\n');
2034       break;
2035     case XML_TOK_CHAR_REF:
2036       {
2037 	XML_Char buf[XML_ENCODE_MAX];
2038 	int i;
2039 	int n = XmlCharRefNumber(encoding, entityTextPtr);
2040 	if (n < 0) {
2041 	  eventPtr = entityTextPtr;
2042 	  return XML_ERROR_BAD_CHAR_REF;
2043 	}
2044 	n = XmlEncode(n, (ICHAR *)buf);
2045 	if (!n) {
2046 	  eventPtr = entityTextPtr;
2047 	  return XML_ERROR_BAD_CHAR_REF;
2048 	}
2049 	for (i = 0; i < n; i++) {
2050 	  if (pool->end == pool->ptr && !poolGrow(pool))
2051 	    return XML_ERROR_NO_MEMORY;
2052 	  *(pool->ptr)++ = buf[i];
2053 	}
2054       }
2055       break;
2056     case XML_TOK_PARTIAL:
2057       eventPtr = entityTextPtr;
2058       return XML_ERROR_INVALID_TOKEN;
2059     case XML_TOK_INVALID:
2060       eventPtr = next;
2061       return XML_ERROR_INVALID_TOKEN;
2062     default:
2063       abort();
2064     }
2065     entityTextPtr = next;
2066   }
2067   /* not reached */
2068 }
2069 
2070 static void
normalizeLines(XML_Char * s)2071 normalizeLines(XML_Char *s)
2072 {
2073   XML_Char *p;
2074   for (;; s++) {
2075     if (*s == XML_T('\0'))
2076       return;
2077     if (*s == XML_T('\r'))
2078       break;
2079   }
2080   p = s;
2081   do {
2082     if (*s == XML_T('\r')) {
2083       *p++ = XML_T('\n');
2084       if (*++s == XML_T('\n'))
2085         s++;
2086     }
2087     else
2088       *p++ = *s++;
2089   } while (*s);
2090   *p = XML_T('\0');
2091 }
2092 
2093 static int
reportProcessingInstruction(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)2094 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
2095 {
2096   const XML_Char *target;
2097   XML_Char *data;
2098   const char *tem;
2099   if (!processingInstructionHandler) {
2100     if (defaultHandler)
2101       reportDefault(parser, enc, start, end);
2102     return 1;
2103   }
2104   start += enc->minBytesPerChar * 2;
2105   tem = start + XmlNameLength(enc, start);
2106   target = poolStoreString(&tempPool, enc, start, tem);
2107   if (!target)
2108     return 0;
2109   poolFinish(&tempPool);
2110   data = poolStoreString(&tempPool, enc,
2111 			XmlSkipS(enc, tem),
2112 			end - enc->minBytesPerChar*2);
2113   if (!data)
2114     return 0;
2115   normalizeLines(data);
2116   processingInstructionHandler(handlerArg, target, data);
2117   poolClear(&tempPool);
2118   return 1;
2119 }
2120 
2121 static void
reportDefault(XML_Parser parser,const ENCODING * enc,const char * s,const char * end)2122 reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
2123 {
2124   if (MUST_CONVERT(enc, s)) {
2125     for (;;) {
2126       ICHAR *dataPtr = (ICHAR *)dataBuf;
2127       XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2128       if (s == end) {
2129 	defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
2130 	break;
2131       }
2132       if (enc == encoding) {
2133 	eventEndPtr = s;
2134 	defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
2135 	eventPtr = s;
2136       }
2137       else
2138 	defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
2139     }
2140   }
2141   else
2142     defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
2143 }
2144 
2145 
2146 static int
defineAttribute(ELEMENT_TYPE * type,ATTRIBUTE_ID * attId,int isCdata,const XML_Char * value)2147 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value)
2148 {
2149   DEFAULT_ATTRIBUTE *att;
2150   if (type->nDefaultAtts == type->allocDefaultAtts) {
2151     if (type->allocDefaultAtts == 0) {
2152       type->allocDefaultAtts = 8;
2153       type->defaultAtts = (DEFAULT_ATTRIBUTE*)malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
2154     }
2155     else {
2156       type->allocDefaultAtts *= 2;
2157       type->defaultAtts = (DEFAULT_ATTRIBUTE*)realloc(type->defaultAtts,
2158 				  type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
2159     }
2160     if (!type->defaultAtts)
2161       return 0;
2162   }
2163   att = type->defaultAtts + type->nDefaultAtts;
2164   att->id = attId;
2165   att->value = value;
2166   att->isCdata = isCdata;
2167   if (!isCdata)
2168     attId->maybeTokenized = 1;
2169   type->nDefaultAtts += 1;
2170   return 1;
2171 }
2172 
2173 static ATTRIBUTE_ID *
getAttributeId(XML_Parser parser,const ENCODING * enc,const char * start,const char * end)2174 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
2175 {
2176   ATTRIBUTE_ID *id;
2177   const XML_Char *name;
2178   if (!poolAppendChar(&dtd.pool, XML_T('\0')))
2179     return 0;
2180   name = poolStoreString(&dtd.pool, enc, start, end);
2181   if (!name)
2182     return 0;
2183   ++name;
2184   id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
2185   if (!id)
2186     return 0;
2187   if (id->name != name)
2188     poolDiscard(&dtd.pool);
2189   else
2190     poolFinish(&dtd.pool);
2191   return id;
2192 }
2193 
2194 static
getOpenEntityNames(XML_Parser parser)2195 const XML_Char *getOpenEntityNames(XML_Parser parser)
2196 {
2197   HASH_TABLE_ITER iter;
2198 
2199   hashTableIterInit(&iter, &(dtd.generalEntities));
2200   for (;;) {
2201     const XML_Char *s;
2202     ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
2203     if (!e)
2204       break;
2205     if (!e->open)
2206       continue;
2207     if (poolLength(&tempPool) > 0 && !poolAppendChar(&tempPool, XML_T(' ')))
2208       return 0;
2209     for (s = e->name; *s; s++)
2210       if (!poolAppendChar(&tempPool, *s))
2211         return 0;
2212   }
2213 
2214   if (!poolAppendChar(&tempPool, XML_T('\0')))
2215     return 0;
2216   return tempPool.start;
2217 }
2218 
2219 static
setOpenEntityNames(XML_Parser parser,const XML_Char * openEntityNames)2220 int setOpenEntityNames(XML_Parser parser, const XML_Char *openEntityNames)
2221 {
2222   const XML_Char *s = openEntityNames;
2223   while (*openEntityNames != XML_T('\0')) {
2224     if (*s == XML_T(' ') || *s == XML_T('\0')) {
2225       ENTITY *e;
2226       if (!poolAppendChar(&tempPool, XML_T('\0')))
2227 	return 0;
2228       e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
2229       if (e)
2230 	e->open = 1;
2231       if (*s == XML_T(' '))
2232 	s++;
2233       openEntityNames = s;
2234       poolDiscard(&tempPool);
2235     }
2236     else {
2237       if (!poolAppendChar(&tempPool, *s))
2238 	return 0;
2239       s++;
2240     }
2241   }
2242   return 1;
2243 }
2244 
2245 
2246 static
normalizePublicId(XML_Char * publicId)2247 void normalizePublicId(XML_Char *publicId)
2248 {
2249   XML_Char *p = publicId;
2250   XML_Char *s;
2251   for (s = publicId; *s; s++) {
2252     switch (*s) {
2253     case XML_T(' '):
2254     case XML_T('\r'):
2255     case XML_T('\n'):
2256       if (p != publicId && p[-1] != XML_T(' '))
2257 	*p++ = XML_T(' ');
2258       break;
2259     default:
2260       *p++ = *s;
2261     }
2262   }
2263   if (p != publicId && p[-1] == XML_T(' '))
2264     --p;
2265   *p = XML_T('\0');
2266 }
2267 
dtdInit(DTD * p)2268 static int dtdInit(DTD *p)
2269 {
2270   poolInit(&(p->pool));
2271   hashTableInit(&(p->generalEntities));
2272   hashTableInit(&(p->elementTypes));
2273   hashTableInit(&(p->attributeIds));
2274   p->complete = 1;
2275   p->standalone = 0;
2276   p->base = 0;
2277   return 1;
2278 }
2279 
dtdDestroy(DTD * p)2280 static void dtdDestroy(DTD *p)
2281 {
2282   HASH_TABLE_ITER iter;
2283   hashTableIterInit(&iter, &(p->elementTypes));
2284   for (;;) {
2285     ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
2286     if (!e)
2287       break;
2288     if (e->allocDefaultAtts != 0)
2289       free(e->defaultAtts);
2290   }
2291   hashTableDestroy(&(p->generalEntities));
2292   hashTableDestroy(&(p->elementTypes));
2293   hashTableDestroy(&(p->attributeIds));
2294   poolDestroy(&(p->pool));
2295 }
2296 
2297 /* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
2298 The new DTD has already been initialized. */
2299 
dtdCopy(DTD * newDtd,const DTD * oldDtd)2300 static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
2301 {
2302   HASH_TABLE_ITER iter;
2303 
2304   if (oldDtd->base) {
2305     const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base);
2306     if (!tem)
2307       return 0;
2308     newDtd->base = tem;
2309   }
2310 
2311   hashTableIterInit(&iter, &(oldDtd->attributeIds));
2312 
2313   /* Copy the attribute id table. */
2314 
2315   for (;;) {
2316     ATTRIBUTE_ID *newA;
2317     const XML_Char *name;
2318     const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
2319 
2320     if (!oldA)
2321       break;
2322     /* Remember to allocate the scratch byte before the name. */
2323     if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
2324       return 0;
2325     name = poolCopyString(&(newDtd->pool), oldA->name);
2326     if (!name)
2327       return 0;
2328     ++name;
2329     newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
2330     if (!newA)
2331       return 0;
2332     newA->maybeTokenized = oldA->maybeTokenized;
2333   }
2334 
2335   /* Copy the element type table. */
2336 
2337   hashTableIterInit(&iter, &(oldDtd->elementTypes));
2338 
2339   for (;;) {
2340     int i;
2341     ELEMENT_TYPE *newE;
2342     const XML_Char *name;
2343     const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
2344     if (!oldE)
2345       break;
2346     name = poolCopyString(&(newDtd->pool), oldE->name);
2347     if (!name)
2348       return 0;
2349     newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
2350     if (!newE)
2351       return 0;
2352     newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
2353     if (!newE->defaultAtts)
2354       return 0;
2355     newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
2356     for (i = 0; i < newE->nDefaultAtts; i++) {
2357       newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
2358       newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
2359       if (oldE->defaultAtts[i].value) {
2360 	newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
2361 	if (!newE->defaultAtts[i].value)
2362   	  return 0;
2363       }
2364       else
2365 	newE->defaultAtts[i].value = 0;
2366     }
2367   }
2368 
2369   /* Copy the entity table. */
2370 
2371   hashTableIterInit(&iter, &(oldDtd->generalEntities));
2372 
2373   for (;;) {
2374     ENTITY *newE;
2375     const XML_Char *name;
2376     const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
2377     if (!oldE)
2378       break;
2379     name = poolCopyString(&(newDtd->pool), oldE->name);
2380     if (!name)
2381       return 0;
2382     newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY));
2383     if (!newE)
2384       return 0;
2385     if (oldE->systemId) {
2386       const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId);
2387       if (!tem)
2388 	return 0;
2389       newE->systemId = tem;
2390       if (oldE->base) {
2391 	if (oldE->base == oldDtd->base)
2392 	  newE->base = newDtd->base;
2393 	tem = poolCopyString(&(newDtd->pool), oldE->base);
2394 	if (!tem)
2395 	  return 0;
2396 	newE->base = tem;
2397       }
2398     }
2399     else {
2400       const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen);
2401       if (!tem)
2402 	return 0;
2403       newE->textPtr = tem;
2404       newE->textLen = oldE->textLen;
2405     }
2406     if (oldE->notation) {
2407       const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation);
2408       if (!tem)
2409 	return 0;
2410       newE->notation = tem;
2411     }
2412   }
2413 
2414   newDtd->complete = oldDtd->complete;
2415   newDtd->standalone = oldDtd->standalone;
2416   return 1;
2417 }
2418 
2419 static
poolInit(STRING_POOL * pool)2420 void poolInit(STRING_POOL *pool)
2421 {
2422   pool->blocks = 0;
2423   pool->freeBlocks = 0;
2424   pool->start = 0;
2425   pool->ptr = 0;
2426   pool->end = 0;
2427 }
2428 
2429 static
poolClear(STRING_POOL * pool)2430 void poolClear(STRING_POOL *pool)
2431 {
2432   if (!pool->freeBlocks)
2433     pool->freeBlocks = pool->blocks;
2434   else {
2435     BLOCK *p = pool->blocks;
2436     while (p) {
2437       BLOCK *tem = p->next;
2438       p->next = pool->freeBlocks;
2439       pool->freeBlocks = p;
2440       p = tem;
2441     }
2442   }
2443   pool->blocks = 0;
2444   pool->start = 0;
2445   pool->ptr = 0;
2446   pool->end = 0;
2447 }
2448 
2449 static
poolDestroy(STRING_POOL * pool)2450 void poolDestroy(STRING_POOL *pool)
2451 {
2452   BLOCK *p = pool->blocks;
2453   while (p) {
2454     BLOCK *tem = p->next;
2455     free(p);
2456     p = tem;
2457   }
2458   pool->blocks = 0;
2459   p = pool->freeBlocks;
2460   while (p) {
2461     BLOCK *tem = p->next;
2462     free(p);
2463     p = tem;
2464   }
2465   pool->freeBlocks = 0;
2466   pool->ptr = 0;
2467   pool->start = 0;
2468   pool->end = 0;
2469 }
2470 
2471 static
poolAppend(STRING_POOL * pool,const ENCODING * enc,const char * ptr,const char * end)2472 XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
2473 		     const char *ptr, const char *end)
2474 {
2475   if (!pool->ptr && !poolGrow(pool))
2476     return 0;
2477   for (;;) {
2478     XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
2479     if (ptr == end)
2480       break;
2481     if (!poolGrow(pool))
2482       return 0;
2483   }
2484   return pool->start;
2485 }
2486 
poolCopyString(STRING_POOL * pool,const XML_Char * s)2487 static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
2488 {
2489   do {
2490     if (!poolAppendChar(pool, *s))
2491       return 0;
2492   } while (*s++);
2493   s = pool->start;
2494   poolFinish(pool);
2495   return s;
2496 }
2497 
poolCopyStringN(STRING_POOL * pool,const XML_Char * s,int n)2498 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
2499 {
2500   if (!pool->ptr && !poolGrow(pool))
2501     return 0;
2502   for (; n > 0; --n, s++) {
2503     if (!poolAppendChar(pool, *s))
2504       return 0;
2505 
2506   }
2507   s = pool->start;
2508   poolFinish(pool);
2509   return s;
2510 }
2511 
2512 static
poolStoreString(STRING_POOL * pool,const ENCODING * enc,const char * ptr,const char * end)2513 XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
2514 			  const char *ptr, const char *end)
2515 {
2516   if (!poolAppend(pool, enc, ptr, end))
2517     return 0;
2518   if (pool->ptr == pool->end && !poolGrow(pool))
2519     return 0;
2520   *(pool->ptr)++ = 0;
2521   return pool->start;
2522 }
2523 
2524 static
poolGrow(STRING_POOL * pool)2525 int poolGrow(STRING_POOL *pool)
2526 {
2527   if (pool->freeBlocks) {
2528     if (pool->start == 0) {
2529       pool->blocks = pool->freeBlocks;
2530       pool->freeBlocks = pool->freeBlocks->next;
2531       pool->blocks->next = 0;
2532       pool->start = pool->blocks->s;
2533       pool->end = pool->start + pool->blocks->size;
2534       pool->ptr = pool->start;
2535       return 1;
2536     }
2537     if (pool->end - pool->start < pool->freeBlocks->size) {
2538       BLOCK *tem = pool->freeBlocks->next;
2539       pool->freeBlocks->next = pool->blocks;
2540       pool->blocks = pool->freeBlocks;
2541       pool->freeBlocks = tem;
2542       memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
2543       pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
2544       pool->start = pool->blocks->s;
2545       pool->end = pool->start + pool->blocks->size;
2546       return 1;
2547     }
2548   }
2549   if (pool->blocks && pool->start == pool->blocks->s) {
2550     int blockSize = (pool->end - pool->start)*2;
2551     pool->blocks = (BLOCK*)realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
2552     if (!pool->blocks)
2553       return 0;
2554     pool->blocks->size = blockSize;
2555     pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
2556     pool->start = pool->blocks->s;
2557     pool->end = pool->start + blockSize;
2558   }
2559   else {
2560     BLOCK *tem;
2561     int blockSize = pool->end - pool->start;
2562     if (blockSize < INIT_BLOCK_SIZE)
2563       blockSize = INIT_BLOCK_SIZE;
2564     else
2565       blockSize *= 2;
2566     tem = (BLOCK*)malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
2567     if (!tem)
2568       return 0;
2569     tem->size = blockSize;
2570     tem->next = pool->blocks;
2571     pool->blocks = tem;
2572     memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
2573     pool->ptr = tem->s + (pool->ptr - pool->start);
2574     pool->start = tem->s;
2575     pool->end = tem->s + blockSize;
2576   }
2577   return 1;
2578 }
2579