/[MITgcm]/mitgcm.org/devel/buildweb/pkg/swish-e/src/expat/xmlparse/xmlparse.c
ViewVC logotype

Contents of /mitgcm.org/devel/buildweb/pkg/swish-e/src/expat/xmlparse/xmlparse.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Fri Sep 20 19:47:30 2002 UTC (22 years, 10 months ago) by adcroft
Branch: Import, MAIN
CVS Tags: baseline, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/plain
Importing web-site building process.

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

  ViewVC Help
Powered by ViewVC 1.1.22