blob: 46f650782698317cb6d68e46e1acbcf7c39f60f6 [file] [log] [blame]
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 See the file COPYING for copying permission.
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003*/
4
Fred Drake08317ae2003-10-21 15:38:55 +00005#define XML_BUILDING_EXPAT 1
6
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00007#ifdef COMPILED_FROM_DSP
Martin v. Löwisfc03a942003-01-25 22:41:29 +00008#include "winconfig.h"
Martin v. Löwisfc03a942003-01-25 22:41:29 +00009#elif defined(MACOS_CLASSIC)
Martin v. Löwisfc03a942003-01-25 22:41:29 +000010#include "macconfig.h"
Trent Mickf08d6632006-06-19 23:21:25 +000011#elif defined(__amigaos4__)
12#include "amigaconfig.h"
Fred Drake31d485c2004-08-03 07:06:22 +000013#elif defined(HAVE_EXPAT_CONFIG_H)
Martin v. Löwisfc03a942003-01-25 22:41:29 +000014#include <expat_config.h>
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000015#endif /* ndef COMPILED_FROM_DSP */
16
Neal Norwitz9652baa2006-05-02 07:27:47 +000017#include <stddef.h>
18#include <string.h> /* memset(), memcpy() */
19#include <assert.h>
Gregory P. Smithc8ff4602012-03-14 15:28:10 -070020#include <limits.h> /* UINT_MAX */
21#include <time.h> /* time() */
Neal Norwitz9652baa2006-05-02 07:27:47 +000022
Fred Drake08317ae2003-10-21 15:38:55 +000023#include "expat.h"
24
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000025#ifdef XML_UNICODE
26#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
27#define XmlConvert XmlUtf16Convert
28#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
29#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
30#define XmlEncode XmlUtf16Encode
31#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
32typedef unsigned short ICHAR;
33#else
34#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
35#define XmlConvert XmlUtf8Convert
36#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
37#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
38#define XmlEncode XmlUtf8Encode
39#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
40typedef char ICHAR;
41#endif
42
43
44#ifndef XML_NS
45
46#define XmlInitEncodingNS XmlInitEncoding
47#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
48#undef XmlGetInternalEncodingNS
49#define XmlGetInternalEncodingNS XmlGetInternalEncoding
50#define XmlParseXmlDeclNS XmlParseXmlDecl
51
52#endif
53
Martin v. Löwisfc03a942003-01-25 22:41:29 +000054#ifdef XML_UNICODE
55
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000056#ifdef XML_UNICODE_WCHAR_T
Martin v. Löwisfc03a942003-01-25 22:41:29 +000057#define XML_T(x) (const wchar_t)x
58#define XML_L(x) L ## x
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000059#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +000060#define XML_T(x) (const unsigned short)x
61#define XML_L(x) x
62#endif
63
64#else
65
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000066#define XML_T(x) x
Martin v. Löwisfc03a942003-01-25 22:41:29 +000067#define XML_L(x) x
68
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000069#endif
70
71/* Round up n to be a multiple of sz, where sz is a power of 2. */
72#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
73
Fred Drake08317ae2003-10-21 15:38:55 +000074/* Handle the case where memmove() doesn't exist. */
75#ifndef HAVE_MEMMOVE
76#ifdef HAVE_BCOPY
77#define memmove(d,s,l) bcopy((s),(d),(l))
78#else
79#error memmove does not exist on this platform, nor is a substitute available
80#endif /* HAVE_BCOPY */
81#endif /* HAVE_MEMMOVE */
82
Martin v. Löwisfc03a942003-01-25 22:41:29 +000083#include "internal.h"
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000084#include "xmltok.h"
85#include "xmlrole.h"
86
87typedef const XML_Char *KEY;
88
89typedef struct {
90 KEY name;
91} NAMED;
92
93typedef struct {
94 NAMED **v;
Fred Drake08317ae2003-10-21 15:38:55 +000095 unsigned char power;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000096 size_t size;
97 size_t used;
Martin v. Löwisfc03a942003-01-25 22:41:29 +000098 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000099} HASH_TABLE;
100
Fred Drake08317ae2003-10-21 15:38:55 +0000101/* Basic character hash algorithm, taken from Python's string hash:
102 h = h * 1000003 ^ character, the constant being a prime number.
103
104*/
105#ifdef XML_UNICODE
106#define CHAR_HASH(h, c) \
107 (((h) * 0xF4243) ^ (unsigned short)(c))
108#else
109#define CHAR_HASH(h, c) \
110 (((h) * 0xF4243) ^ (unsigned char)(c))
111#endif
112
113/* For probing (after a collision) we need a step size relative prime
114 to the hash table size, which is a power of 2. We use double-hashing,
115 since we can calculate a second hash value cheaply by taking those bits
116 of the first hash value that were discarded (masked out) when the table
117 index was calculated: index = hash & mask, where mask = table->size - 1.
118 We limit the maximum step size to table->size / 4 (mask >> 2) and make
119 it odd, since odd numbers are always relative prime to a power of 2.
120*/
121#define SECOND_HASH(hash, mask, power) \
122 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
123#define PROBE_STEP(hash, mask, power) \
124 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
125
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000126typedef struct {
127 NAMED **p;
128 NAMED **end;
129} HASH_TABLE_ITER;
130
131#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
132#define INIT_DATA_BUF_SIZE 1024
133#define INIT_ATTS_SIZE 16
Fred Drake08317ae2003-10-21 15:38:55 +0000134#define INIT_ATTS_VERSION 0xFFFFFFFF
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000135#define INIT_BLOCK_SIZE 1024
136#define INIT_BUFFER_SIZE 1024
137
138#define EXPAND_SPARE 24
139
140typedef struct binding {
141 struct prefix *prefix;
142 struct binding *nextTagBinding;
143 struct binding *prevPrefixBinding;
144 const struct attribute_id *attId;
145 XML_Char *uri;
146 int uriLen;
147 int uriAlloc;
148} BINDING;
149
150typedef struct prefix {
151 const XML_Char *name;
152 BINDING *binding;
153} PREFIX;
154
155typedef struct {
156 const XML_Char *str;
157 const XML_Char *localPart;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000158 const XML_Char *prefix;
159 int strLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000160 int uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000161 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000162} TAG_NAME;
163
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000164/* TAG represents an open element.
165 The name of the element is stored in both the document and API
166 encodings. The memory buffer 'buf' is a separately-allocated
167 memory area which stores the name. During the XML_Parse()/
168 XMLParseBuffer() when the element is open, the memory for the 'raw'
169 version of the name (in the document encoding) is shared with the
170 document buffer. If the element is open across calls to
171 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
172 contain the 'raw' name as well.
173
174 A parser re-uses these structures, maintaining a list of allocated
175 TAG objects in a free list.
176*/
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000177typedef struct tag {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000178 struct tag *parent; /* parent of this element */
179 const char *rawName; /* tagName in the original encoding */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000180 int rawNameLength;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000181 TAG_NAME name; /* tagName in the API encoding */
182 char *buf; /* buffer for name components */
183 char *bufEnd; /* end of the buffer */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000184 BINDING *bindings;
185} TAG;
186
187typedef struct {
188 const XML_Char *name;
189 const XML_Char *textPtr;
Fred Drake31d485c2004-08-03 07:06:22 +0000190 int textLen; /* length in XML_Chars */
191 int processed; /* # of processed bytes - when suspended */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000192 const XML_Char *systemId;
193 const XML_Char *base;
194 const XML_Char *publicId;
195 const XML_Char *notation;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000196 XML_Bool open;
197 XML_Bool is_param;
198 XML_Bool is_internal; /* true if declared in internal subset outside PE */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000199} ENTITY;
200
201typedef struct {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000202 enum XML_Content_Type type;
203 enum XML_Content_Quant quant;
204 const XML_Char * name;
205 int firstchild;
206 int lastchild;
207 int childcnt;
208 int nextsib;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000209} CONTENT_SCAFFOLD;
210
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000211#define INIT_SCAFFOLD_ELEMENTS 32
212
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000213typedef struct block {
214 struct block *next;
215 int size;
216 XML_Char s[1];
217} BLOCK;
218
219typedef struct {
220 BLOCK *blocks;
221 BLOCK *freeBlocks;
222 const XML_Char *end;
223 XML_Char *ptr;
224 XML_Char *start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000225 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000226} STRING_POOL;
227
228/* The XML_Char before the name is used to determine whether
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000229 an attribute has been specified. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000230typedef struct attribute_id {
231 XML_Char *name;
232 PREFIX *prefix;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000233 XML_Bool maybeTokenized;
234 XML_Bool xmlns;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000235} ATTRIBUTE_ID;
236
237typedef struct {
238 const ATTRIBUTE_ID *id;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000239 XML_Bool isCdata;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000240 const XML_Char *value;
241} DEFAULT_ATTRIBUTE;
242
243typedef struct {
Fred Drake08317ae2003-10-21 15:38:55 +0000244 unsigned long version;
245 unsigned long hash;
246 const XML_Char *uriName;
247} NS_ATT;
248
249typedef struct {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000250 const XML_Char *name;
251 PREFIX *prefix;
252 const ATTRIBUTE_ID *idAtt;
253 int nDefaultAtts;
254 int allocDefaultAtts;
255 DEFAULT_ATTRIBUTE *defaultAtts;
256} ELEMENT_TYPE;
257
258typedef struct {
259 HASH_TABLE generalEntities;
260 HASH_TABLE elementTypes;
261 HASH_TABLE attributeIds;
262 HASH_TABLE prefixes;
263 STRING_POOL pool;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000264 STRING_POOL entityValuePool;
265 /* false once a parameter entity reference has been skipped */
266 XML_Bool keepProcessing;
267 /* true once an internal or external PE reference has been encountered;
268 this includes the reference to an external subset */
269 XML_Bool hasParamEntityRefs;
270 XML_Bool standalone;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000271#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000272 /* indicates if external PE has been read */
273 XML_Bool paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000274 HASH_TABLE paramEntities;
275#endif /* XML_DTD */
276 PREFIX defaultPrefix;
277 /* === scaffolding for building content model === */
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000278 XML_Bool in_eldecl;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000279 CONTENT_SCAFFOLD *scaffold;
280 unsigned contentStringLen;
281 unsigned scaffSize;
282 unsigned scaffCount;
283 int scaffLevel;
284 int *scaffIndex;
285} DTD;
286
287typedef struct open_internal_entity {
288 const char *internalEventPtr;
289 const char *internalEventEndPtr;
290 struct open_internal_entity *next;
291 ENTITY *entity;
Fred Drake31d485c2004-08-03 07:06:22 +0000292 int startTagLevel;
293 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000294} OPEN_INTERNAL_ENTITY;
295
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000296typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
297 const char *start,
298 const char *end,
299 const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000300
301static Processor prologProcessor;
302static Processor prologInitProcessor;
303static Processor contentProcessor;
304static Processor cdataSectionProcessor;
305#ifdef XML_DTD
306static Processor ignoreSectionProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000307static Processor externalParEntProcessor;
308static Processor externalParEntInitProcessor;
309static Processor entityValueProcessor;
310static Processor entityValueInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000311#endif /* XML_DTD */
312static Processor epilogProcessor;
313static Processor errorProcessor;
314static Processor externalEntityInitProcessor;
315static Processor externalEntityInitProcessor2;
316static Processor externalEntityInitProcessor3;
317static Processor externalEntityContentProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +0000318static Processor internalEntityProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000319
320static enum XML_Error
321handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
322static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000323processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Fred Drake31d485c2004-08-03 07:06:22 +0000324 const char *s, const char *next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000325static enum XML_Error
326initializeEncoding(XML_Parser parser);
327static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +0000328doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
329 const char *end, int tok, const char *next, const char **nextPtr,
330 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000331static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +0000332processInternalEntity(XML_Parser parser, ENTITY *entity,
333 XML_Bool betweenDecl);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000334static enum XML_Error
335doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
Fred Drake31d485c2004-08-03 07:06:22 +0000336 const char *start, const char *end, const char **endPtr,
337 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000338static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000339doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000340 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000341#ifdef XML_DTD
342static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000343doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000344 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000345#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000346
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000347static enum XML_Error
Fred Drake4faea012003-01-28 06:42:40 +0000348storeAtts(XML_Parser parser, const ENCODING *, const char *s,
349 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000350static enum XML_Error
351addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
352 const XML_Char *uri, BINDING **bindingsPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000353static int
Fred Drake31d485c2004-08-03 07:06:22 +0000354defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
355 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000356static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000357storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
358 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000359static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000360appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
361 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000362static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000363getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
364 const char *end);
365static int
366setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000367static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000368storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
369 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000370static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000371reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
372 const char *start, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000373static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000374reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
375 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000376static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000377reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
378 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000379
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000380static const XML_Char * getContext(XML_Parser parser);
381static XML_Bool
382setContext(XML_Parser parser, const XML_Char *context);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000383
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000384static void FASTCALL normalizePublicId(XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000385
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000386static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
387/* do not call if parentParser != NULL */
388static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
389static void
390dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
391static int
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700392dtdCopy(XML_Parser oldParser,
393 DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000394static int
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700395copyEntityTable(XML_Parser oldParser,
396 HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000397static NAMED *
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700398lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000399static void FASTCALL
400hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
401static void FASTCALL hashTableClear(HASH_TABLE *);
402static void FASTCALL hashTableDestroy(HASH_TABLE *);
403static void FASTCALL
404hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
405static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000406
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000407static void FASTCALL
408poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
409static void FASTCALL poolClear(STRING_POOL *);
410static void FASTCALL poolDestroy(STRING_POOL *);
411static XML_Char *
412poolAppend(STRING_POOL *pool, const ENCODING *enc,
413 const char *ptr, const char *end);
414static XML_Char *
415poolStoreString(STRING_POOL *pool, const ENCODING *enc,
416 const char *ptr, const char *end);
417static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
418static const XML_Char * FASTCALL
419poolCopyString(STRING_POOL *pool, const XML_Char *s);
420static const XML_Char *
421poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
422static const XML_Char * FASTCALL
423poolAppendString(STRING_POOL *pool, const XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000424
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000425static int FASTCALL nextScaffoldPart(XML_Parser parser);
426static XML_Content * build_model(XML_Parser parser);
427static ELEMENT_TYPE *
428getElementType(XML_Parser parser, const ENCODING *enc,
429 const char *ptr, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000430
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700431static unsigned long generate_hash_secret_salt(void);
432static XML_Bool startParsing(XML_Parser parser);
433
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000434static XML_Parser
435parserCreate(const XML_Char *encodingName,
436 const XML_Memory_Handling_Suite *memsuite,
437 const XML_Char *nameSep,
438 DTD *dtd);
439static void
440parserInit(XML_Parser parser, const XML_Char *encodingName);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000441
442#define poolStart(pool) ((pool)->start)
443#define poolEnd(pool) ((pool)->ptr)
444#define poolLength(pool) ((pool)->ptr - (pool)->start)
445#define poolChop(pool) ((void)--(pool->ptr))
446#define poolLastChar(pool) (((pool)->ptr)[-1])
447#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
448#define poolFinish(pool) ((pool)->start = (pool)->ptr)
449#define poolAppendChar(pool, c) \
450 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
451 ? 0 \
452 : ((*((pool)->ptr)++ = c), 1))
453
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000454struct XML_ParserStruct {
455 /* The first member must be userData so that the XML_GetUserData
456 macro works. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000457 void *m_userData;
458 void *m_handlerArg;
459 char *m_buffer;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000460 const XML_Memory_Handling_Suite m_mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000461 /* first character to be parsed */
462 const char *m_bufferPtr;
463 /* past last character to be parsed */
464 char *m_bufferEnd;
465 /* allocated end of buffer */
466 const char *m_bufferLim;
Trent Mickf08d6632006-06-19 23:21:25 +0000467 XML_Index m_parseEndByteIndex;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000468 const char *m_parseEndPtr;
469 XML_Char *m_dataBuf;
470 XML_Char *m_dataBufEnd;
471 XML_StartElementHandler m_startElementHandler;
472 XML_EndElementHandler m_endElementHandler;
473 XML_CharacterDataHandler m_characterDataHandler;
474 XML_ProcessingInstructionHandler m_processingInstructionHandler;
475 XML_CommentHandler m_commentHandler;
476 XML_StartCdataSectionHandler m_startCdataSectionHandler;
477 XML_EndCdataSectionHandler m_endCdataSectionHandler;
478 XML_DefaultHandler m_defaultHandler;
479 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
480 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
481 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
482 XML_NotationDeclHandler m_notationDeclHandler;
483 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
484 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
485 XML_NotStandaloneHandler m_notStandaloneHandler;
486 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000487 XML_Parser m_externalEntityRefHandlerArg;
488 XML_SkippedEntityHandler m_skippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000489 XML_UnknownEncodingHandler m_unknownEncodingHandler;
490 XML_ElementDeclHandler m_elementDeclHandler;
491 XML_AttlistDeclHandler m_attlistDeclHandler;
492 XML_EntityDeclHandler m_entityDeclHandler;
493 XML_XmlDeclHandler m_xmlDeclHandler;
494 const ENCODING *m_encoding;
495 INIT_ENCODING m_initEncoding;
496 const ENCODING *m_internalEncoding;
497 const XML_Char *m_protocolEncodingName;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000498 XML_Bool m_ns;
499 XML_Bool m_ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000500 void *m_unknownEncodingMem;
501 void *m_unknownEncodingData;
502 void *m_unknownEncodingHandlerData;
Fred Drake31d485c2004-08-03 07:06:22 +0000503 void (XMLCALL *m_unknownEncodingRelease)(void *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000504 PROLOG_STATE m_prologState;
505 Processor *m_processor;
506 enum XML_Error m_errorCode;
507 const char *m_eventPtr;
508 const char *m_eventEndPtr;
509 const char *m_positionPtr;
510 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
Fred Drake31d485c2004-08-03 07:06:22 +0000511 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000512 XML_Bool m_defaultExpandInternalEntities;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000513 int m_tagLevel;
514 ENTITY *m_declEntity;
515 const XML_Char *m_doctypeName;
516 const XML_Char *m_doctypeSysid;
517 const XML_Char *m_doctypePubid;
518 const XML_Char *m_declAttributeType;
519 const XML_Char *m_declNotationName;
520 const XML_Char *m_declNotationPublicId;
521 ELEMENT_TYPE *m_declElementType;
522 ATTRIBUTE_ID *m_declAttributeId;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000523 XML_Bool m_declAttributeIsCdata;
524 XML_Bool m_declAttributeIsId;
525 DTD *m_dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000526 const XML_Char *m_curBase;
527 TAG *m_tagStack;
528 TAG *m_freeTagList;
529 BINDING *m_inheritedBindings;
530 BINDING *m_freeBindingList;
531 int m_attsSize;
532 int m_nSpecifiedAtts;
533 int m_idAttIndex;
534 ATTRIBUTE *m_atts;
Fred Drake08317ae2003-10-21 15:38:55 +0000535 NS_ATT *m_nsAtts;
536 unsigned long m_nsAttsVersion;
537 unsigned char m_nsAttsPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000538 POSITION m_position;
539 STRING_POOL m_tempPool;
540 STRING_POOL m_temp2Pool;
541 char *m_groupConnector;
Fred Drake08317ae2003-10-21 15:38:55 +0000542 unsigned int m_groupSize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000543 XML_Char m_namespaceSeparator;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000544 XML_Parser m_parentParser;
Fred Drake31d485c2004-08-03 07:06:22 +0000545 XML_ParsingStatus m_parsingStatus;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000546#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000547 XML_Bool m_isParamEntity;
548 XML_Bool m_useForeignDTD;
549 enum XML_ParamEntityParsing m_paramEntityParsing;
550#endif
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700551 unsigned long m_hash_secret_salt;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000552};
553
554#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
555#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
556#define FREE(p) (parser->m_mem.free_fcn((p)))
557
558#define userData (parser->m_userData)
559#define handlerArg (parser->m_handlerArg)
560#define startElementHandler (parser->m_startElementHandler)
561#define endElementHandler (parser->m_endElementHandler)
562#define characterDataHandler (parser->m_characterDataHandler)
563#define processingInstructionHandler \
564 (parser->m_processingInstructionHandler)
565#define commentHandler (parser->m_commentHandler)
566#define startCdataSectionHandler \
567 (parser->m_startCdataSectionHandler)
568#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
569#define defaultHandler (parser->m_defaultHandler)
570#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
571#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
572#define unparsedEntityDeclHandler \
573 (parser->m_unparsedEntityDeclHandler)
574#define notationDeclHandler (parser->m_notationDeclHandler)
575#define startNamespaceDeclHandler \
576 (parser->m_startNamespaceDeclHandler)
577#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
578#define notStandaloneHandler (parser->m_notStandaloneHandler)
579#define externalEntityRefHandler \
580 (parser->m_externalEntityRefHandler)
581#define externalEntityRefHandlerArg \
582 (parser->m_externalEntityRefHandlerArg)
583#define internalEntityRefHandler \
584 (parser->m_internalEntityRefHandler)
585#define skippedEntityHandler (parser->m_skippedEntityHandler)
586#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
587#define elementDeclHandler (parser->m_elementDeclHandler)
588#define attlistDeclHandler (parser->m_attlistDeclHandler)
589#define entityDeclHandler (parser->m_entityDeclHandler)
590#define xmlDeclHandler (parser->m_xmlDeclHandler)
591#define encoding (parser->m_encoding)
592#define initEncoding (parser->m_initEncoding)
593#define internalEncoding (parser->m_internalEncoding)
594#define unknownEncodingMem (parser->m_unknownEncodingMem)
595#define unknownEncodingData (parser->m_unknownEncodingData)
596#define unknownEncodingHandlerData \
597 (parser->m_unknownEncodingHandlerData)
598#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
599#define protocolEncodingName (parser->m_protocolEncodingName)
600#define ns (parser->m_ns)
601#define ns_triplets (parser->m_ns_triplets)
602#define prologState (parser->m_prologState)
603#define processor (parser->m_processor)
604#define errorCode (parser->m_errorCode)
605#define eventPtr (parser->m_eventPtr)
606#define eventEndPtr (parser->m_eventEndPtr)
607#define positionPtr (parser->m_positionPtr)
608#define position (parser->m_position)
609#define openInternalEntities (parser->m_openInternalEntities)
Fred Drake31d485c2004-08-03 07:06:22 +0000610#define freeInternalEntities (parser->m_freeInternalEntities)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000611#define defaultExpandInternalEntities \
612 (parser->m_defaultExpandInternalEntities)
613#define tagLevel (parser->m_tagLevel)
614#define buffer (parser->m_buffer)
615#define bufferPtr (parser->m_bufferPtr)
616#define bufferEnd (parser->m_bufferEnd)
617#define parseEndByteIndex (parser->m_parseEndByteIndex)
618#define parseEndPtr (parser->m_parseEndPtr)
619#define bufferLim (parser->m_bufferLim)
620#define dataBuf (parser->m_dataBuf)
621#define dataBufEnd (parser->m_dataBufEnd)
622#define _dtd (parser->m_dtd)
623#define curBase (parser->m_curBase)
624#define declEntity (parser->m_declEntity)
625#define doctypeName (parser->m_doctypeName)
626#define doctypeSysid (parser->m_doctypeSysid)
627#define doctypePubid (parser->m_doctypePubid)
628#define declAttributeType (parser->m_declAttributeType)
629#define declNotationName (parser->m_declNotationName)
630#define declNotationPublicId (parser->m_declNotationPublicId)
631#define declElementType (parser->m_declElementType)
632#define declAttributeId (parser->m_declAttributeId)
633#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
634#define declAttributeIsId (parser->m_declAttributeIsId)
635#define freeTagList (parser->m_freeTagList)
636#define freeBindingList (parser->m_freeBindingList)
637#define inheritedBindings (parser->m_inheritedBindings)
638#define tagStack (parser->m_tagStack)
639#define atts (parser->m_atts)
640#define attsSize (parser->m_attsSize)
641#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
642#define idAttIndex (parser->m_idAttIndex)
Fred Drake08317ae2003-10-21 15:38:55 +0000643#define nsAtts (parser->m_nsAtts)
644#define nsAttsVersion (parser->m_nsAttsVersion)
645#define nsAttsPower (parser->m_nsAttsPower)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000646#define tempPool (parser->m_tempPool)
647#define temp2Pool (parser->m_temp2Pool)
648#define groupConnector (parser->m_groupConnector)
649#define groupSize (parser->m_groupSize)
650#define namespaceSeparator (parser->m_namespaceSeparator)
651#define parentParser (parser->m_parentParser)
Trent Mickf08d6632006-06-19 23:21:25 +0000652#define ps_parsing (parser->m_parsingStatus.parsing)
653#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000654#ifdef XML_DTD
655#define isParamEntity (parser->m_isParamEntity)
656#define useForeignDTD (parser->m_useForeignDTD)
657#define paramEntityParsing (parser->m_paramEntityParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000658#endif /* XML_DTD */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700659#define hash_secret_salt (parser->m_hash_secret_salt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000660
Fred Drake08317ae2003-10-21 15:38:55 +0000661XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000662XML_ParserCreate(const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000663{
664 return XML_ParserCreate_MM(encodingName, NULL, NULL);
665}
666
Fred Drake08317ae2003-10-21 15:38:55 +0000667XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000668XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000669{
670 XML_Char tmp[2];
671 *tmp = nsSep;
672 return XML_ParserCreate_MM(encodingName, NULL, tmp);
673}
674
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000675static const XML_Char implicitContext[] = {
676 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
677 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
678 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
679 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
680};
681
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700682static unsigned long
683generate_hash_secret_salt(void)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000684{
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700685 unsigned int seed = time(NULL) % UINT_MAX;
686 srand(seed);
687 return rand();
688}
689
690static XML_Bool /* only valid for root parser */
691startParsing(XML_Parser parser)
692{
693 /* hash functions must be initialized before setContext() is called */
694
695 if (hash_secret_salt == 0)
696 hash_secret_salt = generate_hash_secret_salt();
697 if (ns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000698 /* implicit context only set for root parser, since child
699 parsers (i.e. external entity parsers) will inherit it
700 */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700701 return setContext(parser, implicitContext);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000702 }
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700703 return XML_TRUE;
704}
705
706XML_Parser XMLCALL
707XML_ParserCreate_MM(const XML_Char *encodingName,
708 const XML_Memory_Handling_Suite *memsuite,
709 const XML_Char *nameSep)
710{
711 return parserCreate(encodingName, memsuite, nameSep, NULL);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000712}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000713
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000714static XML_Parser
715parserCreate(const XML_Char *encodingName,
716 const XML_Memory_Handling_Suite *memsuite,
717 const XML_Char *nameSep,
718 DTD *dtd)
719{
720 XML_Parser parser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000721
722 if (memsuite) {
723 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000724 parser = (XML_Parser)
725 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
726 if (parser != NULL) {
727 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
728 mtemp->malloc_fcn = memsuite->malloc_fcn;
729 mtemp->realloc_fcn = memsuite->realloc_fcn;
730 mtemp->free_fcn = memsuite->free_fcn;
731 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000732 }
733 else {
734 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000735 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
736 if (parser != NULL) {
737 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
738 mtemp->malloc_fcn = malloc;
739 mtemp->realloc_fcn = realloc;
740 mtemp->free_fcn = free;
741 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000742 }
743
744 if (!parser)
745 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000746
747 buffer = NULL;
748 bufferLim = NULL;
749
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000750 attsSize = INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000751 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
752 if (atts == NULL) {
753 FREE(parser);
754 return NULL;
755 }
756 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
757 if (dataBuf == NULL) {
758 FREE(atts);
759 FREE(parser);
760 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000761 }
762 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
763
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000764 if (dtd)
765 _dtd = dtd;
766 else {
767 _dtd = dtdCreate(&parser->m_mem);
768 if (_dtd == NULL) {
769 FREE(dataBuf);
770 FREE(atts);
771 FREE(parser);
772 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000773 }
774 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000775
776 freeBindingList = NULL;
777 freeTagList = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000778 freeInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000779
780 groupSize = 0;
781 groupConnector = NULL;
782
783 unknownEncodingHandler = NULL;
784 unknownEncodingHandlerData = NULL;
785
786 namespaceSeparator = '!';
787 ns = XML_FALSE;
788 ns_triplets = XML_FALSE;
789
Fred Drake08317ae2003-10-21 15:38:55 +0000790 nsAtts = NULL;
791 nsAttsVersion = 0;
792 nsAttsPower = 0;
793
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000794 poolInit(&tempPool, &(parser->m_mem));
795 poolInit(&temp2Pool, &(parser->m_mem));
796 parserInit(parser, encodingName);
797
798 if (encodingName && !protocolEncodingName) {
799 XML_ParserFree(parser);
800 return NULL;
801 }
802
803 if (nameSep) {
804 ns = XML_TRUE;
805 internalEncoding = XmlGetInternalEncodingNS();
806 namespaceSeparator = *nameSep;
807 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000808 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000809 internalEncoding = XmlGetInternalEncoding();
810 }
811
812 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000813}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000814
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000815static void
816parserInit(XML_Parser parser, const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000817{
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000818 processor = prologInitProcessor;
819 XmlPrologStateInit(&prologState);
820 protocolEncodingName = (encodingName != NULL
821 ? poolCopyString(&tempPool, encodingName)
822 : NULL);
823 curBase = NULL;
824 XmlInitEncoding(&initEncoding, &encoding, 0);
825 userData = NULL;
826 handlerArg = NULL;
827 startElementHandler = NULL;
828 endElementHandler = NULL;
829 characterDataHandler = NULL;
830 processingInstructionHandler = NULL;
831 commentHandler = NULL;
832 startCdataSectionHandler = NULL;
833 endCdataSectionHandler = NULL;
834 defaultHandler = NULL;
835 startDoctypeDeclHandler = NULL;
836 endDoctypeDeclHandler = NULL;
837 unparsedEntityDeclHandler = NULL;
838 notationDeclHandler = NULL;
839 startNamespaceDeclHandler = NULL;
840 endNamespaceDeclHandler = NULL;
841 notStandaloneHandler = NULL;
842 externalEntityRefHandler = NULL;
843 externalEntityRefHandlerArg = parser;
844 skippedEntityHandler = NULL;
845 elementDeclHandler = NULL;
846 attlistDeclHandler = NULL;
847 entityDeclHandler = NULL;
848 xmlDeclHandler = NULL;
849 bufferPtr = buffer;
850 bufferEnd = buffer;
851 parseEndByteIndex = 0;
852 parseEndPtr = NULL;
853 declElementType = NULL;
854 declAttributeId = NULL;
855 declEntity = NULL;
856 doctypeName = NULL;
857 doctypeSysid = NULL;
858 doctypePubid = NULL;
859 declAttributeType = NULL;
860 declNotationName = NULL;
861 declNotationPublicId = NULL;
862 declAttributeIsCdata = XML_FALSE;
863 declAttributeIsId = XML_FALSE;
864 memset(&position, 0, sizeof(POSITION));
865 errorCode = XML_ERROR_NONE;
866 eventPtr = NULL;
867 eventEndPtr = NULL;
868 positionPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000869 openInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000870 defaultExpandInternalEntities = XML_TRUE;
871 tagLevel = 0;
872 tagStack = NULL;
873 inheritedBindings = NULL;
874 nSpecifiedAtts = 0;
875 unknownEncodingMem = NULL;
876 unknownEncodingRelease = NULL;
877 unknownEncodingData = NULL;
878 parentParser = NULL;
Trent Mickf08d6632006-06-19 23:21:25 +0000879 ps_parsing = XML_INITIALIZED;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000880#ifdef XML_DTD
881 isParamEntity = XML_FALSE;
882 useForeignDTD = XML_FALSE;
883 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
884#endif
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700885 hash_secret_salt = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000886}
887
888/* moves list of bindings to freeBindingList */
889static void FASTCALL
890moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
891{
892 while (bindings) {
893 BINDING *b = bindings;
894 bindings = bindings->nextTagBinding;
895 b->nextTagBinding = freeBindingList;
896 freeBindingList = b;
897 }
898}
899
Fred Drake08317ae2003-10-21 15:38:55 +0000900XML_Bool XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000901XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
902{
903 TAG *tStk;
Fred Drake31d485c2004-08-03 07:06:22 +0000904 OPEN_INTERNAL_ENTITY *openEntityList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000905 if (parentParser)
906 return XML_FALSE;
907 /* move tagStack to freeTagList */
908 tStk = tagStack;
909 while (tStk) {
910 TAG *tag = tStk;
911 tStk = tStk->parent;
912 tag->parent = freeTagList;
913 moveToFreeBindingList(parser, tag->bindings);
914 tag->bindings = NULL;
915 freeTagList = tag;
916 }
Fred Drake31d485c2004-08-03 07:06:22 +0000917 /* move openInternalEntities to freeInternalEntities */
918 openEntityList = openInternalEntities;
919 while (openEntityList) {
920 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
921 openEntityList = openEntity->next;
922 openEntity->next = freeInternalEntities;
923 freeInternalEntities = openEntity;
924 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000925 moveToFreeBindingList(parser, inheritedBindings);
Fred Drake08317ae2003-10-21 15:38:55 +0000926 FREE(unknownEncodingMem);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000927 if (unknownEncodingRelease)
928 unknownEncodingRelease(unknownEncodingData);
929 poolClear(&tempPool);
930 poolClear(&temp2Pool);
931 parserInit(parser, encodingName);
932 dtdReset(_dtd, &parser->m_mem);
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700933 return XML_TRUE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000934}
935
Fred Drake08317ae2003-10-21 15:38:55 +0000936enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000937XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
938{
939 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
940 XXX There's no way for the caller to determine which of the
941 XXX possible error cases caused the XML_STATUS_ERROR return.
942 */
Trent Mickf08d6632006-06-19 23:21:25 +0000943 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000944 return XML_STATUS_ERROR;
945 if (encodingName == NULL)
946 protocolEncodingName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000947 else {
948 protocolEncodingName = poolCopyString(&tempPool, encodingName);
949 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000950 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000951 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000952 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000953}
954
Fred Drake08317ae2003-10-21 15:38:55 +0000955XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000956XML_ExternalEntityParserCreate(XML_Parser oldParser,
957 const XML_Char *context,
958 const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000959{
960 XML_Parser parser = oldParser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000961 DTD *newDtd = NULL;
962 DTD *oldDtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000963 XML_StartElementHandler oldStartElementHandler = startElementHandler;
964 XML_EndElementHandler oldEndElementHandler = endElementHandler;
965 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000966 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
967 = processingInstructionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000968 XML_CommentHandler oldCommentHandler = commentHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000969 XML_StartCdataSectionHandler oldStartCdataSectionHandler
970 = startCdataSectionHandler;
971 XML_EndCdataSectionHandler oldEndCdataSectionHandler
972 = endCdataSectionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000973 XML_DefaultHandler oldDefaultHandler = defaultHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000974 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
975 = unparsedEntityDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000976 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000977 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
978 = startNamespaceDeclHandler;
979 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
980 = endNamespaceDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000981 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000982 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
983 = externalEntityRefHandler;
984 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
985 XML_UnknownEncodingHandler oldUnknownEncodingHandler
986 = unknownEncodingHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000987 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
988 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
989 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
990 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
991 ELEMENT_TYPE * oldDeclElementType = declElementType;
992
993 void *oldUserData = userData;
994 void *oldHandlerArg = handlerArg;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000995 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
996 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000997#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000998 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
999 int oldInEntityValue = prologState.inEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001000#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001001 XML_Bool oldns_triplets = ns_triplets;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001002 /* Note that the new parser shares the same hash secret as the old
1003 parser, so that dtdCopy and copyEntityTable can lookup values
1004 from hash tables associated with either parser without us having
1005 to worry which hash secrets each table has.
1006 */
1007 unsigned long oldhash_secret_salt = hash_secret_salt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001008
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001009#ifdef XML_DTD
1010 if (!context)
1011 newDtd = oldDtd;
1012#endif /* XML_DTD */
1013
1014 /* Note that the magical uses of the pre-processor to make field
1015 access look more like C++ require that `parser' be overwritten
1016 here. This makes this function more painful to follow than it
1017 would be otherwise.
1018 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001019 if (ns) {
1020 XML_Char tmp[2];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001021 *tmp = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001022 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001023 }
1024 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001025 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001026 }
1027
1028 if (!parser)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001029 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001030
1031 startElementHandler = oldStartElementHandler;
1032 endElementHandler = oldEndElementHandler;
1033 characterDataHandler = oldCharacterDataHandler;
1034 processingInstructionHandler = oldProcessingInstructionHandler;
1035 commentHandler = oldCommentHandler;
1036 startCdataSectionHandler = oldStartCdataSectionHandler;
1037 endCdataSectionHandler = oldEndCdataSectionHandler;
1038 defaultHandler = oldDefaultHandler;
1039 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1040 notationDeclHandler = oldNotationDeclHandler;
1041 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1042 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1043 notStandaloneHandler = oldNotStandaloneHandler;
1044 externalEntityRefHandler = oldExternalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001045 skippedEntityHandler = oldSkippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001046 unknownEncodingHandler = oldUnknownEncodingHandler;
1047 elementDeclHandler = oldElementDeclHandler;
1048 attlistDeclHandler = oldAttlistDeclHandler;
1049 entityDeclHandler = oldEntityDeclHandler;
1050 xmlDeclHandler = oldXmlDeclHandler;
1051 declElementType = oldDeclElementType;
1052 userData = oldUserData;
1053 if (oldUserData == oldHandlerArg)
1054 handlerArg = userData;
1055 else
1056 handlerArg = parser;
1057 if (oldExternalEntityRefHandlerArg != oldParser)
1058 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1059 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1060 ns_triplets = oldns_triplets;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001061 hash_secret_salt = oldhash_secret_salt;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001062 parentParser = oldParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001063#ifdef XML_DTD
1064 paramEntityParsing = oldParamEntityParsing;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001065 prologState.inEntityValue = oldInEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001066 if (context) {
1067#endif /* XML_DTD */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001068 if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001069 || !setContext(parser, context)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001070 XML_ParserFree(parser);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001071 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001072 }
1073 processor = externalEntityInitProcessor;
1074#ifdef XML_DTD
1075 }
1076 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001077 /* The DTD instance referenced by _dtd is shared between the document's
1078 root parser and external PE parsers, therefore one does not need to
1079 call setContext. In addition, one also *must* not call setContext,
1080 because this would overwrite existing prefix->binding pointers in
1081 _dtd with ones that get destroyed with the external PE parser.
1082 This would leave those prefixes with dangling pointers.
1083 */
1084 isParamEntity = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001085 XmlPrologStateInitExternalEntity(&prologState);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001086 processor = externalParEntInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001087 }
1088#endif /* XML_DTD */
1089 return parser;
1090}
1091
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001092static void FASTCALL
1093destroyBindings(BINDING *bindings, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001094{
1095 for (;;) {
1096 BINDING *b = bindings;
1097 if (!b)
1098 break;
1099 bindings = b->nextTagBinding;
1100 FREE(b->uri);
1101 FREE(b);
1102 }
1103}
1104
Fred Drake08317ae2003-10-21 15:38:55 +00001105void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001106XML_ParserFree(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001107{
Fred Drake31d485c2004-08-03 07:06:22 +00001108 TAG *tagList;
1109 OPEN_INTERNAL_ENTITY *entityList;
1110 if (parser == NULL)
1111 return;
1112 /* free tagStack and freeTagList */
1113 tagList = tagStack;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001114 for (;;) {
1115 TAG *p;
Fred Drake31d485c2004-08-03 07:06:22 +00001116 if (tagList == NULL) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001117 if (freeTagList == NULL)
1118 break;
Fred Drake31d485c2004-08-03 07:06:22 +00001119 tagList = freeTagList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001120 freeTagList = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001121 }
Fred Drake31d485c2004-08-03 07:06:22 +00001122 p = tagList;
1123 tagList = tagList->parent;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001124 FREE(p->buf);
1125 destroyBindings(p->bindings, parser);
1126 FREE(p);
1127 }
Fred Drake31d485c2004-08-03 07:06:22 +00001128 /* free openInternalEntities and freeInternalEntities */
1129 entityList = openInternalEntities;
1130 for (;;) {
1131 OPEN_INTERNAL_ENTITY *openEntity;
1132 if (entityList == NULL) {
1133 if (freeInternalEntities == NULL)
1134 break;
1135 entityList = freeInternalEntities;
1136 freeInternalEntities = NULL;
1137 }
1138 openEntity = entityList;
1139 entityList = entityList->next;
1140 FREE(openEntity);
1141 }
1142
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001143 destroyBindings(freeBindingList, parser);
1144 destroyBindings(inheritedBindings, parser);
1145 poolDestroy(&tempPool);
1146 poolDestroy(&temp2Pool);
1147#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001148 /* external parameter entity parsers share the DTD structure
1149 parser->m_dtd with the root parser, so we must not destroy it
1150 */
1151 if (!isParamEntity && _dtd)
1152#else
1153 if (_dtd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001154#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001155 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001156 FREE((void *)atts);
Fred Drake08317ae2003-10-21 15:38:55 +00001157 FREE(groupConnector);
1158 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001159 FREE(dataBuf);
Fred Drake08317ae2003-10-21 15:38:55 +00001160 FREE(nsAtts);
1161 FREE(unknownEncodingMem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001162 if (unknownEncodingRelease)
1163 unknownEncodingRelease(unknownEncodingData);
1164 FREE(parser);
1165}
1166
Fred Drake08317ae2003-10-21 15:38:55 +00001167void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001168XML_UseParserAsHandlerArg(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001169{
1170 handlerArg = parser;
1171}
1172
Fred Drake08317ae2003-10-21 15:38:55 +00001173enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001174XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1175{
1176#ifdef XML_DTD
1177 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Trent Mickf08d6632006-06-19 23:21:25 +00001178 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001179 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1180 useForeignDTD = useDTD;
1181 return XML_ERROR_NONE;
1182#else
1183 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1184#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001185}
1186
Fred Drake08317ae2003-10-21 15:38:55 +00001187void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001188XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1189{
1190 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Trent Mickf08d6632006-06-19 23:21:25 +00001191 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001192 return;
1193 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1194}
1195
Fred Drake08317ae2003-10-21 15:38:55 +00001196void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001197XML_SetUserData(XML_Parser parser, void *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001198{
1199 if (handlerArg == userData)
1200 handlerArg = userData = p;
1201 else
1202 userData = p;
1203}
1204
Fred Drake08317ae2003-10-21 15:38:55 +00001205enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001206XML_SetBase(XML_Parser parser, const XML_Char *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001207{
1208 if (p) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001209 p = poolCopyString(&_dtd->pool, p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001210 if (!p)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001211 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001212 curBase = p;
1213 }
1214 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001215 curBase = NULL;
1216 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001217}
1218
Fred Drake08317ae2003-10-21 15:38:55 +00001219const XML_Char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001220XML_GetBase(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001221{
1222 return curBase;
1223}
1224
Fred Drake08317ae2003-10-21 15:38:55 +00001225int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001226XML_GetSpecifiedAttributeCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001227{
1228 return nSpecifiedAtts;
1229}
1230
Fred Drake08317ae2003-10-21 15:38:55 +00001231int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001232XML_GetIdAttributeIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001233{
1234 return idAttIndex;
1235}
1236
Fred Drake08317ae2003-10-21 15:38:55 +00001237void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001238XML_SetElementHandler(XML_Parser parser,
1239 XML_StartElementHandler start,
1240 XML_EndElementHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001241{
1242 startElementHandler = start;
1243 endElementHandler = end;
1244}
1245
Fred Drake08317ae2003-10-21 15:38:55 +00001246void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001247XML_SetStartElementHandler(XML_Parser parser,
1248 XML_StartElementHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001249 startElementHandler = start;
1250}
1251
Fred Drake08317ae2003-10-21 15:38:55 +00001252void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001253XML_SetEndElementHandler(XML_Parser parser,
1254 XML_EndElementHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001255 endElementHandler = end;
1256}
1257
Fred Drake08317ae2003-10-21 15:38:55 +00001258void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001259XML_SetCharacterDataHandler(XML_Parser parser,
1260 XML_CharacterDataHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001261{
1262 characterDataHandler = handler;
1263}
1264
Fred Drake08317ae2003-10-21 15:38:55 +00001265void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001266XML_SetProcessingInstructionHandler(XML_Parser parser,
1267 XML_ProcessingInstructionHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001268{
1269 processingInstructionHandler = handler;
1270}
1271
Fred Drake08317ae2003-10-21 15:38:55 +00001272void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001273XML_SetCommentHandler(XML_Parser parser,
1274 XML_CommentHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001275{
1276 commentHandler = handler;
1277}
1278
Fred Drake08317ae2003-10-21 15:38:55 +00001279void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001280XML_SetCdataSectionHandler(XML_Parser parser,
1281 XML_StartCdataSectionHandler start,
1282 XML_EndCdataSectionHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001283{
1284 startCdataSectionHandler = start;
1285 endCdataSectionHandler = end;
1286}
1287
Fred Drake08317ae2003-10-21 15:38:55 +00001288void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001289XML_SetStartCdataSectionHandler(XML_Parser parser,
1290 XML_StartCdataSectionHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001291 startCdataSectionHandler = start;
1292}
1293
Fred Drake08317ae2003-10-21 15:38:55 +00001294void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001295XML_SetEndCdataSectionHandler(XML_Parser parser,
1296 XML_EndCdataSectionHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001297 endCdataSectionHandler = end;
1298}
1299
Fred Drake08317ae2003-10-21 15:38:55 +00001300void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001301XML_SetDefaultHandler(XML_Parser parser,
1302 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001303{
1304 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001305 defaultExpandInternalEntities = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001306}
1307
Fred Drake08317ae2003-10-21 15:38:55 +00001308void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001309XML_SetDefaultHandlerExpand(XML_Parser parser,
1310 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001311{
1312 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001313 defaultExpandInternalEntities = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001314}
1315
Fred Drake08317ae2003-10-21 15:38:55 +00001316void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001317XML_SetDoctypeDeclHandler(XML_Parser parser,
1318 XML_StartDoctypeDeclHandler start,
1319 XML_EndDoctypeDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001320{
1321 startDoctypeDeclHandler = start;
1322 endDoctypeDeclHandler = end;
1323}
1324
Fred Drake08317ae2003-10-21 15:38:55 +00001325void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001326XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1327 XML_StartDoctypeDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001328 startDoctypeDeclHandler = start;
1329}
1330
Fred Drake08317ae2003-10-21 15:38:55 +00001331void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001332XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1333 XML_EndDoctypeDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001334 endDoctypeDeclHandler = end;
1335}
1336
Fred Drake08317ae2003-10-21 15:38:55 +00001337void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001338XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1339 XML_UnparsedEntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001340{
1341 unparsedEntityDeclHandler = handler;
1342}
1343
Fred Drake08317ae2003-10-21 15:38:55 +00001344void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001345XML_SetNotationDeclHandler(XML_Parser parser,
1346 XML_NotationDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001347{
1348 notationDeclHandler = handler;
1349}
1350
Fred Drake08317ae2003-10-21 15:38:55 +00001351void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001352XML_SetNamespaceDeclHandler(XML_Parser parser,
1353 XML_StartNamespaceDeclHandler start,
1354 XML_EndNamespaceDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001355{
1356 startNamespaceDeclHandler = start;
1357 endNamespaceDeclHandler = end;
1358}
1359
Fred Drake08317ae2003-10-21 15:38:55 +00001360void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001361XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1362 XML_StartNamespaceDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001363 startNamespaceDeclHandler = start;
1364}
1365
Fred Drake08317ae2003-10-21 15:38:55 +00001366void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001367XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1368 XML_EndNamespaceDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001369 endNamespaceDeclHandler = end;
1370}
1371
Fred Drake08317ae2003-10-21 15:38:55 +00001372void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001373XML_SetNotStandaloneHandler(XML_Parser parser,
1374 XML_NotStandaloneHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001375{
1376 notStandaloneHandler = handler;
1377}
1378
Fred Drake08317ae2003-10-21 15:38:55 +00001379void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001380XML_SetExternalEntityRefHandler(XML_Parser parser,
1381 XML_ExternalEntityRefHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001382{
1383 externalEntityRefHandler = handler;
1384}
1385
Fred Drake08317ae2003-10-21 15:38:55 +00001386void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001387XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001388{
1389 if (arg)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001390 externalEntityRefHandlerArg = (XML_Parser)arg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001391 else
1392 externalEntityRefHandlerArg = parser;
1393}
1394
Fred Drake08317ae2003-10-21 15:38:55 +00001395void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001396XML_SetSkippedEntityHandler(XML_Parser parser,
1397 XML_SkippedEntityHandler handler)
1398{
1399 skippedEntityHandler = handler;
1400}
1401
Fred Drake08317ae2003-10-21 15:38:55 +00001402void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001403XML_SetUnknownEncodingHandler(XML_Parser parser,
1404 XML_UnknownEncodingHandler handler,
1405 void *data)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001406{
1407 unknownEncodingHandler = handler;
1408 unknownEncodingHandlerData = data;
1409}
1410
Fred Drake08317ae2003-10-21 15:38:55 +00001411void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001412XML_SetElementDeclHandler(XML_Parser parser,
1413 XML_ElementDeclHandler eldecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001414{
1415 elementDeclHandler = eldecl;
1416}
1417
Fred Drake08317ae2003-10-21 15:38:55 +00001418void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001419XML_SetAttlistDeclHandler(XML_Parser parser,
1420 XML_AttlistDeclHandler attdecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001421{
1422 attlistDeclHandler = attdecl;
1423}
1424
Fred Drake08317ae2003-10-21 15:38:55 +00001425void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001426XML_SetEntityDeclHandler(XML_Parser parser,
1427 XML_EntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001428{
1429 entityDeclHandler = handler;
1430}
1431
Fred Drake08317ae2003-10-21 15:38:55 +00001432void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001433XML_SetXmlDeclHandler(XML_Parser parser,
1434 XML_XmlDeclHandler handler) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001435 xmlDeclHandler = handler;
1436}
1437
Fred Drake08317ae2003-10-21 15:38:55 +00001438int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001439XML_SetParamEntityParsing(XML_Parser parser,
1440 enum XML_ParamEntityParsing peParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001441{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001442 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Trent Mickf08d6632006-06-19 23:21:25 +00001443 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001444 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001445#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001446 paramEntityParsing = peParsing;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001447 return 1;
1448#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001449 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001450#endif
1451}
1452
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001453int XMLCALL
1454XML_SetHashSalt(XML_Parser parser,
1455 unsigned long hash_salt)
1456{
1457 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1458 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1459 return 0;
1460 hash_secret_salt = hash_salt;
1461 return 1;
1462}
1463
Fred Drake08317ae2003-10-21 15:38:55 +00001464enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001465XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001466{
Trent Mickf08d6632006-06-19 23:21:25 +00001467 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001468 case XML_SUSPENDED:
1469 errorCode = XML_ERROR_SUSPENDED;
1470 return XML_STATUS_ERROR;
1471 case XML_FINISHED:
1472 errorCode = XML_ERROR_FINISHED;
1473 return XML_STATUS_ERROR;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001474 case XML_INITIALIZED:
1475 if (parentParser == NULL && !startParsing(parser)) {
1476 errorCode = XML_ERROR_NO_MEMORY;
1477 return XML_STATUS_ERROR;
1478 }
Fred Drake31d485c2004-08-03 07:06:22 +00001479 default:
Trent Mickf08d6632006-06-19 23:21:25 +00001480 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001481 }
1482
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001483 if (len == 0) {
Trent Mickf08d6632006-06-19 23:21:25 +00001484 ps_finalBuffer = (XML_Bool)isFinal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001485 if (!isFinal)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001486 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001487 positionPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001488 parseEndPtr = bufferEnd;
1489
1490 /* If data are left over from last buffer, and we now know that these
1491 data are the final chunk of input, then we have to check them again
Trent Mickf08d6632006-06-19 23:21:25 +00001492 to detect errors based on that fact.
Fred Drake31d485c2004-08-03 07:06:22 +00001493 */
1494 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1495
1496 if (errorCode == XML_ERROR_NONE) {
Trent Mickf08d6632006-06-19 23:21:25 +00001497 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001498 case XML_SUSPENDED:
1499 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1500 positionPtr = bufferPtr;
1501 return XML_STATUS_SUSPENDED;
1502 case XML_INITIALIZED:
1503 case XML_PARSING:
Trent Mickf08d6632006-06-19 23:21:25 +00001504 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001505 /* fall through */
1506 default:
1507 return XML_STATUS_OK;
1508 }
1509 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001510 eventEndPtr = eventPtr;
1511 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001512 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001513 }
1514#ifndef XML_CONTEXT_BYTES
1515 else if (bufferPtr == bufferEnd) {
1516 const char *end;
1517 int nLeftOver;
Fred Drake31d485c2004-08-03 07:06:22 +00001518 enum XML_Error result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001519 parseEndByteIndex += len;
1520 positionPtr = s;
Trent Mickf08d6632006-06-19 23:21:25 +00001521 ps_finalBuffer = (XML_Bool)isFinal;
Fred Drake31d485c2004-08-03 07:06:22 +00001522
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001523 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
Fred Drake31d485c2004-08-03 07:06:22 +00001524
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001525 if (errorCode != XML_ERROR_NONE) {
1526 eventEndPtr = eventPtr;
1527 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001528 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001529 }
Fred Drake31d485c2004-08-03 07:06:22 +00001530 else {
Trent Mickf08d6632006-06-19 23:21:25 +00001531 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001532 case XML_SUSPENDED:
1533 result = XML_STATUS_SUSPENDED;
1534 break;
1535 case XML_INITIALIZED:
1536 case XML_PARSING:
Fred Drake31d485c2004-08-03 07:06:22 +00001537 if (isFinal) {
Trent Mickf08d6632006-06-19 23:21:25 +00001538 ps_parsing = XML_FINISHED;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001539 return XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001540 }
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001541 /* fall through */
1542 default:
1543 result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001544 }
1545 }
1546
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001547 XmlUpdatePosition(encoding, positionPtr, end, &position);
1548 nLeftOver = s + len - end;
1549 if (nLeftOver) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001550 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1551 /* FIXME avoid integer overflow */
1552 char *temp;
1553 temp = (buffer == NULL
1554 ? (char *)MALLOC(len * 2)
1555 : (char *)REALLOC(buffer, len * 2));
1556 if (temp == NULL) {
1557 errorCode = XML_ERROR_NO_MEMORY;
1558 return XML_STATUS_ERROR;
1559 }
1560 buffer = temp;
1561 if (!buffer) {
1562 errorCode = XML_ERROR_NO_MEMORY;
1563 eventPtr = eventEndPtr = NULL;
1564 processor = errorProcessor;
1565 return XML_STATUS_ERROR;
1566 }
1567 bufferLim = buffer + len * 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001568 }
1569 memcpy(buffer, end, nLeftOver);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001570 }
Trent Mickf08d6632006-06-19 23:21:25 +00001571 bufferPtr = buffer;
1572 bufferEnd = buffer + nLeftOver;
1573 positionPtr = bufferPtr;
1574 parseEndPtr = bufferEnd;
1575 eventPtr = bufferPtr;
1576 eventEndPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001577 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001578 }
1579#endif /* not defined XML_CONTEXT_BYTES */
1580 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001581 void *buff = XML_GetBuffer(parser, len);
1582 if (buff == NULL)
1583 return XML_STATUS_ERROR;
1584 else {
1585 memcpy(buff, s, len);
1586 return XML_ParseBuffer(parser, len, isFinal);
1587 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001588 }
1589}
1590
Fred Drake08317ae2003-10-21 15:38:55 +00001591enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001592XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001593{
Fred Drake31d485c2004-08-03 07:06:22 +00001594 const char *start;
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001595 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001596
Trent Mickf08d6632006-06-19 23:21:25 +00001597 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001598 case XML_SUSPENDED:
1599 errorCode = XML_ERROR_SUSPENDED;
1600 return XML_STATUS_ERROR;
1601 case XML_FINISHED:
1602 errorCode = XML_ERROR_FINISHED;
1603 return XML_STATUS_ERROR;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001604 case XML_INITIALIZED:
1605 if (parentParser == NULL && !startParsing(parser)) {
1606 errorCode = XML_ERROR_NO_MEMORY;
1607 return XML_STATUS_ERROR;
1608 }
Fred Drake31d485c2004-08-03 07:06:22 +00001609 default:
Trent Mickf08d6632006-06-19 23:21:25 +00001610 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001611 }
1612
1613 start = bufferPtr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001614 positionPtr = start;
1615 bufferEnd += len;
Fred Drake31d485c2004-08-03 07:06:22 +00001616 parseEndPtr = bufferEnd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001617 parseEndByteIndex += len;
Trent Mickf08d6632006-06-19 23:21:25 +00001618 ps_finalBuffer = (XML_Bool)isFinal;
Fred Drake31d485c2004-08-03 07:06:22 +00001619
1620 errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1621
1622 if (errorCode != XML_ERROR_NONE) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001623 eventEndPtr = eventPtr;
1624 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001625 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001626 }
Fred Drake31d485c2004-08-03 07:06:22 +00001627 else {
Trent Mickf08d6632006-06-19 23:21:25 +00001628 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001629 case XML_SUSPENDED:
1630 result = XML_STATUS_SUSPENDED;
1631 break;
1632 case XML_INITIALIZED:
1633 case XML_PARSING:
1634 if (isFinal) {
Trent Mickf08d6632006-06-19 23:21:25 +00001635 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001636 return result;
1637 }
1638 default: ; /* should not happen */
1639 }
1640 }
1641
1642 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1643 positionPtr = bufferPtr;
1644 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001645}
1646
Fred Drake08317ae2003-10-21 15:38:55 +00001647void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001648XML_GetBuffer(XML_Parser parser, int len)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001649{
Trent Mickf08d6632006-06-19 23:21:25 +00001650 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001651 case XML_SUSPENDED:
1652 errorCode = XML_ERROR_SUSPENDED;
1653 return NULL;
1654 case XML_FINISHED:
1655 errorCode = XML_ERROR_FINISHED;
1656 return NULL;
1657 default: ;
1658 }
1659
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001660 if (len > bufferLim - bufferEnd) {
1661 /* FIXME avoid integer overflow */
Trent Mickf08d6632006-06-19 23:21:25 +00001662 int neededSize = len + (int)(bufferEnd - bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001663#ifdef XML_CONTEXT_BYTES
Trent Mickf08d6632006-06-19 23:21:25 +00001664 int keep = (int)(bufferPtr - buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001665
1666 if (keep > XML_CONTEXT_BYTES)
1667 keep = XML_CONTEXT_BYTES;
1668 neededSize += keep;
1669#endif /* defined XML_CONTEXT_BYTES */
1670 if (neededSize <= bufferLim - buffer) {
1671#ifdef XML_CONTEXT_BYTES
1672 if (keep < bufferPtr - buffer) {
Trent Mickf08d6632006-06-19 23:21:25 +00001673 int offset = (int)(bufferPtr - buffer) - keep;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001674 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1675 bufferEnd -= offset;
1676 bufferPtr -= offset;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001677 }
1678#else
1679 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1680 bufferEnd = buffer + (bufferEnd - bufferPtr);
1681 bufferPtr = buffer;
1682#endif /* not defined XML_CONTEXT_BYTES */
1683 }
1684 else {
1685 char *newBuf;
Trent Mickf08d6632006-06-19 23:21:25 +00001686 int bufferSize = (int)(bufferLim - bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001687 if (bufferSize == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001688 bufferSize = INIT_BUFFER_SIZE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001689 do {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001690 bufferSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001691 } while (bufferSize < neededSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001692 newBuf = (char *)MALLOC(bufferSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001693 if (newBuf == 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001694 errorCode = XML_ERROR_NO_MEMORY;
1695 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001696 }
1697 bufferLim = newBuf + bufferSize;
1698#ifdef XML_CONTEXT_BYTES
1699 if (bufferPtr) {
Trent Mickf08d6632006-06-19 23:21:25 +00001700 int keep = (int)(bufferPtr - buffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001701 if (keep > XML_CONTEXT_BYTES)
1702 keep = XML_CONTEXT_BYTES;
1703 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1704 FREE(buffer);
1705 buffer = newBuf;
1706 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1707 bufferPtr = buffer + keep;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001708 }
1709 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001710 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1711 bufferPtr = buffer = newBuf;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001712 }
1713#else
1714 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001715 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1716 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001717 }
1718 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1719 bufferPtr = buffer = newBuf;
1720#endif /* not defined XML_CONTEXT_BYTES */
1721 }
1722 }
1723 return bufferEnd;
1724}
1725
Fred Drake31d485c2004-08-03 07:06:22 +00001726enum XML_Status XMLCALL
1727XML_StopParser(XML_Parser parser, XML_Bool resumable)
1728{
Trent Mickf08d6632006-06-19 23:21:25 +00001729 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001730 case XML_SUSPENDED:
1731 if (resumable) {
1732 errorCode = XML_ERROR_SUSPENDED;
1733 return XML_STATUS_ERROR;
1734 }
Trent Mickf08d6632006-06-19 23:21:25 +00001735 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001736 break;
1737 case XML_FINISHED:
1738 errorCode = XML_ERROR_FINISHED;
1739 return XML_STATUS_ERROR;
1740 default:
1741 if (resumable) {
1742#ifdef XML_DTD
1743 if (isParamEntity) {
1744 errorCode = XML_ERROR_SUSPEND_PE;
1745 return XML_STATUS_ERROR;
1746 }
1747#endif
Trent Mickf08d6632006-06-19 23:21:25 +00001748 ps_parsing = XML_SUSPENDED;
Fred Drake31d485c2004-08-03 07:06:22 +00001749 }
1750 else
Trent Mickf08d6632006-06-19 23:21:25 +00001751 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001752 }
1753 return XML_STATUS_OK;
1754}
1755
1756enum XML_Status XMLCALL
1757XML_ResumeParser(XML_Parser parser)
1758{
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001759 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001760
Trent Mickf08d6632006-06-19 23:21:25 +00001761 if (ps_parsing != XML_SUSPENDED) {
Fred Drake31d485c2004-08-03 07:06:22 +00001762 errorCode = XML_ERROR_NOT_SUSPENDED;
1763 return XML_STATUS_ERROR;
1764 }
Trent Mickf08d6632006-06-19 23:21:25 +00001765 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001766
1767 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1768
1769 if (errorCode != XML_ERROR_NONE) {
1770 eventEndPtr = eventPtr;
1771 processor = errorProcessor;
1772 return XML_STATUS_ERROR;
1773 }
1774 else {
Trent Mickf08d6632006-06-19 23:21:25 +00001775 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001776 case XML_SUSPENDED:
1777 result = XML_STATUS_SUSPENDED;
1778 break;
1779 case XML_INITIALIZED:
1780 case XML_PARSING:
Trent Mickf08d6632006-06-19 23:21:25 +00001781 if (ps_finalBuffer) {
1782 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001783 return result;
1784 }
1785 default: ;
1786 }
1787 }
1788
1789 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1790 positionPtr = bufferPtr;
1791 return result;
1792}
1793
1794void XMLCALL
1795XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1796{
1797 assert(status != NULL);
1798 *status = parser->m_parsingStatus;
1799}
1800
Fred Drake08317ae2003-10-21 15:38:55 +00001801enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001802XML_GetErrorCode(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001803{
1804 return errorCode;
1805}
1806
Trent Mickf08d6632006-06-19 23:21:25 +00001807XML_Index XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001808XML_GetCurrentByteIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001809{
1810 if (eventPtr)
1811 return parseEndByteIndex - (parseEndPtr - eventPtr);
1812 return -1;
1813}
1814
Fred Drake08317ae2003-10-21 15:38:55 +00001815int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001816XML_GetCurrentByteCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001817{
1818 if (eventEndPtr && eventPtr)
Trent Mickf08d6632006-06-19 23:21:25 +00001819 return (int)(eventEndPtr - eventPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001820 return 0;
1821}
1822
Fred Drake08317ae2003-10-21 15:38:55 +00001823const char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001824XML_GetInputContext(XML_Parser parser, int *offset, int *size)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001825{
1826#ifdef XML_CONTEXT_BYTES
1827 if (eventPtr && buffer) {
Trent Mickf08d6632006-06-19 23:21:25 +00001828 *offset = (int)(eventPtr - buffer);
1829 *size = (int)(bufferEnd - buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001830 return buffer;
1831 }
1832#endif /* defined XML_CONTEXT_BYTES */
1833 return (char *) 0;
1834}
1835
Trent Mickf08d6632006-06-19 23:21:25 +00001836XML_Size XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001837XML_GetCurrentLineNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001838{
Fred Drake31d485c2004-08-03 07:06:22 +00001839 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001840 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1841 positionPtr = eventPtr;
1842 }
1843 return position.lineNumber + 1;
1844}
1845
Trent Mickf08d6632006-06-19 23:21:25 +00001846XML_Size XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001847XML_GetCurrentColumnNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001848{
Fred Drake31d485c2004-08-03 07:06:22 +00001849 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001850 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1851 positionPtr = eventPtr;
1852 }
1853 return position.columnNumber;
1854}
1855
Fred Drake08317ae2003-10-21 15:38:55 +00001856void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001857XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1858{
1859 FREE(model);
1860}
1861
Fred Drake08317ae2003-10-21 15:38:55 +00001862void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001863XML_MemMalloc(XML_Parser parser, size_t size)
1864{
1865 return MALLOC(size);
1866}
1867
Fred Drake08317ae2003-10-21 15:38:55 +00001868void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001869XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1870{
1871 return REALLOC(ptr, size);
1872}
1873
Fred Drake08317ae2003-10-21 15:38:55 +00001874void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001875XML_MemFree(XML_Parser parser, void *ptr)
1876{
1877 FREE(ptr);
1878}
1879
Fred Drake08317ae2003-10-21 15:38:55 +00001880void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001881XML_DefaultCurrent(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001882{
1883 if (defaultHandler) {
1884 if (openInternalEntities)
1885 reportDefault(parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001886 internalEncoding,
1887 openInternalEntities->internalEventPtr,
1888 openInternalEntities->internalEventEndPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001889 else
1890 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1891 }
1892}
1893
Fred Drake08317ae2003-10-21 15:38:55 +00001894const XML_LChar * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001895XML_ErrorString(enum XML_Error code)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001896{
Trent Mickf08d6632006-06-19 23:21:25 +00001897 static const XML_LChar* const message[] = {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001898 0,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001899 XML_L("out of memory"),
1900 XML_L("syntax error"),
1901 XML_L("no element found"),
1902 XML_L("not well-formed (invalid token)"),
1903 XML_L("unclosed token"),
1904 XML_L("partial character"),
1905 XML_L("mismatched tag"),
1906 XML_L("duplicate attribute"),
1907 XML_L("junk after document element"),
1908 XML_L("illegal parameter entity reference"),
1909 XML_L("undefined entity"),
1910 XML_L("recursive entity reference"),
1911 XML_L("asynchronous entity"),
1912 XML_L("reference to invalid character number"),
1913 XML_L("reference to binary entity"),
1914 XML_L("reference to external entity in attribute"),
Trent Mickf08d6632006-06-19 23:21:25 +00001915 XML_L("XML or text declaration not at start of entity"),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001916 XML_L("unknown encoding"),
1917 XML_L("encoding specified in XML declaration is incorrect"),
1918 XML_L("unclosed CDATA section"),
1919 XML_L("error in processing external entity reference"),
1920 XML_L("document is not standalone"),
1921 XML_L("unexpected parser state - please send a bug report"),
1922 XML_L("entity declared in parameter entity"),
1923 XML_L("requested feature requires XML_DTD support in Expat"),
Fred Drake08317ae2003-10-21 15:38:55 +00001924 XML_L("cannot change setting once parsing has begun"),
Fred Drake31d485c2004-08-03 07:06:22 +00001925 XML_L("unbound prefix"),
1926 XML_L("must not undeclare prefix"),
1927 XML_L("incomplete markup in parameter entity"),
1928 XML_L("XML declaration not well-formed"),
1929 XML_L("text declaration not well-formed"),
1930 XML_L("illegal character(s) in public id"),
1931 XML_L("parser suspended"),
1932 XML_L("parser not suspended"),
1933 XML_L("parsing aborted"),
1934 XML_L("parsing finished"),
Trent Mickf08d6632006-06-19 23:21:25 +00001935 XML_L("cannot suspend in external parameter entity"),
1936 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1937 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1938 XML_L("prefix must not be bound to one of the reserved namespace names")
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001939 };
1940 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1941 return message[code];
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001942 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001943}
1944
Fred Drake08317ae2003-10-21 15:38:55 +00001945const XML_LChar * XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001946XML_ExpatVersion(void) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001947
1948 /* V1 is used to string-ize the version number. However, it would
1949 string-ize the actual version macro *names* unless we get them
1950 substituted before being passed to V1. CPP is defined to expand
1951 a macro, then rescan for more expansions. Thus, we use V2 to expand
1952 the version macros, then CPP will expand the resulting V1() macro
1953 with the correct numerals. */
1954 /* ### I'm assuming cpp is portable in this respect... */
1955
1956#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1957#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1958
1959 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1960
1961#undef V1
1962#undef V2
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001963}
1964
Fred Drake08317ae2003-10-21 15:38:55 +00001965XML_Expat_Version XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001966XML_ExpatVersionInfo(void)
1967{
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001968 XML_Expat_Version version;
1969
1970 version.major = XML_MAJOR_VERSION;
1971 version.minor = XML_MINOR_VERSION;
1972 version.micro = XML_MICRO_VERSION;
1973
1974 return version;
1975}
1976
Fred Drake08317ae2003-10-21 15:38:55 +00001977const XML_Feature * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001978XML_GetFeatureList(void)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001979{
Trent Mickf08d6632006-06-19 23:21:25 +00001980 static const XML_Feature features[] = {
1981 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
1982 sizeof(XML_Char)},
1983 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
1984 sizeof(XML_LChar)},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001985#ifdef XML_UNICODE
Fred Drake08317ae2003-10-21 15:38:55 +00001986 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001987#endif
1988#ifdef XML_UNICODE_WCHAR_T
Fred Drake08317ae2003-10-21 15:38:55 +00001989 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001990#endif
1991#ifdef XML_DTD
Fred Drake08317ae2003-10-21 15:38:55 +00001992 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001993#endif
1994#ifdef XML_CONTEXT_BYTES
1995 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1996 XML_CONTEXT_BYTES},
1997#endif
1998#ifdef XML_MIN_SIZE
Fred Drake08317ae2003-10-21 15:38:55 +00001999 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002000#endif
Trent Mickf08d6632006-06-19 23:21:25 +00002001#ifdef XML_NS
2002 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
2003#endif
Fred Drake08317ae2003-10-21 15:38:55 +00002004 {XML_FEATURE_END, NULL, 0}
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002005 };
2006
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002007 return features;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002008}
2009
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002010/* Initially tag->rawName always points into the parse buffer;
2011 for those TAG instances opened while the current parse buffer was
2012 processed, and not yet closed, we need to store tag->rawName in a more
2013 permanent location, since the parse buffer is about to be discarded.
2014*/
2015static XML_Bool
2016storeRawNames(XML_Parser parser)
2017{
2018 TAG *tag = tagStack;
2019 while (tag) {
2020 int bufSize;
2021 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2022 char *rawNameBuf = tag->buf + nameLen;
2023 /* Stop if already stored. Since tagStack is a stack, we can stop
2024 at the first entry that has already been copied; everything
2025 below it in the stack is already been accounted for in a
2026 previous call to this function.
2027 */
2028 if (tag->rawName == rawNameBuf)
2029 break;
2030 /* For re-use purposes we need to ensure that the
2031 size of tag->buf is a multiple of sizeof(XML_Char).
2032 */
2033 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2034 if (bufSize > tag->bufEnd - tag->buf) {
2035 char *temp = (char *)REALLOC(tag->buf, bufSize);
2036 if (temp == NULL)
2037 return XML_FALSE;
2038 /* if tag->name.str points to tag->buf (only when namespace
2039 processing is off) then we have to update it
2040 */
2041 if (tag->name.str == (XML_Char *)tag->buf)
2042 tag->name.str = (XML_Char *)temp;
2043 /* if tag->name.localPart is set (when namespace processing is on)
2044 then update it as well, since it will always point into tag->buf
2045 */
2046 if (tag->name.localPart)
2047 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2048 (XML_Char *)tag->buf);
2049 tag->buf = temp;
2050 tag->bufEnd = temp + bufSize;
2051 rawNameBuf = temp + nameLen;
2052 }
2053 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2054 tag->rawName = rawNameBuf;
2055 tag = tag->parent;
2056 }
2057 return XML_TRUE;
2058}
2059
2060static enum XML_Error PTRCALL
2061contentProcessor(XML_Parser parser,
2062 const char *start,
2063 const char *end,
2064 const char **endPtr)
2065{
Fred Drake31d485c2004-08-03 07:06:22 +00002066 enum XML_Error result = doContent(parser, 0, encoding, start, end,
Trent Mickf08d6632006-06-19 23:21:25 +00002067 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00002068 if (result == XML_ERROR_NONE) {
2069 if (!storeRawNames(parser))
2070 return XML_ERROR_NO_MEMORY;
2071 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002072 return result;
2073}
2074
2075static enum XML_Error PTRCALL
2076externalEntityInitProcessor(XML_Parser parser,
2077 const char *start,
2078 const char *end,
2079 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002080{
2081 enum XML_Error result = initializeEncoding(parser);
2082 if (result != XML_ERROR_NONE)
2083 return result;
2084 processor = externalEntityInitProcessor2;
2085 return externalEntityInitProcessor2(parser, start, end, endPtr);
2086}
2087
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002088static enum XML_Error PTRCALL
2089externalEntityInitProcessor2(XML_Parser parser,
2090 const char *start,
2091 const char *end,
2092 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002093{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002094 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002095 int tok = XmlContentTok(encoding, start, end, &next);
2096 switch (tok) {
2097 case XML_TOK_BOM:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002098 /* If we are at the end of the buffer, this would cause the next stage,
2099 i.e. externalEntityInitProcessor3, to pass control directly to
2100 doContent (by detecting XML_TOK_NONE) without processing any xml text
2101 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2102 */
Trent Mickf08d6632006-06-19 23:21:25 +00002103 if (next == end && !ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002104 *endPtr = next;
2105 return XML_ERROR_NONE;
2106 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002107 start = next;
2108 break;
2109 case XML_TOK_PARTIAL:
Trent Mickf08d6632006-06-19 23:21:25 +00002110 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002111 *endPtr = start;
2112 return XML_ERROR_NONE;
2113 }
2114 eventPtr = start;
2115 return XML_ERROR_UNCLOSED_TOKEN;
2116 case XML_TOK_PARTIAL_CHAR:
Trent Mickf08d6632006-06-19 23:21:25 +00002117 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002118 *endPtr = start;
2119 return XML_ERROR_NONE;
2120 }
2121 eventPtr = start;
2122 return XML_ERROR_PARTIAL_CHAR;
2123 }
2124 processor = externalEntityInitProcessor3;
2125 return externalEntityInitProcessor3(parser, start, end, endPtr);
2126}
2127
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002128static enum XML_Error PTRCALL
2129externalEntityInitProcessor3(XML_Parser parser,
2130 const char *start,
2131 const char *end,
2132 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002133{
Fred Drake31d485c2004-08-03 07:06:22 +00002134 int tok;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002135 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Fred Drake31d485c2004-08-03 07:06:22 +00002136 eventPtr = start;
2137 tok = XmlContentTok(encoding, start, end, &next);
2138 eventEndPtr = next;
2139
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002140 switch (tok) {
2141 case XML_TOK_XML_DECL:
2142 {
Fred Drake31d485c2004-08-03 07:06:22 +00002143 enum XML_Error result;
2144 result = processXmlDecl(parser, 1, start, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002145 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002146 return result;
Trent Mickf08d6632006-06-19 23:21:25 +00002147 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00002148 case XML_SUSPENDED:
2149 *endPtr = next;
2150 return XML_ERROR_NONE;
2151 case XML_FINISHED:
2152 return XML_ERROR_ABORTED;
2153 default:
2154 start = next;
2155 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002156 }
2157 break;
2158 case XML_TOK_PARTIAL:
Trent Mickf08d6632006-06-19 23:21:25 +00002159 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002160 *endPtr = start;
2161 return XML_ERROR_NONE;
2162 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002163 return XML_ERROR_UNCLOSED_TOKEN;
2164 case XML_TOK_PARTIAL_CHAR:
Trent Mickf08d6632006-06-19 23:21:25 +00002165 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002166 *endPtr = start;
2167 return XML_ERROR_NONE;
2168 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002169 return XML_ERROR_PARTIAL_CHAR;
2170 }
2171 processor = externalEntityContentProcessor;
2172 tagLevel = 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002173 return externalEntityContentProcessor(parser, start, end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002174}
2175
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002176static enum XML_Error PTRCALL
2177externalEntityContentProcessor(XML_Parser parser,
2178 const char *start,
2179 const char *end,
2180 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002181{
Fred Drake31d485c2004-08-03 07:06:22 +00002182 enum XML_Error result = doContent(parser, 1, encoding, start, end,
Trent Mickf08d6632006-06-19 23:21:25 +00002183 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00002184 if (result == XML_ERROR_NONE) {
2185 if (!storeRawNames(parser))
2186 return XML_ERROR_NO_MEMORY;
2187 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002188 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002189}
2190
2191static enum XML_Error
2192doContent(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002193 int startTagLevel,
2194 const ENCODING *enc,
2195 const char *s,
2196 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00002197 const char **nextPtr,
2198 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002199{
Fred Drake31d485c2004-08-03 07:06:22 +00002200 /* save one level of indirection */
2201 DTD * const dtd = _dtd;
2202
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002203 const char **eventPP;
2204 const char **eventEndPP;
2205 if (enc == encoding) {
2206 eventPP = &eventPtr;
2207 eventEndPP = &eventEndPtr;
2208 }
2209 else {
2210 eventPP = &(openInternalEntities->internalEventPtr);
2211 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2212 }
2213 *eventPP = s;
Fred Drake31d485c2004-08-03 07:06:22 +00002214
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002215 for (;;) {
2216 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2217 int tok = XmlContentTok(enc, s, end, &next);
2218 *eventEndPP = next;
2219 switch (tok) {
2220 case XML_TOK_TRAILING_CR:
Fred Drake31d485c2004-08-03 07:06:22 +00002221 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002222 *nextPtr = s;
2223 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002224 }
2225 *eventEndPP = end;
2226 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002227 XML_Char c = 0xA;
2228 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002229 }
2230 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002231 reportDefault(parser, enc, s, end);
Fred Drake31d485c2004-08-03 07:06:22 +00002232 /* We are at the end of the final buffer, should we check for
2233 XML_SUSPENDED, XML_FINISHED?
2234 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002235 if (startTagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002236 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002237 if (tagLevel != startTagLevel)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002238 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002239 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002240 return XML_ERROR_NONE;
2241 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00002242 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002243 *nextPtr = s;
2244 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002245 }
2246 if (startTagLevel > 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002247 if (tagLevel != startTagLevel)
2248 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002249 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002250 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002251 }
2252 return XML_ERROR_NO_ELEMENTS;
2253 case XML_TOK_INVALID:
2254 *eventPP = next;
2255 return XML_ERROR_INVALID_TOKEN;
2256 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00002257 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002258 *nextPtr = s;
2259 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002260 }
2261 return XML_ERROR_UNCLOSED_TOKEN;
2262 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00002263 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002264 *nextPtr = s;
2265 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002266 }
2267 return XML_ERROR_PARTIAL_CHAR;
2268 case XML_TOK_ENTITY_REF:
2269 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002270 const XML_Char *name;
2271 ENTITY *entity;
2272 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2273 s + enc->minBytesPerChar,
2274 next - enc->minBytesPerChar);
2275 if (ch) {
2276 if (characterDataHandler)
2277 characterDataHandler(handlerArg, &ch, 1);
2278 else if (defaultHandler)
2279 reportDefault(parser, enc, s, next);
2280 break;
2281 }
2282 name = poolStoreString(&dtd->pool, enc,
2283 s + enc->minBytesPerChar,
2284 next - enc->minBytesPerChar);
2285 if (!name)
2286 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002287 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002288 poolDiscard(&dtd->pool);
2289 /* First, determine if a check for an existing declaration is needed;
2290 if yes, check that the entity exists, and that it is internal,
2291 otherwise call the skipped entity or default handler.
2292 */
2293 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2294 if (!entity)
2295 return XML_ERROR_UNDEFINED_ENTITY;
2296 else if (!entity->is_internal)
2297 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2298 }
2299 else if (!entity) {
2300 if (skippedEntityHandler)
2301 skippedEntityHandler(handlerArg, name, 0);
2302 else if (defaultHandler)
2303 reportDefault(parser, enc, s, next);
2304 break;
2305 }
2306 if (entity->open)
2307 return XML_ERROR_RECURSIVE_ENTITY_REF;
2308 if (entity->notation)
2309 return XML_ERROR_BINARY_ENTITY_REF;
2310 if (entity->textPtr) {
2311 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002312 if (!defaultExpandInternalEntities) {
2313 if (skippedEntityHandler)
2314 skippedEntityHandler(handlerArg, entity->name, 0);
2315 else if (defaultHandler)
2316 reportDefault(parser, enc, s, next);
2317 break;
2318 }
Fred Drake31d485c2004-08-03 07:06:22 +00002319 result = processInternalEntity(parser, entity, XML_FALSE);
2320 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002321 return result;
2322 }
2323 else if (externalEntityRefHandler) {
2324 const XML_Char *context;
2325 entity->open = XML_TRUE;
2326 context = getContext(parser);
2327 entity->open = XML_FALSE;
2328 if (!context)
2329 return XML_ERROR_NO_MEMORY;
Fred Drake31d485c2004-08-03 07:06:22 +00002330 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002331 context,
2332 entity->base,
2333 entity->systemId,
2334 entity->publicId))
2335 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2336 poolDiscard(&tempPool);
2337 }
2338 else if (defaultHandler)
2339 reportDefault(parser, enc, s, next);
2340 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002341 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002342 case XML_TOK_START_TAG_NO_ATTS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002343 /* fall through */
2344 case XML_TOK_START_TAG_WITH_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002345 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002346 TAG *tag;
2347 enum XML_Error result;
2348 XML_Char *toPtr;
2349 if (freeTagList) {
2350 tag = freeTagList;
2351 freeTagList = freeTagList->parent;
2352 }
2353 else {
2354 tag = (TAG *)MALLOC(sizeof(TAG));
2355 if (!tag)
2356 return XML_ERROR_NO_MEMORY;
2357 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2358 if (!tag->buf) {
2359 FREE(tag);
2360 return XML_ERROR_NO_MEMORY;
2361 }
2362 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2363 }
2364 tag->bindings = NULL;
2365 tag->parent = tagStack;
2366 tagStack = tag;
2367 tag->name.localPart = NULL;
2368 tag->name.prefix = NULL;
2369 tag->rawName = s + enc->minBytesPerChar;
2370 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2371 ++tagLevel;
2372 {
2373 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2374 const char *fromPtr = tag->rawName;
2375 toPtr = (XML_Char *)tag->buf;
2376 for (;;) {
2377 int bufSize;
2378 int convLen;
2379 XmlConvert(enc,
2380 &fromPtr, rawNameEnd,
2381 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
Trent Mickf08d6632006-06-19 23:21:25 +00002382 convLen = (int)(toPtr - (XML_Char *)tag->buf);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002383 if (fromPtr == rawNameEnd) {
2384 tag->name.strLen = convLen;
2385 break;
2386 }
Trent Mickf08d6632006-06-19 23:21:25 +00002387 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002388 {
2389 char *temp = (char *)REALLOC(tag->buf, bufSize);
2390 if (temp == NULL)
2391 return XML_ERROR_NO_MEMORY;
2392 tag->buf = temp;
2393 tag->bufEnd = temp + bufSize;
2394 toPtr = (XML_Char *)temp + convLen;
2395 }
2396 }
2397 }
2398 tag->name.str = (XML_Char *)tag->buf;
2399 *toPtr = XML_T('\0');
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002400 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2401 if (result)
2402 return result;
2403 if (startElementHandler)
2404 startElementHandler(handlerArg, tag->name.str,
2405 (const XML_Char **)atts);
2406 else if (defaultHandler)
2407 reportDefault(parser, enc, s, next);
2408 poolClear(&tempPool);
2409 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002410 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002411 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002412 /* fall through */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002413 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2414 {
2415 const char *rawName = s + enc->minBytesPerChar;
2416 enum XML_Error result;
2417 BINDING *bindings = NULL;
2418 XML_Bool noElmHandlers = XML_TRUE;
2419 TAG_NAME name;
2420 name.str = poolStoreString(&tempPool, enc, rawName,
2421 rawName + XmlNameLength(enc, rawName));
2422 if (!name.str)
2423 return XML_ERROR_NO_MEMORY;
2424 poolFinish(&tempPool);
Fred Drake4faea012003-01-28 06:42:40 +00002425 result = storeAtts(parser, enc, s, &name, &bindings);
2426 if (result)
2427 return result;
2428 poolFinish(&tempPool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002429 if (startElementHandler) {
2430 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2431 noElmHandlers = XML_FALSE;
2432 }
2433 if (endElementHandler) {
2434 if (startElementHandler)
2435 *eventPP = *eventEndPP;
2436 endElementHandler(handlerArg, name.str);
2437 noElmHandlers = XML_FALSE;
2438 }
2439 if (noElmHandlers && defaultHandler)
2440 reportDefault(parser, enc, s, next);
2441 poolClear(&tempPool);
2442 while (bindings) {
2443 BINDING *b = bindings;
2444 if (endNamespaceDeclHandler)
2445 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2446 bindings = bindings->nextTagBinding;
2447 b->nextTagBinding = freeBindingList;
2448 freeBindingList = b;
2449 b->prefix->binding = b->prevPrefixBinding;
2450 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002451 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002452 if (tagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002453 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002454 break;
2455 case XML_TOK_END_TAG:
2456 if (tagLevel == startTagLevel)
2457 return XML_ERROR_ASYNC_ENTITY;
2458 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002459 int len;
2460 const char *rawName;
2461 TAG *tag = tagStack;
2462 tagStack = tag->parent;
2463 tag->parent = freeTagList;
2464 freeTagList = tag;
2465 rawName = s + enc->minBytesPerChar*2;
2466 len = XmlNameLength(enc, rawName);
2467 if (len != tag->rawNameLength
2468 || memcmp(tag->rawName, rawName, len) != 0) {
2469 *eventPP = rawName;
2470 return XML_ERROR_TAG_MISMATCH;
2471 }
2472 --tagLevel;
2473 if (endElementHandler) {
2474 const XML_Char *localPart;
2475 const XML_Char *prefix;
2476 XML_Char *uri;
2477 localPart = tag->name.localPart;
2478 if (ns && localPart) {
2479 /* localPart and prefix may have been overwritten in
2480 tag->name.str, since this points to the binding->uri
2481 buffer which gets re-used; so we have to add them again
2482 */
2483 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2484 /* don't need to check for space - already done in storeAtts() */
2485 while (*localPart) *uri++ = *localPart++;
2486 prefix = (XML_Char *)tag->name.prefix;
2487 if (ns_triplets && prefix) {
2488 *uri++ = namespaceSeparator;
2489 while (*prefix) *uri++ = *prefix++;
2490 }
2491 *uri = XML_T('\0');
2492 }
2493 endElementHandler(handlerArg, tag->name.str);
2494 }
2495 else if (defaultHandler)
2496 reportDefault(parser, enc, s, next);
2497 while (tag->bindings) {
2498 BINDING *b = tag->bindings;
2499 if (endNamespaceDeclHandler)
2500 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2501 tag->bindings = tag->bindings->nextTagBinding;
2502 b->nextTagBinding = freeBindingList;
2503 freeBindingList = b;
2504 b->prefix->binding = b->prevPrefixBinding;
2505 }
2506 if (tagLevel == 0)
2507 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002508 }
2509 break;
2510 case XML_TOK_CHAR_REF:
2511 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002512 int n = XmlCharRefNumber(enc, s);
2513 if (n < 0)
2514 return XML_ERROR_BAD_CHAR_REF;
2515 if (characterDataHandler) {
2516 XML_Char buf[XML_ENCODE_MAX];
2517 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2518 }
2519 else if (defaultHandler)
2520 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002521 }
2522 break;
2523 case XML_TOK_XML_DECL:
2524 return XML_ERROR_MISPLACED_XML_PI;
2525 case XML_TOK_DATA_NEWLINE:
2526 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002527 XML_Char c = 0xA;
2528 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002529 }
2530 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002531 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002532 break;
2533 case XML_TOK_CDATA_SECT_OPEN:
2534 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002535 enum XML_Error result;
2536 if (startCdataSectionHandler)
2537 startCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002538#if 0
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002539 /* Suppose you doing a transformation on a document that involves
2540 changing only the character data. You set up a defaultHandler
2541 and a characterDataHandler. The defaultHandler simply copies
2542 characters through. The characterDataHandler does the
2543 transformation and writes the characters out escaping them as
2544 necessary. This case will fail to work if we leave out the
2545 following two lines (because & and < inside CDATA sections will
2546 be incorrectly escaped).
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002547
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002548 However, now we have a start/endCdataSectionHandler, so it seems
2549 easier to let the user deal with this.
2550 */
2551 else if (characterDataHandler)
2552 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002553#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002554 else if (defaultHandler)
2555 reportDefault(parser, enc, s, next);
Fred Drake31d485c2004-08-03 07:06:22 +00002556 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2557 if (result != XML_ERROR_NONE)
2558 return result;
2559 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002560 processor = cdataSectionProcessor;
2561 return result;
2562 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002563 }
2564 break;
2565 case XML_TOK_TRAILING_RSQB:
Fred Drake31d485c2004-08-03 07:06:22 +00002566 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002567 *nextPtr = s;
2568 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002569 }
2570 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002571 if (MUST_CONVERT(enc, s)) {
2572 ICHAR *dataPtr = (ICHAR *)dataBuf;
2573 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2574 characterDataHandler(handlerArg, dataBuf,
Trent Mickf08d6632006-06-19 23:21:25 +00002575 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002576 }
2577 else
2578 characterDataHandler(handlerArg,
2579 (XML_Char *)s,
Trent Mickf08d6632006-06-19 23:21:25 +00002580 (int)((XML_Char *)end - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002581 }
2582 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002583 reportDefault(parser, enc, s, end);
Fred Drake31d485c2004-08-03 07:06:22 +00002584 /* We are at the end of the final buffer, should we check for
2585 XML_SUSPENDED, XML_FINISHED?
2586 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002587 if (startTagLevel == 0) {
2588 *eventPP = end;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002589 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002590 }
2591 if (tagLevel != startTagLevel) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002592 *eventPP = end;
2593 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002594 }
Fred Drake31d485c2004-08-03 07:06:22 +00002595 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002596 return XML_ERROR_NONE;
2597 case XML_TOK_DATA_CHARS:
2598 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002599 if (MUST_CONVERT(enc, s)) {
2600 for (;;) {
2601 ICHAR *dataPtr = (ICHAR *)dataBuf;
2602 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2603 *eventEndPP = s;
2604 characterDataHandler(handlerArg, dataBuf,
Trent Mickf08d6632006-06-19 23:21:25 +00002605 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002606 if (s == next)
2607 break;
2608 *eventPP = s;
2609 }
2610 }
2611 else
2612 characterDataHandler(handlerArg,
2613 (XML_Char *)s,
Trent Mickf08d6632006-06-19 23:21:25 +00002614 (int)((XML_Char *)next - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002615 }
2616 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002617 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002618 break;
2619 case XML_TOK_PI:
2620 if (!reportProcessingInstruction(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002621 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002622 break;
2623 case XML_TOK_COMMENT:
2624 if (!reportComment(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002625 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002626 break;
2627 default:
2628 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002629 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002630 break;
2631 }
2632 *eventPP = s = next;
Trent Mickf08d6632006-06-19 23:21:25 +00002633 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00002634 case XML_SUSPENDED:
2635 *nextPtr = next;
2636 return XML_ERROR_NONE;
2637 case XML_FINISHED:
2638 return XML_ERROR_ABORTED;
2639 default: ;
2640 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002641 }
2642 /* not reached */
2643}
2644
Fred Drake4faea012003-01-28 06:42:40 +00002645/* Precondition: all arguments must be non-NULL;
2646 Purpose:
2647 - normalize attributes
2648 - check attributes for well-formedness
2649 - generate namespace aware attribute names (URI, prefix)
2650 - build list of attributes for startElementHandler
2651 - default attributes
2652 - process namespace declarations (check and report them)
2653 - generate namespace aware element name (URI, prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002654*/
2655static enum XML_Error
2656storeAtts(XML_Parser parser, const ENCODING *enc,
2657 const char *attStr, TAG_NAME *tagNamePtr,
2658 BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002659{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002660 DTD * const dtd = _dtd; /* save one level of indirection */
Fred Drake08317ae2003-10-21 15:38:55 +00002661 ELEMENT_TYPE *elementType;
2662 int nDefaultAtts;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002663 const XML_Char **appAtts; /* the attribute list for the application */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002664 int attIndex = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002665 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002666 int i;
2667 int n;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002668 XML_Char *uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002669 int nPrefixes = 0;
2670 BINDING *binding;
2671 const XML_Char *localPart;
2672
2673 /* lookup the element type name */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002674 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
Fred Drake4faea012003-01-28 06:42:40 +00002675 if (!elementType) {
2676 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2677 if (!name)
2678 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002679 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
Fred Drake4faea012003-01-28 06:42:40 +00002680 sizeof(ELEMENT_TYPE));
2681 if (!elementType)
2682 return XML_ERROR_NO_MEMORY;
2683 if (ns && !setElementTypePrefix(parser, elementType))
2684 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002685 }
Fred Drake4faea012003-01-28 06:42:40 +00002686 nDefaultAtts = elementType->nDefaultAtts;
2687
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002688 /* get the attributes from the tokenizer */
2689 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2690 if (n + nDefaultAtts > attsSize) {
2691 int oldAttsSize = attsSize;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002692 ATTRIBUTE *temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002693 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002694 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2695 if (temp == NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002696 return XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002697 atts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002698 if (n > oldAttsSize)
2699 XmlGetAttributes(enc, attStr, n, atts);
2700 }
Fred Drake4faea012003-01-28 06:42:40 +00002701
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002702 appAtts = (const XML_Char **)atts;
2703 for (i = 0; i < n; i++) {
2704 /* add the name and value to the attribute list */
2705 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002706 atts[i].name
2707 + XmlNameLength(enc, atts[i].name));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002708 if (!attId)
2709 return XML_ERROR_NO_MEMORY;
Fred Drake08317ae2003-10-21 15:38:55 +00002710 /* Detect duplicate attributes by their QNames. This does not work when
2711 namespace processing is turned on and different prefixes for the same
2712 namespace are used. For this case we have a check further down.
2713 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002714 if ((attId->name)[-1]) {
2715 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002716 eventPtr = atts[i].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002717 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2718 }
2719 (attId->name)[-1] = 1;
2720 appAtts[attIndex++] = attId->name;
2721 if (!atts[i].normalized) {
2722 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002723 XML_Bool isCdata = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002724
2725 /* figure out whether declared as other than CDATA */
2726 if (attId->maybeTokenized) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002727 int j;
2728 for (j = 0; j < nDefaultAtts; j++) {
2729 if (attId == elementType->defaultAtts[j].id) {
2730 isCdata = elementType->defaultAtts[j].isCdata;
2731 break;
2732 }
2733 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002734 }
2735
2736 /* normalize the attribute value */
2737 result = storeAttributeValue(parser, enc, isCdata,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002738 atts[i].valuePtr, atts[i].valueEnd,
2739 &tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002740 if (result)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002741 return result;
Fred Drake4faea012003-01-28 06:42:40 +00002742 appAtts[attIndex] = poolStart(&tempPool);
2743 poolFinish(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002744 }
Fred Drake4faea012003-01-28 06:42:40 +00002745 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002746 /* the value did not need normalizing */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002747 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2748 atts[i].valueEnd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002749 if (appAtts[attIndex] == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002750 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002751 poolFinish(&tempPool);
2752 }
2753 /* handle prefixed attribute names */
Fred Drake4faea012003-01-28 06:42:40 +00002754 if (attId->prefix) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002755 if (attId->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002756 /* deal with namespace declarations here */
2757 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2758 appAtts[attIndex], bindingsPtr);
2759 if (result)
2760 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002761 --attIndex;
2762 }
2763 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002764 /* deal with other prefixed names later */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002765 attIndex++;
2766 nPrefixes++;
2767 (attId->name)[-1] = 2;
2768 }
2769 }
2770 else
2771 attIndex++;
2772 }
Fred Drake4faea012003-01-28 06:42:40 +00002773
2774 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2775 nSpecifiedAtts = attIndex;
2776 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2777 for (i = 0; i < attIndex; i += 2)
2778 if (appAtts[i] == elementType->idAtt->name) {
2779 idAttIndex = i;
2780 break;
2781 }
2782 }
2783 else
2784 idAttIndex = -1;
2785
2786 /* do attribute defaulting */
2787 for (i = 0; i < nDefaultAtts; i++) {
2788 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2789 if (!(da->id->name)[-1] && da->value) {
2790 if (da->id->prefix) {
2791 if (da->id->xmlns) {
2792 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2793 da->value, bindingsPtr);
2794 if (result)
2795 return result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002796 }
2797 else {
Fred Drake4faea012003-01-28 06:42:40 +00002798 (da->id->name)[-1] = 2;
2799 nPrefixes++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002800 appAtts[attIndex++] = da->id->name;
2801 appAtts[attIndex++] = da->value;
2802 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002803 }
Fred Drake4faea012003-01-28 06:42:40 +00002804 else {
2805 (da->id->name)[-1] = 1;
2806 appAtts[attIndex++] = da->id->name;
2807 appAtts[attIndex++] = da->value;
2808 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002809 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002810 }
Fred Drake4faea012003-01-28 06:42:40 +00002811 appAtts[attIndex] = 0;
2812
Fred Drake08317ae2003-10-21 15:38:55 +00002813 /* expand prefixed attribute names, check for duplicates,
2814 and clear flags that say whether attributes were specified */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002815 i = 0;
2816 if (nPrefixes) {
Fred Drake08317ae2003-10-21 15:38:55 +00002817 int j; /* hash table index */
2818 unsigned long version = nsAttsVersion;
2819 int nsAttsSize = (int)1 << nsAttsPower;
2820 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2821 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2822 NS_ATT *temp;
2823 /* hash table size must also be a power of 2 and >= 8 */
2824 while (nPrefixes >> nsAttsPower++);
2825 if (nsAttsPower < 3)
2826 nsAttsPower = 3;
2827 nsAttsSize = (int)1 << nsAttsPower;
2828 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2829 if (!temp)
2830 return XML_ERROR_NO_MEMORY;
2831 nsAtts = temp;
2832 version = 0; /* force re-initialization of nsAtts hash table */
2833 }
2834 /* using a version flag saves us from initializing nsAtts every time */
2835 if (!version) { /* initialize version flags when version wraps around */
2836 version = INIT_ATTS_VERSION;
2837 for (j = nsAttsSize; j != 0; )
2838 nsAtts[--j].version = version;
2839 }
2840 nsAttsVersion = --version;
2841
2842 /* expand prefixed names and check for duplicates */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002843 for (; i < attIndex; i += 2) {
Fred Drake08317ae2003-10-21 15:38:55 +00002844 const XML_Char *s = appAtts[i];
2845 if (s[-1] == 2) { /* prefixed */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002846 ATTRIBUTE_ID *id;
Fred Drake08317ae2003-10-21 15:38:55 +00002847 const BINDING *b;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002848 unsigned long uriHash = hash_secret_salt;
Fred Drake08317ae2003-10-21 15:38:55 +00002849 ((XML_Char *)s)[-1] = 0; /* clear flag */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002850 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
Neal Norwitz26a8abf2006-08-13 18:12:26 +00002851 if (!id)
2852 return XML_ERROR_NO_MEMORY;
Fred Drake08317ae2003-10-21 15:38:55 +00002853 b = id->prefix->binding;
2854 if (!b)
2855 return XML_ERROR_UNBOUND_PREFIX;
2856
2857 /* as we expand the name we also calculate its hash value */
2858 for (j = 0; j < b->uriLen; j++) {
2859 const XML_Char c = b->uri[j];
2860 if (!poolAppendChar(&tempPool, c))
2861 return XML_ERROR_NO_MEMORY;
2862 uriHash = CHAR_HASH(uriHash, c);
2863 }
2864 while (*s++ != XML_T(':'))
2865 ;
2866 do { /* copies null terminator */
2867 const XML_Char c = *s;
2868 if (!poolAppendChar(&tempPool, *s))
2869 return XML_ERROR_NO_MEMORY;
2870 uriHash = CHAR_HASH(uriHash, c);
2871 } while (*s++);
2872
2873 { /* Check hash table for duplicate of expanded name (uriName).
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002874 Derived from code in lookup(parser, HASH_TABLE *table, ...).
Fred Drake08317ae2003-10-21 15:38:55 +00002875 */
2876 unsigned char step = 0;
2877 unsigned long mask = nsAttsSize - 1;
2878 j = uriHash & mask; /* index into hash table */
2879 while (nsAtts[j].version == version) {
2880 /* for speed we compare stored hash values first */
2881 if (uriHash == nsAtts[j].hash) {
2882 const XML_Char *s1 = poolStart(&tempPool);
2883 const XML_Char *s2 = nsAtts[j].uriName;
2884 /* s1 is null terminated, but not s2 */
2885 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2886 if (*s1 == 0)
2887 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2888 }
2889 if (!step)
2890 step = PROBE_STEP(uriHash, mask, nsAttsPower);
Trent Mickf08d6632006-06-19 23:21:25 +00002891 j < step ? (j += nsAttsSize - step) : (j -= step);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002892 }
Fred Drake08317ae2003-10-21 15:38:55 +00002893 }
2894
2895 if (ns_triplets) { /* append namespace separator and prefix */
2896 tempPool.ptr[-1] = namespaceSeparator;
2897 s = b->prefix->name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002898 do {
2899 if (!poolAppendChar(&tempPool, *s))
2900 return XML_ERROR_NO_MEMORY;
2901 } while (*s++);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002902 }
Fred Drake08317ae2003-10-21 15:38:55 +00002903
2904 /* store expanded name in attribute list */
2905 s = poolStart(&tempPool);
2906 poolFinish(&tempPool);
2907 appAtts[i] = s;
2908
2909 /* fill empty slot with new version, uriName and hash value */
2910 nsAtts[j].version = version;
2911 nsAtts[j].hash = uriHash;
2912 nsAtts[j].uriName = s;
2913
Trent Mickf08d6632006-06-19 23:21:25 +00002914 if (!--nPrefixes) {
2915 i += 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002916 break;
Trent Mickf08d6632006-06-19 23:21:25 +00002917 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002918 }
Fred Drake08317ae2003-10-21 15:38:55 +00002919 else /* not prefixed */
2920 ((XML_Char *)s)[-1] = 0; /* clear flag */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002921 }
2922 }
Fred Drake08317ae2003-10-21 15:38:55 +00002923 /* clear flags for the remaining attributes */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002924 for (; i < attIndex; i += 2)
2925 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002926 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2927 binding->attId->name[-1] = 0;
Fred Drake4faea012003-01-28 06:42:40 +00002928
Fred Drake08317ae2003-10-21 15:38:55 +00002929 if (!ns)
2930 return XML_ERROR_NONE;
2931
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002932 /* expand the element type name */
2933 if (elementType->prefix) {
2934 binding = elementType->prefix->binding;
2935 if (!binding)
Fred Drake08317ae2003-10-21 15:38:55 +00002936 return XML_ERROR_UNBOUND_PREFIX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002937 localPart = tagNamePtr->str;
2938 while (*localPart++ != XML_T(':'))
2939 ;
2940 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002941 else if (dtd->defaultPrefix.binding) {
2942 binding = dtd->defaultPrefix.binding;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002943 localPart = tagNamePtr->str;
2944 }
2945 else
2946 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002947 prefixLen = 0;
Fred Drake08317ae2003-10-21 15:38:55 +00002948 if (ns_triplets && binding->prefix->name) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002949 for (; binding->prefix->name[prefixLen++];)
Trent Mickf08d6632006-06-19 23:21:25 +00002950 ; /* prefixLen includes null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002951 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002952 tagNamePtr->localPart = localPart;
2953 tagNamePtr->uriLen = binding->uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002954 tagNamePtr->prefix = binding->prefix->name;
2955 tagNamePtr->prefixLen = prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002956 for (i = 0; localPart[i++];)
Trent Mickf08d6632006-06-19 23:21:25 +00002957 ; /* i includes null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002958 n = i + binding->uriLen + prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002959 if (n > binding->uriAlloc) {
2960 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002961 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002962 if (!uri)
2963 return XML_ERROR_NO_MEMORY;
2964 binding->uriAlloc = n + EXPAND_SPARE;
2965 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2966 for (p = tagStack; p; p = p->parent)
2967 if (p->name.str == binding->uri)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002968 p->name.str = uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002969 FREE(binding->uri);
2970 binding->uri = uri;
2971 }
Trent Mickf08d6632006-06-19 23:21:25 +00002972 /* if namespaceSeparator != '\0' then uri includes it already */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002973 uri = binding->uri + binding->uriLen;
2974 memcpy(uri, localPart, i * sizeof(XML_Char));
Trent Mickf08d6632006-06-19 23:21:25 +00002975 /* we always have a namespace separator between localPart and prefix */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002976 if (prefixLen) {
Trent Mickf08d6632006-06-19 23:21:25 +00002977 uri += i - 1;
2978 *uri = namespaceSeparator; /* replace null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002979 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2980 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002981 tagNamePtr->str = binding->uri;
2982 return XML_ERROR_NONE;
2983}
2984
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002985/* addBinding() overwrites the value of prefix->binding without checking.
2986 Therefore one must keep track of the old value outside of addBinding().
2987*/
2988static enum XML_Error
2989addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2990 const XML_Char *uri, BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002991{
Trent Mickf08d6632006-06-19 23:21:25 +00002992 static const XML_Char xmlNamespace[] = {
2993 'h', 't', 't', 'p', ':', '/', '/',
2994 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2995 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
2996 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
2997 };
2998 static const int xmlLen =
2999 (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3000 static const XML_Char xmlnsNamespace[] = {
3001 'h', 't', 't', 'p', ':', '/', '/',
3002 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
3003 '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
3004 };
3005 static const int xmlnsLen =
3006 (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3007
3008 XML_Bool mustBeXML = XML_FALSE;
3009 XML_Bool isXML = XML_TRUE;
3010 XML_Bool isXMLNS = XML_TRUE;
3011
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003012 BINDING *b;
3013 int len;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003014
Fred Drake31d485c2004-08-03 07:06:22 +00003015 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003016 if (*uri == XML_T('\0') && prefix->name)
Fred Drake31d485c2004-08-03 07:06:22 +00003017 return XML_ERROR_UNDECLARING_PREFIX;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003018
Trent Mickf08d6632006-06-19 23:21:25 +00003019 if (prefix->name
3020 && prefix->name[0] == XML_T('x')
3021 && prefix->name[1] == XML_T('m')
3022 && prefix->name[2] == XML_T('l')) {
3023
3024 /* Not allowed to bind xmlns */
3025 if (prefix->name[3] == XML_T('n')
3026 && prefix->name[4] == XML_T('s')
3027 && prefix->name[5] == XML_T('\0'))
3028 return XML_ERROR_RESERVED_PREFIX_XMLNS;
3029
3030 if (prefix->name[3] == XML_T('\0'))
3031 mustBeXML = XML_TRUE;
3032 }
3033
3034 for (len = 0; uri[len]; len++) {
3035 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3036 isXML = XML_FALSE;
3037
3038 if (!mustBeXML && isXMLNS
3039 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3040 isXMLNS = XML_FALSE;
3041 }
3042 isXML = isXML && len == xmlLen;
3043 isXMLNS = isXMLNS && len == xmlnsLen;
3044
3045 if (mustBeXML != isXML)
3046 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3047 : XML_ERROR_RESERVED_NAMESPACE_URI;
3048
3049 if (isXMLNS)
3050 return XML_ERROR_RESERVED_NAMESPACE_URI;
3051
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003052 if (namespaceSeparator)
3053 len++;
3054 if (freeBindingList) {
3055 b = freeBindingList;
3056 if (len > b->uriAlloc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003057 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3058 sizeof(XML_Char) * (len + EXPAND_SPARE));
3059 if (temp == NULL)
3060 return XML_ERROR_NO_MEMORY;
3061 b->uri = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003062 b->uriAlloc = len + EXPAND_SPARE;
3063 }
3064 freeBindingList = b->nextTagBinding;
3065 }
3066 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003067 b = (BINDING *)MALLOC(sizeof(BINDING));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003068 if (!b)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003069 return XML_ERROR_NO_MEMORY;
3070 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003071 if (!b->uri) {
3072 FREE(b);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003073 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003074 }
3075 b->uriAlloc = len + EXPAND_SPARE;
3076 }
3077 b->uriLen = len;
3078 memcpy(b->uri, uri, len * sizeof(XML_Char));
3079 if (namespaceSeparator)
3080 b->uri[len - 1] = namespaceSeparator;
3081 b->prefix = prefix;
3082 b->attId = attId;
3083 b->prevPrefixBinding = prefix->binding;
Fred Drake08317ae2003-10-21 15:38:55 +00003084 /* NULL binding when default namespace undeclared */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003085 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3086 prefix->binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003087 else
3088 prefix->binding = b;
3089 b->nextTagBinding = *bindingsPtr;
3090 *bindingsPtr = b;
Fred Drake31d485c2004-08-03 07:06:22 +00003091 /* if attId == NULL then we are not starting a namespace scope */
3092 if (attId && startNamespaceDeclHandler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003093 startNamespaceDeclHandler(handlerArg, prefix->name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003094 prefix->binding ? uri : 0);
3095 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003096}
3097
3098/* The idea here is to avoid using stack for each CDATA section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003099 the whole file is parsed with one call.
3100*/
3101static enum XML_Error PTRCALL
3102cdataSectionProcessor(XML_Parser parser,
3103 const char *start,
3104 const char *end,
3105 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003106{
Fred Drake31d485c2004-08-03 07:06:22 +00003107 enum XML_Error result = doCdataSection(parser, encoding, &start, end,
Trent Mickf08d6632006-06-19 23:21:25 +00003108 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00003109 if (result != XML_ERROR_NONE)
3110 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003111 if (start) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003112 if (parentParser) { /* we are parsing an external entity */
3113 processor = externalEntityContentProcessor;
3114 return externalEntityContentProcessor(parser, start, end, endPtr);
3115 }
3116 else {
3117 processor = contentProcessor;
3118 return contentProcessor(parser, start, end, endPtr);
3119 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003120 }
3121 return result;
3122}
3123
Fred Drake31d485c2004-08-03 07:06:22 +00003124/* startPtr gets set to non-null if the section is closed, and to null if
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003125 the section is not yet closed.
3126*/
3127static enum XML_Error
3128doCdataSection(XML_Parser parser,
3129 const ENCODING *enc,
3130 const char **startPtr,
3131 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003132 const char **nextPtr,
3133 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003134{
3135 const char *s = *startPtr;
3136 const char **eventPP;
3137 const char **eventEndPP;
3138 if (enc == encoding) {
3139 eventPP = &eventPtr;
3140 *eventPP = s;
3141 eventEndPP = &eventEndPtr;
3142 }
3143 else {
3144 eventPP = &(openInternalEntities->internalEventPtr);
3145 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3146 }
3147 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003148 *startPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00003149
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003150 for (;;) {
3151 const char *next;
3152 int tok = XmlCdataSectionTok(enc, s, end, &next);
3153 *eventEndPP = next;
3154 switch (tok) {
3155 case XML_TOK_CDATA_SECT_CLOSE:
3156 if (endCdataSectionHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003157 endCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003158#if 0
3159 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3160 else if (characterDataHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003161 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003162#endif
3163 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003164 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003165 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003166 *nextPtr = next;
Trent Mickf08d6632006-06-19 23:21:25 +00003167 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00003168 return XML_ERROR_ABORTED;
3169 else
3170 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003171 case XML_TOK_DATA_NEWLINE:
3172 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003173 XML_Char c = 0xA;
3174 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003175 }
3176 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003177 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003178 break;
3179 case XML_TOK_DATA_CHARS:
3180 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003181 if (MUST_CONVERT(enc, s)) {
3182 for (;;) {
3183 ICHAR *dataPtr = (ICHAR *)dataBuf;
3184 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3185 *eventEndPP = next;
3186 characterDataHandler(handlerArg, dataBuf,
Trent Mickf08d6632006-06-19 23:21:25 +00003187 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003188 if (s == next)
3189 break;
3190 *eventPP = s;
3191 }
3192 }
3193 else
3194 characterDataHandler(handlerArg,
3195 (XML_Char *)s,
Trent Mickf08d6632006-06-19 23:21:25 +00003196 (int)((XML_Char *)next - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003197 }
3198 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003199 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003200 break;
3201 case XML_TOK_INVALID:
3202 *eventPP = next;
3203 return XML_ERROR_INVALID_TOKEN;
3204 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003205 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003206 *nextPtr = s;
3207 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003208 }
3209 return XML_ERROR_PARTIAL_CHAR;
3210 case XML_TOK_PARTIAL:
3211 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003212 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003213 *nextPtr = s;
3214 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003215 }
3216 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3217 default:
3218 *eventPP = next;
3219 return XML_ERROR_UNEXPECTED_STATE;
3220 }
Fred Drake31d485c2004-08-03 07:06:22 +00003221
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003222 *eventPP = s = next;
Trent Mickf08d6632006-06-19 23:21:25 +00003223 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00003224 case XML_SUSPENDED:
3225 *nextPtr = next;
3226 return XML_ERROR_NONE;
3227 case XML_FINISHED:
3228 return XML_ERROR_ABORTED;
3229 default: ;
3230 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003231 }
3232 /* not reached */
3233}
3234
3235#ifdef XML_DTD
3236
3237/* The idea here is to avoid using stack for each IGNORE section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003238 the whole file is parsed with one call.
3239*/
3240static enum XML_Error PTRCALL
3241ignoreSectionProcessor(XML_Parser parser,
3242 const char *start,
3243 const char *end,
3244 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003245{
Fred Drake31d485c2004-08-03 07:06:22 +00003246 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
Trent Mickf08d6632006-06-19 23:21:25 +00003247 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00003248 if (result != XML_ERROR_NONE)
3249 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003250 if (start) {
3251 processor = prologProcessor;
3252 return prologProcessor(parser, start, end, endPtr);
3253 }
3254 return result;
3255}
3256
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003257/* startPtr gets set to non-null is the section is closed, and to null
3258 if the section is not yet closed.
3259*/
3260static enum XML_Error
3261doIgnoreSection(XML_Parser parser,
3262 const ENCODING *enc,
3263 const char **startPtr,
3264 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003265 const char **nextPtr,
3266 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003267{
3268 const char *next;
3269 int tok;
3270 const char *s = *startPtr;
3271 const char **eventPP;
3272 const char **eventEndPP;
3273 if (enc == encoding) {
3274 eventPP = &eventPtr;
3275 *eventPP = s;
3276 eventEndPP = &eventEndPtr;
3277 }
3278 else {
3279 eventPP = &(openInternalEntities->internalEventPtr);
3280 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3281 }
3282 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003283 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003284 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3285 *eventEndPP = next;
3286 switch (tok) {
3287 case XML_TOK_IGNORE_SECT:
3288 if (defaultHandler)
3289 reportDefault(parser, enc, s, next);
3290 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003291 *nextPtr = next;
Trent Mickf08d6632006-06-19 23:21:25 +00003292 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00003293 return XML_ERROR_ABORTED;
3294 else
3295 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003296 case XML_TOK_INVALID:
3297 *eventPP = next;
3298 return XML_ERROR_INVALID_TOKEN;
3299 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003300 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003301 *nextPtr = s;
3302 return XML_ERROR_NONE;
3303 }
3304 return XML_ERROR_PARTIAL_CHAR;
3305 case XML_TOK_PARTIAL:
3306 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003307 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003308 *nextPtr = s;
3309 return XML_ERROR_NONE;
3310 }
3311 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3312 default:
3313 *eventPP = next;
3314 return XML_ERROR_UNEXPECTED_STATE;
3315 }
3316 /* not reached */
3317}
3318
3319#endif /* XML_DTD */
3320
3321static enum XML_Error
3322initializeEncoding(XML_Parser parser)
3323{
3324 const char *s;
3325#ifdef XML_UNICODE
3326 char encodingBuf[128];
3327 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003328 s = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003329 else {
3330 int i;
3331 for (i = 0; protocolEncodingName[i]; i++) {
3332 if (i == sizeof(encodingBuf) - 1
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003333 || (protocolEncodingName[i] & ~0x7f) != 0) {
3334 encodingBuf[0] = '\0';
3335 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003336 }
3337 encodingBuf[i] = (char)protocolEncodingName[i];
3338 }
3339 encodingBuf[i] = '\0';
3340 s = encodingBuf;
3341 }
3342#else
3343 s = protocolEncodingName;
3344#endif
3345 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3346 return XML_ERROR_NONE;
3347 return handleUnknownEncoding(parser, protocolEncodingName);
3348}
3349
3350static enum XML_Error
3351processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003352 const char *s, const char *next)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003353{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003354 const char *encodingName = NULL;
3355 const XML_Char *storedEncName = NULL;
3356 const ENCODING *newEncoding = NULL;
3357 const char *version = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003358 const char *versionend;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003359 const XML_Char *storedversion = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003360 int standalone = -1;
3361 if (!(ns
3362 ? XmlParseXmlDeclNS
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003363 : XmlParseXmlDecl)(isGeneralTextEntity,
3364 encoding,
3365 s,
3366 next,
3367 &eventPtr,
3368 &version,
3369 &versionend,
3370 &encodingName,
3371 &newEncoding,
Fred Drake31d485c2004-08-03 07:06:22 +00003372 &standalone)) {
3373 if (isGeneralTextEntity)
3374 return XML_ERROR_TEXT_DECL;
3375 else
3376 return XML_ERROR_XML_DECL;
3377 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003378 if (!isGeneralTextEntity && standalone == 1) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003379 _dtd->standalone = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003380#ifdef XML_DTD
3381 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3382 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3383#endif /* XML_DTD */
3384 }
3385 if (xmlDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003386 if (encodingName != NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003387 storedEncName = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003388 encoding,
3389 encodingName,
3390 encodingName
3391 + XmlNameLength(encoding, encodingName));
3392 if (!storedEncName)
3393 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003394 poolFinish(&temp2Pool);
3395 }
3396 if (version) {
3397 storedversion = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003398 encoding,
3399 version,
3400 versionend - encoding->minBytesPerChar);
3401 if (!storedversion)
3402 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003403 }
3404 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3405 }
3406 else if (defaultHandler)
3407 reportDefault(parser, encoding, s, next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003408 if (protocolEncodingName == NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003409 if (newEncoding) {
3410 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003411 eventPtr = encodingName;
3412 return XML_ERROR_INCORRECT_ENCODING;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003413 }
3414 encoding = newEncoding;
3415 }
3416 else if (encodingName) {
3417 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003418 if (!storedEncName) {
3419 storedEncName = poolStoreString(
3420 &temp2Pool, encoding, encodingName,
3421 encodingName + XmlNameLength(encoding, encodingName));
3422 if (!storedEncName)
3423 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003424 }
3425 result = handleUnknownEncoding(parser, storedEncName);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003426 poolClear(&temp2Pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003427 if (result == XML_ERROR_UNKNOWN_ENCODING)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003428 eventPtr = encodingName;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003429 return result;
3430 }
3431 }
3432
3433 if (storedEncName || storedversion)
3434 poolClear(&temp2Pool);
3435
3436 return XML_ERROR_NONE;
3437}
3438
3439static enum XML_Error
3440handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3441{
3442 if (unknownEncodingHandler) {
3443 XML_Encoding info;
3444 int i;
3445 for (i = 0; i < 256; i++)
3446 info.map[i] = -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003447 info.convert = NULL;
3448 info.data = NULL;
3449 info.release = NULL;
3450 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3451 &info)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003452 ENCODING *enc;
3453 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3454 if (!unknownEncodingMem) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003455 if (info.release)
3456 info.release(info.data);
3457 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003458 }
3459 enc = (ns
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003460 ? XmlInitUnknownEncodingNS
3461 : XmlInitUnknownEncoding)(unknownEncodingMem,
3462 info.map,
3463 info.convert,
3464 info.data);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003465 if (enc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003466 unknownEncodingData = info.data;
3467 unknownEncodingRelease = info.release;
3468 encoding = enc;
3469 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003470 }
3471 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003472 if (info.release != NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003473 info.release(info.data);
3474 }
3475 return XML_ERROR_UNKNOWN_ENCODING;
3476}
3477
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003478static enum XML_Error PTRCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003479prologInitProcessor(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003480 const char *s,
3481 const char *end,
3482 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003483{
3484 enum XML_Error result = initializeEncoding(parser);
3485 if (result != XML_ERROR_NONE)
3486 return result;
3487 processor = prologProcessor;
3488 return prologProcessor(parser, s, end, nextPtr);
3489}
3490
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003491#ifdef XML_DTD
3492
3493static enum XML_Error PTRCALL
3494externalParEntInitProcessor(XML_Parser parser,
3495 const char *s,
3496 const char *end,
3497 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003498{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003499 enum XML_Error result = initializeEncoding(parser);
3500 if (result != XML_ERROR_NONE)
3501 return result;
3502
3503 /* we know now that XML_Parse(Buffer) has been called,
3504 so we consider the external parameter entity read */
3505 _dtd->paramEntityRead = XML_TRUE;
3506
3507 if (prologState.inEntityValue) {
3508 processor = entityValueInitProcessor;
3509 return entityValueInitProcessor(parser, s, end, nextPtr);
3510 }
3511 else {
3512 processor = externalParEntProcessor;
3513 return externalParEntProcessor(parser, s, end, nextPtr);
3514 }
3515}
3516
3517static enum XML_Error PTRCALL
3518entityValueInitProcessor(XML_Parser parser,
3519 const char *s,
3520 const char *end,
3521 const char **nextPtr)
3522{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003523 int tok;
Fred Drake31d485c2004-08-03 07:06:22 +00003524 const char *start = s;
3525 const char *next = start;
3526 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003527
Fred Drake31d485c2004-08-03 07:06:22 +00003528 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003529 tok = XmlPrologTok(encoding, start, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003530 eventEndPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003531 if (tok <= 0) {
Trent Mickf08d6632006-06-19 23:21:25 +00003532 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Fred Drake31d485c2004-08-03 07:06:22 +00003533 *nextPtr = s;
3534 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003535 }
3536 switch (tok) {
3537 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003538 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003539 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003540 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003541 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003542 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003543 case XML_TOK_NONE: /* start == end */
3544 default:
3545 break;
3546 }
Fred Drake31d485c2004-08-03 07:06:22 +00003547 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003548 return storeEntityValue(parser, encoding, s, end);
3549 }
3550 else if (tok == XML_TOK_XML_DECL) {
Fred Drake31d485c2004-08-03 07:06:22 +00003551 enum XML_Error result;
3552 result = processXmlDecl(parser, 0, start, next);
3553 if (result != XML_ERROR_NONE)
3554 return result;
Trent Mickf08d6632006-06-19 23:21:25 +00003555 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00003556 case XML_SUSPENDED:
3557 *nextPtr = next;
3558 return XML_ERROR_NONE;
3559 case XML_FINISHED:
3560 return XML_ERROR_ABORTED;
3561 default:
3562 *nextPtr = next;
3563 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003564 /* stop scanning for text declaration - we found one */
3565 processor = entityValueProcessor;
3566 return entityValueProcessor(parser, next, end, nextPtr);
3567 }
3568 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3569 return XML_TOK_NONE on the next call, which would then cause the
3570 function to exit with *nextPtr set to s - that is what we want for other
3571 tokens, but not for the BOM - we would rather like to skip it;
3572 then, when this routine is entered the next time, XmlPrologTok will
3573 return XML_TOK_INVALID, since the BOM is still in the buffer
3574 */
Trent Mickf08d6632006-06-19 23:21:25 +00003575 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003576 *nextPtr = next;
3577 return XML_ERROR_NONE;
3578 }
3579 start = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003580 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003581 }
3582}
3583
3584static enum XML_Error PTRCALL
3585externalParEntProcessor(XML_Parser parser,
3586 const char *s,
3587 const char *end,
3588 const char **nextPtr)
3589{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003590 const char *next = s;
3591 int tok;
3592
Fred Drake31d485c2004-08-03 07:06:22 +00003593 tok = XmlPrologTok(encoding, s, end, &next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003594 if (tok <= 0) {
Trent Mickf08d6632006-06-19 23:21:25 +00003595 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003596 *nextPtr = s;
3597 return XML_ERROR_NONE;
3598 }
3599 switch (tok) {
3600 case XML_TOK_INVALID:
3601 return XML_ERROR_INVALID_TOKEN;
3602 case XML_TOK_PARTIAL:
3603 return XML_ERROR_UNCLOSED_TOKEN;
3604 case XML_TOK_PARTIAL_CHAR:
3605 return XML_ERROR_PARTIAL_CHAR;
3606 case XML_TOK_NONE: /* start == end */
3607 default:
3608 break;
3609 }
3610 }
3611 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3612 However, when parsing an external subset, doProlog will not accept a BOM
3613 as valid, and report a syntax error, so we have to skip the BOM
3614 */
3615 else if (tok == XML_TOK_BOM) {
3616 s = next;
3617 tok = XmlPrologTok(encoding, s, end, &next);
3618 }
3619
3620 processor = prologProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +00003621 return doProlog(parser, encoding, s, end, tok, next,
Trent Mickf08d6632006-06-19 23:21:25 +00003622 nextPtr, (XML_Bool)!ps_finalBuffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003623}
3624
3625static enum XML_Error PTRCALL
3626entityValueProcessor(XML_Parser parser,
3627 const char *s,
3628 const char *end,
3629 const char **nextPtr)
3630{
3631 const char *start = s;
3632 const char *next = s;
3633 const ENCODING *enc = encoding;
3634 int tok;
3635
3636 for (;;) {
3637 tok = XmlPrologTok(enc, start, end, &next);
3638 if (tok <= 0) {
Trent Mickf08d6632006-06-19 23:21:25 +00003639 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003640 *nextPtr = s;
3641 return XML_ERROR_NONE;
3642 }
3643 switch (tok) {
3644 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003645 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003646 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003647 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003648 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003649 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003650 case XML_TOK_NONE: /* start == end */
3651 default:
3652 break;
3653 }
Fred Drake31d485c2004-08-03 07:06:22 +00003654 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003655 return storeEntityValue(parser, enc, s, end);
3656 }
3657 start = next;
3658 }
3659}
3660
3661#endif /* XML_DTD */
3662
3663static enum XML_Error PTRCALL
3664prologProcessor(XML_Parser parser,
3665 const char *s,
3666 const char *end,
3667 const char **nextPtr)
3668{
3669 const char *next = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003670 int tok = XmlPrologTok(encoding, s, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003671 return doProlog(parser, encoding, s, end, tok, next,
Trent Mickf08d6632006-06-19 23:21:25 +00003672 nextPtr, (XML_Bool)!ps_finalBuffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003673}
3674
3675static enum XML_Error
3676doProlog(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003677 const ENCODING *enc,
3678 const char *s,
3679 const char *end,
3680 int tok,
3681 const char *next,
Fred Drake31d485c2004-08-03 07:06:22 +00003682 const char **nextPtr,
3683 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003684{
3685#ifdef XML_DTD
3686 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3687#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003688 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3689 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3690 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3691 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3692 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3693 static const XML_Char atypeENTITIES[] =
3694 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3695 static const XML_Char atypeNMTOKEN[] = {
3696 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3697 static const XML_Char atypeNMTOKENS[] = {
3698 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3699 static const XML_Char notationPrefix[] = {
3700 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3701 static const XML_Char enumValueSep[] = { '|', '\0' };
3702 static const XML_Char enumValueStart[] = { '(', '\0' };
3703
Fred Drake31d485c2004-08-03 07:06:22 +00003704 /* save one level of indirection */
3705 DTD * const dtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003706
3707 const char **eventPP;
3708 const char **eventEndPP;
3709 enum XML_Content_Quant quant;
3710
3711 if (enc == encoding) {
3712 eventPP = &eventPtr;
3713 eventEndPP = &eventEndPtr;
3714 }
3715 else {
3716 eventPP = &(openInternalEntities->internalEventPtr);
3717 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3718 }
Fred Drake31d485c2004-08-03 07:06:22 +00003719
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003720 for (;;) {
3721 int role;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003722 XML_Bool handleDefault = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003723 *eventPP = s;
3724 *eventEndPP = next;
3725 if (tok <= 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00003726 if (haveMore && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003727 *nextPtr = s;
3728 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003729 }
3730 switch (tok) {
3731 case XML_TOK_INVALID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003732 *eventPP = next;
3733 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003734 case XML_TOK_PARTIAL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003735 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003736 case XML_TOK_PARTIAL_CHAR:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003737 return XML_ERROR_PARTIAL_CHAR;
Matthias Klose0d948ac2010-01-22 00:39:04 +00003738 case -XML_TOK_PROLOG_S:
3739 tok = -tok;
3740 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003741 case XML_TOK_NONE:
3742#ifdef XML_DTD
Fred Drake31d485c2004-08-03 07:06:22 +00003743 /* for internal PE NOT referenced between declarations */
3744 if (enc != encoding && !openInternalEntities->betweenDecl) {
3745 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003746 return XML_ERROR_NONE;
Fred Drake31d485c2004-08-03 07:06:22 +00003747 }
3748 /* WFC: PE Between Declarations - must check that PE contains
3749 complete markup, not only for external PEs, but also for
3750 internal PEs if the reference occurs between declarations.
3751 */
3752 if (isParamEntity || enc != encoding) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003753 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3754 == XML_ROLE_ERROR)
Fred Drake31d485c2004-08-03 07:06:22 +00003755 return XML_ERROR_INCOMPLETE_PE;
3756 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003757 return XML_ERROR_NONE;
3758 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003759#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003760 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003761 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003762 tok = -tok;
3763 next = end;
3764 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003765 }
3766 }
3767 role = XmlTokenRole(&prologState, tok, s, next, enc);
3768 switch (role) {
3769 case XML_ROLE_XML_DECL:
3770 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003771 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3772 if (result != XML_ERROR_NONE)
3773 return result;
3774 enc = encoding;
3775 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003776 }
3777 break;
3778 case XML_ROLE_DOCTYPE_NAME:
3779 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003780 doctypeName = poolStoreString(&tempPool, enc, s, next);
3781 if (!doctypeName)
3782 return XML_ERROR_NO_MEMORY;
3783 poolFinish(&tempPool);
3784 doctypePubid = NULL;
3785 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003786 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003787 doctypeSysid = NULL; /* always initialize to NULL */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003788 break;
3789 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3790 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003791 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3792 doctypePubid, 1);
3793 doctypeName = NULL;
3794 poolClear(&tempPool);
3795 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003796 }
3797 break;
3798#ifdef XML_DTD
3799 case XML_ROLE_TEXT_DECL:
3800 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003801 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3802 if (result != XML_ERROR_NONE)
3803 return result;
3804 enc = encoding;
3805 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003806 }
3807 break;
3808#endif /* XML_DTD */
3809 case XML_ROLE_DOCTYPE_PUBLIC_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003810#ifdef XML_DTD
3811 useForeignDTD = XML_FALSE;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07003812 declEntity = (ENTITY *)lookup(parser,
3813 &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003814 externalSubsetName,
3815 sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003816 if (!declEntity)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003817 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003818#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00003819 dtd->hasParamEntityRefs = XML_TRUE;
3820 if (startDoctypeDeclHandler) {
3821 if (!XmlIsPublicId(enc, s, next, eventPP))
3822 return XML_ERROR_PUBLICID;
3823 doctypePubid = poolStoreString(&tempPool, enc,
3824 s + enc->minBytesPerChar,
3825 next - enc->minBytesPerChar);
3826 if (!doctypePubid)
3827 return XML_ERROR_NO_MEMORY;
3828 normalizePublicId((XML_Char *)doctypePubid);
3829 poolFinish(&tempPool);
3830 handleDefault = XML_FALSE;
3831 goto alreadyChecked;
3832 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003833 /* fall through */
3834 case XML_ROLE_ENTITY_PUBLIC_ID:
3835 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00003836 return XML_ERROR_PUBLICID;
3837 alreadyChecked:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003838 if (dtd->keepProcessing && declEntity) {
3839 XML_Char *tem = poolStoreString(&dtd->pool,
3840 enc,
3841 s + enc->minBytesPerChar,
3842 next - enc->minBytesPerChar);
3843 if (!tem)
3844 return XML_ERROR_NO_MEMORY;
3845 normalizePublicId(tem);
3846 declEntity->publicId = tem;
3847 poolFinish(&dtd->pool);
3848 if (entityDeclHandler)
3849 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003850 }
3851 break;
3852 case XML_ROLE_DOCTYPE_CLOSE:
3853 if (doctypeName) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003854 startDoctypeDeclHandler(handlerArg, doctypeName,
3855 doctypeSysid, doctypePubid, 0);
3856 poolClear(&tempPool);
3857 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003858 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003859 /* doctypeSysid will be non-NULL in the case of a previous
3860 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3861 was not set, indicating an external subset
3862 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003863#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003864 if (doctypeSysid || useForeignDTD) {
Trent Mickf08d6632006-06-19 23:21:25 +00003865 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3866 dtd->hasParamEntityRefs = XML_TRUE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003867 if (paramEntityParsing && externalEntityRefHandler) {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07003868 ENTITY *entity = (ENTITY *)lookup(parser,
3869 &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003870 externalSubsetName,
3871 sizeof(ENTITY));
3872 if (!entity)
3873 return XML_ERROR_NO_MEMORY;
3874 if (useForeignDTD)
3875 entity->base = curBase;
3876 dtd->paramEntityRead = XML_FALSE;
3877 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3878 0,
3879 entity->base,
3880 entity->systemId,
3881 entity->publicId))
3882 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
Trent Mickf08d6632006-06-19 23:21:25 +00003883 if (dtd->paramEntityRead) {
3884 if (!dtd->standalone &&
3885 notStandaloneHandler &&
3886 !notStandaloneHandler(handlerArg))
3887 return XML_ERROR_NOT_STANDALONE;
3888 }
3889 /* if we didn't read the foreign DTD then this means that there
3890 is no external subset and we must reset dtd->hasParamEntityRefs
3891 */
3892 else if (!doctypeSysid)
3893 dtd->hasParamEntityRefs = hadParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003894 /* end of DTD - no need to update dtd->keepProcessing */
3895 }
3896 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003897 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003898#endif /* XML_DTD */
3899 if (endDoctypeDeclHandler) {
3900 endDoctypeDeclHandler(handlerArg);
3901 handleDefault = XML_FALSE;
3902 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003903 break;
3904 case XML_ROLE_INSTANCE_START:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003905#ifdef XML_DTD
3906 /* if there is no DOCTYPE declaration then now is the
3907 last chance to read the foreign DTD
3908 */
3909 if (useForeignDTD) {
Trent Mickf08d6632006-06-19 23:21:25 +00003910 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003911 dtd->hasParamEntityRefs = XML_TRUE;
3912 if (paramEntityParsing && externalEntityRefHandler) {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07003913 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003914 externalSubsetName,
3915 sizeof(ENTITY));
3916 if (!entity)
3917 return XML_ERROR_NO_MEMORY;
3918 entity->base = curBase;
3919 dtd->paramEntityRead = XML_FALSE;
3920 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3921 0,
3922 entity->base,
3923 entity->systemId,
3924 entity->publicId))
3925 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
Trent Mickf08d6632006-06-19 23:21:25 +00003926 if (dtd->paramEntityRead) {
3927 if (!dtd->standalone &&
3928 notStandaloneHandler &&
3929 !notStandaloneHandler(handlerArg))
3930 return XML_ERROR_NOT_STANDALONE;
3931 }
3932 /* if we didn't read the foreign DTD then this means that there
3933 is no external subset and we must reset dtd->hasParamEntityRefs
3934 */
3935 else
3936 dtd->hasParamEntityRefs = hadParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003937 /* end of DTD - no need to update dtd->keepProcessing */
3938 }
3939 }
3940#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003941 processor = contentProcessor;
3942 return contentProcessor(parser, s, end, nextPtr);
3943 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3944 declElementType = getElementType(parser, enc, s, next);
3945 if (!declElementType)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003946 return XML_ERROR_NO_MEMORY;
3947 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003948 case XML_ROLE_ATTRIBUTE_NAME:
3949 declAttributeId = getAttributeId(parser, enc, s, next);
3950 if (!declAttributeId)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003951 return XML_ERROR_NO_MEMORY;
3952 declAttributeIsCdata = XML_FALSE;
3953 declAttributeType = NULL;
3954 declAttributeIsId = XML_FALSE;
3955 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003956 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003957 declAttributeIsCdata = XML_TRUE;
3958 declAttributeType = atypeCDATA;
3959 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003960 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003961 declAttributeIsId = XML_TRUE;
3962 declAttributeType = atypeID;
3963 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003964 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003965 declAttributeType = atypeIDREF;
3966 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003967 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003968 declAttributeType = atypeIDREFS;
3969 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003970 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003971 declAttributeType = atypeENTITY;
3972 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003973 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003974 declAttributeType = atypeENTITIES;
3975 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003976 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003977 declAttributeType = atypeNMTOKEN;
3978 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003979 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003980 declAttributeType = atypeNMTOKENS;
3981 checkAttListDeclHandler:
3982 if (dtd->keepProcessing && attlistDeclHandler)
3983 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003984 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003985 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3986 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003987 if (dtd->keepProcessing && attlistDeclHandler) {
3988 const XML_Char *prefix;
3989 if (declAttributeType) {
3990 prefix = enumValueSep;
3991 }
3992 else {
3993 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3994 ? notationPrefix
3995 : enumValueStart);
3996 }
3997 if (!poolAppendString(&tempPool, prefix))
3998 return XML_ERROR_NO_MEMORY;
3999 if (!poolAppend(&tempPool, enc, s, next))
4000 return XML_ERROR_NO_MEMORY;
4001 declAttributeType = tempPool.start;
4002 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004003 }
4004 break;
4005 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4006 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004007 if (dtd->keepProcessing) {
4008 if (!defineAttribute(declElementType, declAttributeId,
Fred Drake08317ae2003-10-21 15:38:55 +00004009 declAttributeIsCdata, declAttributeIsId,
4010 0, parser))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004011 return XML_ERROR_NO_MEMORY;
4012 if (attlistDeclHandler && declAttributeType) {
4013 if (*declAttributeType == XML_T('(')
4014 || (*declAttributeType == XML_T('N')
4015 && declAttributeType[1] == XML_T('O'))) {
4016 /* Enumerated or Notation type */
4017 if (!poolAppendChar(&tempPool, XML_T(')'))
4018 || !poolAppendChar(&tempPool, XML_T('\0')))
4019 return XML_ERROR_NO_MEMORY;
4020 declAttributeType = tempPool.start;
4021 poolFinish(&tempPool);
4022 }
4023 *eventEndPP = s;
4024 attlistDeclHandler(handlerArg, declElementType->name,
4025 declAttributeId->name, declAttributeType,
4026 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4027 poolClear(&tempPool);
4028 handleDefault = XML_FALSE;
4029 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004030 }
4031 break;
4032 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4033 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004034 if (dtd->keepProcessing) {
4035 const XML_Char *attVal;
Fred Drake08317ae2003-10-21 15:38:55 +00004036 enum XML_Error result =
4037 storeAttributeValue(parser, enc, declAttributeIsCdata,
4038 s + enc->minBytesPerChar,
4039 next - enc->minBytesPerChar,
4040 &dtd->pool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004041 if (result)
4042 return result;
4043 attVal = poolStart(&dtd->pool);
4044 poolFinish(&dtd->pool);
4045 /* ID attributes aren't allowed to have a default */
4046 if (!defineAttribute(declElementType, declAttributeId,
4047 declAttributeIsCdata, XML_FALSE, attVal, parser))
4048 return XML_ERROR_NO_MEMORY;
4049 if (attlistDeclHandler && declAttributeType) {
4050 if (*declAttributeType == XML_T('(')
4051 || (*declAttributeType == XML_T('N')
4052 && declAttributeType[1] == XML_T('O'))) {
4053 /* Enumerated or Notation type */
4054 if (!poolAppendChar(&tempPool, XML_T(')'))
4055 || !poolAppendChar(&tempPool, XML_T('\0')))
4056 return XML_ERROR_NO_MEMORY;
4057 declAttributeType = tempPool.start;
4058 poolFinish(&tempPool);
4059 }
4060 *eventEndPP = s;
4061 attlistDeclHandler(handlerArg, declElementType->name,
4062 declAttributeId->name, declAttributeType,
4063 attVal,
4064 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4065 poolClear(&tempPool);
4066 handleDefault = XML_FALSE;
4067 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004068 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004069 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004070 case XML_ROLE_ENTITY_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004071 if (dtd->keepProcessing) {
4072 enum XML_Error result = storeEntityValue(parser, enc,
4073 s + enc->minBytesPerChar,
4074 next - enc->minBytesPerChar);
4075 if (declEntity) {
4076 declEntity->textPtr = poolStart(&dtd->entityValuePool);
Trent Mickf08d6632006-06-19 23:21:25 +00004077 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004078 poolFinish(&dtd->entityValuePool);
4079 if (entityDeclHandler) {
4080 *eventEndPP = s;
4081 entityDeclHandler(handlerArg,
4082 declEntity->name,
4083 declEntity->is_param,
4084 declEntity->textPtr,
4085 declEntity->textLen,
4086 curBase, 0, 0, 0);
4087 handleDefault = XML_FALSE;
4088 }
4089 }
4090 else
4091 poolDiscard(&dtd->entityValuePool);
4092 if (result != XML_ERROR_NONE)
4093 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004094 }
4095 break;
4096 case XML_ROLE_DOCTYPE_SYSTEM_ID:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004097#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004098 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004099#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004100 dtd->hasParamEntityRefs = XML_TRUE;
4101 if (startDoctypeDeclHandler) {
4102 doctypeSysid = poolStoreString(&tempPool, enc,
4103 s + enc->minBytesPerChar,
4104 next - enc->minBytesPerChar);
4105 if (doctypeSysid == NULL)
4106 return XML_ERROR_NO_MEMORY;
4107 poolFinish(&tempPool);
4108 handleDefault = XML_FALSE;
4109 }
4110#ifdef XML_DTD
4111 else
4112 /* use externalSubsetName to make doctypeSysid non-NULL
4113 for the case where no startDoctypeDeclHandler is set */
4114 doctypeSysid = externalSubsetName;
4115#endif /* XML_DTD */
4116 if (!dtd->standalone
4117#ifdef XML_DTD
4118 && !paramEntityParsing
4119#endif /* XML_DTD */
4120 && notStandaloneHandler
4121 && !notStandaloneHandler(handlerArg))
4122 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004123#ifndef XML_DTD
4124 break;
4125#else /* XML_DTD */
4126 if (!declEntity) {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004127 declEntity = (ENTITY *)lookup(parser,
4128 &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004129 externalSubsetName,
4130 sizeof(ENTITY));
4131 if (!declEntity)
4132 return XML_ERROR_NO_MEMORY;
4133 declEntity->publicId = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004134 }
4135 /* fall through */
4136#endif /* XML_DTD */
4137 case XML_ROLE_ENTITY_SYSTEM_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004138 if (dtd->keepProcessing && declEntity) {
4139 declEntity->systemId = poolStoreString(&dtd->pool, enc,
4140 s + enc->minBytesPerChar,
4141 next - enc->minBytesPerChar);
4142 if (!declEntity->systemId)
4143 return XML_ERROR_NO_MEMORY;
4144 declEntity->base = curBase;
4145 poolFinish(&dtd->pool);
4146 if (entityDeclHandler)
4147 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004148 }
4149 break;
4150 case XML_ROLE_ENTITY_COMPLETE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004151 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4152 *eventEndPP = s;
4153 entityDeclHandler(handlerArg,
4154 declEntity->name,
4155 declEntity->is_param,
4156 0,0,
4157 declEntity->base,
4158 declEntity->systemId,
4159 declEntity->publicId,
4160 0);
4161 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004162 }
4163 break;
4164 case XML_ROLE_ENTITY_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004165 if (dtd->keepProcessing && declEntity) {
4166 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4167 if (!declEntity->notation)
4168 return XML_ERROR_NO_MEMORY;
4169 poolFinish(&dtd->pool);
4170 if (unparsedEntityDeclHandler) {
4171 *eventEndPP = s;
4172 unparsedEntityDeclHandler(handlerArg,
4173 declEntity->name,
4174 declEntity->base,
4175 declEntity->systemId,
4176 declEntity->publicId,
4177 declEntity->notation);
4178 handleDefault = XML_FALSE;
4179 }
4180 else if (entityDeclHandler) {
4181 *eventEndPP = s;
4182 entityDeclHandler(handlerArg,
4183 declEntity->name,
4184 0,0,0,
4185 declEntity->base,
4186 declEntity->systemId,
4187 declEntity->publicId,
4188 declEntity->notation);
4189 handleDefault = XML_FALSE;
4190 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004191 }
4192 break;
4193 case XML_ROLE_GENERAL_ENTITY_NAME:
4194 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004195 if (XmlPredefinedEntityName(enc, s, next)) {
4196 declEntity = NULL;
4197 break;
4198 }
4199 if (dtd->keepProcessing) {
4200 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4201 if (!name)
4202 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004203 declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004204 sizeof(ENTITY));
4205 if (!declEntity)
4206 return XML_ERROR_NO_MEMORY;
4207 if (declEntity->name != name) {
4208 poolDiscard(&dtd->pool);
4209 declEntity = NULL;
4210 }
4211 else {
4212 poolFinish(&dtd->pool);
4213 declEntity->publicId = NULL;
4214 declEntity->is_param = XML_FALSE;
4215 /* if we have a parent parser or are reading an internal parameter
4216 entity, then the entity declaration is not considered "internal"
4217 */
4218 declEntity->is_internal = !(parentParser || openInternalEntities);
4219 if (entityDeclHandler)
4220 handleDefault = XML_FALSE;
4221 }
4222 }
4223 else {
4224 poolDiscard(&dtd->pool);
4225 declEntity = NULL;
4226 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004227 }
4228 break;
4229 case XML_ROLE_PARAM_ENTITY_NAME:
4230#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004231 if (dtd->keepProcessing) {
4232 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4233 if (!name)
4234 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004235 declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004236 name, sizeof(ENTITY));
4237 if (!declEntity)
4238 return XML_ERROR_NO_MEMORY;
4239 if (declEntity->name != name) {
4240 poolDiscard(&dtd->pool);
4241 declEntity = NULL;
4242 }
4243 else {
4244 poolFinish(&dtd->pool);
4245 declEntity->publicId = NULL;
4246 declEntity->is_param = XML_TRUE;
4247 /* if we have a parent parser or are reading an internal parameter
4248 entity, then the entity declaration is not considered "internal"
4249 */
4250 declEntity->is_internal = !(parentParser || openInternalEntities);
4251 if (entityDeclHandler)
4252 handleDefault = XML_FALSE;
4253 }
4254 }
4255 else {
4256 poolDiscard(&dtd->pool);
4257 declEntity = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004258 }
4259#else /* not XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004260 declEntity = NULL;
4261#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004262 break;
4263 case XML_ROLE_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004264 declNotationPublicId = NULL;
4265 declNotationName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004266 if (notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004267 declNotationName = poolStoreString(&tempPool, enc, s, next);
4268 if (!declNotationName)
4269 return XML_ERROR_NO_MEMORY;
4270 poolFinish(&tempPool);
4271 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004272 }
4273 break;
4274 case XML_ROLE_NOTATION_PUBLIC_ID:
4275 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00004276 return XML_ERROR_PUBLICID;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004277 if (declNotationName) { /* means notationDeclHandler != NULL */
4278 XML_Char *tem = poolStoreString(&tempPool,
4279 enc,
4280 s + enc->minBytesPerChar,
4281 next - enc->minBytesPerChar);
4282 if (!tem)
4283 return XML_ERROR_NO_MEMORY;
4284 normalizePublicId(tem);
4285 declNotationPublicId = tem;
4286 poolFinish(&tempPool);
4287 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004288 }
4289 break;
4290 case XML_ROLE_NOTATION_SYSTEM_ID:
4291 if (declNotationName && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004292 const XML_Char *systemId
4293 = poolStoreString(&tempPool, enc,
4294 s + enc->minBytesPerChar,
4295 next - enc->minBytesPerChar);
4296 if (!systemId)
4297 return XML_ERROR_NO_MEMORY;
4298 *eventEndPP = s;
4299 notationDeclHandler(handlerArg,
4300 declNotationName,
4301 curBase,
4302 systemId,
4303 declNotationPublicId);
4304 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004305 }
4306 poolClear(&tempPool);
4307 break;
4308 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4309 if (declNotationPublicId && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004310 *eventEndPP = s;
4311 notationDeclHandler(handlerArg,
4312 declNotationName,
4313 curBase,
4314 0,
4315 declNotationPublicId);
4316 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004317 }
4318 poolClear(&tempPool);
4319 break;
4320 case XML_ROLE_ERROR:
4321 switch (tok) {
4322 case XML_TOK_PARAM_ENTITY_REF:
Fred Drake31d485c2004-08-03 07:06:22 +00004323 /* PE references in internal subset are
4324 not allowed within declarations. */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004325 return XML_ERROR_PARAM_ENTITY_REF;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004326 case XML_TOK_XML_DECL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004327 return XML_ERROR_MISPLACED_XML_PI;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004328 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004329 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004330 }
4331#ifdef XML_DTD
4332 case XML_ROLE_IGNORE_SECT:
4333 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004334 enum XML_Error result;
4335 if (defaultHandler)
4336 reportDefault(parser, enc, s, next);
4337 handleDefault = XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00004338 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4339 if (result != XML_ERROR_NONE)
4340 return result;
4341 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004342 processor = ignoreSectionProcessor;
4343 return result;
4344 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004345 }
4346 break;
4347#endif /* XML_DTD */
4348 case XML_ROLE_GROUP_OPEN:
4349 if (prologState.level >= groupSize) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004350 if (groupSize) {
4351 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4352 if (temp == NULL)
4353 return XML_ERROR_NO_MEMORY;
4354 groupConnector = temp;
4355 if (dtd->scaffIndex) {
4356 int *temp = (int *)REALLOC(dtd->scaffIndex,
4357 groupSize * sizeof(int));
4358 if (temp == NULL)
4359 return XML_ERROR_NO_MEMORY;
4360 dtd->scaffIndex = temp;
4361 }
4362 }
4363 else {
4364 groupConnector = (char *)MALLOC(groupSize = 32);
4365 if (!groupConnector)
4366 return XML_ERROR_NO_MEMORY;
4367 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004368 }
4369 groupConnector[prologState.level] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004370 if (dtd->in_eldecl) {
4371 int myindex = nextScaffoldPart(parser);
4372 if (myindex < 0)
4373 return XML_ERROR_NO_MEMORY;
4374 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4375 dtd->scaffLevel++;
4376 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4377 if (elementDeclHandler)
4378 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004379 }
4380 break;
4381 case XML_ROLE_GROUP_SEQUENCE:
4382 if (groupConnector[prologState.level] == '|')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004383 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004384 groupConnector[prologState.level] = ',';
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004385 if (dtd->in_eldecl && elementDeclHandler)
4386 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004387 break;
4388 case XML_ROLE_GROUP_CHOICE:
4389 if (groupConnector[prologState.level] == ',')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004390 return XML_ERROR_SYNTAX;
4391 if (dtd->in_eldecl
4392 && !groupConnector[prologState.level]
4393 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4394 != XML_CTYPE_MIXED)
4395 ) {
4396 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4397 = XML_CTYPE_CHOICE;
4398 if (elementDeclHandler)
4399 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004400 }
4401 groupConnector[prologState.level] = '|';
4402 break;
4403 case XML_ROLE_PARAM_ENTITY_REF:
4404#ifdef XML_DTD
4405 case XML_ROLE_INNER_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004406 dtd->hasParamEntityRefs = XML_TRUE;
4407 if (!paramEntityParsing)
4408 dtd->keepProcessing = dtd->standalone;
4409 else {
4410 const XML_Char *name;
4411 ENTITY *entity;
4412 name = poolStoreString(&dtd->pool, enc,
4413 s + enc->minBytesPerChar,
4414 next - enc->minBytesPerChar);
4415 if (!name)
4416 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004417 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004418 poolDiscard(&dtd->pool);
4419 /* first, determine if a check for an existing declaration is needed;
4420 if yes, check that the entity exists, and that it is internal,
4421 otherwise call the skipped entity handler
4422 */
4423 if (prologState.documentEntity &&
4424 (dtd->standalone
4425 ? !openInternalEntities
4426 : !dtd->hasParamEntityRefs)) {
4427 if (!entity)
4428 return XML_ERROR_UNDEFINED_ENTITY;
4429 else if (!entity->is_internal)
4430 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4431 }
4432 else if (!entity) {
4433 dtd->keepProcessing = dtd->standalone;
4434 /* cannot report skipped entities in declarations */
4435 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4436 skippedEntityHandler(handlerArg, name, 1);
4437 handleDefault = XML_FALSE;
4438 }
4439 break;
4440 }
4441 if (entity->open)
4442 return XML_ERROR_RECURSIVE_ENTITY_REF;
4443 if (entity->textPtr) {
4444 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004445 XML_Bool betweenDecl =
4446 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4447 result = processInternalEntity(parser, entity, betweenDecl);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004448 if (result != XML_ERROR_NONE)
4449 return result;
4450 handleDefault = XML_FALSE;
4451 break;
4452 }
4453 if (externalEntityRefHandler) {
4454 dtd->paramEntityRead = XML_FALSE;
4455 entity->open = XML_TRUE;
4456 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4457 0,
4458 entity->base,
4459 entity->systemId,
4460 entity->publicId)) {
4461 entity->open = XML_FALSE;
4462 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4463 }
4464 entity->open = XML_FALSE;
4465 handleDefault = XML_FALSE;
4466 if (!dtd->paramEntityRead) {
4467 dtd->keepProcessing = dtd->standalone;
4468 break;
4469 }
4470 }
4471 else {
4472 dtd->keepProcessing = dtd->standalone;
4473 break;
4474 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004475 }
4476#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004477 if (!dtd->standalone &&
4478 notStandaloneHandler &&
4479 !notStandaloneHandler(handlerArg))
4480 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004481 break;
4482
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004483 /* Element declaration stuff */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004484
4485 case XML_ROLE_ELEMENT_NAME:
4486 if (elementDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004487 declElementType = getElementType(parser, enc, s, next);
4488 if (!declElementType)
4489 return XML_ERROR_NO_MEMORY;
4490 dtd->scaffLevel = 0;
4491 dtd->scaffCount = 0;
4492 dtd->in_eldecl = XML_TRUE;
4493 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004494 }
4495 break;
4496
4497 case XML_ROLE_CONTENT_ANY:
4498 case XML_ROLE_CONTENT_EMPTY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004499 if (dtd->in_eldecl) {
4500 if (elementDeclHandler) {
4501 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4502 if (!content)
4503 return XML_ERROR_NO_MEMORY;
4504 content->quant = XML_CQUANT_NONE;
4505 content->name = NULL;
4506 content->numchildren = 0;
4507 content->children = NULL;
4508 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4509 XML_CTYPE_ANY :
4510 XML_CTYPE_EMPTY);
4511 *eventEndPP = s;
4512 elementDeclHandler(handlerArg, declElementType->name, content);
4513 handleDefault = XML_FALSE;
4514 }
4515 dtd->in_eldecl = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004516 }
4517 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004518
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004519 case XML_ROLE_CONTENT_PCDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004520 if (dtd->in_eldecl) {
4521 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4522 = XML_CTYPE_MIXED;
4523 if (elementDeclHandler)
4524 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004525 }
4526 break;
4527
4528 case XML_ROLE_CONTENT_ELEMENT:
4529 quant = XML_CQUANT_NONE;
4530 goto elementContent;
4531 case XML_ROLE_CONTENT_ELEMENT_OPT:
4532 quant = XML_CQUANT_OPT;
4533 goto elementContent;
4534 case XML_ROLE_CONTENT_ELEMENT_REP:
4535 quant = XML_CQUANT_REP;
4536 goto elementContent;
4537 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4538 quant = XML_CQUANT_PLUS;
4539 elementContent:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004540 if (dtd->in_eldecl) {
4541 ELEMENT_TYPE *el;
4542 const XML_Char *name;
4543 int nameLen;
4544 const char *nxt = (quant == XML_CQUANT_NONE
4545 ? next
4546 : next - enc->minBytesPerChar);
4547 int myindex = nextScaffoldPart(parser);
4548 if (myindex < 0)
4549 return XML_ERROR_NO_MEMORY;
4550 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4551 dtd->scaffold[myindex].quant = quant;
4552 el = getElementType(parser, enc, s, nxt);
4553 if (!el)
4554 return XML_ERROR_NO_MEMORY;
4555 name = el->name;
4556 dtd->scaffold[myindex].name = name;
4557 nameLen = 0;
4558 for (; name[nameLen++]; );
4559 dtd->contentStringLen += nameLen;
4560 if (elementDeclHandler)
4561 handleDefault = XML_FALSE;
4562 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004563 break;
4564
4565 case XML_ROLE_GROUP_CLOSE:
4566 quant = XML_CQUANT_NONE;
4567 goto closeGroup;
4568 case XML_ROLE_GROUP_CLOSE_OPT:
4569 quant = XML_CQUANT_OPT;
4570 goto closeGroup;
4571 case XML_ROLE_GROUP_CLOSE_REP:
4572 quant = XML_CQUANT_REP;
4573 goto closeGroup;
4574 case XML_ROLE_GROUP_CLOSE_PLUS:
4575 quant = XML_CQUANT_PLUS;
4576 closeGroup:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004577 if (dtd->in_eldecl) {
4578 if (elementDeclHandler)
4579 handleDefault = XML_FALSE;
4580 dtd->scaffLevel--;
4581 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4582 if (dtd->scaffLevel == 0) {
4583 if (!handleDefault) {
4584 XML_Content *model = build_model(parser);
4585 if (!model)
4586 return XML_ERROR_NO_MEMORY;
4587 *eventEndPP = s;
4588 elementDeclHandler(handlerArg, declElementType->name, model);
4589 }
4590 dtd->in_eldecl = XML_FALSE;
4591 dtd->contentStringLen = 0;
4592 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004593 }
4594 break;
4595 /* End element declaration stuff */
4596
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004597 case XML_ROLE_PI:
4598 if (!reportProcessingInstruction(parser, enc, s, next))
4599 return XML_ERROR_NO_MEMORY;
4600 handleDefault = XML_FALSE;
4601 break;
4602 case XML_ROLE_COMMENT:
4603 if (!reportComment(parser, enc, s, next))
4604 return XML_ERROR_NO_MEMORY;
4605 handleDefault = XML_FALSE;
4606 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004607 case XML_ROLE_NONE:
4608 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004609 case XML_TOK_BOM:
4610 handleDefault = XML_FALSE;
4611 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004612 }
4613 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004614 case XML_ROLE_DOCTYPE_NONE:
4615 if (startDoctypeDeclHandler)
4616 handleDefault = XML_FALSE;
4617 break;
4618 case XML_ROLE_ENTITY_NONE:
4619 if (dtd->keepProcessing && entityDeclHandler)
4620 handleDefault = XML_FALSE;
4621 break;
4622 case XML_ROLE_NOTATION_NONE:
4623 if (notationDeclHandler)
4624 handleDefault = XML_FALSE;
4625 break;
4626 case XML_ROLE_ATTLIST_NONE:
4627 if (dtd->keepProcessing && attlistDeclHandler)
4628 handleDefault = XML_FALSE;
4629 break;
4630 case XML_ROLE_ELEMENT_NONE:
4631 if (elementDeclHandler)
4632 handleDefault = XML_FALSE;
4633 break;
4634 } /* end of big switch */
4635
4636 if (handleDefault && defaultHandler)
4637 reportDefault(parser, enc, s, next);
4638
Trent Mickf08d6632006-06-19 23:21:25 +00004639 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00004640 case XML_SUSPENDED:
4641 *nextPtr = next;
4642 return XML_ERROR_NONE;
4643 case XML_FINISHED:
4644 return XML_ERROR_ABORTED;
4645 default:
4646 s = next;
4647 tok = XmlPrologTok(enc, s, end, &next);
4648 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004649 }
4650 /* not reached */
4651}
4652
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004653static enum XML_Error PTRCALL
4654epilogProcessor(XML_Parser parser,
4655 const char *s,
4656 const char *end,
4657 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004658{
4659 processor = epilogProcessor;
4660 eventPtr = s;
4661 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004662 const char *next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004663 int tok = XmlPrologTok(encoding, s, end, &next);
4664 eventEndPtr = next;
4665 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004666 /* report partial linebreak - it might be the last token */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004667 case -XML_TOK_PROLOG_S:
4668 if (defaultHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004669 reportDefault(parser, encoding, s, next);
Trent Mickf08d6632006-06-19 23:21:25 +00004670 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00004671 return XML_ERROR_ABORTED;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004672 }
Fred Drake31d485c2004-08-03 07:06:22 +00004673 *nextPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004674 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004675 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00004676 *nextPtr = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004677 return XML_ERROR_NONE;
4678 case XML_TOK_PROLOG_S:
4679 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004680 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004681 break;
4682 case XML_TOK_PI:
4683 if (!reportProcessingInstruction(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004684 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004685 break;
4686 case XML_TOK_COMMENT:
4687 if (!reportComment(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004688 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004689 break;
4690 case XML_TOK_INVALID:
4691 eventPtr = next;
4692 return XML_ERROR_INVALID_TOKEN;
4693 case XML_TOK_PARTIAL:
Trent Mickf08d6632006-06-19 23:21:25 +00004694 if (!ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004695 *nextPtr = s;
4696 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004697 }
4698 return XML_ERROR_UNCLOSED_TOKEN;
4699 case XML_TOK_PARTIAL_CHAR:
Trent Mickf08d6632006-06-19 23:21:25 +00004700 if (!ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004701 *nextPtr = s;
4702 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004703 }
4704 return XML_ERROR_PARTIAL_CHAR;
4705 default:
4706 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4707 }
4708 eventPtr = s = next;
Trent Mickf08d6632006-06-19 23:21:25 +00004709 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00004710 case XML_SUSPENDED:
4711 *nextPtr = next;
4712 return XML_ERROR_NONE;
4713 case XML_FINISHED:
4714 return XML_ERROR_ABORTED;
4715 default: ;
4716 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004717 }
4718}
4719
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004720static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +00004721processInternalEntity(XML_Parser parser, ENTITY *entity,
4722 XML_Bool betweenDecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004723{
Fred Drake31d485c2004-08-03 07:06:22 +00004724 const char *textStart, *textEnd;
4725 const char *next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004726 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004727 OPEN_INTERNAL_ENTITY *openEntity;
4728
4729 if (freeInternalEntities) {
4730 openEntity = freeInternalEntities;
4731 freeInternalEntities = openEntity->next;
4732 }
4733 else {
4734 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4735 if (!openEntity)
4736 return XML_ERROR_NO_MEMORY;
4737 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004738 entity->open = XML_TRUE;
Fred Drake31d485c2004-08-03 07:06:22 +00004739 entity->processed = 0;
4740 openEntity->next = openInternalEntities;
4741 openInternalEntities = openEntity;
4742 openEntity->entity = entity;
4743 openEntity->startTagLevel = tagLevel;
4744 openEntity->betweenDecl = betweenDecl;
4745 openEntity->internalEventPtr = NULL;
4746 openEntity->internalEventEndPtr = NULL;
4747 textStart = (char *)entity->textPtr;
4748 textEnd = (char *)(entity->textPtr + entity->textLen);
4749
4750#ifdef XML_DTD
4751 if (entity->is_param) {
4752 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4753 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4754 next, &next, XML_FALSE);
4755 }
4756 else
4757#endif /* XML_DTD */
4758 result = doContent(parser, tagLevel, internalEncoding, textStart,
4759 textEnd, &next, XML_FALSE);
4760
4761 if (result == XML_ERROR_NONE) {
Trent Mickf08d6632006-06-19 23:21:25 +00004762 if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4763 entity->processed = (int)(next - textStart);
Fred Drake31d485c2004-08-03 07:06:22 +00004764 processor = internalEntityProcessor;
4765 }
4766 else {
4767 entity->open = XML_FALSE;
4768 openInternalEntities = openEntity->next;
4769 /* put openEntity back in list of free instances */
4770 openEntity->next = freeInternalEntities;
4771 freeInternalEntities = openEntity;
4772 }
4773 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004774 return result;
4775}
4776
Fred Drake31d485c2004-08-03 07:06:22 +00004777static enum XML_Error PTRCALL
4778internalEntityProcessor(XML_Parser parser,
4779 const char *s,
4780 const char *end,
4781 const char **nextPtr)
4782{
4783 ENTITY *entity;
4784 const char *textStart, *textEnd;
4785 const char *next;
4786 enum XML_Error result;
4787 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4788 if (!openEntity)
4789 return XML_ERROR_UNEXPECTED_STATE;
4790
4791 entity = openEntity->entity;
4792 textStart = ((char *)entity->textPtr) + entity->processed;
4793 textEnd = (char *)(entity->textPtr + entity->textLen);
4794
4795#ifdef XML_DTD
4796 if (entity->is_param) {
4797 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4798 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4799 next, &next, XML_FALSE);
4800 }
4801 else
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004802#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00004803 result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4804 textStart, textEnd, &next, XML_FALSE);
4805
4806 if (result != XML_ERROR_NONE)
4807 return result;
Trent Mickf08d6632006-06-19 23:21:25 +00004808 else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4809 entity->processed = (int)(next - (char *)entity->textPtr);
Fred Drake31d485c2004-08-03 07:06:22 +00004810 return result;
4811 }
4812 else {
4813 entity->open = XML_FALSE;
4814 openInternalEntities = openEntity->next;
4815 /* put openEntity back in list of free instances */
4816 openEntity->next = freeInternalEntities;
4817 freeInternalEntities = openEntity;
4818 }
4819
4820#ifdef XML_DTD
4821 if (entity->is_param) {
4822 int tok;
4823 processor = prologProcessor;
4824 tok = XmlPrologTok(encoding, s, end, &next);
4825 return doProlog(parser, encoding, s, end, tok, next, nextPtr,
Trent Mickf08d6632006-06-19 23:21:25 +00004826 (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00004827 }
4828 else
4829#endif /* XML_DTD */
4830 {
4831 processor = contentProcessor;
4832 /* see externalEntityContentProcessor vs contentProcessor */
4833 return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
Trent Mickf08d6632006-06-19 23:21:25 +00004834 nextPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00004835 }
4836}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004837
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004838static enum XML_Error PTRCALL
4839errorProcessor(XML_Parser parser,
4840 const char *s,
4841 const char *end,
4842 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004843{
4844 return errorCode;
4845}
4846
4847static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004848storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4849 const char *ptr, const char *end,
4850 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004851{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004852 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4853 end, pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004854 if (result)
4855 return result;
4856 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4857 poolChop(pool);
4858 if (!poolAppendChar(pool, XML_T('\0')))
4859 return XML_ERROR_NO_MEMORY;
4860 return XML_ERROR_NONE;
4861}
4862
4863static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004864appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4865 const char *ptr, const char *end,
4866 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004867{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004868 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004869 for (;;) {
4870 const char *next;
4871 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4872 switch (tok) {
4873 case XML_TOK_NONE:
4874 return XML_ERROR_NONE;
4875 case XML_TOK_INVALID:
4876 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004877 eventPtr = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004878 return XML_ERROR_INVALID_TOKEN;
4879 case XML_TOK_PARTIAL:
4880 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004881 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004882 return XML_ERROR_INVALID_TOKEN;
4883 case XML_TOK_CHAR_REF:
4884 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004885 XML_Char buf[XML_ENCODE_MAX];
4886 int i;
4887 int n = XmlCharRefNumber(enc, ptr);
4888 if (n < 0) {
4889 if (enc == encoding)
4890 eventPtr = ptr;
4891 return XML_ERROR_BAD_CHAR_REF;
4892 }
4893 if (!isCdata
4894 && n == 0x20 /* space */
4895 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4896 break;
4897 n = XmlEncode(n, (ICHAR *)buf);
4898 if (!n) {
4899 if (enc == encoding)
4900 eventPtr = ptr;
4901 return XML_ERROR_BAD_CHAR_REF;
4902 }
4903 for (i = 0; i < n; i++) {
4904 if (!poolAppendChar(pool, buf[i]))
4905 return XML_ERROR_NO_MEMORY;
4906 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004907 }
4908 break;
4909 case XML_TOK_DATA_CHARS:
4910 if (!poolAppend(pool, enc, ptr, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004911 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004912 break;
4913 case XML_TOK_TRAILING_CR:
4914 next = ptr + enc->minBytesPerChar;
4915 /* fall through */
4916 case XML_TOK_ATTRIBUTE_VALUE_S:
4917 case XML_TOK_DATA_NEWLINE:
4918 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004919 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004920 if (!poolAppendChar(pool, 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004921 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004922 break;
4923 case XML_TOK_ENTITY_REF:
4924 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004925 const XML_Char *name;
4926 ENTITY *entity;
4927 char checkEntityDecl;
4928 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4929 ptr + enc->minBytesPerChar,
4930 next - enc->minBytesPerChar);
4931 if (ch) {
4932 if (!poolAppendChar(pool, ch))
4933 return XML_ERROR_NO_MEMORY;
4934 break;
4935 }
4936 name = poolStoreString(&temp2Pool, enc,
4937 ptr + enc->minBytesPerChar,
4938 next - enc->minBytesPerChar);
4939 if (!name)
4940 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004941 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004942 poolDiscard(&temp2Pool);
Trent Mickf08d6632006-06-19 23:21:25 +00004943 /* First, determine if a check for an existing declaration is needed;
4944 if yes, check that the entity exists, and that it is internal.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004945 */
4946 if (pool == &dtd->pool) /* are we called from prolog? */
4947 checkEntityDecl =
4948#ifdef XML_DTD
4949 prologState.documentEntity &&
4950#endif /* XML_DTD */
4951 (dtd->standalone
4952 ? !openInternalEntities
4953 : !dtd->hasParamEntityRefs);
4954 else /* if (pool == &tempPool): we are called from content */
4955 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4956 if (checkEntityDecl) {
4957 if (!entity)
4958 return XML_ERROR_UNDEFINED_ENTITY;
4959 else if (!entity->is_internal)
4960 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4961 }
4962 else if (!entity) {
Trent Mickf08d6632006-06-19 23:21:25 +00004963 /* Cannot report skipped entity here - see comments on
4964 skippedEntityHandler.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004965 if (skippedEntityHandler)
4966 skippedEntityHandler(handlerArg, name, 0);
4967 */
Trent Mickf08d6632006-06-19 23:21:25 +00004968 /* Cannot call the default handler because this would be
4969 out of sync with the call to the startElementHandler.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004970 if ((pool == &tempPool) && defaultHandler)
4971 reportDefault(parser, enc, ptr, next);
Trent Mickf08d6632006-06-19 23:21:25 +00004972 */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004973 break;
4974 }
4975 if (entity->open) {
4976 if (enc == encoding)
4977 eventPtr = ptr;
4978 return XML_ERROR_RECURSIVE_ENTITY_REF;
4979 }
4980 if (entity->notation) {
4981 if (enc == encoding)
4982 eventPtr = ptr;
4983 return XML_ERROR_BINARY_ENTITY_REF;
4984 }
4985 if (!entity->textPtr) {
4986 if (enc == encoding)
4987 eventPtr = ptr;
4988 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4989 }
4990 else {
4991 enum XML_Error result;
4992 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4993 entity->open = XML_TRUE;
4994 result = appendAttributeValue(parser, internalEncoding, isCdata,
4995 (char *)entity->textPtr,
4996 (char *)textEnd, pool);
4997 entity->open = XML_FALSE;
4998 if (result)
4999 return result;
5000 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005001 }
5002 break;
5003 default:
5004 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005005 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005006 return XML_ERROR_UNEXPECTED_STATE;
5007 }
5008 ptr = next;
5009 }
5010 /* not reached */
5011}
5012
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005013static enum XML_Error
5014storeEntityValue(XML_Parser parser,
5015 const ENCODING *enc,
5016 const char *entityTextPtr,
5017 const char *entityTextEnd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005018{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005019 DTD * const dtd = _dtd; /* save one level of indirection */
5020 STRING_POOL *pool = &(dtd->entityValuePool);
5021 enum XML_Error result = XML_ERROR_NONE;
5022#ifdef XML_DTD
5023 int oldInEntityValue = prologState.inEntityValue;
5024 prologState.inEntityValue = 1;
5025#endif /* XML_DTD */
5026 /* never return Null for the value argument in EntityDeclHandler,
5027 since this would indicate an external entity; therefore we
5028 have to make sure that entityValuePool.start is not null */
5029 if (!pool->blocks) {
5030 if (!poolGrow(pool))
5031 return XML_ERROR_NO_MEMORY;
5032 }
5033
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005034 for (;;) {
5035 const char *next;
5036 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5037 switch (tok) {
5038 case XML_TOK_PARAM_ENTITY_REF:
5039#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005040 if (isParamEntity || enc != encoding) {
5041 const XML_Char *name;
5042 ENTITY *entity;
5043 name = poolStoreString(&tempPool, enc,
5044 entityTextPtr + enc->minBytesPerChar,
5045 next - enc->minBytesPerChar);
5046 if (!name) {
5047 result = XML_ERROR_NO_MEMORY;
5048 goto endEntityValue;
5049 }
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005050 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005051 poolDiscard(&tempPool);
5052 if (!entity) {
5053 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5054 /* cannot report skipped entity here - see comments on
5055 skippedEntityHandler
5056 if (skippedEntityHandler)
5057 skippedEntityHandler(handlerArg, name, 0);
5058 */
5059 dtd->keepProcessing = dtd->standalone;
5060 goto endEntityValue;
5061 }
5062 if (entity->open) {
5063 if (enc == encoding)
5064 eventPtr = entityTextPtr;
5065 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5066 goto endEntityValue;
5067 }
5068 if (entity->systemId) {
5069 if (externalEntityRefHandler) {
5070 dtd->paramEntityRead = XML_FALSE;
5071 entity->open = XML_TRUE;
5072 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5073 0,
5074 entity->base,
5075 entity->systemId,
5076 entity->publicId)) {
5077 entity->open = XML_FALSE;
5078 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5079 goto endEntityValue;
5080 }
5081 entity->open = XML_FALSE;
5082 if (!dtd->paramEntityRead)
5083 dtd->keepProcessing = dtd->standalone;
5084 }
5085 else
5086 dtd->keepProcessing = dtd->standalone;
5087 }
5088 else {
5089 entity->open = XML_TRUE;
5090 result = storeEntityValue(parser,
5091 internalEncoding,
5092 (char *)entity->textPtr,
5093 (char *)(entity->textPtr
5094 + entity->textLen));
5095 entity->open = XML_FALSE;
5096 if (result)
5097 goto endEntityValue;
5098 }
5099 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005100 }
5101#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00005102 /* In the internal subset, PE references are not legal
5103 within markup declarations, e.g entity values in this case. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005104 eventPtr = entityTextPtr;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005105 result = XML_ERROR_PARAM_ENTITY_REF;
5106 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005107 case XML_TOK_NONE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005108 result = XML_ERROR_NONE;
5109 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005110 case XML_TOK_ENTITY_REF:
5111 case XML_TOK_DATA_CHARS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005112 if (!poolAppend(pool, enc, entityTextPtr, next)) {
5113 result = XML_ERROR_NO_MEMORY;
5114 goto endEntityValue;
5115 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005116 break;
5117 case XML_TOK_TRAILING_CR:
5118 next = entityTextPtr + enc->minBytesPerChar;
5119 /* fall through */
5120 case XML_TOK_DATA_NEWLINE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005121 if (pool->end == pool->ptr && !poolGrow(pool)) {
5122 result = XML_ERROR_NO_MEMORY;
5123 goto endEntityValue;
5124 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005125 *(pool->ptr)++ = 0xA;
5126 break;
5127 case XML_TOK_CHAR_REF:
5128 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005129 XML_Char buf[XML_ENCODE_MAX];
5130 int i;
5131 int n = XmlCharRefNumber(enc, entityTextPtr);
5132 if (n < 0) {
5133 if (enc == encoding)
5134 eventPtr = entityTextPtr;
5135 result = XML_ERROR_BAD_CHAR_REF;
5136 goto endEntityValue;
5137 }
5138 n = XmlEncode(n, (ICHAR *)buf);
5139 if (!n) {
5140 if (enc == encoding)
5141 eventPtr = entityTextPtr;
5142 result = XML_ERROR_BAD_CHAR_REF;
5143 goto endEntityValue;
5144 }
5145 for (i = 0; i < n; i++) {
5146 if (pool->end == pool->ptr && !poolGrow(pool)) {
5147 result = XML_ERROR_NO_MEMORY;
5148 goto endEntityValue;
5149 }
5150 *(pool->ptr)++ = buf[i];
5151 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005152 }
5153 break;
5154 case XML_TOK_PARTIAL:
5155 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005156 eventPtr = entityTextPtr;
5157 result = XML_ERROR_INVALID_TOKEN;
5158 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005159 case XML_TOK_INVALID:
5160 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005161 eventPtr = next;
5162 result = XML_ERROR_INVALID_TOKEN;
5163 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005164 default:
5165 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005166 eventPtr = entityTextPtr;
5167 result = XML_ERROR_UNEXPECTED_STATE;
5168 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005169 }
5170 entityTextPtr = next;
5171 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005172endEntityValue:
5173#ifdef XML_DTD
5174 prologState.inEntityValue = oldInEntityValue;
5175#endif /* XML_DTD */
5176 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005177}
5178
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005179static void FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005180normalizeLines(XML_Char *s)
5181{
5182 XML_Char *p;
5183 for (;; s++) {
5184 if (*s == XML_T('\0'))
5185 return;
5186 if (*s == 0xD)
5187 break;
5188 }
5189 p = s;
5190 do {
5191 if (*s == 0xD) {
5192 *p++ = 0xA;
5193 if (*++s == 0xA)
5194 s++;
5195 }
5196 else
5197 *p++ = *s++;
5198 } while (*s);
5199 *p = XML_T('\0');
5200}
5201
5202static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005203reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5204 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005205{
5206 const XML_Char *target;
5207 XML_Char *data;
5208 const char *tem;
5209 if (!processingInstructionHandler) {
5210 if (defaultHandler)
5211 reportDefault(parser, enc, start, end);
5212 return 1;
5213 }
5214 start += enc->minBytesPerChar * 2;
5215 tem = start + XmlNameLength(enc, start);
5216 target = poolStoreString(&tempPool, enc, start, tem);
5217 if (!target)
5218 return 0;
5219 poolFinish(&tempPool);
5220 data = poolStoreString(&tempPool, enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005221 XmlSkipS(enc, tem),
5222 end - enc->minBytesPerChar*2);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005223 if (!data)
5224 return 0;
5225 normalizeLines(data);
5226 processingInstructionHandler(handlerArg, target, data);
5227 poolClear(&tempPool);
5228 return 1;
5229}
5230
5231static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005232reportComment(XML_Parser parser, const ENCODING *enc,
5233 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005234{
5235 XML_Char *data;
5236 if (!commentHandler) {
5237 if (defaultHandler)
5238 reportDefault(parser, enc, start, end);
5239 return 1;
5240 }
5241 data = poolStoreString(&tempPool,
5242 enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005243 start + enc->minBytesPerChar * 4,
5244 end - enc->minBytesPerChar * 3);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005245 if (!data)
5246 return 0;
5247 normalizeLines(data);
5248 commentHandler(handlerArg, data);
5249 poolClear(&tempPool);
5250 return 1;
5251}
5252
5253static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005254reportDefault(XML_Parser parser, const ENCODING *enc,
5255 const char *s, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005256{
5257 if (MUST_CONVERT(enc, s)) {
5258 const char **eventPP;
5259 const char **eventEndPP;
5260 if (enc == encoding) {
5261 eventPP = &eventPtr;
5262 eventEndPP = &eventEndPtr;
5263 }
5264 else {
5265 eventPP = &(openInternalEntities->internalEventPtr);
5266 eventEndPP = &(openInternalEntities->internalEventEndPtr);
5267 }
5268 do {
5269 ICHAR *dataPtr = (ICHAR *)dataBuf;
5270 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5271 *eventEndPP = s;
Trent Mickf08d6632006-06-19 23:21:25 +00005272 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005273 *eventPP = s;
5274 } while (s != end);
5275 }
5276 else
Trent Mickf08d6632006-06-19 23:21:25 +00005277 defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005278}
5279
5280
5281static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005282defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5283 XML_Bool isId, const XML_Char *value, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005284{
5285 DEFAULT_ATTRIBUTE *att;
5286 if (value || isId) {
5287 /* The handling of default attributes gets messed up if we have
5288 a default which duplicates a non-default. */
5289 int i;
5290 for (i = 0; i < type->nDefaultAtts; i++)
5291 if (attId == type->defaultAtts[i].id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005292 return 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005293 if (isId && !type->idAtt && !attId->xmlns)
5294 type->idAtt = attId;
5295 }
5296 if (type->nDefaultAtts == type->allocDefaultAtts) {
5297 if (type->allocDefaultAtts == 0) {
5298 type->allocDefaultAtts = 8;
Fred Drake08317ae2003-10-21 15:38:55 +00005299 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005300 * sizeof(DEFAULT_ATTRIBUTE));
5301 if (!type->defaultAtts)
5302 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005303 }
5304 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005305 DEFAULT_ATTRIBUTE *temp;
5306 int count = type->allocDefaultAtts * 2;
5307 temp = (DEFAULT_ATTRIBUTE *)
5308 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5309 if (temp == NULL)
5310 return 0;
5311 type->allocDefaultAtts = count;
5312 type->defaultAtts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005313 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005314 }
5315 att = type->defaultAtts + type->nDefaultAtts;
5316 att->id = attId;
5317 att->value = value;
5318 att->isCdata = isCdata;
5319 if (!isCdata)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005320 attId->maybeTokenized = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005321 type->nDefaultAtts += 1;
5322 return 1;
5323}
5324
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005325static int
5326setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005327{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005328 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005329 const XML_Char *name;
5330 for (name = elementType->name; *name; name++) {
5331 if (*name == XML_T(':')) {
5332 PREFIX *prefix;
5333 const XML_Char *s;
5334 for (s = elementType->name; s != name; s++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005335 if (!poolAppendChar(&dtd->pool, *s))
5336 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005337 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005338 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5339 return 0;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005340 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005341 sizeof(PREFIX));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005342 if (!prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005343 return 0;
5344 if (prefix->name == poolStart(&dtd->pool))
5345 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005346 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005347 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005348 elementType->prefix = prefix;
5349
5350 }
5351 }
5352 return 1;
5353}
5354
5355static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005356getAttributeId(XML_Parser parser, const ENCODING *enc,
5357 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005358{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005359 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005360 ATTRIBUTE_ID *id;
5361 const XML_Char *name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005362 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5363 return NULL;
5364 name = poolStoreString(&dtd->pool, enc, start, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005365 if (!name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005366 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005367 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005368 ++name;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005369 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005370 if (!id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005371 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005372 if (id->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005373 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005374 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005375 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005376 if (!ns)
5377 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005378 else if (name[0] == XML_T('x')
5379 && name[1] == XML_T('m')
5380 && name[2] == XML_T('l')
5381 && name[3] == XML_T('n')
5382 && name[4] == XML_T('s')
5383 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
5384 if (name[5] == XML_T('\0'))
5385 id->prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005386 else
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005387 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005388 id->xmlns = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005389 }
5390 else {
5391 int i;
5392 for (i = 0; name[i]; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005393 /* attributes without prefix are *not* in the default namespace */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005394 if (name[i] == XML_T(':')) {
5395 int j;
5396 for (j = 0; j < i; j++) {
5397 if (!poolAppendChar(&dtd->pool, name[j]))
5398 return NULL;
5399 }
5400 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5401 return NULL;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005402 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005403 sizeof(PREFIX));
Neal Norwitz26a8abf2006-08-13 18:12:26 +00005404 if (!id->prefix)
5405 return NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005406 if (id->prefix->name == poolStart(&dtd->pool))
5407 poolFinish(&dtd->pool);
5408 else
5409 poolDiscard(&dtd->pool);
5410 break;
5411 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005412 }
5413 }
5414 }
5415 return id;
5416}
5417
5418#define CONTEXT_SEP XML_T('\f')
5419
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005420static const XML_Char *
5421getContext(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005422{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005423 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005424 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005425 XML_Bool needSep = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005426
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005427 if (dtd->defaultPrefix.binding) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005428 int i;
5429 int len;
5430 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005431 return NULL;
5432 len = dtd->defaultPrefix.binding->uriLen;
Trent Mickf08d6632006-06-19 23:21:25 +00005433 if (namespaceSeparator)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005434 len--;
5435 for (i = 0; i < len; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005436 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5437 return NULL;
5438 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005439 }
5440
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005441 hashTableIterInit(&iter, &(dtd->prefixes));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005442 for (;;) {
5443 int i;
5444 int len;
5445 const XML_Char *s;
5446 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5447 if (!prefix)
5448 break;
5449 if (!prefix->binding)
5450 continue;
5451 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005452 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005453 for (s = prefix->name; *s; s++)
5454 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005455 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005456 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005457 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005458 len = prefix->binding->uriLen;
Trent Mickf08d6632006-06-19 23:21:25 +00005459 if (namespaceSeparator)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005460 len--;
5461 for (i = 0; i < len; i++)
5462 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005463 return NULL;
5464 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005465 }
5466
5467
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005468 hashTableIterInit(&iter, &(dtd->generalEntities));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005469 for (;;) {
5470 const XML_Char *s;
5471 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5472 if (!e)
5473 break;
5474 if (!e->open)
5475 continue;
5476 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005477 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005478 for (s = e->name; *s; s++)
5479 if (!poolAppendChar(&tempPool, *s))
5480 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005481 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005482 }
5483
5484 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005485 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005486 return tempPool.start;
5487}
5488
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005489static XML_Bool
5490setContext(XML_Parser parser, const XML_Char *context)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005491{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005492 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005493 const XML_Char *s = context;
5494
5495 while (*context != XML_T('\0')) {
5496 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5497 ENTITY *e;
5498 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005499 return XML_FALSE;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005500 e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005501 if (e)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005502 e->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005503 if (*s != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005504 s++;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005505 context = s;
5506 poolDiscard(&tempPool);
5507 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005508 else if (*s == XML_T('=')) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005509 PREFIX *prefix;
5510 if (poolLength(&tempPool) == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005511 prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005512 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005513 if (!poolAppendChar(&tempPool, XML_T('\0')))
5514 return XML_FALSE;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005515 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005516 sizeof(PREFIX));
5517 if (!prefix)
5518 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005519 if (prefix->name == poolStart(&tempPool)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005520 prefix->name = poolCopyString(&dtd->pool, prefix->name);
5521 if (!prefix->name)
5522 return XML_FALSE;
5523 }
5524 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005525 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005526 for (context = s + 1;
5527 *context != CONTEXT_SEP && *context != XML_T('\0');
5528 context++)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005529 if (!poolAppendChar(&tempPool, *context))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005530 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005531 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005532 return XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00005533 if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005534 &inheritedBindings) != XML_ERROR_NONE)
5535 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005536 poolDiscard(&tempPool);
5537 if (*context != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005538 ++context;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005539 s = context;
5540 }
5541 else {
5542 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005543 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005544 s++;
5545 }
5546 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005547 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005548}
5549
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005550static void FASTCALL
5551normalizePublicId(XML_Char *publicId)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005552{
5553 XML_Char *p = publicId;
5554 XML_Char *s;
5555 for (s = publicId; *s; s++) {
5556 switch (*s) {
5557 case 0x20:
5558 case 0xD:
5559 case 0xA:
5560 if (p != publicId && p[-1] != 0x20)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005561 *p++ = 0x20;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005562 break;
5563 default:
5564 *p++ = *s;
5565 }
5566 }
5567 if (p != publicId && p[-1] == 0x20)
5568 --p;
5569 *p = XML_T('\0');
5570}
5571
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005572static DTD *
5573dtdCreate(const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005574{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005575 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5576 if (p == NULL)
5577 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005578 poolInit(&(p->pool), ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005579 poolInit(&(p->entityValuePool), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005580 hashTableInit(&(p->generalEntities), ms);
5581 hashTableInit(&(p->elementTypes), ms);
5582 hashTableInit(&(p->attributeIds), ms);
5583 hashTableInit(&(p->prefixes), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005584#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005585 p->paramEntityRead = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005586 hashTableInit(&(p->paramEntities), ms);
5587#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005588 p->defaultPrefix.name = NULL;
5589 p->defaultPrefix.binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005590
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005591 p->in_eldecl = XML_FALSE;
5592 p->scaffIndex = NULL;
5593 p->scaffold = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005594 p->scaffLevel = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005595 p->scaffSize = 0;
5596 p->scaffCount = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005597 p->contentStringLen = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005598
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005599 p->keepProcessing = XML_TRUE;
5600 p->hasParamEntityRefs = XML_FALSE;
5601 p->standalone = XML_FALSE;
5602 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005603}
5604
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005605static void
5606dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005607{
5608 HASH_TABLE_ITER iter;
5609 hashTableIterInit(&iter, &(p->elementTypes));
5610 for (;;) {
5611 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5612 if (!e)
5613 break;
5614 if (e->allocDefaultAtts != 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005615 ms->free_fcn(e->defaultAtts);
5616 }
5617 hashTableClear(&(p->generalEntities));
5618#ifdef XML_DTD
5619 p->paramEntityRead = XML_FALSE;
5620 hashTableClear(&(p->paramEntities));
5621#endif /* XML_DTD */
5622 hashTableClear(&(p->elementTypes));
5623 hashTableClear(&(p->attributeIds));
5624 hashTableClear(&(p->prefixes));
5625 poolClear(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005626 poolClear(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005627 p->defaultPrefix.name = NULL;
5628 p->defaultPrefix.binding = NULL;
5629
5630 p->in_eldecl = XML_FALSE;
Fred Drake08317ae2003-10-21 15:38:55 +00005631
5632 ms->free_fcn(p->scaffIndex);
5633 p->scaffIndex = NULL;
5634 ms->free_fcn(p->scaffold);
5635 p->scaffold = NULL;
5636
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005637 p->scaffLevel = 0;
5638 p->scaffSize = 0;
5639 p->scaffCount = 0;
5640 p->contentStringLen = 0;
5641
5642 p->keepProcessing = XML_TRUE;
5643 p->hasParamEntityRefs = XML_FALSE;
5644 p->standalone = XML_FALSE;
5645}
5646
5647static void
5648dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5649{
5650 HASH_TABLE_ITER iter;
5651 hashTableIterInit(&iter, &(p->elementTypes));
5652 for (;;) {
5653 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5654 if (!e)
5655 break;
5656 if (e->allocDefaultAtts != 0)
5657 ms->free_fcn(e->defaultAtts);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005658 }
5659 hashTableDestroy(&(p->generalEntities));
5660#ifdef XML_DTD
5661 hashTableDestroy(&(p->paramEntities));
5662#endif /* XML_DTD */
5663 hashTableDestroy(&(p->elementTypes));
5664 hashTableDestroy(&(p->attributeIds));
5665 hashTableDestroy(&(p->prefixes));
5666 poolDestroy(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005667 poolDestroy(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005668 if (isDocEntity) {
Fred Drake08317ae2003-10-21 15:38:55 +00005669 ms->free_fcn(p->scaffIndex);
5670 ms->free_fcn(p->scaffold);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005671 }
5672 ms->free_fcn(p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005673}
5674
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005675/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5676 The new DTD has already been initialized.
5677*/
5678static int
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005679dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005680{
5681 HASH_TABLE_ITER iter;
5682
5683 /* Copy the prefix table. */
5684
5685 hashTableIterInit(&iter, &(oldDtd->prefixes));
5686 for (;;) {
5687 const XML_Char *name;
5688 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5689 if (!oldP)
5690 break;
5691 name = poolCopyString(&(newDtd->pool), oldP->name);
5692 if (!name)
5693 return 0;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005694 if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005695 return 0;
5696 }
5697
5698 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5699
5700 /* Copy the attribute id table. */
5701
5702 for (;;) {
5703 ATTRIBUTE_ID *newA;
5704 const XML_Char *name;
5705 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5706
5707 if (!oldA)
5708 break;
5709 /* Remember to allocate the scratch byte before the name. */
5710 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5711 return 0;
5712 name = poolCopyString(&(newDtd->pool), oldA->name);
5713 if (!name)
5714 return 0;
5715 ++name;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005716 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005717 sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005718 if (!newA)
5719 return 0;
5720 newA->maybeTokenized = oldA->maybeTokenized;
5721 if (oldA->prefix) {
5722 newA->xmlns = oldA->xmlns;
5723 if (oldA->prefix == &oldDtd->defaultPrefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005724 newA->prefix = &newDtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005725 else
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005726 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005727 oldA->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005728 }
5729 }
5730
5731 /* Copy the element type table. */
5732
5733 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5734
5735 for (;;) {
5736 int i;
5737 ELEMENT_TYPE *newE;
5738 const XML_Char *name;
5739 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5740 if (!oldE)
5741 break;
5742 name = poolCopyString(&(newDtd->pool), oldE->name);
5743 if (!name)
5744 return 0;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005745 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005746 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005747 if (!newE)
5748 return 0;
5749 if (oldE->nDefaultAtts) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005750 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5751 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5752 if (!newE->defaultAtts) {
5753 ms->free_fcn(newE);
5754 return 0;
5755 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005756 }
5757 if (oldE->idAtt)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005758 newE->idAtt = (ATTRIBUTE_ID *)
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005759 lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005760 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5761 if (oldE->prefix)
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005762 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005763 oldE->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005764 for (i = 0; i < newE->nDefaultAtts; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005765 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005766 lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005767 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5768 if (oldE->defaultAtts[i].value) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005769 newE->defaultAtts[i].value
5770 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5771 if (!newE->defaultAtts[i].value)
5772 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005773 }
5774 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005775 newE->defaultAtts[i].value = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005776 }
5777 }
5778
5779 /* Copy the entity tables. */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005780 if (!copyEntityTable(oldParser,
5781 &(newDtd->generalEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005782 &(newDtd->pool),
5783 &(oldDtd->generalEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005784 return 0;
5785
5786#ifdef XML_DTD
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005787 if (!copyEntityTable(oldParser,
5788 &(newDtd->paramEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005789 &(newDtd->pool),
5790 &(oldDtd->paramEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005791 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005792 newDtd->paramEntityRead = oldDtd->paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005793#endif /* XML_DTD */
5794
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005795 newDtd->keepProcessing = oldDtd->keepProcessing;
5796 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005797 newDtd->standalone = oldDtd->standalone;
5798
5799 /* Don't want deep copying for scaffolding */
5800 newDtd->in_eldecl = oldDtd->in_eldecl;
5801 newDtd->scaffold = oldDtd->scaffold;
5802 newDtd->contentStringLen = oldDtd->contentStringLen;
5803 newDtd->scaffSize = oldDtd->scaffSize;
5804 newDtd->scaffLevel = oldDtd->scaffLevel;
5805 newDtd->scaffIndex = oldDtd->scaffIndex;
5806
5807 return 1;
5808} /* End dtdCopy */
5809
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005810static int
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005811copyEntityTable(XML_Parser oldParser,
5812 HASH_TABLE *newTable,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005813 STRING_POOL *newPool,
5814 const HASH_TABLE *oldTable)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005815{
5816 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005817 const XML_Char *cachedOldBase = NULL;
5818 const XML_Char *cachedNewBase = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005819
5820 hashTableIterInit(&iter, oldTable);
5821
5822 for (;;) {
5823 ENTITY *newE;
5824 const XML_Char *name;
5825 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5826 if (!oldE)
5827 break;
5828 name = poolCopyString(newPool, oldE->name);
5829 if (!name)
5830 return 0;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005831 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005832 if (!newE)
5833 return 0;
5834 if (oldE->systemId) {
5835 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5836 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005837 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005838 newE->systemId = tem;
5839 if (oldE->base) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005840 if (oldE->base == cachedOldBase)
5841 newE->base = cachedNewBase;
5842 else {
5843 cachedOldBase = oldE->base;
5844 tem = poolCopyString(newPool, cachedOldBase);
5845 if (!tem)
5846 return 0;
5847 cachedNewBase = newE->base = tem;
5848 }
5849 }
5850 if (oldE->publicId) {
5851 tem = poolCopyString(newPool, oldE->publicId);
5852 if (!tem)
5853 return 0;
5854 newE->publicId = tem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005855 }
5856 }
5857 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005858 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5859 oldE->textLen);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005860 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005861 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005862 newE->textPtr = tem;
5863 newE->textLen = oldE->textLen;
5864 }
5865 if (oldE->notation) {
5866 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5867 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005868 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005869 newE->notation = tem;
5870 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005871 newE->is_param = oldE->is_param;
5872 newE->is_internal = oldE->is_internal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005873 }
5874 return 1;
5875}
5876
Fred Drake08317ae2003-10-21 15:38:55 +00005877#define INIT_POWER 6
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005878
Fred Drake08317ae2003-10-21 15:38:55 +00005879static XML_Bool FASTCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005880keyeq(KEY s1, KEY s2)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005881{
5882 for (; *s1 == *s2; s1++, s2++)
5883 if (*s1 == 0)
Fred Drake08317ae2003-10-21 15:38:55 +00005884 return XML_TRUE;
5885 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005886}
5887
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005888static unsigned long FASTCALL
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005889hash(XML_Parser parser, KEY s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005890{
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005891 unsigned long h = hash_secret_salt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005892 while (*s)
Fred Drake08317ae2003-10-21 15:38:55 +00005893 h = CHAR_HASH(h, *s++);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005894 return h;
5895}
5896
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005897static NAMED *
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005898lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005899{
5900 size_t i;
5901 if (table->size == 0) {
5902 size_t tsize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005903 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005904 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005905 table->power = INIT_POWER;
5906 /* table->size is a power of 2 */
5907 table->size = (size_t)1 << INIT_POWER;
5908 tsize = table->size * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005909 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Fred Drake31d485c2004-08-03 07:06:22 +00005910 if (!table->v) {
5911 table->size = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005912 return NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00005913 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005914 memset(table->v, 0, tsize);
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005915 i = hash(parser, name) & ((unsigned long)table->size - 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005916 }
5917 else {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005918 unsigned long h = hash(parser, name);
Fred Drake08317ae2003-10-21 15:38:55 +00005919 unsigned long mask = (unsigned long)table->size - 1;
5920 unsigned char step = 0;
5921 i = h & mask;
5922 while (table->v[i]) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005923 if (keyeq(name, table->v[i]->name))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005924 return table->v[i];
Fred Drake08317ae2003-10-21 15:38:55 +00005925 if (!step)
5926 step = PROBE_STEP(h, mask, table->power);
5927 i < step ? (i += table->size - step) : (i -= step);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005928 }
5929 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005930 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005931
5932 /* check for overflow (table is half full) */
5933 if (table->used >> (table->power - 1)) {
5934 unsigned char newPower = table->power + 1;
5935 size_t newSize = (size_t)1 << newPower;
5936 unsigned long newMask = (unsigned long)newSize - 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005937 size_t tsize = newSize * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005938 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005939 if (!newV)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005940 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005941 memset(newV, 0, tsize);
5942 for (i = 0; i < table->size; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005943 if (table->v[i]) {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005944 unsigned long newHash = hash(parser, table->v[i]->name);
Fred Drake08317ae2003-10-21 15:38:55 +00005945 size_t j = newHash & newMask;
5946 step = 0;
5947 while (newV[j]) {
5948 if (!step)
5949 step = PROBE_STEP(newHash, newMask, newPower);
5950 j < step ? (j += newSize - step) : (j -= step);
5951 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005952 newV[j] = table->v[i];
5953 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005954 table->mem->free_fcn(table->v);
5955 table->v = newV;
Fred Drake08317ae2003-10-21 15:38:55 +00005956 table->power = newPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005957 table->size = newSize;
Fred Drake08317ae2003-10-21 15:38:55 +00005958 i = h & newMask;
5959 step = 0;
5960 while (table->v[i]) {
5961 if (!step)
5962 step = PROBE_STEP(h, newMask, newPower);
5963 i < step ? (i += newSize - step) : (i -= step);
5964 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005965 }
5966 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005967 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005968 if (!table->v[i])
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005969 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005970 memset(table->v[i], 0, createSize);
5971 table->v[i]->name = name;
5972 (table->used)++;
5973 return table->v[i];
5974}
5975
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005976static void FASTCALL
5977hashTableClear(HASH_TABLE *table)
5978{
5979 size_t i;
5980 for (i = 0; i < table->size; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005981 table->mem->free_fcn(table->v[i]);
5982 table->v[i] = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005983 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005984 table->used = 0;
5985}
5986
5987static void FASTCALL
5988hashTableDestroy(HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005989{
5990 size_t i;
Fred Drake08317ae2003-10-21 15:38:55 +00005991 for (i = 0; i < table->size; i++)
5992 table->mem->free_fcn(table->v[i]);
5993 table->mem->free_fcn(table->v);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005994}
5995
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005996static void FASTCALL
5997hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005998{
Fred Drake08317ae2003-10-21 15:38:55 +00005999 p->power = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006000 p->size = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006001 p->used = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006002 p->v = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006003 p->mem = ms;
6004}
6005
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006006static void FASTCALL
6007hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006008{
6009 iter->p = table->v;
6010 iter->end = iter->p + table->size;
6011}
6012
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006013static NAMED * FASTCALL
6014hashTableIterNext(HASH_TABLE_ITER *iter)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006015{
6016 while (iter->p != iter->end) {
6017 NAMED *tem = *(iter->p)++;
6018 if (tem)
6019 return tem;
6020 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006021 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006022}
6023
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006024static void FASTCALL
6025poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006026{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006027 pool->blocks = NULL;
6028 pool->freeBlocks = NULL;
6029 pool->start = NULL;
6030 pool->ptr = NULL;
6031 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006032 pool->mem = ms;
6033}
6034
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006035static void FASTCALL
6036poolClear(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006037{
6038 if (!pool->freeBlocks)
6039 pool->freeBlocks = pool->blocks;
6040 else {
6041 BLOCK *p = pool->blocks;
6042 while (p) {
6043 BLOCK *tem = p->next;
6044 p->next = pool->freeBlocks;
6045 pool->freeBlocks = p;
6046 p = tem;
6047 }
6048 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006049 pool->blocks = NULL;
6050 pool->start = NULL;
6051 pool->ptr = NULL;
6052 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006053}
6054
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006055static void FASTCALL
6056poolDestroy(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006057{
6058 BLOCK *p = pool->blocks;
6059 while (p) {
6060 BLOCK *tem = p->next;
6061 pool->mem->free_fcn(p);
6062 p = tem;
6063 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006064 p = pool->freeBlocks;
6065 while (p) {
6066 BLOCK *tem = p->next;
6067 pool->mem->free_fcn(p);
6068 p = tem;
6069 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006070}
6071
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006072static XML_Char *
6073poolAppend(STRING_POOL *pool, const ENCODING *enc,
6074 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006075{
6076 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006077 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006078 for (;;) {
6079 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6080 if (ptr == end)
6081 break;
6082 if (!poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006083 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006084 }
6085 return pool->start;
6086}
6087
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006088static const XML_Char * FASTCALL
6089poolCopyString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006090{
6091 do {
6092 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006093 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006094 } while (*s++);
6095 s = pool->start;
6096 poolFinish(pool);
6097 return s;
6098}
6099
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006100static const XML_Char *
6101poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006102{
6103 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006104 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006105 for (; n > 0; --n, s++) {
6106 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006107 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006108 }
6109 s = pool->start;
6110 poolFinish(pool);
6111 return s;
6112}
6113
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006114static const XML_Char * FASTCALL
6115poolAppendString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006116{
6117 while (*s) {
6118 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006119 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006120 s++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006121 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006122 return pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006123}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006124
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006125static XML_Char *
6126poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6127 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006128{
6129 if (!poolAppend(pool, enc, ptr, end))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006130 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006131 if (pool->ptr == pool->end && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006132 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006133 *(pool->ptr)++ = 0;
6134 return pool->start;
6135}
6136
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006137static XML_Bool FASTCALL
6138poolGrow(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006139{
6140 if (pool->freeBlocks) {
6141 if (pool->start == 0) {
6142 pool->blocks = pool->freeBlocks;
6143 pool->freeBlocks = pool->freeBlocks->next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006144 pool->blocks->next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006145 pool->start = pool->blocks->s;
6146 pool->end = pool->start + pool->blocks->size;
6147 pool->ptr = pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006148 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006149 }
6150 if (pool->end - pool->start < pool->freeBlocks->size) {
6151 BLOCK *tem = pool->freeBlocks->next;
6152 pool->freeBlocks->next = pool->blocks;
6153 pool->blocks = pool->freeBlocks;
6154 pool->freeBlocks = tem;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006155 memcpy(pool->blocks->s, pool->start,
6156 (pool->end - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006157 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6158 pool->start = pool->blocks->s;
6159 pool->end = pool->start + pool->blocks->size;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006160 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006161 }
6162 }
6163 if (pool->blocks && pool->start == pool->blocks->s) {
Trent Mickf08d6632006-06-19 23:21:25 +00006164 int blockSize = (int)(pool->end - pool->start)*2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006165 pool->blocks = (BLOCK *)
6166 pool->mem->realloc_fcn(pool->blocks,
Fred Drake08317ae2003-10-21 15:38:55 +00006167 (offsetof(BLOCK, s)
6168 + blockSize * sizeof(XML_Char)));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006169 if (pool->blocks == NULL)
6170 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006171 pool->blocks->size = blockSize;
6172 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6173 pool->start = pool->blocks->s;
6174 pool->end = pool->start + blockSize;
6175 }
6176 else {
6177 BLOCK *tem;
Trent Mickf08d6632006-06-19 23:21:25 +00006178 int blockSize = (int)(pool->end - pool->start);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006179 if (blockSize < INIT_BLOCK_SIZE)
6180 blockSize = INIT_BLOCK_SIZE;
6181 else
6182 blockSize *= 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006183 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
Fred Drake08317ae2003-10-21 15:38:55 +00006184 + blockSize * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006185 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006186 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006187 tem->size = blockSize;
6188 tem->next = pool->blocks;
6189 pool->blocks = tem;
6190 if (pool->ptr != pool->start)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006191 memcpy(tem->s, pool->start,
6192 (pool->ptr - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006193 pool->ptr = tem->s + (pool->ptr - pool->start);
6194 pool->start = tem->s;
6195 pool->end = tem->s + blockSize;
6196 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006197 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006198}
6199
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006200static int FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006201nextScaffoldPart(XML_Parser parser)
6202{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006203 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006204 CONTENT_SCAFFOLD * me;
6205 int next;
6206
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006207 if (!dtd->scaffIndex) {
6208 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6209 if (!dtd->scaffIndex)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006210 return -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006211 dtd->scaffIndex[0] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006212 }
6213
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006214 if (dtd->scaffCount >= dtd->scaffSize) {
6215 CONTENT_SCAFFOLD *temp;
6216 if (dtd->scaffold) {
6217 temp = (CONTENT_SCAFFOLD *)
6218 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6219 if (temp == NULL)
6220 return -1;
6221 dtd->scaffSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006222 }
6223 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006224 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6225 * sizeof(CONTENT_SCAFFOLD));
6226 if (temp == NULL)
6227 return -1;
6228 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006229 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006230 dtd->scaffold = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006231 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006232 next = dtd->scaffCount++;
6233 me = &dtd->scaffold[next];
6234 if (dtd->scaffLevel) {
6235 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006236 if (parent->lastchild) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006237 dtd->scaffold[parent->lastchild].nextsib = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006238 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006239 if (!parent->childcnt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006240 parent->firstchild = next;
6241 parent->lastchild = next;
6242 parent->childcnt++;
6243 }
6244 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6245 return next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006246}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006247
6248static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006249build_node(XML_Parser parser,
6250 int src_node,
6251 XML_Content *dest,
6252 XML_Content **contpos,
6253 XML_Char **strpos)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006254{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006255 DTD * const dtd = _dtd; /* save one level of indirection */
6256 dest->type = dtd->scaffold[src_node].type;
6257 dest->quant = dtd->scaffold[src_node].quant;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006258 if (dest->type == XML_CTYPE_NAME) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006259 const XML_Char *src;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006260 dest->name = *strpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006261 src = dtd->scaffold[src_node].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006262 for (;;) {
6263 *(*strpos)++ = *src;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006264 if (!*src)
6265 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006266 src++;
6267 }
6268 dest->numchildren = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006269 dest->children = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006270 }
6271 else {
6272 unsigned int i;
6273 int cn;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006274 dest->numchildren = dtd->scaffold[src_node].childcnt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006275 dest->children = *contpos;
6276 *contpos += dest->numchildren;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006277 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6278 i < dest->numchildren;
6279 i++, cn = dtd->scaffold[cn].nextsib) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006280 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6281 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006282 dest->name = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006283 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006284}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006285
6286static XML_Content *
6287build_model (XML_Parser parser)
6288{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006289 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006290 XML_Content *ret;
6291 XML_Content *cpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006292 XML_Char * str;
6293 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6294 + (dtd->contentStringLen * sizeof(XML_Char)));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006295
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006296 ret = (XML_Content *)MALLOC(allocsize);
6297 if (!ret)
6298 return NULL;
6299
6300 str = (XML_Char *) (&ret[dtd->scaffCount]);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006301 cpos = &ret[1];
6302
6303 build_node(parser, 0, ret, &cpos, &str);
6304 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006305}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006306
6307static ELEMENT_TYPE *
6308getElementType(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006309 const ENCODING *enc,
6310 const char *ptr,
6311 const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006312{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006313 DTD * const dtd = _dtd; /* save one level of indirection */
6314 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006315 ELEMENT_TYPE *ret;
6316
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006317 if (!name)
6318 return NULL;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07006319 ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006320 if (!ret)
6321 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006322 if (ret->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006323 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006324 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006325 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006326 if (!setElementTypePrefix(parser, ret))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006327 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006328 }
6329 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006330}