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