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