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