blob: 105958b64965463f510ef0ff6c4b57478bbcffb2 [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"
Thomas Wouters0e3f5912006-08-11 14:57:12 +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
Thomas Wouters477c8d52006-05-27 19:21:47 +000017#include <stddef.h>
18#include <string.h> /* memset(), memcpy() */
19#include <assert.h>
20
Fred Drake08317ae2003-10-21 15:38:55 +000021#include "expat.h"
22
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000023#ifdef XML_UNICODE
24#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
25#define XmlConvert XmlUtf16Convert
26#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
27#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
28#define XmlEncode XmlUtf16Encode
29#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
30typedef unsigned short ICHAR;
31#else
32#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
33#define XmlConvert XmlUtf8Convert
34#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
35#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
36#define XmlEncode XmlUtf8Encode
37#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
38typedef char ICHAR;
39#endif
40
41
42#ifndef XML_NS
43
44#define XmlInitEncodingNS XmlInitEncoding
45#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
46#undef XmlGetInternalEncodingNS
47#define XmlGetInternalEncodingNS XmlGetInternalEncoding
48#define XmlParseXmlDeclNS XmlParseXmlDecl
49
50#endif
51
Martin v. Löwisfc03a942003-01-25 22:41:29 +000052#ifdef XML_UNICODE
53
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000054#ifdef XML_UNICODE_WCHAR_T
Martin v. Löwisfc03a942003-01-25 22:41:29 +000055#define XML_T(x) (const wchar_t)x
56#define XML_L(x) L ## x
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000057#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +000058#define XML_T(x) (const unsigned short)x
59#define XML_L(x) x
60#endif
61
62#else
63
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000064#define XML_T(x) x
Martin v. Löwisfc03a942003-01-25 22:41:29 +000065#define XML_L(x) x
66
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000067#endif
68
69/* Round up n to be a multiple of sz, where sz is a power of 2. */
70#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
71
Fred Drake08317ae2003-10-21 15:38:55 +000072/* Handle the case where memmove() doesn't exist. */
73#ifndef HAVE_MEMMOVE
74#ifdef HAVE_BCOPY
75#define memmove(d,s,l) bcopy((s),(d),(l))
76#else
77#error memmove does not exist on this platform, nor is a substitute available
78#endif /* HAVE_BCOPY */
79#endif /* HAVE_MEMMOVE */
80
Martin v. Löwisfc03a942003-01-25 22:41:29 +000081#include "internal.h"
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000082#include "xmltok.h"
83#include "xmlrole.h"
84
85typedef const XML_Char *KEY;
86
87typedef struct {
88 KEY name;
89} NAMED;
90
91typedef struct {
92 NAMED **v;
Fred Drake08317ae2003-10-21 15:38:55 +000093 unsigned char power;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000094 size_t size;
95 size_t used;
Martin v. Löwisfc03a942003-01-25 22:41:29 +000096 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000097} HASH_TABLE;
98
Fred Drake08317ae2003-10-21 15:38:55 +000099/* Basic character hash algorithm, taken from Python's string hash:
100 h = h * 1000003 ^ character, the constant being a prime number.
101
102*/
103#ifdef XML_UNICODE
104#define CHAR_HASH(h, c) \
105 (((h) * 0xF4243) ^ (unsigned short)(c))
106#else
107#define CHAR_HASH(h, c) \
108 (((h) * 0xF4243) ^ (unsigned char)(c))
109#endif
110
111/* For probing (after a collision) we need a step size relative prime
112 to the hash table size, which is a power of 2. We use double-hashing,
113 since we can calculate a second hash value cheaply by taking those bits
114 of the first hash value that were discarded (masked out) when the table
115 index was calculated: index = hash & mask, where mask = table->size - 1.
116 We limit the maximum step size to table->size / 4 (mask >> 2) and make
117 it odd, since odd numbers are always relative prime to a power of 2.
118*/
119#define SECOND_HASH(hash, mask, power) \
120 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
121#define PROBE_STEP(hash, mask, power) \
122 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
123
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000124typedef struct {
125 NAMED **p;
126 NAMED **end;
127} HASH_TABLE_ITER;
128
129#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
130#define INIT_DATA_BUF_SIZE 1024
131#define INIT_ATTS_SIZE 16
Fred Drake08317ae2003-10-21 15:38:55 +0000132#define INIT_ATTS_VERSION 0xFFFFFFFF
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000133#define INIT_BLOCK_SIZE 1024
134#define INIT_BUFFER_SIZE 1024
135
136#define EXPAND_SPARE 24
137
138typedef struct binding {
139 struct prefix *prefix;
140 struct binding *nextTagBinding;
141 struct binding *prevPrefixBinding;
142 const struct attribute_id *attId;
143 XML_Char *uri;
144 int uriLen;
145 int uriAlloc;
146} BINDING;
147
148typedef struct prefix {
149 const XML_Char *name;
150 BINDING *binding;
151} PREFIX;
152
153typedef struct {
154 const XML_Char *str;
155 const XML_Char *localPart;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000156 const XML_Char *prefix;
157 int strLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000158 int uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000159 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000160} TAG_NAME;
161
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000162/* TAG represents an open element.
163 The name of the element is stored in both the document and API
164 encodings. The memory buffer 'buf' is a separately-allocated
165 memory area which stores the name. During the XML_Parse()/
166 XMLParseBuffer() when the element is open, the memory for the 'raw'
167 version of the name (in the document encoding) is shared with the
168 document buffer. If the element is open across calls to
169 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
170 contain the 'raw' name as well.
171
172 A parser re-uses these structures, maintaining a list of allocated
173 TAG objects in a free list.
174*/
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000175typedef struct tag {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000176 struct tag *parent; /* parent of this element */
177 const char *rawName; /* tagName in the original encoding */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000178 int rawNameLength;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000179 TAG_NAME name; /* tagName in the API encoding */
180 char *buf; /* buffer for name components */
181 char *bufEnd; /* end of the buffer */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000182 BINDING *bindings;
183} TAG;
184
185typedef struct {
186 const XML_Char *name;
187 const XML_Char *textPtr;
Fred Drake31d485c2004-08-03 07:06:22 +0000188 int textLen; /* length in XML_Chars */
189 int processed; /* # of processed bytes - when suspended */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000190 const XML_Char *systemId;
191 const XML_Char *base;
192 const XML_Char *publicId;
193 const XML_Char *notation;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000194 XML_Bool open;
195 XML_Bool is_param;
196 XML_Bool is_internal; /* true if declared in internal subset outside PE */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000197} ENTITY;
198
199typedef struct {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000200 enum XML_Content_Type type;
201 enum XML_Content_Quant quant;
202 const XML_Char * name;
203 int firstchild;
204 int lastchild;
205 int childcnt;
206 int nextsib;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000207} CONTENT_SCAFFOLD;
208
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000209#define INIT_SCAFFOLD_ELEMENTS 32
210
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000211typedef struct block {
212 struct block *next;
213 int size;
214 XML_Char s[1];
215} BLOCK;
216
217typedef struct {
218 BLOCK *blocks;
219 BLOCK *freeBlocks;
220 const XML_Char *end;
221 XML_Char *ptr;
222 XML_Char *start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000223 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000224} STRING_POOL;
225
226/* The XML_Char before the name is used to determine whether
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000227 an attribute has been specified. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000228typedef struct attribute_id {
229 XML_Char *name;
230 PREFIX *prefix;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000231 XML_Bool maybeTokenized;
232 XML_Bool xmlns;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000233} ATTRIBUTE_ID;
234
235typedef struct {
236 const ATTRIBUTE_ID *id;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000237 XML_Bool isCdata;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000238 const XML_Char *value;
239} DEFAULT_ATTRIBUTE;
240
241typedef struct {
Fred Drake08317ae2003-10-21 15:38:55 +0000242 unsigned long version;
243 unsigned long hash;
244 const XML_Char *uriName;
245} NS_ATT;
246
247typedef struct {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000248 const XML_Char *name;
249 PREFIX *prefix;
250 const ATTRIBUTE_ID *idAtt;
251 int nDefaultAtts;
252 int allocDefaultAtts;
253 DEFAULT_ATTRIBUTE *defaultAtts;
254} ELEMENT_TYPE;
255
256typedef struct {
257 HASH_TABLE generalEntities;
258 HASH_TABLE elementTypes;
259 HASH_TABLE attributeIds;
260 HASH_TABLE prefixes;
261 STRING_POOL pool;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000262 STRING_POOL entityValuePool;
263 /* false once a parameter entity reference has been skipped */
264 XML_Bool keepProcessing;
265 /* true once an internal or external PE reference has been encountered;
266 this includes the reference to an external subset */
267 XML_Bool hasParamEntityRefs;
268 XML_Bool standalone;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000269#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000270 /* indicates if external PE has been read */
271 XML_Bool paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000272 HASH_TABLE paramEntities;
273#endif /* XML_DTD */
274 PREFIX defaultPrefix;
275 /* === scaffolding for building content model === */
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000276 XML_Bool in_eldecl;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000277 CONTENT_SCAFFOLD *scaffold;
278 unsigned contentStringLen;
279 unsigned scaffSize;
280 unsigned scaffCount;
281 int scaffLevel;
282 int *scaffIndex;
283} DTD;
284
285typedef struct open_internal_entity {
286 const char *internalEventPtr;
287 const char *internalEventEndPtr;
288 struct open_internal_entity *next;
289 ENTITY *entity;
Fred Drake31d485c2004-08-03 07:06:22 +0000290 int startTagLevel;
291 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000292} OPEN_INTERNAL_ENTITY;
293
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000294typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
295 const char *start,
296 const char *end,
297 const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000298
299static Processor prologProcessor;
300static Processor prologInitProcessor;
301static Processor contentProcessor;
302static Processor cdataSectionProcessor;
303#ifdef XML_DTD
304static Processor ignoreSectionProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000305static Processor externalParEntProcessor;
306static Processor externalParEntInitProcessor;
307static Processor entityValueProcessor;
308static Processor entityValueInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000309#endif /* XML_DTD */
310static Processor epilogProcessor;
311static Processor errorProcessor;
312static Processor externalEntityInitProcessor;
313static Processor externalEntityInitProcessor2;
314static Processor externalEntityInitProcessor3;
315static Processor externalEntityContentProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +0000316static Processor internalEntityProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000317
318static enum XML_Error
319handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
320static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000321processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Fred Drake31d485c2004-08-03 07:06:22 +0000322 const char *s, const char *next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000323static enum XML_Error
324initializeEncoding(XML_Parser parser);
325static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +0000326doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
327 const char *end, int tok, const char *next, const char **nextPtr,
328 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000329static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +0000330processInternalEntity(XML_Parser parser, ENTITY *entity,
331 XML_Bool betweenDecl);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000332static enum XML_Error
333doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
Fred Drake31d485c2004-08-03 07:06:22 +0000334 const char *start, const char *end, const char **endPtr,
335 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000336static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000337doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000338 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000339#ifdef XML_DTD
340static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000341doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000342 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000343#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000344
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000345static enum XML_Error
Fred Drake4faea012003-01-28 06:42:40 +0000346storeAtts(XML_Parser parser, const ENCODING *, const char *s,
347 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000348static enum XML_Error
349addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
350 const XML_Char *uri, BINDING **bindingsPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000351static int
Fred Drake31d485c2004-08-03 07:06:22 +0000352defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
353 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000354static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000355storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
356 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000357static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000358appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
359 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000360static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000361getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
362 const char *end);
363static int
364setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000365static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000366storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
367 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000368static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000369reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
370 const char *start, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000371static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000372reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
373 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000374static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000375reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
376 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000377
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000378static const XML_Char * getContext(XML_Parser parser);
379static XML_Bool
380setContext(XML_Parser parser, const XML_Char *context);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000381
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000382static void FASTCALL normalizePublicId(XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000383
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000384static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
385/* do not call if parentParser != NULL */
386static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
387static void
388dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
389static int
390dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
391static int
392copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000393
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000394static NAMED *
395lookup(HASH_TABLE *table, KEY name, size_t createSize);
396static void FASTCALL
397hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
398static void FASTCALL hashTableClear(HASH_TABLE *);
399static void FASTCALL hashTableDestroy(HASH_TABLE *);
400static void FASTCALL
401hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
402static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000403
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000404static void FASTCALL
405poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
406static void FASTCALL poolClear(STRING_POOL *);
407static void FASTCALL poolDestroy(STRING_POOL *);
408static XML_Char *
409poolAppend(STRING_POOL *pool, const ENCODING *enc,
410 const char *ptr, const char *end);
411static XML_Char *
412poolStoreString(STRING_POOL *pool, const ENCODING *enc,
413 const char *ptr, const char *end);
414static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
415static const XML_Char * FASTCALL
416poolCopyString(STRING_POOL *pool, const XML_Char *s);
417static const XML_Char *
418poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
419static const XML_Char * FASTCALL
420poolAppendString(STRING_POOL *pool, const XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000421
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000422static int FASTCALL nextScaffoldPart(XML_Parser parser);
423static XML_Content * build_model(XML_Parser parser);
424static ELEMENT_TYPE *
425getElementType(XML_Parser parser, const ENCODING *enc,
426 const char *ptr, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000427
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000428static XML_Parser
429parserCreate(const XML_Char *encodingName,
430 const XML_Memory_Handling_Suite *memsuite,
431 const XML_Char *nameSep,
432 DTD *dtd);
433static void
434parserInit(XML_Parser parser, const XML_Char *encodingName);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000435
436#define poolStart(pool) ((pool)->start)
437#define poolEnd(pool) ((pool)->ptr)
438#define poolLength(pool) ((pool)->ptr - (pool)->start)
439#define poolChop(pool) ((void)--(pool->ptr))
440#define poolLastChar(pool) (((pool)->ptr)[-1])
441#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
442#define poolFinish(pool) ((pool)->start = (pool)->ptr)
443#define poolAppendChar(pool, c) \
444 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
445 ? 0 \
446 : ((*((pool)->ptr)++ = c), 1))
447
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000448struct XML_ParserStruct {
449 /* The first member must be userData so that the XML_GetUserData
450 macro works. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000451 void *m_userData;
452 void *m_handlerArg;
453 char *m_buffer;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000454 const XML_Memory_Handling_Suite m_mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000455 /* first character to be parsed */
456 const char *m_bufferPtr;
457 /* past last character to be parsed */
458 char *m_bufferEnd;
459 /* allocated end of buffer */
460 const char *m_bufferLim;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000461 XML_Index m_parseEndByteIndex;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000462 const char *m_parseEndPtr;
463 XML_Char *m_dataBuf;
464 XML_Char *m_dataBufEnd;
465 XML_StartElementHandler m_startElementHandler;
466 XML_EndElementHandler m_endElementHandler;
467 XML_CharacterDataHandler m_characterDataHandler;
468 XML_ProcessingInstructionHandler m_processingInstructionHandler;
469 XML_CommentHandler m_commentHandler;
470 XML_StartCdataSectionHandler m_startCdataSectionHandler;
471 XML_EndCdataSectionHandler m_endCdataSectionHandler;
472 XML_DefaultHandler m_defaultHandler;
473 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
474 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
475 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
476 XML_NotationDeclHandler m_notationDeclHandler;
477 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
478 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
479 XML_NotStandaloneHandler m_notStandaloneHandler;
480 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000481 XML_Parser m_externalEntityRefHandlerArg;
482 XML_SkippedEntityHandler m_skippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000483 XML_UnknownEncodingHandler m_unknownEncodingHandler;
484 XML_ElementDeclHandler m_elementDeclHandler;
485 XML_AttlistDeclHandler m_attlistDeclHandler;
486 XML_EntityDeclHandler m_entityDeclHandler;
487 XML_XmlDeclHandler m_xmlDeclHandler;
488 const ENCODING *m_encoding;
489 INIT_ENCODING m_initEncoding;
490 const ENCODING *m_internalEncoding;
491 const XML_Char *m_protocolEncodingName;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000492 XML_Bool m_ns;
493 XML_Bool m_ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000494 void *m_unknownEncodingMem;
495 void *m_unknownEncodingData;
496 void *m_unknownEncodingHandlerData;
Fred Drake31d485c2004-08-03 07:06:22 +0000497 void (XMLCALL *m_unknownEncodingRelease)(void *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000498 PROLOG_STATE m_prologState;
499 Processor *m_processor;
500 enum XML_Error m_errorCode;
501 const char *m_eventPtr;
502 const char *m_eventEndPtr;
503 const char *m_positionPtr;
504 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
Fred Drake31d485c2004-08-03 07:06:22 +0000505 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000506 XML_Bool m_defaultExpandInternalEntities;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000507 int m_tagLevel;
508 ENTITY *m_declEntity;
509 const XML_Char *m_doctypeName;
510 const XML_Char *m_doctypeSysid;
511 const XML_Char *m_doctypePubid;
512 const XML_Char *m_declAttributeType;
513 const XML_Char *m_declNotationName;
514 const XML_Char *m_declNotationPublicId;
515 ELEMENT_TYPE *m_declElementType;
516 ATTRIBUTE_ID *m_declAttributeId;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000517 XML_Bool m_declAttributeIsCdata;
518 XML_Bool m_declAttributeIsId;
519 DTD *m_dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000520 const XML_Char *m_curBase;
521 TAG *m_tagStack;
522 TAG *m_freeTagList;
523 BINDING *m_inheritedBindings;
524 BINDING *m_freeBindingList;
525 int m_attsSize;
526 int m_nSpecifiedAtts;
527 int m_idAttIndex;
528 ATTRIBUTE *m_atts;
Fred Drake08317ae2003-10-21 15:38:55 +0000529 NS_ATT *m_nsAtts;
530 unsigned long m_nsAttsVersion;
531 unsigned char m_nsAttsPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000532 POSITION m_position;
533 STRING_POOL m_tempPool;
534 STRING_POOL m_temp2Pool;
535 char *m_groupConnector;
Fred Drake08317ae2003-10-21 15:38:55 +0000536 unsigned int m_groupSize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000537 XML_Char m_namespaceSeparator;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000538 XML_Parser m_parentParser;
Fred Drake31d485c2004-08-03 07:06:22 +0000539 XML_ParsingStatus m_parsingStatus;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000540#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000541 XML_Bool m_isParamEntity;
542 XML_Bool m_useForeignDTD;
543 enum XML_ParamEntityParsing m_paramEntityParsing;
544#endif
545};
546
547#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
548#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
549#define FREE(p) (parser->m_mem.free_fcn((p)))
550
551#define userData (parser->m_userData)
552#define handlerArg (parser->m_handlerArg)
553#define startElementHandler (parser->m_startElementHandler)
554#define endElementHandler (parser->m_endElementHandler)
555#define characterDataHandler (parser->m_characterDataHandler)
556#define processingInstructionHandler \
557 (parser->m_processingInstructionHandler)
558#define commentHandler (parser->m_commentHandler)
559#define startCdataSectionHandler \
560 (parser->m_startCdataSectionHandler)
561#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
562#define defaultHandler (parser->m_defaultHandler)
563#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
564#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
565#define unparsedEntityDeclHandler \
566 (parser->m_unparsedEntityDeclHandler)
567#define notationDeclHandler (parser->m_notationDeclHandler)
568#define startNamespaceDeclHandler \
569 (parser->m_startNamespaceDeclHandler)
570#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
571#define notStandaloneHandler (parser->m_notStandaloneHandler)
572#define externalEntityRefHandler \
573 (parser->m_externalEntityRefHandler)
574#define externalEntityRefHandlerArg \
575 (parser->m_externalEntityRefHandlerArg)
576#define internalEntityRefHandler \
577 (parser->m_internalEntityRefHandler)
578#define skippedEntityHandler (parser->m_skippedEntityHandler)
579#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
580#define elementDeclHandler (parser->m_elementDeclHandler)
581#define attlistDeclHandler (parser->m_attlistDeclHandler)
582#define entityDeclHandler (parser->m_entityDeclHandler)
583#define xmlDeclHandler (parser->m_xmlDeclHandler)
584#define encoding (parser->m_encoding)
585#define initEncoding (parser->m_initEncoding)
586#define internalEncoding (parser->m_internalEncoding)
587#define unknownEncodingMem (parser->m_unknownEncodingMem)
588#define unknownEncodingData (parser->m_unknownEncodingData)
589#define unknownEncodingHandlerData \
590 (parser->m_unknownEncodingHandlerData)
591#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
592#define protocolEncodingName (parser->m_protocolEncodingName)
593#define ns (parser->m_ns)
594#define ns_triplets (parser->m_ns_triplets)
595#define prologState (parser->m_prologState)
596#define processor (parser->m_processor)
597#define errorCode (parser->m_errorCode)
598#define eventPtr (parser->m_eventPtr)
599#define eventEndPtr (parser->m_eventEndPtr)
600#define positionPtr (parser->m_positionPtr)
601#define position (parser->m_position)
602#define openInternalEntities (parser->m_openInternalEntities)
Fred Drake31d485c2004-08-03 07:06:22 +0000603#define freeInternalEntities (parser->m_freeInternalEntities)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000604#define defaultExpandInternalEntities \
605 (parser->m_defaultExpandInternalEntities)
606#define tagLevel (parser->m_tagLevel)
607#define buffer (parser->m_buffer)
608#define bufferPtr (parser->m_bufferPtr)
609#define bufferEnd (parser->m_bufferEnd)
610#define parseEndByteIndex (parser->m_parseEndByteIndex)
611#define parseEndPtr (parser->m_parseEndPtr)
612#define bufferLim (parser->m_bufferLim)
613#define dataBuf (parser->m_dataBuf)
614#define dataBufEnd (parser->m_dataBufEnd)
615#define _dtd (parser->m_dtd)
616#define curBase (parser->m_curBase)
617#define declEntity (parser->m_declEntity)
618#define doctypeName (parser->m_doctypeName)
619#define doctypeSysid (parser->m_doctypeSysid)
620#define doctypePubid (parser->m_doctypePubid)
621#define declAttributeType (parser->m_declAttributeType)
622#define declNotationName (parser->m_declNotationName)
623#define declNotationPublicId (parser->m_declNotationPublicId)
624#define declElementType (parser->m_declElementType)
625#define declAttributeId (parser->m_declAttributeId)
626#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
627#define declAttributeIsId (parser->m_declAttributeIsId)
628#define freeTagList (parser->m_freeTagList)
629#define freeBindingList (parser->m_freeBindingList)
630#define inheritedBindings (parser->m_inheritedBindings)
631#define tagStack (parser->m_tagStack)
632#define atts (parser->m_atts)
633#define attsSize (parser->m_attsSize)
634#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
635#define idAttIndex (parser->m_idAttIndex)
Fred Drake08317ae2003-10-21 15:38:55 +0000636#define nsAtts (parser->m_nsAtts)
637#define nsAttsVersion (parser->m_nsAttsVersion)
638#define nsAttsPower (parser->m_nsAttsPower)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000639#define tempPool (parser->m_tempPool)
640#define temp2Pool (parser->m_temp2Pool)
641#define groupConnector (parser->m_groupConnector)
642#define groupSize (parser->m_groupSize)
643#define namespaceSeparator (parser->m_namespaceSeparator)
644#define parentParser (parser->m_parentParser)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000645#define ps_parsing (parser->m_parsingStatus.parsing)
646#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000647#ifdef XML_DTD
648#define isParamEntity (parser->m_isParamEntity)
649#define useForeignDTD (parser->m_useForeignDTD)
650#define paramEntityParsing (parser->m_paramEntityParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000651#endif /* XML_DTD */
652
Fred Drake08317ae2003-10-21 15:38:55 +0000653XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000654XML_ParserCreate(const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000655{
656 return XML_ParserCreate_MM(encodingName, NULL, NULL);
657}
658
Fred Drake08317ae2003-10-21 15:38:55 +0000659XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000660XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000661{
662 XML_Char tmp[2];
663 *tmp = nsSep;
664 return XML_ParserCreate_MM(encodingName, NULL, tmp);
665}
666
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000667static const XML_Char implicitContext[] = {
668 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
669 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
670 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
671 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
672};
673
Fred Drake08317ae2003-10-21 15:38:55 +0000674XML_Parser XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000675XML_ParserCreate_MM(const XML_Char *encodingName,
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000676 const XML_Memory_Handling_Suite *memsuite,
677 const XML_Char *nameSep)
678{
679 XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);
680 if (parser != NULL && ns) {
681 /* implicit context only set for root parser, since child
682 parsers (i.e. external entity parsers) will inherit it
683 */
684 if (!setContext(parser, implicitContext)) {
685 XML_ParserFree(parser);
686 return NULL;
687 }
688 }
689 return parser;
690}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000691
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000692static XML_Parser
693parserCreate(const XML_Char *encodingName,
694 const XML_Memory_Handling_Suite *memsuite,
695 const XML_Char *nameSep,
696 DTD *dtd)
697{
698 XML_Parser parser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000699
700 if (memsuite) {
701 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000702 parser = (XML_Parser)
703 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
704 if (parser != NULL) {
705 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
706 mtemp->malloc_fcn = memsuite->malloc_fcn;
707 mtemp->realloc_fcn = memsuite->realloc_fcn;
708 mtemp->free_fcn = memsuite->free_fcn;
709 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000710 }
711 else {
712 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000713 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
714 if (parser != NULL) {
715 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
716 mtemp->malloc_fcn = malloc;
717 mtemp->realloc_fcn = realloc;
718 mtemp->free_fcn = free;
719 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000720 }
721
722 if (!parser)
723 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000724
725 buffer = NULL;
726 bufferLim = NULL;
727
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000728 attsSize = INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000729 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
730 if (atts == NULL) {
731 FREE(parser);
732 return NULL;
733 }
734 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
735 if (dataBuf == NULL) {
736 FREE(atts);
737 FREE(parser);
738 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000739 }
740 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
741
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000742 if (dtd)
743 _dtd = dtd;
744 else {
745 _dtd = dtdCreate(&parser->m_mem);
746 if (_dtd == NULL) {
747 FREE(dataBuf);
748 FREE(atts);
749 FREE(parser);
750 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000751 }
752 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000753
754 freeBindingList = NULL;
755 freeTagList = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000756 freeInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000757
758 groupSize = 0;
759 groupConnector = NULL;
760
761 unknownEncodingHandler = NULL;
762 unknownEncodingHandlerData = NULL;
763
764 namespaceSeparator = '!';
765 ns = XML_FALSE;
766 ns_triplets = XML_FALSE;
767
Fred Drake08317ae2003-10-21 15:38:55 +0000768 nsAtts = NULL;
769 nsAttsVersion = 0;
770 nsAttsPower = 0;
771
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000772 poolInit(&tempPool, &(parser->m_mem));
773 poolInit(&temp2Pool, &(parser->m_mem));
774 parserInit(parser, encodingName);
775
776 if (encodingName && !protocolEncodingName) {
777 XML_ParserFree(parser);
778 return NULL;
779 }
780
781 if (nameSep) {
782 ns = XML_TRUE;
783 internalEncoding = XmlGetInternalEncodingNS();
784 namespaceSeparator = *nameSep;
785 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000786 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000787 internalEncoding = XmlGetInternalEncoding();
788 }
789
790 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000791}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000792
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000793static void
794parserInit(XML_Parser parser, const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000795{
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000796 processor = prologInitProcessor;
797 XmlPrologStateInit(&prologState);
798 protocolEncodingName = (encodingName != NULL
799 ? poolCopyString(&tempPool, encodingName)
800 : NULL);
801 curBase = NULL;
802 XmlInitEncoding(&initEncoding, &encoding, 0);
803 userData = NULL;
804 handlerArg = NULL;
805 startElementHandler = NULL;
806 endElementHandler = NULL;
807 characterDataHandler = NULL;
808 processingInstructionHandler = NULL;
809 commentHandler = NULL;
810 startCdataSectionHandler = NULL;
811 endCdataSectionHandler = NULL;
812 defaultHandler = NULL;
813 startDoctypeDeclHandler = NULL;
814 endDoctypeDeclHandler = NULL;
815 unparsedEntityDeclHandler = NULL;
816 notationDeclHandler = NULL;
817 startNamespaceDeclHandler = NULL;
818 endNamespaceDeclHandler = NULL;
819 notStandaloneHandler = NULL;
820 externalEntityRefHandler = NULL;
821 externalEntityRefHandlerArg = parser;
822 skippedEntityHandler = NULL;
823 elementDeclHandler = NULL;
824 attlistDeclHandler = NULL;
825 entityDeclHandler = NULL;
826 xmlDeclHandler = NULL;
827 bufferPtr = buffer;
828 bufferEnd = buffer;
829 parseEndByteIndex = 0;
830 parseEndPtr = NULL;
831 declElementType = NULL;
832 declAttributeId = NULL;
833 declEntity = NULL;
834 doctypeName = NULL;
835 doctypeSysid = NULL;
836 doctypePubid = NULL;
837 declAttributeType = NULL;
838 declNotationName = NULL;
839 declNotationPublicId = NULL;
840 declAttributeIsCdata = XML_FALSE;
841 declAttributeIsId = XML_FALSE;
842 memset(&position, 0, sizeof(POSITION));
843 errorCode = XML_ERROR_NONE;
844 eventPtr = NULL;
845 eventEndPtr = NULL;
846 positionPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000847 openInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000848 defaultExpandInternalEntities = XML_TRUE;
849 tagLevel = 0;
850 tagStack = NULL;
851 inheritedBindings = NULL;
852 nSpecifiedAtts = 0;
853 unknownEncodingMem = NULL;
854 unknownEncodingRelease = NULL;
855 unknownEncodingData = NULL;
856 parentParser = NULL;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000857 ps_parsing = XML_INITIALIZED;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000858#ifdef XML_DTD
859 isParamEntity = XML_FALSE;
860 useForeignDTD = XML_FALSE;
861 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
862#endif
863}
864
865/* moves list of bindings to freeBindingList */
866static void FASTCALL
867moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
868{
869 while (bindings) {
870 BINDING *b = bindings;
871 bindings = bindings->nextTagBinding;
872 b->nextTagBinding = freeBindingList;
873 freeBindingList = b;
874 }
875}
876
Fred Drake08317ae2003-10-21 15:38:55 +0000877XML_Bool XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000878XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
879{
880 TAG *tStk;
Fred Drake31d485c2004-08-03 07:06:22 +0000881 OPEN_INTERNAL_ENTITY *openEntityList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000882 if (parentParser)
883 return XML_FALSE;
884 /* move tagStack to freeTagList */
885 tStk = tagStack;
886 while (tStk) {
887 TAG *tag = tStk;
888 tStk = tStk->parent;
889 tag->parent = freeTagList;
890 moveToFreeBindingList(parser, tag->bindings);
891 tag->bindings = NULL;
892 freeTagList = tag;
893 }
Fred Drake31d485c2004-08-03 07:06:22 +0000894 /* move openInternalEntities to freeInternalEntities */
895 openEntityList = openInternalEntities;
896 while (openEntityList) {
897 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
898 openEntityList = openEntity->next;
899 openEntity->next = freeInternalEntities;
900 freeInternalEntities = openEntity;
901 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000902 moveToFreeBindingList(parser, inheritedBindings);
Fred Drake08317ae2003-10-21 15:38:55 +0000903 FREE(unknownEncodingMem);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000904 if (unknownEncodingRelease)
905 unknownEncodingRelease(unknownEncodingData);
906 poolClear(&tempPool);
907 poolClear(&temp2Pool);
908 parserInit(parser, encodingName);
909 dtdReset(_dtd, &parser->m_mem);
910 return setContext(parser, implicitContext);
911}
912
Fred Drake08317ae2003-10-21 15:38:55 +0000913enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000914XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
915{
916 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
917 XXX There's no way for the caller to determine which of the
918 XXX possible error cases caused the XML_STATUS_ERROR return.
919 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000920 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000921 return XML_STATUS_ERROR;
922 if (encodingName == NULL)
923 protocolEncodingName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000924 else {
925 protocolEncodingName = poolCopyString(&tempPool, encodingName);
926 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000927 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000928 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000929 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000930}
931
Fred Drake08317ae2003-10-21 15:38:55 +0000932XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000933XML_ExternalEntityParserCreate(XML_Parser oldParser,
934 const XML_Char *context,
935 const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000936{
937 XML_Parser parser = oldParser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000938 DTD *newDtd = NULL;
939 DTD *oldDtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000940 XML_StartElementHandler oldStartElementHandler = startElementHandler;
941 XML_EndElementHandler oldEndElementHandler = endElementHandler;
942 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000943 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
944 = processingInstructionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000945 XML_CommentHandler oldCommentHandler = commentHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000946 XML_StartCdataSectionHandler oldStartCdataSectionHandler
947 = startCdataSectionHandler;
948 XML_EndCdataSectionHandler oldEndCdataSectionHandler
949 = endCdataSectionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000950 XML_DefaultHandler oldDefaultHandler = defaultHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000951 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
952 = unparsedEntityDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000953 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000954 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
955 = startNamespaceDeclHandler;
956 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
957 = endNamespaceDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000958 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000959 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
960 = externalEntityRefHandler;
961 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
962 XML_UnknownEncodingHandler oldUnknownEncodingHandler
963 = unknownEncodingHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000964 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
965 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
966 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
967 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
968 ELEMENT_TYPE * oldDeclElementType = declElementType;
969
970 void *oldUserData = userData;
971 void *oldHandlerArg = handlerArg;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000972 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
973 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000974#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000975 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
976 int oldInEntityValue = prologState.inEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000977#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000978 XML_Bool oldns_triplets = ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000979
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000980#ifdef XML_DTD
981 if (!context)
982 newDtd = oldDtd;
983#endif /* XML_DTD */
984
985 /* Note that the magical uses of the pre-processor to make field
986 access look more like C++ require that `parser' be overwritten
987 here. This makes this function more painful to follow than it
988 would be otherwise.
989 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000990 if (ns) {
991 XML_Char tmp[2];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000992 *tmp = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000993 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000994 }
995 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000996 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000997 }
998
999 if (!parser)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001000 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001001
1002 startElementHandler = oldStartElementHandler;
1003 endElementHandler = oldEndElementHandler;
1004 characterDataHandler = oldCharacterDataHandler;
1005 processingInstructionHandler = oldProcessingInstructionHandler;
1006 commentHandler = oldCommentHandler;
1007 startCdataSectionHandler = oldStartCdataSectionHandler;
1008 endCdataSectionHandler = oldEndCdataSectionHandler;
1009 defaultHandler = oldDefaultHandler;
1010 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1011 notationDeclHandler = oldNotationDeclHandler;
1012 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1013 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1014 notStandaloneHandler = oldNotStandaloneHandler;
1015 externalEntityRefHandler = oldExternalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001016 skippedEntityHandler = oldSkippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001017 unknownEncodingHandler = oldUnknownEncodingHandler;
1018 elementDeclHandler = oldElementDeclHandler;
1019 attlistDeclHandler = oldAttlistDeclHandler;
1020 entityDeclHandler = oldEntityDeclHandler;
1021 xmlDeclHandler = oldXmlDeclHandler;
1022 declElementType = oldDeclElementType;
1023 userData = oldUserData;
1024 if (oldUserData == oldHandlerArg)
1025 handlerArg = userData;
1026 else
1027 handlerArg = parser;
1028 if (oldExternalEntityRefHandlerArg != oldParser)
1029 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1030 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1031 ns_triplets = oldns_triplets;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001032 parentParser = oldParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001033#ifdef XML_DTD
1034 paramEntityParsing = oldParamEntityParsing;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001035 prologState.inEntityValue = oldInEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001036 if (context) {
1037#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001038 if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
1039 || !setContext(parser, context)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001040 XML_ParserFree(parser);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001041 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001042 }
1043 processor = externalEntityInitProcessor;
1044#ifdef XML_DTD
1045 }
1046 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001047 /* The DTD instance referenced by _dtd is shared between the document's
1048 root parser and external PE parsers, therefore one does not need to
1049 call setContext. In addition, one also *must* not call setContext,
1050 because this would overwrite existing prefix->binding pointers in
1051 _dtd with ones that get destroyed with the external PE parser.
1052 This would leave those prefixes with dangling pointers.
1053 */
1054 isParamEntity = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001055 XmlPrologStateInitExternalEntity(&prologState);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001056 processor = externalParEntInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001057 }
1058#endif /* XML_DTD */
1059 return parser;
1060}
1061
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001062static void FASTCALL
1063destroyBindings(BINDING *bindings, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001064{
1065 for (;;) {
1066 BINDING *b = bindings;
1067 if (!b)
1068 break;
1069 bindings = b->nextTagBinding;
1070 FREE(b->uri);
1071 FREE(b);
1072 }
1073}
1074
Fred Drake08317ae2003-10-21 15:38:55 +00001075void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001076XML_ParserFree(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001077{
Fred Drake31d485c2004-08-03 07:06:22 +00001078 TAG *tagList;
1079 OPEN_INTERNAL_ENTITY *entityList;
1080 if (parser == NULL)
1081 return;
1082 /* free tagStack and freeTagList */
1083 tagList = tagStack;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001084 for (;;) {
1085 TAG *p;
Fred Drake31d485c2004-08-03 07:06:22 +00001086 if (tagList == NULL) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001087 if (freeTagList == NULL)
1088 break;
Fred Drake31d485c2004-08-03 07:06:22 +00001089 tagList = freeTagList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001090 freeTagList = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001091 }
Fred Drake31d485c2004-08-03 07:06:22 +00001092 p = tagList;
1093 tagList = tagList->parent;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001094 FREE(p->buf);
1095 destroyBindings(p->bindings, parser);
1096 FREE(p);
1097 }
Fred Drake31d485c2004-08-03 07:06:22 +00001098 /* free openInternalEntities and freeInternalEntities */
1099 entityList = openInternalEntities;
1100 for (;;) {
1101 OPEN_INTERNAL_ENTITY *openEntity;
1102 if (entityList == NULL) {
1103 if (freeInternalEntities == NULL)
1104 break;
1105 entityList = freeInternalEntities;
1106 freeInternalEntities = NULL;
1107 }
1108 openEntity = entityList;
1109 entityList = entityList->next;
1110 FREE(openEntity);
1111 }
1112
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001113 destroyBindings(freeBindingList, parser);
1114 destroyBindings(inheritedBindings, parser);
1115 poolDestroy(&tempPool);
1116 poolDestroy(&temp2Pool);
1117#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001118 /* external parameter entity parsers share the DTD structure
1119 parser->m_dtd with the root parser, so we must not destroy it
1120 */
1121 if (!isParamEntity && _dtd)
1122#else
1123 if (_dtd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001124#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001125 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001126 FREE((void *)atts);
Fred Drake08317ae2003-10-21 15:38:55 +00001127 FREE(groupConnector);
1128 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001129 FREE(dataBuf);
Fred Drake08317ae2003-10-21 15:38:55 +00001130 FREE(nsAtts);
1131 FREE(unknownEncodingMem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001132 if (unknownEncodingRelease)
1133 unknownEncodingRelease(unknownEncodingData);
1134 FREE(parser);
1135}
1136
Fred Drake08317ae2003-10-21 15:38:55 +00001137void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001138XML_UseParserAsHandlerArg(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001139{
1140 handlerArg = parser;
1141}
1142
Fred Drake08317ae2003-10-21 15:38:55 +00001143enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001144XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1145{
1146#ifdef XML_DTD
1147 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001148 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001149 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1150 useForeignDTD = useDTD;
1151 return XML_ERROR_NONE;
1152#else
1153 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1154#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001155}
1156
Fred Drake08317ae2003-10-21 15:38:55 +00001157void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001158XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1159{
1160 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001161 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001162 return;
1163 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1164}
1165
Fred Drake08317ae2003-10-21 15:38:55 +00001166void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001167XML_SetUserData(XML_Parser parser, void *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001168{
1169 if (handlerArg == userData)
1170 handlerArg = userData = p;
1171 else
1172 userData = p;
1173}
1174
Fred Drake08317ae2003-10-21 15:38:55 +00001175enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001176XML_SetBase(XML_Parser parser, const XML_Char *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001177{
1178 if (p) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001179 p = poolCopyString(&_dtd->pool, p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001180 if (!p)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001181 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001182 curBase = p;
1183 }
1184 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001185 curBase = NULL;
1186 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001187}
1188
Fred Drake08317ae2003-10-21 15:38:55 +00001189const XML_Char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001190XML_GetBase(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001191{
1192 return curBase;
1193}
1194
Fred Drake08317ae2003-10-21 15:38:55 +00001195int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001196XML_GetSpecifiedAttributeCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001197{
1198 return nSpecifiedAtts;
1199}
1200
Fred Drake08317ae2003-10-21 15:38:55 +00001201int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001202XML_GetIdAttributeIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001203{
1204 return idAttIndex;
1205}
1206
Fred Drake08317ae2003-10-21 15:38:55 +00001207void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001208XML_SetElementHandler(XML_Parser parser,
1209 XML_StartElementHandler start,
1210 XML_EndElementHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001211{
1212 startElementHandler = start;
1213 endElementHandler = end;
1214}
1215
Fred Drake08317ae2003-10-21 15:38:55 +00001216void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001217XML_SetStartElementHandler(XML_Parser parser,
1218 XML_StartElementHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001219 startElementHandler = start;
1220}
1221
Fred Drake08317ae2003-10-21 15:38:55 +00001222void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001223XML_SetEndElementHandler(XML_Parser parser,
1224 XML_EndElementHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001225 endElementHandler = end;
1226}
1227
Fred Drake08317ae2003-10-21 15:38:55 +00001228void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001229XML_SetCharacterDataHandler(XML_Parser parser,
1230 XML_CharacterDataHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001231{
1232 characterDataHandler = handler;
1233}
1234
Fred Drake08317ae2003-10-21 15:38:55 +00001235void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001236XML_SetProcessingInstructionHandler(XML_Parser parser,
1237 XML_ProcessingInstructionHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001238{
1239 processingInstructionHandler = handler;
1240}
1241
Fred Drake08317ae2003-10-21 15:38:55 +00001242void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001243XML_SetCommentHandler(XML_Parser parser,
1244 XML_CommentHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001245{
1246 commentHandler = handler;
1247}
1248
Fred Drake08317ae2003-10-21 15:38:55 +00001249void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001250XML_SetCdataSectionHandler(XML_Parser parser,
1251 XML_StartCdataSectionHandler start,
1252 XML_EndCdataSectionHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001253{
1254 startCdataSectionHandler = start;
1255 endCdataSectionHandler = end;
1256}
1257
Fred Drake08317ae2003-10-21 15:38:55 +00001258void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001259XML_SetStartCdataSectionHandler(XML_Parser parser,
1260 XML_StartCdataSectionHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001261 startCdataSectionHandler = start;
1262}
1263
Fred Drake08317ae2003-10-21 15:38:55 +00001264void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001265XML_SetEndCdataSectionHandler(XML_Parser parser,
1266 XML_EndCdataSectionHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001267 endCdataSectionHandler = end;
1268}
1269
Fred Drake08317ae2003-10-21 15:38:55 +00001270void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001271XML_SetDefaultHandler(XML_Parser parser,
1272 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001273{
1274 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001275 defaultExpandInternalEntities = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001276}
1277
Fred Drake08317ae2003-10-21 15:38:55 +00001278void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001279XML_SetDefaultHandlerExpand(XML_Parser parser,
1280 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001281{
1282 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001283 defaultExpandInternalEntities = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001284}
1285
Fred Drake08317ae2003-10-21 15:38:55 +00001286void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001287XML_SetDoctypeDeclHandler(XML_Parser parser,
1288 XML_StartDoctypeDeclHandler start,
1289 XML_EndDoctypeDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001290{
1291 startDoctypeDeclHandler = start;
1292 endDoctypeDeclHandler = end;
1293}
1294
Fred Drake08317ae2003-10-21 15:38:55 +00001295void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001296XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1297 XML_StartDoctypeDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001298 startDoctypeDeclHandler = start;
1299}
1300
Fred Drake08317ae2003-10-21 15:38:55 +00001301void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001302XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1303 XML_EndDoctypeDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001304 endDoctypeDeclHandler = end;
1305}
1306
Fred Drake08317ae2003-10-21 15:38:55 +00001307void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001308XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1309 XML_UnparsedEntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001310{
1311 unparsedEntityDeclHandler = handler;
1312}
1313
Fred Drake08317ae2003-10-21 15:38:55 +00001314void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001315XML_SetNotationDeclHandler(XML_Parser parser,
1316 XML_NotationDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001317{
1318 notationDeclHandler = handler;
1319}
1320
Fred Drake08317ae2003-10-21 15:38:55 +00001321void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001322XML_SetNamespaceDeclHandler(XML_Parser parser,
1323 XML_StartNamespaceDeclHandler start,
1324 XML_EndNamespaceDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001325{
1326 startNamespaceDeclHandler = start;
1327 endNamespaceDeclHandler = end;
1328}
1329
Fred Drake08317ae2003-10-21 15:38:55 +00001330void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001331XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1332 XML_StartNamespaceDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001333 startNamespaceDeclHandler = start;
1334}
1335
Fred Drake08317ae2003-10-21 15:38:55 +00001336void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001337XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1338 XML_EndNamespaceDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001339 endNamespaceDeclHandler = end;
1340}
1341
Fred Drake08317ae2003-10-21 15:38:55 +00001342void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001343XML_SetNotStandaloneHandler(XML_Parser parser,
1344 XML_NotStandaloneHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001345{
1346 notStandaloneHandler = handler;
1347}
1348
Fred Drake08317ae2003-10-21 15:38:55 +00001349void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001350XML_SetExternalEntityRefHandler(XML_Parser parser,
1351 XML_ExternalEntityRefHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001352{
1353 externalEntityRefHandler = handler;
1354}
1355
Fred Drake08317ae2003-10-21 15:38:55 +00001356void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001357XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001358{
1359 if (arg)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001360 externalEntityRefHandlerArg = (XML_Parser)arg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001361 else
1362 externalEntityRefHandlerArg = parser;
1363}
1364
Fred Drake08317ae2003-10-21 15:38:55 +00001365void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001366XML_SetSkippedEntityHandler(XML_Parser parser,
1367 XML_SkippedEntityHandler handler)
1368{
1369 skippedEntityHandler = handler;
1370}
1371
Fred Drake08317ae2003-10-21 15:38:55 +00001372void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001373XML_SetUnknownEncodingHandler(XML_Parser parser,
1374 XML_UnknownEncodingHandler handler,
1375 void *data)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001376{
1377 unknownEncodingHandler = handler;
1378 unknownEncodingHandlerData = data;
1379}
1380
Fred Drake08317ae2003-10-21 15:38:55 +00001381void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001382XML_SetElementDeclHandler(XML_Parser parser,
1383 XML_ElementDeclHandler eldecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001384{
1385 elementDeclHandler = eldecl;
1386}
1387
Fred Drake08317ae2003-10-21 15:38:55 +00001388void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001389XML_SetAttlistDeclHandler(XML_Parser parser,
1390 XML_AttlistDeclHandler attdecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001391{
1392 attlistDeclHandler = attdecl;
1393}
1394
Fred Drake08317ae2003-10-21 15:38:55 +00001395void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001396XML_SetEntityDeclHandler(XML_Parser parser,
1397 XML_EntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001398{
1399 entityDeclHandler = handler;
1400}
1401
Fred Drake08317ae2003-10-21 15:38:55 +00001402void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001403XML_SetXmlDeclHandler(XML_Parser parser,
1404 XML_XmlDeclHandler handler) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001405 xmlDeclHandler = handler;
1406}
1407
Fred Drake08317ae2003-10-21 15:38:55 +00001408int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001409XML_SetParamEntityParsing(XML_Parser parser,
1410 enum XML_ParamEntityParsing peParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001411{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001412 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001413 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001414 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001415#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001416 paramEntityParsing = peParsing;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001417 return 1;
1418#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001419 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001420#endif
1421}
1422
Fred Drake08317ae2003-10-21 15:38:55 +00001423enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001424XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001425{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001426 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001427 case XML_SUSPENDED:
1428 errorCode = XML_ERROR_SUSPENDED;
1429 return XML_STATUS_ERROR;
1430 case XML_FINISHED:
1431 errorCode = XML_ERROR_FINISHED;
1432 return XML_STATUS_ERROR;
1433 default:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001434 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001435 }
1436
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001437 if (len == 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001438 ps_finalBuffer = (XML_Bool)isFinal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001439 if (!isFinal)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001440 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001441 positionPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001442 parseEndPtr = bufferEnd;
1443
1444 /* If data are left over from last buffer, and we now know that these
1445 data are the final chunk of input, then we have to check them again
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001446 to detect errors based on that fact.
Fred Drake31d485c2004-08-03 07:06:22 +00001447 */
1448 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1449
1450 if (errorCode == XML_ERROR_NONE) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001451 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001452 case XML_SUSPENDED:
1453 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1454 positionPtr = bufferPtr;
1455 return XML_STATUS_SUSPENDED;
1456 case XML_INITIALIZED:
1457 case XML_PARSING:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001458 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001459 /* fall through */
1460 default:
1461 return XML_STATUS_OK;
1462 }
1463 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001464 eventEndPtr = eventPtr;
1465 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001466 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001467 }
1468#ifndef XML_CONTEXT_BYTES
1469 else if (bufferPtr == bufferEnd) {
1470 const char *end;
1471 int nLeftOver;
Fred Drake31d485c2004-08-03 07:06:22 +00001472 enum XML_Error result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001473 parseEndByteIndex += len;
1474 positionPtr = s;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001475 ps_finalBuffer = (XML_Bool)isFinal;
Fred Drake31d485c2004-08-03 07:06:22 +00001476
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001477 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
Fred Drake31d485c2004-08-03 07:06:22 +00001478
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001479 if (errorCode != XML_ERROR_NONE) {
1480 eventEndPtr = eventPtr;
1481 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001482 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001483 }
Fred Drake31d485c2004-08-03 07:06:22 +00001484 else {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001485 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001486 case XML_SUSPENDED:
1487 result = XML_STATUS_SUSPENDED;
1488 break;
1489 case XML_INITIALIZED:
1490 case XML_PARSING:
1491 result = XML_STATUS_OK;
1492 if (isFinal) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001493 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001494 return result;
1495 }
1496 }
1497 }
1498
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001499 XmlUpdatePosition(encoding, positionPtr, end, &position);
1500 nLeftOver = s + len - end;
1501 if (nLeftOver) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001502 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1503 /* FIXME avoid integer overflow */
1504 char *temp;
1505 temp = (buffer == NULL
1506 ? (char *)MALLOC(len * 2)
1507 : (char *)REALLOC(buffer, len * 2));
1508 if (temp == NULL) {
1509 errorCode = XML_ERROR_NO_MEMORY;
1510 return XML_STATUS_ERROR;
1511 }
1512 buffer = temp;
1513 if (!buffer) {
1514 errorCode = XML_ERROR_NO_MEMORY;
1515 eventPtr = eventEndPtr = NULL;
1516 processor = errorProcessor;
1517 return XML_STATUS_ERROR;
1518 }
1519 bufferLim = buffer + len * 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001520 }
1521 memcpy(buffer, end, nLeftOver);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001522 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001523 bufferPtr = buffer;
1524 bufferEnd = buffer + nLeftOver;
1525 positionPtr = bufferPtr;
1526 parseEndPtr = bufferEnd;
1527 eventPtr = bufferPtr;
1528 eventEndPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001529 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001530 }
1531#endif /* not defined XML_CONTEXT_BYTES */
1532 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001533 void *buff = XML_GetBuffer(parser, len);
1534 if (buff == NULL)
1535 return XML_STATUS_ERROR;
1536 else {
1537 memcpy(buff, s, len);
1538 return XML_ParseBuffer(parser, len, isFinal);
1539 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001540 }
1541}
1542
Fred Drake08317ae2003-10-21 15:38:55 +00001543enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001544XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001545{
Fred Drake31d485c2004-08-03 07:06:22 +00001546 const char *start;
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001547 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001548
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001549 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001550 case XML_SUSPENDED:
1551 errorCode = XML_ERROR_SUSPENDED;
1552 return XML_STATUS_ERROR;
1553 case XML_FINISHED:
1554 errorCode = XML_ERROR_FINISHED;
1555 return XML_STATUS_ERROR;
1556 default:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001557 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001558 }
1559
1560 start = bufferPtr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001561 positionPtr = start;
1562 bufferEnd += len;
Fred Drake31d485c2004-08-03 07:06:22 +00001563 parseEndPtr = bufferEnd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001564 parseEndByteIndex += len;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001565 ps_finalBuffer = (XML_Bool)isFinal;
Fred Drake31d485c2004-08-03 07:06:22 +00001566
1567 errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1568
1569 if (errorCode != XML_ERROR_NONE) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001570 eventEndPtr = eventPtr;
1571 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001572 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001573 }
Fred Drake31d485c2004-08-03 07:06:22 +00001574 else {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001575 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001576 case XML_SUSPENDED:
1577 result = XML_STATUS_SUSPENDED;
1578 break;
1579 case XML_INITIALIZED:
1580 case XML_PARSING:
1581 if (isFinal) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001582 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001583 return result;
1584 }
1585 default: ; /* should not happen */
1586 }
1587 }
1588
1589 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1590 positionPtr = bufferPtr;
1591 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001592}
1593
Fred Drake08317ae2003-10-21 15:38:55 +00001594void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001595XML_GetBuffer(XML_Parser parser, int len)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001596{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001597 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001598 case XML_SUSPENDED:
1599 errorCode = XML_ERROR_SUSPENDED;
1600 return NULL;
1601 case XML_FINISHED:
1602 errorCode = XML_ERROR_FINISHED;
1603 return NULL;
1604 default: ;
1605 }
1606
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001607 if (len > bufferLim - bufferEnd) {
1608 /* FIXME avoid integer overflow */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001609 int neededSize = len + (int)(bufferEnd - bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001610#ifdef XML_CONTEXT_BYTES
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001611 int keep = (int)(bufferPtr - buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001612
1613 if (keep > XML_CONTEXT_BYTES)
1614 keep = XML_CONTEXT_BYTES;
1615 neededSize += keep;
1616#endif /* defined XML_CONTEXT_BYTES */
1617 if (neededSize <= bufferLim - buffer) {
1618#ifdef XML_CONTEXT_BYTES
1619 if (keep < bufferPtr - buffer) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001620 int offset = (int)(bufferPtr - buffer) - keep;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001621 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1622 bufferEnd -= offset;
1623 bufferPtr -= offset;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001624 }
1625#else
1626 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1627 bufferEnd = buffer + (bufferEnd - bufferPtr);
1628 bufferPtr = buffer;
1629#endif /* not defined XML_CONTEXT_BYTES */
1630 }
1631 else {
1632 char *newBuf;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001633 int bufferSize = (int)(bufferLim - bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001634 if (bufferSize == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001635 bufferSize = INIT_BUFFER_SIZE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001636 do {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001637 bufferSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001638 } while (bufferSize < neededSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001639 newBuf = (char *)MALLOC(bufferSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001640 if (newBuf == 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001641 errorCode = XML_ERROR_NO_MEMORY;
1642 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001643 }
1644 bufferLim = newBuf + bufferSize;
1645#ifdef XML_CONTEXT_BYTES
1646 if (bufferPtr) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001647 int keep = (int)(bufferPtr - buffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001648 if (keep > XML_CONTEXT_BYTES)
1649 keep = XML_CONTEXT_BYTES;
1650 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1651 FREE(buffer);
1652 buffer = newBuf;
1653 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1654 bufferPtr = buffer + keep;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001655 }
1656 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001657 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1658 bufferPtr = buffer = newBuf;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001659 }
1660#else
1661 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001662 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1663 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001664 }
1665 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1666 bufferPtr = buffer = newBuf;
1667#endif /* not defined XML_CONTEXT_BYTES */
1668 }
1669 }
1670 return bufferEnd;
1671}
1672
Fred Drake31d485c2004-08-03 07:06:22 +00001673enum XML_Status XMLCALL
1674XML_StopParser(XML_Parser parser, XML_Bool resumable)
1675{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001676 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001677 case XML_SUSPENDED:
1678 if (resumable) {
1679 errorCode = XML_ERROR_SUSPENDED;
1680 return XML_STATUS_ERROR;
1681 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001682 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001683 break;
1684 case XML_FINISHED:
1685 errorCode = XML_ERROR_FINISHED;
1686 return XML_STATUS_ERROR;
1687 default:
1688 if (resumable) {
1689#ifdef XML_DTD
1690 if (isParamEntity) {
1691 errorCode = XML_ERROR_SUSPEND_PE;
1692 return XML_STATUS_ERROR;
1693 }
1694#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001695 ps_parsing = XML_SUSPENDED;
Fred Drake31d485c2004-08-03 07:06:22 +00001696 }
1697 else
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001698 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001699 }
1700 return XML_STATUS_OK;
1701}
1702
1703enum XML_Status XMLCALL
1704XML_ResumeParser(XML_Parser parser)
1705{
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001706 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001707
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001708 if (ps_parsing != XML_SUSPENDED) {
Fred Drake31d485c2004-08-03 07:06:22 +00001709 errorCode = XML_ERROR_NOT_SUSPENDED;
1710 return XML_STATUS_ERROR;
1711 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001712 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001713
1714 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1715
1716 if (errorCode != XML_ERROR_NONE) {
1717 eventEndPtr = eventPtr;
1718 processor = errorProcessor;
1719 return XML_STATUS_ERROR;
1720 }
1721 else {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001722 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001723 case XML_SUSPENDED:
1724 result = XML_STATUS_SUSPENDED;
1725 break;
1726 case XML_INITIALIZED:
1727 case XML_PARSING:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001728 if (ps_finalBuffer) {
1729 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001730 return result;
1731 }
1732 default: ;
1733 }
1734 }
1735
1736 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1737 positionPtr = bufferPtr;
1738 return result;
1739}
1740
1741void XMLCALL
1742XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1743{
1744 assert(status != NULL);
1745 *status = parser->m_parsingStatus;
1746}
1747
Fred Drake08317ae2003-10-21 15:38:55 +00001748enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001749XML_GetErrorCode(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001750{
1751 return errorCode;
1752}
1753
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001754XML_Index XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001755XML_GetCurrentByteIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001756{
1757 if (eventPtr)
1758 return parseEndByteIndex - (parseEndPtr - eventPtr);
1759 return -1;
1760}
1761
Fred Drake08317ae2003-10-21 15:38:55 +00001762int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001763XML_GetCurrentByteCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001764{
1765 if (eventEndPtr && eventPtr)
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001766 return (int)(eventEndPtr - eventPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001767 return 0;
1768}
1769
Fred Drake08317ae2003-10-21 15:38:55 +00001770const char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001771XML_GetInputContext(XML_Parser parser, int *offset, int *size)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001772{
1773#ifdef XML_CONTEXT_BYTES
1774 if (eventPtr && buffer) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001775 *offset = (int)(eventPtr - buffer);
1776 *size = (int)(bufferEnd - buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001777 return buffer;
1778 }
1779#endif /* defined XML_CONTEXT_BYTES */
1780 return (char *) 0;
1781}
1782
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001783XML_Size XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001784XML_GetCurrentLineNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001785{
Fred Drake31d485c2004-08-03 07:06:22 +00001786 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001787 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1788 positionPtr = eventPtr;
1789 }
1790 return position.lineNumber + 1;
1791}
1792
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001793XML_Size XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001794XML_GetCurrentColumnNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001795{
Fred Drake31d485c2004-08-03 07:06:22 +00001796 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001797 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1798 positionPtr = eventPtr;
1799 }
1800 return position.columnNumber;
1801}
1802
Fred Drake08317ae2003-10-21 15:38:55 +00001803void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001804XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1805{
1806 FREE(model);
1807}
1808
Fred Drake08317ae2003-10-21 15:38:55 +00001809void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001810XML_MemMalloc(XML_Parser parser, size_t size)
1811{
1812 return MALLOC(size);
1813}
1814
Fred Drake08317ae2003-10-21 15:38:55 +00001815void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001816XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1817{
1818 return REALLOC(ptr, size);
1819}
1820
Fred Drake08317ae2003-10-21 15:38:55 +00001821void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001822XML_MemFree(XML_Parser parser, void *ptr)
1823{
1824 FREE(ptr);
1825}
1826
Fred Drake08317ae2003-10-21 15:38:55 +00001827void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001828XML_DefaultCurrent(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001829{
1830 if (defaultHandler) {
1831 if (openInternalEntities)
1832 reportDefault(parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001833 internalEncoding,
1834 openInternalEntities->internalEventPtr,
1835 openInternalEntities->internalEventEndPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001836 else
1837 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1838 }
1839}
1840
Fred Drake08317ae2003-10-21 15:38:55 +00001841const XML_LChar * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001842XML_ErrorString(enum XML_Error code)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001843{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001844 static const XML_LChar* const message[] = {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001845 0,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001846 XML_L("out of memory"),
1847 XML_L("syntax error"),
1848 XML_L("no element found"),
1849 XML_L("not well-formed (invalid token)"),
1850 XML_L("unclosed token"),
1851 XML_L("partial character"),
1852 XML_L("mismatched tag"),
1853 XML_L("duplicate attribute"),
1854 XML_L("junk after document element"),
1855 XML_L("illegal parameter entity reference"),
1856 XML_L("undefined entity"),
1857 XML_L("recursive entity reference"),
1858 XML_L("asynchronous entity"),
1859 XML_L("reference to invalid character number"),
1860 XML_L("reference to binary entity"),
1861 XML_L("reference to external entity in attribute"),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001862 XML_L("XML or text declaration not at start of entity"),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001863 XML_L("unknown encoding"),
1864 XML_L("encoding specified in XML declaration is incorrect"),
1865 XML_L("unclosed CDATA section"),
1866 XML_L("error in processing external entity reference"),
1867 XML_L("document is not standalone"),
1868 XML_L("unexpected parser state - please send a bug report"),
1869 XML_L("entity declared in parameter entity"),
1870 XML_L("requested feature requires XML_DTD support in Expat"),
Fred Drake08317ae2003-10-21 15:38:55 +00001871 XML_L("cannot change setting once parsing has begun"),
Fred Drake31d485c2004-08-03 07:06:22 +00001872 XML_L("unbound prefix"),
1873 XML_L("must not undeclare prefix"),
1874 XML_L("incomplete markup in parameter entity"),
1875 XML_L("XML declaration not well-formed"),
1876 XML_L("text declaration not well-formed"),
1877 XML_L("illegal character(s) in public id"),
1878 XML_L("parser suspended"),
1879 XML_L("parser not suspended"),
1880 XML_L("parsing aborted"),
1881 XML_L("parsing finished"),
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001882 XML_L("cannot suspend in external parameter entity"),
1883 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1884 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1885 XML_L("prefix must not be bound to one of the reserved namespace names")
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001886 };
1887 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1888 return message[code];
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001889 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001890}
1891
Fred Drake08317ae2003-10-21 15:38:55 +00001892const XML_LChar * XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001893XML_ExpatVersion(void) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001894
1895 /* V1 is used to string-ize the version number. However, it would
1896 string-ize the actual version macro *names* unless we get them
1897 substituted before being passed to V1. CPP is defined to expand
1898 a macro, then rescan for more expansions. Thus, we use V2 to expand
1899 the version macros, then CPP will expand the resulting V1() macro
1900 with the correct numerals. */
1901 /* ### I'm assuming cpp is portable in this respect... */
1902
1903#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1904#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1905
1906 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1907
1908#undef V1
1909#undef V2
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001910}
1911
Fred Drake08317ae2003-10-21 15:38:55 +00001912XML_Expat_Version XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001913XML_ExpatVersionInfo(void)
1914{
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001915 XML_Expat_Version version;
1916
1917 version.major = XML_MAJOR_VERSION;
1918 version.minor = XML_MINOR_VERSION;
1919 version.micro = XML_MICRO_VERSION;
1920
1921 return version;
1922}
1923
Fred Drake08317ae2003-10-21 15:38:55 +00001924const XML_Feature * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001925XML_GetFeatureList(void)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001926{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001927 static const XML_Feature features[] = {
1928 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
1929 sizeof(XML_Char)},
1930 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
1931 sizeof(XML_LChar)},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001932#ifdef XML_UNICODE
Fred Drake08317ae2003-10-21 15:38:55 +00001933 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001934#endif
1935#ifdef XML_UNICODE_WCHAR_T
Fred Drake08317ae2003-10-21 15:38:55 +00001936 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001937#endif
1938#ifdef XML_DTD
Fred Drake08317ae2003-10-21 15:38:55 +00001939 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001940#endif
1941#ifdef XML_CONTEXT_BYTES
1942 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
1943 XML_CONTEXT_BYTES},
1944#endif
1945#ifdef XML_MIN_SIZE
Fred Drake08317ae2003-10-21 15:38:55 +00001946 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001947#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001948#ifdef XML_NS
1949 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
1950#endif
Fred Drake08317ae2003-10-21 15:38:55 +00001951 {XML_FEATURE_END, NULL, 0}
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001952 };
1953
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001954 return features;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001955}
1956
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001957/* Initially tag->rawName always points into the parse buffer;
1958 for those TAG instances opened while the current parse buffer was
1959 processed, and not yet closed, we need to store tag->rawName in a more
1960 permanent location, since the parse buffer is about to be discarded.
1961*/
1962static XML_Bool
1963storeRawNames(XML_Parser parser)
1964{
1965 TAG *tag = tagStack;
1966 while (tag) {
1967 int bufSize;
1968 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
1969 char *rawNameBuf = tag->buf + nameLen;
1970 /* Stop if already stored. Since tagStack is a stack, we can stop
1971 at the first entry that has already been copied; everything
1972 below it in the stack is already been accounted for in a
1973 previous call to this function.
1974 */
1975 if (tag->rawName == rawNameBuf)
1976 break;
1977 /* For re-use purposes we need to ensure that the
1978 size of tag->buf is a multiple of sizeof(XML_Char).
1979 */
1980 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
1981 if (bufSize > tag->bufEnd - tag->buf) {
1982 char *temp = (char *)REALLOC(tag->buf, bufSize);
1983 if (temp == NULL)
1984 return XML_FALSE;
1985 /* if tag->name.str points to tag->buf (only when namespace
1986 processing is off) then we have to update it
1987 */
1988 if (tag->name.str == (XML_Char *)tag->buf)
1989 tag->name.str = (XML_Char *)temp;
1990 /* if tag->name.localPart is set (when namespace processing is on)
1991 then update it as well, since it will always point into tag->buf
1992 */
1993 if (tag->name.localPart)
1994 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
1995 (XML_Char *)tag->buf);
1996 tag->buf = temp;
1997 tag->bufEnd = temp + bufSize;
1998 rawNameBuf = temp + nameLen;
1999 }
2000 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2001 tag->rawName = rawNameBuf;
2002 tag = tag->parent;
2003 }
2004 return XML_TRUE;
2005}
2006
2007static enum XML_Error PTRCALL
2008contentProcessor(XML_Parser parser,
2009 const char *start,
2010 const char *end,
2011 const char **endPtr)
2012{
Fred Drake31d485c2004-08-03 07:06:22 +00002013 enum XML_Error result = doContent(parser, 0, encoding, start, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002014 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00002015 if (result == XML_ERROR_NONE) {
2016 if (!storeRawNames(parser))
2017 return XML_ERROR_NO_MEMORY;
2018 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002019 return result;
2020}
2021
2022static enum XML_Error PTRCALL
2023externalEntityInitProcessor(XML_Parser parser,
2024 const char *start,
2025 const char *end,
2026 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002027{
2028 enum XML_Error result = initializeEncoding(parser);
2029 if (result != XML_ERROR_NONE)
2030 return result;
2031 processor = externalEntityInitProcessor2;
2032 return externalEntityInitProcessor2(parser, start, end, endPtr);
2033}
2034
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002035static enum XML_Error PTRCALL
2036externalEntityInitProcessor2(XML_Parser parser,
2037 const char *start,
2038 const char *end,
2039 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002040{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002041 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002042 int tok = XmlContentTok(encoding, start, end, &next);
2043 switch (tok) {
2044 case XML_TOK_BOM:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002045 /* If we are at the end of the buffer, this would cause the next stage,
2046 i.e. externalEntityInitProcessor3, to pass control directly to
2047 doContent (by detecting XML_TOK_NONE) without processing any xml text
2048 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2049 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002050 if (next == end && !ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002051 *endPtr = next;
2052 return XML_ERROR_NONE;
2053 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002054 start = next;
2055 break;
2056 case XML_TOK_PARTIAL:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002057 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002058 *endPtr = start;
2059 return XML_ERROR_NONE;
2060 }
2061 eventPtr = start;
2062 return XML_ERROR_UNCLOSED_TOKEN;
2063 case XML_TOK_PARTIAL_CHAR:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002064 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002065 *endPtr = start;
2066 return XML_ERROR_NONE;
2067 }
2068 eventPtr = start;
2069 return XML_ERROR_PARTIAL_CHAR;
2070 }
2071 processor = externalEntityInitProcessor3;
2072 return externalEntityInitProcessor3(parser, start, end, endPtr);
2073}
2074
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002075static enum XML_Error PTRCALL
2076externalEntityInitProcessor3(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{
Fred Drake31d485c2004-08-03 07:06:22 +00002081 int tok;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002082 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Fred Drake31d485c2004-08-03 07:06:22 +00002083 eventPtr = start;
2084 tok = XmlContentTok(encoding, start, end, &next);
2085 eventEndPtr = next;
2086
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002087 switch (tok) {
2088 case XML_TOK_XML_DECL:
2089 {
Fred Drake31d485c2004-08-03 07:06:22 +00002090 enum XML_Error result;
2091 result = processXmlDecl(parser, 1, start, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002092 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002093 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002094 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00002095 case XML_SUSPENDED:
2096 *endPtr = next;
2097 return XML_ERROR_NONE;
2098 case XML_FINISHED:
2099 return XML_ERROR_ABORTED;
2100 default:
2101 start = next;
2102 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002103 }
2104 break;
2105 case XML_TOK_PARTIAL:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002106 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002107 *endPtr = start;
2108 return XML_ERROR_NONE;
2109 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002110 return XML_ERROR_UNCLOSED_TOKEN;
2111 case XML_TOK_PARTIAL_CHAR:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002112 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002113 *endPtr = start;
2114 return XML_ERROR_NONE;
2115 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002116 return XML_ERROR_PARTIAL_CHAR;
2117 }
2118 processor = externalEntityContentProcessor;
2119 tagLevel = 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002120 return externalEntityContentProcessor(parser, start, end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002121}
2122
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002123static enum XML_Error PTRCALL
2124externalEntityContentProcessor(XML_Parser parser,
2125 const char *start,
2126 const char *end,
2127 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002128{
Fred Drake31d485c2004-08-03 07:06:22 +00002129 enum XML_Error result = doContent(parser, 1, encoding, start, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002130 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00002131 if (result == XML_ERROR_NONE) {
2132 if (!storeRawNames(parser))
2133 return XML_ERROR_NO_MEMORY;
2134 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002135 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002136}
2137
2138static enum XML_Error
2139doContent(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002140 int startTagLevel,
2141 const ENCODING *enc,
2142 const char *s,
2143 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00002144 const char **nextPtr,
2145 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002146{
Fred Drake31d485c2004-08-03 07:06:22 +00002147 /* save one level of indirection */
2148 DTD * const dtd = _dtd;
2149
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002150 const char **eventPP;
2151 const char **eventEndPP;
2152 if (enc == encoding) {
2153 eventPP = &eventPtr;
2154 eventEndPP = &eventEndPtr;
2155 }
2156 else {
2157 eventPP = &(openInternalEntities->internalEventPtr);
2158 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2159 }
2160 *eventPP = s;
Fred Drake31d485c2004-08-03 07:06:22 +00002161
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002162 for (;;) {
2163 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2164 int tok = XmlContentTok(enc, s, end, &next);
2165 *eventEndPP = next;
2166 switch (tok) {
2167 case XML_TOK_TRAILING_CR:
Fred Drake31d485c2004-08-03 07:06:22 +00002168 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002169 *nextPtr = s;
2170 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002171 }
2172 *eventEndPP = end;
2173 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002174 XML_Char c = 0xA;
2175 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002176 }
2177 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002178 reportDefault(parser, enc, s, end);
Fred Drake31d485c2004-08-03 07:06:22 +00002179 /* We are at the end of the final buffer, should we check for
2180 XML_SUSPENDED, XML_FINISHED?
2181 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002182 if (startTagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002183 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002184 if (tagLevel != startTagLevel)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002185 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002186 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002187 return XML_ERROR_NONE;
2188 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00002189 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002190 *nextPtr = s;
2191 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002192 }
2193 if (startTagLevel > 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002194 if (tagLevel != startTagLevel)
2195 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002196 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002197 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002198 }
2199 return XML_ERROR_NO_ELEMENTS;
2200 case XML_TOK_INVALID:
2201 *eventPP = next;
2202 return XML_ERROR_INVALID_TOKEN;
2203 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00002204 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002205 *nextPtr = s;
2206 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002207 }
2208 return XML_ERROR_UNCLOSED_TOKEN;
2209 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00002210 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002211 *nextPtr = s;
2212 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002213 }
2214 return XML_ERROR_PARTIAL_CHAR;
2215 case XML_TOK_ENTITY_REF:
2216 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002217 const XML_Char *name;
2218 ENTITY *entity;
2219 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2220 s + enc->minBytesPerChar,
2221 next - enc->minBytesPerChar);
2222 if (ch) {
2223 if (characterDataHandler)
2224 characterDataHandler(handlerArg, &ch, 1);
2225 else if (defaultHandler)
2226 reportDefault(parser, enc, s, next);
2227 break;
2228 }
2229 name = poolStoreString(&dtd->pool, enc,
2230 s + enc->minBytesPerChar,
2231 next - enc->minBytesPerChar);
2232 if (!name)
2233 return XML_ERROR_NO_MEMORY;
2234 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
2235 poolDiscard(&dtd->pool);
2236 /* First, determine if a check for an existing declaration is needed;
2237 if yes, check that the entity exists, and that it is internal,
2238 otherwise call the skipped entity or default handler.
2239 */
2240 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2241 if (!entity)
2242 return XML_ERROR_UNDEFINED_ENTITY;
2243 else if (!entity->is_internal)
2244 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2245 }
2246 else if (!entity) {
2247 if (skippedEntityHandler)
2248 skippedEntityHandler(handlerArg, name, 0);
2249 else if (defaultHandler)
2250 reportDefault(parser, enc, s, next);
2251 break;
2252 }
2253 if (entity->open)
2254 return XML_ERROR_RECURSIVE_ENTITY_REF;
2255 if (entity->notation)
2256 return XML_ERROR_BINARY_ENTITY_REF;
2257 if (entity->textPtr) {
2258 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002259 if (!defaultExpandInternalEntities) {
2260 if (skippedEntityHandler)
2261 skippedEntityHandler(handlerArg, entity->name, 0);
2262 else if (defaultHandler)
2263 reportDefault(parser, enc, s, next);
2264 break;
2265 }
Fred Drake31d485c2004-08-03 07:06:22 +00002266 result = processInternalEntity(parser, entity, XML_FALSE);
2267 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002268 return result;
2269 }
2270 else if (externalEntityRefHandler) {
2271 const XML_Char *context;
2272 entity->open = XML_TRUE;
2273 context = getContext(parser);
2274 entity->open = XML_FALSE;
2275 if (!context)
2276 return XML_ERROR_NO_MEMORY;
Fred Drake31d485c2004-08-03 07:06:22 +00002277 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002278 context,
2279 entity->base,
2280 entity->systemId,
2281 entity->publicId))
2282 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2283 poolDiscard(&tempPool);
2284 }
2285 else if (defaultHandler)
2286 reportDefault(parser, enc, s, next);
2287 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002288 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002289 case XML_TOK_START_TAG_NO_ATTS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002290 /* fall through */
2291 case XML_TOK_START_TAG_WITH_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002292 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002293 TAG *tag;
2294 enum XML_Error result;
2295 XML_Char *toPtr;
2296 if (freeTagList) {
2297 tag = freeTagList;
2298 freeTagList = freeTagList->parent;
2299 }
2300 else {
2301 tag = (TAG *)MALLOC(sizeof(TAG));
2302 if (!tag)
2303 return XML_ERROR_NO_MEMORY;
2304 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2305 if (!tag->buf) {
2306 FREE(tag);
2307 return XML_ERROR_NO_MEMORY;
2308 }
2309 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2310 }
2311 tag->bindings = NULL;
2312 tag->parent = tagStack;
2313 tagStack = tag;
2314 tag->name.localPart = NULL;
2315 tag->name.prefix = NULL;
2316 tag->rawName = s + enc->minBytesPerChar;
2317 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2318 ++tagLevel;
2319 {
2320 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2321 const char *fromPtr = tag->rawName;
2322 toPtr = (XML_Char *)tag->buf;
2323 for (;;) {
2324 int bufSize;
2325 int convLen;
2326 XmlConvert(enc,
2327 &fromPtr, rawNameEnd,
2328 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002329 convLen = (int)(toPtr - (XML_Char *)tag->buf);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002330 if (fromPtr == rawNameEnd) {
2331 tag->name.strLen = convLen;
2332 break;
2333 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002334 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002335 {
2336 char *temp = (char *)REALLOC(tag->buf, bufSize);
2337 if (temp == NULL)
2338 return XML_ERROR_NO_MEMORY;
2339 tag->buf = temp;
2340 tag->bufEnd = temp + bufSize;
2341 toPtr = (XML_Char *)temp + convLen;
2342 }
2343 }
2344 }
2345 tag->name.str = (XML_Char *)tag->buf;
2346 *toPtr = XML_T('\0');
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002347 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2348 if (result)
2349 return result;
2350 if (startElementHandler)
2351 startElementHandler(handlerArg, tag->name.str,
2352 (const XML_Char **)atts);
2353 else if (defaultHandler)
2354 reportDefault(parser, enc, s, next);
2355 poolClear(&tempPool);
2356 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002357 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002358 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002359 /* fall through */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002360 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2361 {
2362 const char *rawName = s + enc->minBytesPerChar;
2363 enum XML_Error result;
2364 BINDING *bindings = NULL;
2365 XML_Bool noElmHandlers = XML_TRUE;
2366 TAG_NAME name;
2367 name.str = poolStoreString(&tempPool, enc, rawName,
2368 rawName + XmlNameLength(enc, rawName));
2369 if (!name.str)
2370 return XML_ERROR_NO_MEMORY;
2371 poolFinish(&tempPool);
Fred Drake4faea012003-01-28 06:42:40 +00002372 result = storeAtts(parser, enc, s, &name, &bindings);
2373 if (result)
2374 return result;
2375 poolFinish(&tempPool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002376 if (startElementHandler) {
2377 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2378 noElmHandlers = XML_FALSE;
2379 }
2380 if (endElementHandler) {
2381 if (startElementHandler)
2382 *eventPP = *eventEndPP;
2383 endElementHandler(handlerArg, name.str);
2384 noElmHandlers = XML_FALSE;
2385 }
2386 if (noElmHandlers && defaultHandler)
2387 reportDefault(parser, enc, s, next);
2388 poolClear(&tempPool);
2389 while (bindings) {
2390 BINDING *b = bindings;
2391 if (endNamespaceDeclHandler)
2392 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2393 bindings = bindings->nextTagBinding;
2394 b->nextTagBinding = freeBindingList;
2395 freeBindingList = b;
2396 b->prefix->binding = b->prevPrefixBinding;
2397 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002398 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002399 if (tagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002400 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002401 break;
2402 case XML_TOK_END_TAG:
2403 if (tagLevel == startTagLevel)
2404 return XML_ERROR_ASYNC_ENTITY;
2405 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002406 int len;
2407 const char *rawName;
2408 TAG *tag = tagStack;
2409 tagStack = tag->parent;
2410 tag->parent = freeTagList;
2411 freeTagList = tag;
2412 rawName = s + enc->minBytesPerChar*2;
2413 len = XmlNameLength(enc, rawName);
2414 if (len != tag->rawNameLength
2415 || memcmp(tag->rawName, rawName, len) != 0) {
2416 *eventPP = rawName;
2417 return XML_ERROR_TAG_MISMATCH;
2418 }
2419 --tagLevel;
2420 if (endElementHandler) {
2421 const XML_Char *localPart;
2422 const XML_Char *prefix;
2423 XML_Char *uri;
2424 localPart = tag->name.localPart;
2425 if (ns && localPart) {
2426 /* localPart and prefix may have been overwritten in
2427 tag->name.str, since this points to the binding->uri
2428 buffer which gets re-used; so we have to add them again
2429 */
2430 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2431 /* don't need to check for space - already done in storeAtts() */
2432 while (*localPart) *uri++ = *localPart++;
2433 prefix = (XML_Char *)tag->name.prefix;
2434 if (ns_triplets && prefix) {
2435 *uri++ = namespaceSeparator;
2436 while (*prefix) *uri++ = *prefix++;
2437 }
2438 *uri = XML_T('\0');
2439 }
2440 endElementHandler(handlerArg, tag->name.str);
2441 }
2442 else if (defaultHandler)
2443 reportDefault(parser, enc, s, next);
2444 while (tag->bindings) {
2445 BINDING *b = tag->bindings;
2446 if (endNamespaceDeclHandler)
2447 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2448 tag->bindings = tag->bindings->nextTagBinding;
2449 b->nextTagBinding = freeBindingList;
2450 freeBindingList = b;
2451 b->prefix->binding = b->prevPrefixBinding;
2452 }
2453 if (tagLevel == 0)
2454 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002455 }
2456 break;
2457 case XML_TOK_CHAR_REF:
2458 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002459 int n = XmlCharRefNumber(enc, s);
2460 if (n < 0)
2461 return XML_ERROR_BAD_CHAR_REF;
2462 if (characterDataHandler) {
2463 XML_Char buf[XML_ENCODE_MAX];
2464 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2465 }
2466 else if (defaultHandler)
2467 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002468 }
2469 break;
2470 case XML_TOK_XML_DECL:
2471 return XML_ERROR_MISPLACED_XML_PI;
2472 case XML_TOK_DATA_NEWLINE:
2473 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002474 XML_Char c = 0xA;
2475 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002476 }
2477 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002478 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002479 break;
2480 case XML_TOK_CDATA_SECT_OPEN:
2481 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002482 enum XML_Error result;
2483 if (startCdataSectionHandler)
2484 startCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002485#if 0
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002486 /* Suppose you doing a transformation on a document that involves
2487 changing only the character data. You set up a defaultHandler
2488 and a characterDataHandler. The defaultHandler simply copies
2489 characters through. The characterDataHandler does the
2490 transformation and writes the characters out escaping them as
2491 necessary. This case will fail to work if we leave out the
2492 following two lines (because & and < inside CDATA sections will
2493 be incorrectly escaped).
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002494
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002495 However, now we have a start/endCdataSectionHandler, so it seems
2496 easier to let the user deal with this.
2497 */
2498 else if (characterDataHandler)
2499 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002500#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002501 else if (defaultHandler)
2502 reportDefault(parser, enc, s, next);
Fred Drake31d485c2004-08-03 07:06:22 +00002503 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2504 if (result != XML_ERROR_NONE)
2505 return result;
2506 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002507 processor = cdataSectionProcessor;
2508 return result;
2509 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002510 }
2511 break;
2512 case XML_TOK_TRAILING_RSQB:
Fred Drake31d485c2004-08-03 07:06:22 +00002513 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002514 *nextPtr = s;
2515 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002516 }
2517 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002518 if (MUST_CONVERT(enc, s)) {
2519 ICHAR *dataPtr = (ICHAR *)dataBuf;
2520 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2521 characterDataHandler(handlerArg, dataBuf,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002522 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002523 }
2524 else
2525 characterDataHandler(handlerArg,
2526 (XML_Char *)s,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002527 (int)((XML_Char *)end - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002528 }
2529 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002530 reportDefault(parser, enc, s, end);
Fred Drake31d485c2004-08-03 07:06:22 +00002531 /* We are at the end of the final buffer, should we check for
2532 XML_SUSPENDED, XML_FINISHED?
2533 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002534 if (startTagLevel == 0) {
2535 *eventPP = end;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002536 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002537 }
2538 if (tagLevel != startTagLevel) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002539 *eventPP = end;
2540 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002541 }
Fred Drake31d485c2004-08-03 07:06:22 +00002542 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002543 return XML_ERROR_NONE;
2544 case XML_TOK_DATA_CHARS:
2545 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002546 if (MUST_CONVERT(enc, s)) {
2547 for (;;) {
2548 ICHAR *dataPtr = (ICHAR *)dataBuf;
2549 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2550 *eventEndPP = s;
2551 characterDataHandler(handlerArg, dataBuf,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002552 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002553 if (s == next)
2554 break;
2555 *eventPP = s;
2556 }
2557 }
2558 else
2559 characterDataHandler(handlerArg,
2560 (XML_Char *)s,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002561 (int)((XML_Char *)next - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002562 }
2563 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002564 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002565 break;
2566 case XML_TOK_PI:
2567 if (!reportProcessingInstruction(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002568 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002569 break;
2570 case XML_TOK_COMMENT:
2571 if (!reportComment(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002572 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002573 break;
2574 default:
2575 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002576 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002577 break;
2578 }
2579 *eventPP = s = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002580 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00002581 case XML_SUSPENDED:
2582 *nextPtr = next;
2583 return XML_ERROR_NONE;
2584 case XML_FINISHED:
2585 return XML_ERROR_ABORTED;
2586 default: ;
2587 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002588 }
2589 /* not reached */
2590}
2591
Fred Drake4faea012003-01-28 06:42:40 +00002592/* Precondition: all arguments must be non-NULL;
2593 Purpose:
2594 - normalize attributes
2595 - check attributes for well-formedness
2596 - generate namespace aware attribute names (URI, prefix)
2597 - build list of attributes for startElementHandler
2598 - default attributes
2599 - process namespace declarations (check and report them)
2600 - generate namespace aware element name (URI, prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002601*/
2602static enum XML_Error
2603storeAtts(XML_Parser parser, const ENCODING *enc,
2604 const char *attStr, TAG_NAME *tagNamePtr,
2605 BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002606{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002607 DTD * const dtd = _dtd; /* save one level of indirection */
Fred Drake08317ae2003-10-21 15:38:55 +00002608 ELEMENT_TYPE *elementType;
2609 int nDefaultAtts;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002610 const XML_Char **appAtts; /* the attribute list for the application */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002611 int attIndex = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002612 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002613 int i;
2614 int n;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002615 XML_Char *uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002616 int nPrefixes = 0;
2617 BINDING *binding;
2618 const XML_Char *localPart;
2619
2620 /* lookup the element type name */
Fred Drake4faea012003-01-28 06:42:40 +00002621 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
2622 if (!elementType) {
2623 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2624 if (!name)
2625 return XML_ERROR_NO_MEMORY;
2626 elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
2627 sizeof(ELEMENT_TYPE));
2628 if (!elementType)
2629 return XML_ERROR_NO_MEMORY;
2630 if (ns && !setElementTypePrefix(parser, elementType))
2631 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002632 }
Fred Drake4faea012003-01-28 06:42:40 +00002633 nDefaultAtts = elementType->nDefaultAtts;
2634
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002635 /* get the attributes from the tokenizer */
2636 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2637 if (n + nDefaultAtts > attsSize) {
2638 int oldAttsSize = attsSize;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002639 ATTRIBUTE *temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002640 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002641 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2642 if (temp == NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002643 return XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002644 atts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002645 if (n > oldAttsSize)
2646 XmlGetAttributes(enc, attStr, n, atts);
2647 }
Fred Drake4faea012003-01-28 06:42:40 +00002648
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002649 appAtts = (const XML_Char **)atts;
2650 for (i = 0; i < n; i++) {
2651 /* add the name and value to the attribute list */
2652 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002653 atts[i].name
2654 + XmlNameLength(enc, atts[i].name));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002655 if (!attId)
2656 return XML_ERROR_NO_MEMORY;
Fred Drake08317ae2003-10-21 15:38:55 +00002657 /* Detect duplicate attributes by their QNames. This does not work when
2658 namespace processing is turned on and different prefixes for the same
2659 namespace are used. For this case we have a check further down.
2660 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002661 if ((attId->name)[-1]) {
2662 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002663 eventPtr = atts[i].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002664 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2665 }
2666 (attId->name)[-1] = 1;
2667 appAtts[attIndex++] = attId->name;
2668 if (!atts[i].normalized) {
2669 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002670 XML_Bool isCdata = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002671
2672 /* figure out whether declared as other than CDATA */
2673 if (attId->maybeTokenized) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002674 int j;
2675 for (j = 0; j < nDefaultAtts; j++) {
2676 if (attId == elementType->defaultAtts[j].id) {
2677 isCdata = elementType->defaultAtts[j].isCdata;
2678 break;
2679 }
2680 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002681 }
2682
2683 /* normalize the attribute value */
2684 result = storeAttributeValue(parser, enc, isCdata,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002685 atts[i].valuePtr, atts[i].valueEnd,
2686 &tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002687 if (result)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002688 return result;
Fred Drake4faea012003-01-28 06:42:40 +00002689 appAtts[attIndex] = poolStart(&tempPool);
2690 poolFinish(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002691 }
Fred Drake4faea012003-01-28 06:42:40 +00002692 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002693 /* the value did not need normalizing */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002694 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2695 atts[i].valueEnd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002696 if (appAtts[attIndex] == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002697 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002698 poolFinish(&tempPool);
2699 }
2700 /* handle prefixed attribute names */
Fred Drake4faea012003-01-28 06:42:40 +00002701 if (attId->prefix) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002702 if (attId->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002703 /* deal with namespace declarations here */
2704 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2705 appAtts[attIndex], bindingsPtr);
2706 if (result)
2707 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002708 --attIndex;
2709 }
2710 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002711 /* deal with other prefixed names later */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002712 attIndex++;
2713 nPrefixes++;
2714 (attId->name)[-1] = 2;
2715 }
2716 }
2717 else
2718 attIndex++;
2719 }
Fred Drake4faea012003-01-28 06:42:40 +00002720
2721 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2722 nSpecifiedAtts = attIndex;
2723 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2724 for (i = 0; i < attIndex; i += 2)
2725 if (appAtts[i] == elementType->idAtt->name) {
2726 idAttIndex = i;
2727 break;
2728 }
2729 }
2730 else
2731 idAttIndex = -1;
2732
2733 /* do attribute defaulting */
2734 for (i = 0; i < nDefaultAtts; i++) {
2735 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2736 if (!(da->id->name)[-1] && da->value) {
2737 if (da->id->prefix) {
2738 if (da->id->xmlns) {
2739 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2740 da->value, bindingsPtr);
2741 if (result)
2742 return result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002743 }
2744 else {
Fred Drake4faea012003-01-28 06:42:40 +00002745 (da->id->name)[-1] = 2;
2746 nPrefixes++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002747 appAtts[attIndex++] = da->id->name;
2748 appAtts[attIndex++] = da->value;
2749 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002750 }
Fred Drake4faea012003-01-28 06:42:40 +00002751 else {
2752 (da->id->name)[-1] = 1;
2753 appAtts[attIndex++] = da->id->name;
2754 appAtts[attIndex++] = da->value;
2755 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002756 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002757 }
Fred Drake4faea012003-01-28 06:42:40 +00002758 appAtts[attIndex] = 0;
2759
Fred Drake08317ae2003-10-21 15:38:55 +00002760 /* expand prefixed attribute names, check for duplicates,
2761 and clear flags that say whether attributes were specified */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002762 i = 0;
2763 if (nPrefixes) {
Fred Drake08317ae2003-10-21 15:38:55 +00002764 int j; /* hash table index */
2765 unsigned long version = nsAttsVersion;
2766 int nsAttsSize = (int)1 << nsAttsPower;
2767 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2768 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2769 NS_ATT *temp;
2770 /* hash table size must also be a power of 2 and >= 8 */
2771 while (nPrefixes >> nsAttsPower++);
2772 if (nsAttsPower < 3)
2773 nsAttsPower = 3;
2774 nsAttsSize = (int)1 << nsAttsPower;
2775 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2776 if (!temp)
2777 return XML_ERROR_NO_MEMORY;
2778 nsAtts = temp;
2779 version = 0; /* force re-initialization of nsAtts hash table */
2780 }
2781 /* using a version flag saves us from initializing nsAtts every time */
2782 if (!version) { /* initialize version flags when version wraps around */
2783 version = INIT_ATTS_VERSION;
2784 for (j = nsAttsSize; j != 0; )
2785 nsAtts[--j].version = version;
2786 }
2787 nsAttsVersion = --version;
2788
2789 /* expand prefixed names and check for duplicates */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002790 for (; i < attIndex; i += 2) {
Fred Drake08317ae2003-10-21 15:38:55 +00002791 const XML_Char *s = appAtts[i];
2792 if (s[-1] == 2) { /* prefixed */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002793 ATTRIBUTE_ID *id;
Fred Drake08317ae2003-10-21 15:38:55 +00002794 const BINDING *b;
2795 unsigned long uriHash = 0;
2796 ((XML_Char *)s)[-1] = 0; /* clear flag */
2797 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00002798 if (!id)
2799 return XML_ERROR_NO_MEMORY;
Fred Drake08317ae2003-10-21 15:38:55 +00002800 b = id->prefix->binding;
2801 if (!b)
2802 return XML_ERROR_UNBOUND_PREFIX;
2803
2804 /* as we expand the name we also calculate its hash value */
2805 for (j = 0; j < b->uriLen; j++) {
2806 const XML_Char c = b->uri[j];
2807 if (!poolAppendChar(&tempPool, c))
2808 return XML_ERROR_NO_MEMORY;
2809 uriHash = CHAR_HASH(uriHash, c);
2810 }
2811 while (*s++ != XML_T(':'))
2812 ;
2813 do { /* copies null terminator */
2814 const XML_Char c = *s;
2815 if (!poolAppendChar(&tempPool, *s))
2816 return XML_ERROR_NO_MEMORY;
2817 uriHash = CHAR_HASH(uriHash, c);
2818 } while (*s++);
2819
2820 { /* Check hash table for duplicate of expanded name (uriName).
2821 Derived from code in lookup(HASH_TABLE *table, ...).
2822 */
2823 unsigned char step = 0;
2824 unsigned long mask = nsAttsSize - 1;
2825 j = uriHash & mask; /* index into hash table */
2826 while (nsAtts[j].version == version) {
2827 /* for speed we compare stored hash values first */
2828 if (uriHash == nsAtts[j].hash) {
2829 const XML_Char *s1 = poolStart(&tempPool);
2830 const XML_Char *s2 = nsAtts[j].uriName;
2831 /* s1 is null terminated, but not s2 */
2832 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2833 if (*s1 == 0)
2834 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2835 }
2836 if (!step)
2837 step = PROBE_STEP(uriHash, mask, nsAttsPower);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002838 j < step ? (j += nsAttsSize - step) : (j -= step);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002839 }
Fred Drake08317ae2003-10-21 15:38:55 +00002840 }
2841
2842 if (ns_triplets) { /* append namespace separator and prefix */
2843 tempPool.ptr[-1] = namespaceSeparator;
2844 s = b->prefix->name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002845 do {
2846 if (!poolAppendChar(&tempPool, *s))
2847 return XML_ERROR_NO_MEMORY;
2848 } while (*s++);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002849 }
Fred Drake08317ae2003-10-21 15:38:55 +00002850
2851 /* store expanded name in attribute list */
2852 s = poolStart(&tempPool);
2853 poolFinish(&tempPool);
2854 appAtts[i] = s;
2855
2856 /* fill empty slot with new version, uriName and hash value */
2857 nsAtts[j].version = version;
2858 nsAtts[j].hash = uriHash;
2859 nsAtts[j].uriName = s;
2860
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002861 if (!--nPrefixes) {
2862 i += 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002863 break;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002864 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002865 }
Fred Drake08317ae2003-10-21 15:38:55 +00002866 else /* not prefixed */
2867 ((XML_Char *)s)[-1] = 0; /* clear flag */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002868 }
2869 }
Fred Drake08317ae2003-10-21 15:38:55 +00002870 /* clear flags for the remaining attributes */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002871 for (; i < attIndex; i += 2)
2872 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002873 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2874 binding->attId->name[-1] = 0;
Fred Drake4faea012003-01-28 06:42:40 +00002875
Fred Drake08317ae2003-10-21 15:38:55 +00002876 if (!ns)
2877 return XML_ERROR_NONE;
2878
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002879 /* expand the element type name */
2880 if (elementType->prefix) {
2881 binding = elementType->prefix->binding;
2882 if (!binding)
Fred Drake08317ae2003-10-21 15:38:55 +00002883 return XML_ERROR_UNBOUND_PREFIX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002884 localPart = tagNamePtr->str;
2885 while (*localPart++ != XML_T(':'))
2886 ;
2887 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002888 else if (dtd->defaultPrefix.binding) {
2889 binding = dtd->defaultPrefix.binding;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002890 localPart = tagNamePtr->str;
2891 }
2892 else
2893 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002894 prefixLen = 0;
Fred Drake08317ae2003-10-21 15:38:55 +00002895 if (ns_triplets && binding->prefix->name) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002896 for (; binding->prefix->name[prefixLen++];)
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002897 ; /* prefixLen includes null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002898 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002899 tagNamePtr->localPart = localPart;
2900 tagNamePtr->uriLen = binding->uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002901 tagNamePtr->prefix = binding->prefix->name;
2902 tagNamePtr->prefixLen = prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002903 for (i = 0; localPart[i++];)
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002904 ; /* i includes null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002905 n = i + binding->uriLen + prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002906 if (n > binding->uriAlloc) {
2907 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002908 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002909 if (!uri)
2910 return XML_ERROR_NO_MEMORY;
2911 binding->uriAlloc = n + EXPAND_SPARE;
2912 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
2913 for (p = tagStack; p; p = p->parent)
2914 if (p->name.str == binding->uri)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002915 p->name.str = uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002916 FREE(binding->uri);
2917 binding->uri = uri;
2918 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002919 /* if namespaceSeparator != '\0' then uri includes it already */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002920 uri = binding->uri + binding->uriLen;
2921 memcpy(uri, localPart, i * sizeof(XML_Char));
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002922 /* we always have a namespace separator between localPart and prefix */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002923 if (prefixLen) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002924 uri += i - 1;
2925 *uri = namespaceSeparator; /* replace null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002926 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
2927 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002928 tagNamePtr->str = binding->uri;
2929 return XML_ERROR_NONE;
2930}
2931
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002932/* addBinding() overwrites the value of prefix->binding without checking.
2933 Therefore one must keep track of the old value outside of addBinding().
2934*/
2935static enum XML_Error
2936addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
2937 const XML_Char *uri, BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002938{
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002939 static const XML_Char xmlNamespace[] = {
2940 'h', 't', 't', 'p', ':', '/', '/',
2941 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2942 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
2943 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
2944 };
2945 static const int xmlLen =
2946 (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
2947 static const XML_Char xmlnsNamespace[] = {
2948 'h', 't', 't', 'p', ':', '/', '/',
2949 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
2950 '2', '0', '0', '0', '/', 'x', 'm', 'l', 'n', 's', '/', '\0'
2951 };
2952 static const int xmlnsLen =
2953 (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
2954
2955 XML_Bool mustBeXML = XML_FALSE;
2956 XML_Bool isXML = XML_TRUE;
2957 XML_Bool isXMLNS = XML_TRUE;
2958
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002959 BINDING *b;
2960 int len;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002961
Fred Drake31d485c2004-08-03 07:06:22 +00002962 /* 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 +00002963 if (*uri == XML_T('\0') && prefix->name)
Fred Drake31d485c2004-08-03 07:06:22 +00002964 return XML_ERROR_UNDECLARING_PREFIX;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002965
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002966 if (prefix->name
2967 && prefix->name[0] == XML_T('x')
2968 && prefix->name[1] == XML_T('m')
2969 && prefix->name[2] == XML_T('l')) {
2970
2971 /* Not allowed to bind xmlns */
2972 if (prefix->name[3] == XML_T('n')
2973 && prefix->name[4] == XML_T('s')
2974 && prefix->name[5] == XML_T('\0'))
2975 return XML_ERROR_RESERVED_PREFIX_XMLNS;
2976
2977 if (prefix->name[3] == XML_T('\0'))
2978 mustBeXML = XML_TRUE;
2979 }
2980
2981 for (len = 0; uri[len]; len++) {
2982 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
2983 isXML = XML_FALSE;
2984
2985 if (!mustBeXML && isXMLNS
2986 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
2987 isXMLNS = XML_FALSE;
2988 }
2989 isXML = isXML && len == xmlLen;
2990 isXMLNS = isXMLNS && len == xmlnsLen;
2991
2992 if (mustBeXML != isXML)
2993 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
2994 : XML_ERROR_RESERVED_NAMESPACE_URI;
2995
2996 if (isXMLNS)
2997 return XML_ERROR_RESERVED_NAMESPACE_URI;
2998
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002999 if (namespaceSeparator)
3000 len++;
3001 if (freeBindingList) {
3002 b = freeBindingList;
3003 if (len > b->uriAlloc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003004 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3005 sizeof(XML_Char) * (len + EXPAND_SPARE));
3006 if (temp == NULL)
3007 return XML_ERROR_NO_MEMORY;
3008 b->uri = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003009 b->uriAlloc = len + EXPAND_SPARE;
3010 }
3011 freeBindingList = b->nextTagBinding;
3012 }
3013 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003014 b = (BINDING *)MALLOC(sizeof(BINDING));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003015 if (!b)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003016 return XML_ERROR_NO_MEMORY;
3017 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003018 if (!b->uri) {
3019 FREE(b);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003020 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003021 }
3022 b->uriAlloc = len + EXPAND_SPARE;
3023 }
3024 b->uriLen = len;
3025 memcpy(b->uri, uri, len * sizeof(XML_Char));
3026 if (namespaceSeparator)
3027 b->uri[len - 1] = namespaceSeparator;
3028 b->prefix = prefix;
3029 b->attId = attId;
3030 b->prevPrefixBinding = prefix->binding;
Fred Drake08317ae2003-10-21 15:38:55 +00003031 /* NULL binding when default namespace undeclared */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003032 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3033 prefix->binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003034 else
3035 prefix->binding = b;
3036 b->nextTagBinding = *bindingsPtr;
3037 *bindingsPtr = b;
Fred Drake31d485c2004-08-03 07:06:22 +00003038 /* if attId == NULL then we are not starting a namespace scope */
3039 if (attId && startNamespaceDeclHandler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003040 startNamespaceDeclHandler(handlerArg, prefix->name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003041 prefix->binding ? uri : 0);
3042 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003043}
3044
3045/* The idea here is to avoid using stack for each CDATA section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003046 the whole file is parsed with one call.
3047*/
3048static enum XML_Error PTRCALL
3049cdataSectionProcessor(XML_Parser parser,
3050 const char *start,
3051 const char *end,
3052 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003053{
Fred Drake31d485c2004-08-03 07:06:22 +00003054 enum XML_Error result = doCdataSection(parser, encoding, &start, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003055 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00003056 if (result != XML_ERROR_NONE)
3057 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003058 if (start) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003059 if (parentParser) { /* we are parsing an external entity */
3060 processor = externalEntityContentProcessor;
3061 return externalEntityContentProcessor(parser, start, end, endPtr);
3062 }
3063 else {
3064 processor = contentProcessor;
3065 return contentProcessor(parser, start, end, endPtr);
3066 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003067 }
3068 return result;
3069}
3070
Fred Drake31d485c2004-08-03 07:06:22 +00003071/* startPtr gets set to non-null if the section is closed, and to null if
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003072 the section is not yet closed.
3073*/
3074static enum XML_Error
3075doCdataSection(XML_Parser parser,
3076 const ENCODING *enc,
3077 const char **startPtr,
3078 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003079 const char **nextPtr,
3080 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003081{
3082 const char *s = *startPtr;
3083 const char **eventPP;
3084 const char **eventEndPP;
3085 if (enc == encoding) {
3086 eventPP = &eventPtr;
3087 *eventPP = s;
3088 eventEndPP = &eventEndPtr;
3089 }
3090 else {
3091 eventPP = &(openInternalEntities->internalEventPtr);
3092 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3093 }
3094 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003095 *startPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00003096
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003097 for (;;) {
3098 const char *next;
3099 int tok = XmlCdataSectionTok(enc, s, end, &next);
3100 *eventEndPP = next;
3101 switch (tok) {
3102 case XML_TOK_CDATA_SECT_CLOSE:
3103 if (endCdataSectionHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003104 endCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003105#if 0
3106 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3107 else if (characterDataHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003108 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003109#endif
3110 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003111 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003112 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003113 *nextPtr = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003114 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00003115 return XML_ERROR_ABORTED;
3116 else
3117 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003118 case XML_TOK_DATA_NEWLINE:
3119 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003120 XML_Char c = 0xA;
3121 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003122 }
3123 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003124 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003125 break;
3126 case XML_TOK_DATA_CHARS:
3127 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003128 if (MUST_CONVERT(enc, s)) {
3129 for (;;) {
3130 ICHAR *dataPtr = (ICHAR *)dataBuf;
3131 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3132 *eventEndPP = next;
3133 characterDataHandler(handlerArg, dataBuf,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003134 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003135 if (s == next)
3136 break;
3137 *eventPP = s;
3138 }
3139 }
3140 else
3141 characterDataHandler(handlerArg,
3142 (XML_Char *)s,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003143 (int)((XML_Char *)next - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003144 }
3145 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003146 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003147 break;
3148 case XML_TOK_INVALID:
3149 *eventPP = next;
3150 return XML_ERROR_INVALID_TOKEN;
3151 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003152 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003153 *nextPtr = s;
3154 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003155 }
3156 return XML_ERROR_PARTIAL_CHAR;
3157 case XML_TOK_PARTIAL:
3158 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003159 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003160 *nextPtr = s;
3161 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003162 }
3163 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3164 default:
3165 *eventPP = next;
3166 return XML_ERROR_UNEXPECTED_STATE;
3167 }
Fred Drake31d485c2004-08-03 07:06:22 +00003168
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003169 *eventPP = s = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003170 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00003171 case XML_SUSPENDED:
3172 *nextPtr = next;
3173 return XML_ERROR_NONE;
3174 case XML_FINISHED:
3175 return XML_ERROR_ABORTED;
3176 default: ;
3177 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003178 }
3179 /* not reached */
3180}
3181
3182#ifdef XML_DTD
3183
3184/* The idea here is to avoid using stack for each IGNORE section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003185 the whole file is parsed with one call.
3186*/
3187static enum XML_Error PTRCALL
3188ignoreSectionProcessor(XML_Parser parser,
3189 const char *start,
3190 const char *end,
3191 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003192{
Fred Drake31d485c2004-08-03 07:06:22 +00003193 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003194 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00003195 if (result != XML_ERROR_NONE)
3196 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003197 if (start) {
3198 processor = prologProcessor;
3199 return prologProcessor(parser, start, end, endPtr);
3200 }
3201 return result;
3202}
3203
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003204/* startPtr gets set to non-null is the section is closed, and to null
3205 if the section is not yet closed.
3206*/
3207static enum XML_Error
3208doIgnoreSection(XML_Parser parser,
3209 const ENCODING *enc,
3210 const char **startPtr,
3211 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003212 const char **nextPtr,
3213 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003214{
3215 const char *next;
3216 int tok;
3217 const char *s = *startPtr;
3218 const char **eventPP;
3219 const char **eventEndPP;
3220 if (enc == encoding) {
3221 eventPP = &eventPtr;
3222 *eventPP = s;
3223 eventEndPP = &eventEndPtr;
3224 }
3225 else {
3226 eventPP = &(openInternalEntities->internalEventPtr);
3227 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3228 }
3229 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003230 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003231 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3232 *eventEndPP = next;
3233 switch (tok) {
3234 case XML_TOK_IGNORE_SECT:
3235 if (defaultHandler)
3236 reportDefault(parser, enc, s, next);
3237 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003238 *nextPtr = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003239 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00003240 return XML_ERROR_ABORTED;
3241 else
3242 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003243 case XML_TOK_INVALID:
3244 *eventPP = next;
3245 return XML_ERROR_INVALID_TOKEN;
3246 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003247 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003248 *nextPtr = s;
3249 return XML_ERROR_NONE;
3250 }
3251 return XML_ERROR_PARTIAL_CHAR;
3252 case XML_TOK_PARTIAL:
3253 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003254 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003255 *nextPtr = s;
3256 return XML_ERROR_NONE;
3257 }
3258 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3259 default:
3260 *eventPP = next;
3261 return XML_ERROR_UNEXPECTED_STATE;
3262 }
3263 /* not reached */
3264}
3265
3266#endif /* XML_DTD */
3267
3268static enum XML_Error
3269initializeEncoding(XML_Parser parser)
3270{
3271 const char *s;
3272#ifdef XML_UNICODE
3273 char encodingBuf[128];
3274 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003275 s = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003276 else {
3277 int i;
3278 for (i = 0; protocolEncodingName[i]; i++) {
3279 if (i == sizeof(encodingBuf) - 1
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003280 || (protocolEncodingName[i] & ~0x7f) != 0) {
3281 encodingBuf[0] = '\0';
3282 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003283 }
3284 encodingBuf[i] = (char)protocolEncodingName[i];
3285 }
3286 encodingBuf[i] = '\0';
3287 s = encodingBuf;
3288 }
3289#else
3290 s = protocolEncodingName;
3291#endif
3292 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3293 return XML_ERROR_NONE;
3294 return handleUnknownEncoding(parser, protocolEncodingName);
3295}
3296
3297static enum XML_Error
3298processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003299 const char *s, const char *next)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003300{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003301 const char *encodingName = NULL;
3302 const XML_Char *storedEncName = NULL;
3303 const ENCODING *newEncoding = NULL;
3304 const char *version = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003305 const char *versionend;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003306 const XML_Char *storedversion = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003307 int standalone = -1;
3308 if (!(ns
3309 ? XmlParseXmlDeclNS
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003310 : XmlParseXmlDecl)(isGeneralTextEntity,
3311 encoding,
3312 s,
3313 next,
3314 &eventPtr,
3315 &version,
3316 &versionend,
3317 &encodingName,
3318 &newEncoding,
Fred Drake31d485c2004-08-03 07:06:22 +00003319 &standalone)) {
3320 if (isGeneralTextEntity)
3321 return XML_ERROR_TEXT_DECL;
3322 else
3323 return XML_ERROR_XML_DECL;
3324 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003325 if (!isGeneralTextEntity && standalone == 1) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003326 _dtd->standalone = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003327#ifdef XML_DTD
3328 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3329 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3330#endif /* XML_DTD */
3331 }
3332 if (xmlDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003333 if (encodingName != NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003334 storedEncName = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003335 encoding,
3336 encodingName,
3337 encodingName
3338 + XmlNameLength(encoding, encodingName));
3339 if (!storedEncName)
3340 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003341 poolFinish(&temp2Pool);
3342 }
3343 if (version) {
3344 storedversion = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003345 encoding,
3346 version,
3347 versionend - encoding->minBytesPerChar);
3348 if (!storedversion)
3349 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003350 }
3351 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3352 }
3353 else if (defaultHandler)
3354 reportDefault(parser, encoding, s, next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003355 if (protocolEncodingName == NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003356 if (newEncoding) {
3357 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003358 eventPtr = encodingName;
3359 return XML_ERROR_INCORRECT_ENCODING;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003360 }
3361 encoding = newEncoding;
3362 }
3363 else if (encodingName) {
3364 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003365 if (!storedEncName) {
3366 storedEncName = poolStoreString(
3367 &temp2Pool, encoding, encodingName,
3368 encodingName + XmlNameLength(encoding, encodingName));
3369 if (!storedEncName)
3370 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003371 }
3372 result = handleUnknownEncoding(parser, storedEncName);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003373 poolClear(&temp2Pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003374 if (result == XML_ERROR_UNKNOWN_ENCODING)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003375 eventPtr = encodingName;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003376 return result;
3377 }
3378 }
3379
3380 if (storedEncName || storedversion)
3381 poolClear(&temp2Pool);
3382
3383 return XML_ERROR_NONE;
3384}
3385
3386static enum XML_Error
3387handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3388{
3389 if (unknownEncodingHandler) {
3390 XML_Encoding info;
3391 int i;
3392 for (i = 0; i < 256; i++)
3393 info.map[i] = -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003394 info.convert = NULL;
3395 info.data = NULL;
3396 info.release = NULL;
3397 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3398 &info)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003399 ENCODING *enc;
3400 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3401 if (!unknownEncodingMem) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003402 if (info.release)
3403 info.release(info.data);
3404 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003405 }
3406 enc = (ns
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003407 ? XmlInitUnknownEncodingNS
3408 : XmlInitUnknownEncoding)(unknownEncodingMem,
3409 info.map,
3410 info.convert,
3411 info.data);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003412 if (enc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003413 unknownEncodingData = info.data;
3414 unknownEncodingRelease = info.release;
3415 encoding = enc;
3416 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003417 }
3418 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003419 if (info.release != NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003420 info.release(info.data);
3421 }
3422 return XML_ERROR_UNKNOWN_ENCODING;
3423}
3424
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003425static enum XML_Error PTRCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003426prologInitProcessor(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003427 const char *s,
3428 const char *end,
3429 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003430{
3431 enum XML_Error result = initializeEncoding(parser);
3432 if (result != XML_ERROR_NONE)
3433 return result;
3434 processor = prologProcessor;
3435 return prologProcessor(parser, s, end, nextPtr);
3436}
3437
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003438#ifdef XML_DTD
3439
3440static enum XML_Error PTRCALL
3441externalParEntInitProcessor(XML_Parser parser,
3442 const char *s,
3443 const char *end,
3444 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003445{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003446 enum XML_Error result = initializeEncoding(parser);
3447 if (result != XML_ERROR_NONE)
3448 return result;
3449
3450 /* we know now that XML_Parse(Buffer) has been called,
3451 so we consider the external parameter entity read */
3452 _dtd->paramEntityRead = XML_TRUE;
3453
3454 if (prologState.inEntityValue) {
3455 processor = entityValueInitProcessor;
3456 return entityValueInitProcessor(parser, s, end, nextPtr);
3457 }
3458 else {
3459 processor = externalParEntProcessor;
3460 return externalParEntProcessor(parser, s, end, nextPtr);
3461 }
3462}
3463
3464static enum XML_Error PTRCALL
3465entityValueInitProcessor(XML_Parser parser,
3466 const char *s,
3467 const char *end,
3468 const char **nextPtr)
3469{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003470 int tok;
Fred Drake31d485c2004-08-03 07:06:22 +00003471 const char *start = s;
3472 const char *next = start;
3473 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003474
Fred Drake31d485c2004-08-03 07:06:22 +00003475 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003476 tok = XmlPrologTok(encoding, start, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003477 eventEndPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003478 if (tok <= 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003479 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Fred Drake31d485c2004-08-03 07:06:22 +00003480 *nextPtr = s;
3481 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003482 }
3483 switch (tok) {
3484 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003485 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003486 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003487 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003488 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003489 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003490 case XML_TOK_NONE: /* start == end */
3491 default:
3492 break;
3493 }
Fred Drake31d485c2004-08-03 07:06:22 +00003494 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003495 return storeEntityValue(parser, encoding, s, end);
3496 }
3497 else if (tok == XML_TOK_XML_DECL) {
Fred Drake31d485c2004-08-03 07:06:22 +00003498 enum XML_Error result;
3499 result = processXmlDecl(parser, 0, start, next);
3500 if (result != XML_ERROR_NONE)
3501 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003502 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00003503 case XML_SUSPENDED:
3504 *nextPtr = next;
3505 return XML_ERROR_NONE;
3506 case XML_FINISHED:
3507 return XML_ERROR_ABORTED;
3508 default:
3509 *nextPtr = next;
3510 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003511 /* stop scanning for text declaration - we found one */
3512 processor = entityValueProcessor;
3513 return entityValueProcessor(parser, next, end, nextPtr);
3514 }
3515 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3516 return XML_TOK_NONE on the next call, which would then cause the
3517 function to exit with *nextPtr set to s - that is what we want for other
3518 tokens, but not for the BOM - we would rather like to skip it;
3519 then, when this routine is entered the next time, XmlPrologTok will
3520 return XML_TOK_INVALID, since the BOM is still in the buffer
3521 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003522 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003523 *nextPtr = next;
3524 return XML_ERROR_NONE;
3525 }
3526 start = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003527 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003528 }
3529}
3530
3531static enum XML_Error PTRCALL
3532externalParEntProcessor(XML_Parser parser,
3533 const char *s,
3534 const char *end,
3535 const char **nextPtr)
3536{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003537 const char *next = s;
3538 int tok;
3539
Fred Drake31d485c2004-08-03 07:06:22 +00003540 tok = XmlPrologTok(encoding, s, end, &next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003541 if (tok <= 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003542 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003543 *nextPtr = s;
3544 return XML_ERROR_NONE;
3545 }
3546 switch (tok) {
3547 case XML_TOK_INVALID:
3548 return XML_ERROR_INVALID_TOKEN;
3549 case XML_TOK_PARTIAL:
3550 return XML_ERROR_UNCLOSED_TOKEN;
3551 case XML_TOK_PARTIAL_CHAR:
3552 return XML_ERROR_PARTIAL_CHAR;
3553 case XML_TOK_NONE: /* start == end */
3554 default:
3555 break;
3556 }
3557 }
3558 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3559 However, when parsing an external subset, doProlog will not accept a BOM
3560 as valid, and report a syntax error, so we have to skip the BOM
3561 */
3562 else if (tok == XML_TOK_BOM) {
3563 s = next;
3564 tok = XmlPrologTok(encoding, s, end, &next);
3565 }
3566
3567 processor = prologProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +00003568 return doProlog(parser, encoding, s, end, tok, next,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003569 nextPtr, (XML_Bool)!ps_finalBuffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003570}
3571
3572static enum XML_Error PTRCALL
3573entityValueProcessor(XML_Parser parser,
3574 const char *s,
3575 const char *end,
3576 const char **nextPtr)
3577{
3578 const char *start = s;
3579 const char *next = s;
3580 const ENCODING *enc = encoding;
3581 int tok;
3582
3583 for (;;) {
3584 tok = XmlPrologTok(enc, start, end, &next);
3585 if (tok <= 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003586 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003587 *nextPtr = s;
3588 return XML_ERROR_NONE;
3589 }
3590 switch (tok) {
3591 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003592 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003593 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003594 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003595 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003596 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003597 case XML_TOK_NONE: /* start == end */
3598 default:
3599 break;
3600 }
Fred Drake31d485c2004-08-03 07:06:22 +00003601 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003602 return storeEntityValue(parser, enc, s, end);
3603 }
3604 start = next;
3605 }
3606}
3607
3608#endif /* XML_DTD */
3609
3610static enum XML_Error PTRCALL
3611prologProcessor(XML_Parser parser,
3612 const char *s,
3613 const char *end,
3614 const char **nextPtr)
3615{
3616 const char *next = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003617 int tok = XmlPrologTok(encoding, s, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003618 return doProlog(parser, encoding, s, end, tok, next,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003619 nextPtr, (XML_Bool)!ps_finalBuffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003620}
3621
3622static enum XML_Error
3623doProlog(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003624 const ENCODING *enc,
3625 const char *s,
3626 const char *end,
3627 int tok,
3628 const char *next,
Fred Drake31d485c2004-08-03 07:06:22 +00003629 const char **nextPtr,
3630 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003631{
3632#ifdef XML_DTD
3633 static const XML_Char externalSubsetName[] = { '#' , '\0' };
3634#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003635 static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
3636 static const XML_Char atypeID[] = { 'I', 'D', '\0' };
3637 static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
3638 static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
3639 static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
3640 static const XML_Char atypeENTITIES[] =
3641 { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
3642 static const XML_Char atypeNMTOKEN[] = {
3643 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
3644 static const XML_Char atypeNMTOKENS[] = {
3645 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
3646 static const XML_Char notationPrefix[] = {
3647 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
3648 static const XML_Char enumValueSep[] = { '|', '\0' };
3649 static const XML_Char enumValueStart[] = { '(', '\0' };
3650
Fred Drake31d485c2004-08-03 07:06:22 +00003651 /* save one level of indirection */
3652 DTD * const dtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003653
3654 const char **eventPP;
3655 const char **eventEndPP;
3656 enum XML_Content_Quant quant;
3657
3658 if (enc == encoding) {
3659 eventPP = &eventPtr;
3660 eventEndPP = &eventEndPtr;
3661 }
3662 else {
3663 eventPP = &(openInternalEntities->internalEventPtr);
3664 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3665 }
Fred Drake31d485c2004-08-03 07:06:22 +00003666
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003667 for (;;) {
3668 int role;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003669 XML_Bool handleDefault = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003670 *eventPP = s;
3671 *eventEndPP = next;
3672 if (tok <= 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00003673 if (haveMore && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003674 *nextPtr = s;
3675 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003676 }
3677 switch (tok) {
3678 case XML_TOK_INVALID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003679 *eventPP = next;
3680 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003681 case XML_TOK_PARTIAL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003682 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003683 case XML_TOK_PARTIAL_CHAR:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003684 return XML_ERROR_PARTIAL_CHAR;
Matthias Klose865e33b2010-01-22 01:13:15 +00003685 case -XML_TOK_PROLOG_S:
3686 tok = -tok;
3687 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003688 case XML_TOK_NONE:
3689#ifdef XML_DTD
Fred Drake31d485c2004-08-03 07:06:22 +00003690 /* for internal PE NOT referenced between declarations */
3691 if (enc != encoding && !openInternalEntities->betweenDecl) {
3692 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003693 return XML_ERROR_NONE;
Fred Drake31d485c2004-08-03 07:06:22 +00003694 }
3695 /* WFC: PE Between Declarations - must check that PE contains
3696 complete markup, not only for external PEs, but also for
3697 internal PEs if the reference occurs between declarations.
3698 */
3699 if (isParamEntity || enc != encoding) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003700 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3701 == XML_ROLE_ERROR)
Fred Drake31d485c2004-08-03 07:06:22 +00003702 return XML_ERROR_INCOMPLETE_PE;
3703 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003704 return XML_ERROR_NONE;
3705 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003706#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003707 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003708 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003709 tok = -tok;
3710 next = end;
3711 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003712 }
3713 }
3714 role = XmlTokenRole(&prologState, tok, s, next, enc);
3715 switch (role) {
3716 case XML_ROLE_XML_DECL:
3717 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003718 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3719 if (result != XML_ERROR_NONE)
3720 return result;
3721 enc = encoding;
3722 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003723 }
3724 break;
3725 case XML_ROLE_DOCTYPE_NAME:
3726 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003727 doctypeName = poolStoreString(&tempPool, enc, s, next);
3728 if (!doctypeName)
3729 return XML_ERROR_NO_MEMORY;
3730 poolFinish(&tempPool);
3731 doctypePubid = NULL;
3732 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003733 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003734 doctypeSysid = NULL; /* always initialize to NULL */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003735 break;
3736 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3737 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003738 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3739 doctypePubid, 1);
3740 doctypeName = NULL;
3741 poolClear(&tempPool);
3742 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003743 }
3744 break;
3745#ifdef XML_DTD
3746 case XML_ROLE_TEXT_DECL:
3747 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003748 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3749 if (result != XML_ERROR_NONE)
3750 return result;
3751 enc = encoding;
3752 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003753 }
3754 break;
3755#endif /* XML_DTD */
3756 case XML_ROLE_DOCTYPE_PUBLIC_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003757#ifdef XML_DTD
3758 useForeignDTD = XML_FALSE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003759 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
3760 externalSubsetName,
3761 sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003762 if (!declEntity)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003763 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003764#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00003765 dtd->hasParamEntityRefs = XML_TRUE;
3766 if (startDoctypeDeclHandler) {
3767 if (!XmlIsPublicId(enc, s, next, eventPP))
3768 return XML_ERROR_PUBLICID;
3769 doctypePubid = poolStoreString(&tempPool, enc,
3770 s + enc->minBytesPerChar,
3771 next - enc->minBytesPerChar);
3772 if (!doctypePubid)
3773 return XML_ERROR_NO_MEMORY;
3774 normalizePublicId((XML_Char *)doctypePubid);
3775 poolFinish(&tempPool);
3776 handleDefault = XML_FALSE;
3777 goto alreadyChecked;
3778 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003779 /* fall through */
3780 case XML_ROLE_ENTITY_PUBLIC_ID:
3781 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00003782 return XML_ERROR_PUBLICID;
3783 alreadyChecked:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003784 if (dtd->keepProcessing && declEntity) {
3785 XML_Char *tem = poolStoreString(&dtd->pool,
3786 enc,
3787 s + enc->minBytesPerChar,
3788 next - enc->minBytesPerChar);
3789 if (!tem)
3790 return XML_ERROR_NO_MEMORY;
3791 normalizePublicId(tem);
3792 declEntity->publicId = tem;
3793 poolFinish(&dtd->pool);
3794 if (entityDeclHandler)
3795 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003796 }
3797 break;
3798 case XML_ROLE_DOCTYPE_CLOSE:
3799 if (doctypeName) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003800 startDoctypeDeclHandler(handlerArg, doctypeName,
3801 doctypeSysid, doctypePubid, 0);
3802 poolClear(&tempPool);
3803 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003804 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003805 /* doctypeSysid will be non-NULL in the case of a previous
3806 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3807 was not set, indicating an external subset
3808 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003809#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003810 if (doctypeSysid || useForeignDTD) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003811 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3812 dtd->hasParamEntityRefs = XML_TRUE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003813 if (paramEntityParsing && externalEntityRefHandler) {
3814 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3815 externalSubsetName,
3816 sizeof(ENTITY));
3817 if (!entity)
3818 return XML_ERROR_NO_MEMORY;
3819 if (useForeignDTD)
3820 entity->base = curBase;
3821 dtd->paramEntityRead = XML_FALSE;
3822 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3823 0,
3824 entity->base,
3825 entity->systemId,
3826 entity->publicId))
3827 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003828 if (dtd->paramEntityRead) {
3829 if (!dtd->standalone &&
3830 notStandaloneHandler &&
3831 !notStandaloneHandler(handlerArg))
3832 return XML_ERROR_NOT_STANDALONE;
3833 }
3834 /* if we didn't read the foreign DTD then this means that there
3835 is no external subset and we must reset dtd->hasParamEntityRefs
3836 */
3837 else if (!doctypeSysid)
3838 dtd->hasParamEntityRefs = hadParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003839 /* end of DTD - no need to update dtd->keepProcessing */
3840 }
3841 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003842 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003843#endif /* XML_DTD */
3844 if (endDoctypeDeclHandler) {
3845 endDoctypeDeclHandler(handlerArg);
3846 handleDefault = XML_FALSE;
3847 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003848 break;
3849 case XML_ROLE_INSTANCE_START:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003850#ifdef XML_DTD
3851 /* if there is no DOCTYPE declaration then now is the
3852 last chance to read the foreign DTD
3853 */
3854 if (useForeignDTD) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003855 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003856 dtd->hasParamEntityRefs = XML_TRUE;
3857 if (paramEntityParsing && externalEntityRefHandler) {
3858 ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
3859 externalSubsetName,
3860 sizeof(ENTITY));
3861 if (!entity)
3862 return XML_ERROR_NO_MEMORY;
3863 entity->base = curBase;
3864 dtd->paramEntityRead = XML_FALSE;
3865 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3866 0,
3867 entity->base,
3868 entity->systemId,
3869 entity->publicId))
3870 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00003871 if (dtd->paramEntityRead) {
3872 if (!dtd->standalone &&
3873 notStandaloneHandler &&
3874 !notStandaloneHandler(handlerArg))
3875 return XML_ERROR_NOT_STANDALONE;
3876 }
3877 /* if we didn't read the foreign DTD then this means that there
3878 is no external subset and we must reset dtd->hasParamEntityRefs
3879 */
3880 else
3881 dtd->hasParamEntityRefs = hadParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003882 /* end of DTD - no need to update dtd->keepProcessing */
3883 }
3884 }
3885#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003886 processor = contentProcessor;
3887 return contentProcessor(parser, s, end, nextPtr);
3888 case XML_ROLE_ATTLIST_ELEMENT_NAME:
3889 declElementType = getElementType(parser, enc, s, next);
3890 if (!declElementType)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003891 return XML_ERROR_NO_MEMORY;
3892 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003893 case XML_ROLE_ATTRIBUTE_NAME:
3894 declAttributeId = getAttributeId(parser, enc, s, next);
3895 if (!declAttributeId)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003896 return XML_ERROR_NO_MEMORY;
3897 declAttributeIsCdata = XML_FALSE;
3898 declAttributeType = NULL;
3899 declAttributeIsId = XML_FALSE;
3900 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003901 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003902 declAttributeIsCdata = XML_TRUE;
3903 declAttributeType = atypeCDATA;
3904 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003905 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003906 declAttributeIsId = XML_TRUE;
3907 declAttributeType = atypeID;
3908 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003909 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003910 declAttributeType = atypeIDREF;
3911 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003912 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003913 declAttributeType = atypeIDREFS;
3914 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003915 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003916 declAttributeType = atypeENTITY;
3917 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003918 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003919 declAttributeType = atypeENTITIES;
3920 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003921 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003922 declAttributeType = atypeNMTOKEN;
3923 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003924 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003925 declAttributeType = atypeNMTOKENS;
3926 checkAttListDeclHandler:
3927 if (dtd->keepProcessing && attlistDeclHandler)
3928 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003929 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003930 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
3931 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003932 if (dtd->keepProcessing && attlistDeclHandler) {
3933 const XML_Char *prefix;
3934 if (declAttributeType) {
3935 prefix = enumValueSep;
3936 }
3937 else {
3938 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
3939 ? notationPrefix
3940 : enumValueStart);
3941 }
3942 if (!poolAppendString(&tempPool, prefix))
3943 return XML_ERROR_NO_MEMORY;
3944 if (!poolAppend(&tempPool, enc, s, next))
3945 return XML_ERROR_NO_MEMORY;
3946 declAttributeType = tempPool.start;
3947 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003948 }
3949 break;
3950 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
3951 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003952 if (dtd->keepProcessing) {
3953 if (!defineAttribute(declElementType, declAttributeId,
Fred Drake08317ae2003-10-21 15:38:55 +00003954 declAttributeIsCdata, declAttributeIsId,
3955 0, parser))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003956 return XML_ERROR_NO_MEMORY;
3957 if (attlistDeclHandler && declAttributeType) {
3958 if (*declAttributeType == XML_T('(')
3959 || (*declAttributeType == XML_T('N')
3960 && declAttributeType[1] == XML_T('O'))) {
3961 /* Enumerated or Notation type */
3962 if (!poolAppendChar(&tempPool, XML_T(')'))
3963 || !poolAppendChar(&tempPool, XML_T('\0')))
3964 return XML_ERROR_NO_MEMORY;
3965 declAttributeType = tempPool.start;
3966 poolFinish(&tempPool);
3967 }
3968 *eventEndPP = s;
3969 attlistDeclHandler(handlerArg, declElementType->name,
3970 declAttributeId->name, declAttributeType,
3971 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
3972 poolClear(&tempPool);
3973 handleDefault = XML_FALSE;
3974 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003975 }
3976 break;
3977 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
3978 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003979 if (dtd->keepProcessing) {
3980 const XML_Char *attVal;
Fred Drake08317ae2003-10-21 15:38:55 +00003981 enum XML_Error result =
3982 storeAttributeValue(parser, enc, declAttributeIsCdata,
3983 s + enc->minBytesPerChar,
3984 next - enc->minBytesPerChar,
3985 &dtd->pool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003986 if (result)
3987 return result;
3988 attVal = poolStart(&dtd->pool);
3989 poolFinish(&dtd->pool);
3990 /* ID attributes aren't allowed to have a default */
3991 if (!defineAttribute(declElementType, declAttributeId,
3992 declAttributeIsCdata, XML_FALSE, attVal, parser))
3993 return XML_ERROR_NO_MEMORY;
3994 if (attlistDeclHandler && declAttributeType) {
3995 if (*declAttributeType == XML_T('(')
3996 || (*declAttributeType == XML_T('N')
3997 && declAttributeType[1] == XML_T('O'))) {
3998 /* Enumerated or Notation type */
3999 if (!poolAppendChar(&tempPool, XML_T(')'))
4000 || !poolAppendChar(&tempPool, XML_T('\0')))
4001 return XML_ERROR_NO_MEMORY;
4002 declAttributeType = tempPool.start;
4003 poolFinish(&tempPool);
4004 }
4005 *eventEndPP = s;
4006 attlistDeclHandler(handlerArg, declElementType->name,
4007 declAttributeId->name, declAttributeType,
4008 attVal,
4009 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4010 poolClear(&tempPool);
4011 handleDefault = XML_FALSE;
4012 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004013 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004014 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004015 case XML_ROLE_ENTITY_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004016 if (dtd->keepProcessing) {
4017 enum XML_Error result = storeEntityValue(parser, enc,
4018 s + enc->minBytesPerChar,
4019 next - enc->minBytesPerChar);
4020 if (declEntity) {
4021 declEntity->textPtr = poolStart(&dtd->entityValuePool);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004022 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004023 poolFinish(&dtd->entityValuePool);
4024 if (entityDeclHandler) {
4025 *eventEndPP = s;
4026 entityDeclHandler(handlerArg,
4027 declEntity->name,
4028 declEntity->is_param,
4029 declEntity->textPtr,
4030 declEntity->textLen,
4031 curBase, 0, 0, 0);
4032 handleDefault = XML_FALSE;
4033 }
4034 }
4035 else
4036 poolDiscard(&dtd->entityValuePool);
4037 if (result != XML_ERROR_NONE)
4038 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004039 }
4040 break;
4041 case XML_ROLE_DOCTYPE_SYSTEM_ID:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004042#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004043 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004044#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004045 dtd->hasParamEntityRefs = XML_TRUE;
4046 if (startDoctypeDeclHandler) {
4047 doctypeSysid = poolStoreString(&tempPool, enc,
4048 s + enc->minBytesPerChar,
4049 next - enc->minBytesPerChar);
4050 if (doctypeSysid == NULL)
4051 return XML_ERROR_NO_MEMORY;
4052 poolFinish(&tempPool);
4053 handleDefault = XML_FALSE;
4054 }
4055#ifdef XML_DTD
4056 else
4057 /* use externalSubsetName to make doctypeSysid non-NULL
4058 for the case where no startDoctypeDeclHandler is set */
4059 doctypeSysid = externalSubsetName;
4060#endif /* XML_DTD */
4061 if (!dtd->standalone
4062#ifdef XML_DTD
4063 && !paramEntityParsing
4064#endif /* XML_DTD */
4065 && notStandaloneHandler
4066 && !notStandaloneHandler(handlerArg))
4067 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004068#ifndef XML_DTD
4069 break;
4070#else /* XML_DTD */
4071 if (!declEntity) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004072 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4073 externalSubsetName,
4074 sizeof(ENTITY));
4075 if (!declEntity)
4076 return XML_ERROR_NO_MEMORY;
4077 declEntity->publicId = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004078 }
4079 /* fall through */
4080#endif /* XML_DTD */
4081 case XML_ROLE_ENTITY_SYSTEM_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004082 if (dtd->keepProcessing && declEntity) {
4083 declEntity->systemId = poolStoreString(&dtd->pool, enc,
4084 s + enc->minBytesPerChar,
4085 next - enc->minBytesPerChar);
4086 if (!declEntity->systemId)
4087 return XML_ERROR_NO_MEMORY;
4088 declEntity->base = curBase;
4089 poolFinish(&dtd->pool);
4090 if (entityDeclHandler)
4091 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004092 }
4093 break;
4094 case XML_ROLE_ENTITY_COMPLETE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004095 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4096 *eventEndPP = s;
4097 entityDeclHandler(handlerArg,
4098 declEntity->name,
4099 declEntity->is_param,
4100 0,0,
4101 declEntity->base,
4102 declEntity->systemId,
4103 declEntity->publicId,
4104 0);
4105 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004106 }
4107 break;
4108 case XML_ROLE_ENTITY_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004109 if (dtd->keepProcessing && declEntity) {
4110 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4111 if (!declEntity->notation)
4112 return XML_ERROR_NO_MEMORY;
4113 poolFinish(&dtd->pool);
4114 if (unparsedEntityDeclHandler) {
4115 *eventEndPP = s;
4116 unparsedEntityDeclHandler(handlerArg,
4117 declEntity->name,
4118 declEntity->base,
4119 declEntity->systemId,
4120 declEntity->publicId,
4121 declEntity->notation);
4122 handleDefault = XML_FALSE;
4123 }
4124 else if (entityDeclHandler) {
4125 *eventEndPP = s;
4126 entityDeclHandler(handlerArg,
4127 declEntity->name,
4128 0,0,0,
4129 declEntity->base,
4130 declEntity->systemId,
4131 declEntity->publicId,
4132 declEntity->notation);
4133 handleDefault = XML_FALSE;
4134 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004135 }
4136 break;
4137 case XML_ROLE_GENERAL_ENTITY_NAME:
4138 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004139 if (XmlPredefinedEntityName(enc, s, next)) {
4140 declEntity = NULL;
4141 break;
4142 }
4143 if (dtd->keepProcessing) {
4144 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4145 if (!name)
4146 return XML_ERROR_NO_MEMORY;
4147 declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
4148 sizeof(ENTITY));
4149 if (!declEntity)
4150 return XML_ERROR_NO_MEMORY;
4151 if (declEntity->name != name) {
4152 poolDiscard(&dtd->pool);
4153 declEntity = NULL;
4154 }
4155 else {
4156 poolFinish(&dtd->pool);
4157 declEntity->publicId = NULL;
4158 declEntity->is_param = XML_FALSE;
4159 /* if we have a parent parser or are reading an internal parameter
4160 entity, then the entity declaration is not considered "internal"
4161 */
4162 declEntity->is_internal = !(parentParser || openInternalEntities);
4163 if (entityDeclHandler)
4164 handleDefault = XML_FALSE;
4165 }
4166 }
4167 else {
4168 poolDiscard(&dtd->pool);
4169 declEntity = NULL;
4170 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004171 }
4172 break;
4173 case XML_ROLE_PARAM_ENTITY_NAME:
4174#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004175 if (dtd->keepProcessing) {
4176 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4177 if (!name)
4178 return XML_ERROR_NO_MEMORY;
4179 declEntity = (ENTITY *)lookup(&dtd->paramEntities,
4180 name, sizeof(ENTITY));
4181 if (!declEntity)
4182 return XML_ERROR_NO_MEMORY;
4183 if (declEntity->name != name) {
4184 poolDiscard(&dtd->pool);
4185 declEntity = NULL;
4186 }
4187 else {
4188 poolFinish(&dtd->pool);
4189 declEntity->publicId = NULL;
4190 declEntity->is_param = XML_TRUE;
4191 /* if we have a parent parser or are reading an internal parameter
4192 entity, then the entity declaration is not considered "internal"
4193 */
4194 declEntity->is_internal = !(parentParser || openInternalEntities);
4195 if (entityDeclHandler)
4196 handleDefault = XML_FALSE;
4197 }
4198 }
4199 else {
4200 poolDiscard(&dtd->pool);
4201 declEntity = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004202 }
4203#else /* not XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004204 declEntity = NULL;
4205#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004206 break;
4207 case XML_ROLE_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004208 declNotationPublicId = NULL;
4209 declNotationName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004210 if (notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004211 declNotationName = poolStoreString(&tempPool, enc, s, next);
4212 if (!declNotationName)
4213 return XML_ERROR_NO_MEMORY;
4214 poolFinish(&tempPool);
4215 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004216 }
4217 break;
4218 case XML_ROLE_NOTATION_PUBLIC_ID:
4219 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00004220 return XML_ERROR_PUBLICID;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004221 if (declNotationName) { /* means notationDeclHandler != NULL */
4222 XML_Char *tem = poolStoreString(&tempPool,
4223 enc,
4224 s + enc->minBytesPerChar,
4225 next - enc->minBytesPerChar);
4226 if (!tem)
4227 return XML_ERROR_NO_MEMORY;
4228 normalizePublicId(tem);
4229 declNotationPublicId = tem;
4230 poolFinish(&tempPool);
4231 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004232 }
4233 break;
4234 case XML_ROLE_NOTATION_SYSTEM_ID:
4235 if (declNotationName && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004236 const XML_Char *systemId
4237 = poolStoreString(&tempPool, enc,
4238 s + enc->minBytesPerChar,
4239 next - enc->minBytesPerChar);
4240 if (!systemId)
4241 return XML_ERROR_NO_MEMORY;
4242 *eventEndPP = s;
4243 notationDeclHandler(handlerArg,
4244 declNotationName,
4245 curBase,
4246 systemId,
4247 declNotationPublicId);
4248 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004249 }
4250 poolClear(&tempPool);
4251 break;
4252 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4253 if (declNotationPublicId && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004254 *eventEndPP = s;
4255 notationDeclHandler(handlerArg,
4256 declNotationName,
4257 curBase,
4258 0,
4259 declNotationPublicId);
4260 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004261 }
4262 poolClear(&tempPool);
4263 break;
4264 case XML_ROLE_ERROR:
4265 switch (tok) {
4266 case XML_TOK_PARAM_ENTITY_REF:
Fred Drake31d485c2004-08-03 07:06:22 +00004267 /* PE references in internal subset are
4268 not allowed within declarations. */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004269 return XML_ERROR_PARAM_ENTITY_REF;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004270 case XML_TOK_XML_DECL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004271 return XML_ERROR_MISPLACED_XML_PI;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004272 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004273 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004274 }
4275#ifdef XML_DTD
4276 case XML_ROLE_IGNORE_SECT:
4277 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004278 enum XML_Error result;
4279 if (defaultHandler)
4280 reportDefault(parser, enc, s, next);
4281 handleDefault = XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00004282 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4283 if (result != XML_ERROR_NONE)
4284 return result;
4285 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004286 processor = ignoreSectionProcessor;
4287 return result;
4288 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004289 }
4290 break;
4291#endif /* XML_DTD */
4292 case XML_ROLE_GROUP_OPEN:
4293 if (prologState.level >= groupSize) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004294 if (groupSize) {
4295 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4296 if (temp == NULL)
4297 return XML_ERROR_NO_MEMORY;
4298 groupConnector = temp;
4299 if (dtd->scaffIndex) {
4300 int *temp = (int *)REALLOC(dtd->scaffIndex,
4301 groupSize * sizeof(int));
4302 if (temp == NULL)
4303 return XML_ERROR_NO_MEMORY;
4304 dtd->scaffIndex = temp;
4305 }
4306 }
4307 else {
4308 groupConnector = (char *)MALLOC(groupSize = 32);
4309 if (!groupConnector)
4310 return XML_ERROR_NO_MEMORY;
4311 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004312 }
4313 groupConnector[prologState.level] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004314 if (dtd->in_eldecl) {
4315 int myindex = nextScaffoldPart(parser);
4316 if (myindex < 0)
4317 return XML_ERROR_NO_MEMORY;
4318 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4319 dtd->scaffLevel++;
4320 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4321 if (elementDeclHandler)
4322 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004323 }
4324 break;
4325 case XML_ROLE_GROUP_SEQUENCE:
4326 if (groupConnector[prologState.level] == '|')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004327 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004328 groupConnector[prologState.level] = ',';
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004329 if (dtd->in_eldecl && elementDeclHandler)
4330 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004331 break;
4332 case XML_ROLE_GROUP_CHOICE:
4333 if (groupConnector[prologState.level] == ',')
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004334 return XML_ERROR_SYNTAX;
4335 if (dtd->in_eldecl
4336 && !groupConnector[prologState.level]
4337 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4338 != XML_CTYPE_MIXED)
4339 ) {
4340 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4341 = XML_CTYPE_CHOICE;
4342 if (elementDeclHandler)
4343 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004344 }
4345 groupConnector[prologState.level] = '|';
4346 break;
4347 case XML_ROLE_PARAM_ENTITY_REF:
4348#ifdef XML_DTD
4349 case XML_ROLE_INNER_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004350 dtd->hasParamEntityRefs = XML_TRUE;
4351 if (!paramEntityParsing)
4352 dtd->keepProcessing = dtd->standalone;
4353 else {
4354 const XML_Char *name;
4355 ENTITY *entity;
4356 name = poolStoreString(&dtd->pool, enc,
4357 s + enc->minBytesPerChar,
4358 next - enc->minBytesPerChar);
4359 if (!name)
4360 return XML_ERROR_NO_MEMORY;
4361 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4362 poolDiscard(&dtd->pool);
4363 /* first, determine if a check for an existing declaration is needed;
4364 if yes, check that the entity exists, and that it is internal,
4365 otherwise call the skipped entity handler
4366 */
4367 if (prologState.documentEntity &&
4368 (dtd->standalone
4369 ? !openInternalEntities
4370 : !dtd->hasParamEntityRefs)) {
4371 if (!entity)
4372 return XML_ERROR_UNDEFINED_ENTITY;
4373 else if (!entity->is_internal)
4374 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4375 }
4376 else if (!entity) {
4377 dtd->keepProcessing = dtd->standalone;
4378 /* cannot report skipped entities in declarations */
4379 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4380 skippedEntityHandler(handlerArg, name, 1);
4381 handleDefault = XML_FALSE;
4382 }
4383 break;
4384 }
4385 if (entity->open)
4386 return XML_ERROR_RECURSIVE_ENTITY_REF;
4387 if (entity->textPtr) {
4388 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004389 XML_Bool betweenDecl =
4390 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4391 result = processInternalEntity(parser, entity, betweenDecl);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004392 if (result != XML_ERROR_NONE)
4393 return result;
4394 handleDefault = XML_FALSE;
4395 break;
4396 }
4397 if (externalEntityRefHandler) {
4398 dtd->paramEntityRead = XML_FALSE;
4399 entity->open = XML_TRUE;
4400 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4401 0,
4402 entity->base,
4403 entity->systemId,
4404 entity->publicId)) {
4405 entity->open = XML_FALSE;
4406 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4407 }
4408 entity->open = XML_FALSE;
4409 handleDefault = XML_FALSE;
4410 if (!dtd->paramEntityRead) {
4411 dtd->keepProcessing = dtd->standalone;
4412 break;
4413 }
4414 }
4415 else {
4416 dtd->keepProcessing = dtd->standalone;
4417 break;
4418 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004419 }
4420#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004421 if (!dtd->standalone &&
4422 notStandaloneHandler &&
4423 !notStandaloneHandler(handlerArg))
4424 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004425 break;
4426
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004427 /* Element declaration stuff */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004428
4429 case XML_ROLE_ELEMENT_NAME:
4430 if (elementDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004431 declElementType = getElementType(parser, enc, s, next);
4432 if (!declElementType)
4433 return XML_ERROR_NO_MEMORY;
4434 dtd->scaffLevel = 0;
4435 dtd->scaffCount = 0;
4436 dtd->in_eldecl = XML_TRUE;
4437 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004438 }
4439 break;
4440
4441 case XML_ROLE_CONTENT_ANY:
4442 case XML_ROLE_CONTENT_EMPTY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004443 if (dtd->in_eldecl) {
4444 if (elementDeclHandler) {
4445 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4446 if (!content)
4447 return XML_ERROR_NO_MEMORY;
4448 content->quant = XML_CQUANT_NONE;
4449 content->name = NULL;
4450 content->numchildren = 0;
4451 content->children = NULL;
4452 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4453 XML_CTYPE_ANY :
4454 XML_CTYPE_EMPTY);
4455 *eventEndPP = s;
4456 elementDeclHandler(handlerArg, declElementType->name, content);
4457 handleDefault = XML_FALSE;
4458 }
4459 dtd->in_eldecl = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004460 }
4461 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004462
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004463 case XML_ROLE_CONTENT_PCDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004464 if (dtd->in_eldecl) {
4465 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4466 = XML_CTYPE_MIXED;
4467 if (elementDeclHandler)
4468 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004469 }
4470 break;
4471
4472 case XML_ROLE_CONTENT_ELEMENT:
4473 quant = XML_CQUANT_NONE;
4474 goto elementContent;
4475 case XML_ROLE_CONTENT_ELEMENT_OPT:
4476 quant = XML_CQUANT_OPT;
4477 goto elementContent;
4478 case XML_ROLE_CONTENT_ELEMENT_REP:
4479 quant = XML_CQUANT_REP;
4480 goto elementContent;
4481 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4482 quant = XML_CQUANT_PLUS;
4483 elementContent:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004484 if (dtd->in_eldecl) {
4485 ELEMENT_TYPE *el;
4486 const XML_Char *name;
4487 int nameLen;
4488 const char *nxt = (quant == XML_CQUANT_NONE
4489 ? next
4490 : next - enc->minBytesPerChar);
4491 int myindex = nextScaffoldPart(parser);
4492 if (myindex < 0)
4493 return XML_ERROR_NO_MEMORY;
4494 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4495 dtd->scaffold[myindex].quant = quant;
4496 el = getElementType(parser, enc, s, nxt);
4497 if (!el)
4498 return XML_ERROR_NO_MEMORY;
4499 name = el->name;
4500 dtd->scaffold[myindex].name = name;
4501 nameLen = 0;
4502 for (; name[nameLen++]; );
4503 dtd->contentStringLen += nameLen;
4504 if (elementDeclHandler)
4505 handleDefault = XML_FALSE;
4506 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004507 break;
4508
4509 case XML_ROLE_GROUP_CLOSE:
4510 quant = XML_CQUANT_NONE;
4511 goto closeGroup;
4512 case XML_ROLE_GROUP_CLOSE_OPT:
4513 quant = XML_CQUANT_OPT;
4514 goto closeGroup;
4515 case XML_ROLE_GROUP_CLOSE_REP:
4516 quant = XML_CQUANT_REP;
4517 goto closeGroup;
4518 case XML_ROLE_GROUP_CLOSE_PLUS:
4519 quant = XML_CQUANT_PLUS;
4520 closeGroup:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004521 if (dtd->in_eldecl) {
4522 if (elementDeclHandler)
4523 handleDefault = XML_FALSE;
4524 dtd->scaffLevel--;
4525 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4526 if (dtd->scaffLevel == 0) {
4527 if (!handleDefault) {
4528 XML_Content *model = build_model(parser);
4529 if (!model)
4530 return XML_ERROR_NO_MEMORY;
4531 *eventEndPP = s;
4532 elementDeclHandler(handlerArg, declElementType->name, model);
4533 }
4534 dtd->in_eldecl = XML_FALSE;
4535 dtd->contentStringLen = 0;
4536 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004537 }
4538 break;
4539 /* End element declaration stuff */
4540
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004541 case XML_ROLE_PI:
4542 if (!reportProcessingInstruction(parser, enc, s, next))
4543 return XML_ERROR_NO_MEMORY;
4544 handleDefault = XML_FALSE;
4545 break;
4546 case XML_ROLE_COMMENT:
4547 if (!reportComment(parser, enc, s, next))
4548 return XML_ERROR_NO_MEMORY;
4549 handleDefault = XML_FALSE;
4550 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004551 case XML_ROLE_NONE:
4552 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004553 case XML_TOK_BOM:
4554 handleDefault = XML_FALSE;
4555 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004556 }
4557 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004558 case XML_ROLE_DOCTYPE_NONE:
4559 if (startDoctypeDeclHandler)
4560 handleDefault = XML_FALSE;
4561 break;
4562 case XML_ROLE_ENTITY_NONE:
4563 if (dtd->keepProcessing && entityDeclHandler)
4564 handleDefault = XML_FALSE;
4565 break;
4566 case XML_ROLE_NOTATION_NONE:
4567 if (notationDeclHandler)
4568 handleDefault = XML_FALSE;
4569 break;
4570 case XML_ROLE_ATTLIST_NONE:
4571 if (dtd->keepProcessing && attlistDeclHandler)
4572 handleDefault = XML_FALSE;
4573 break;
4574 case XML_ROLE_ELEMENT_NONE:
4575 if (elementDeclHandler)
4576 handleDefault = XML_FALSE;
4577 break;
4578 } /* end of big switch */
4579
4580 if (handleDefault && defaultHandler)
4581 reportDefault(parser, enc, s, next);
4582
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004583 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00004584 case XML_SUSPENDED:
4585 *nextPtr = next;
4586 return XML_ERROR_NONE;
4587 case XML_FINISHED:
4588 return XML_ERROR_ABORTED;
4589 default:
4590 s = next;
4591 tok = XmlPrologTok(enc, s, end, &next);
4592 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004593 }
4594 /* not reached */
4595}
4596
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004597static enum XML_Error PTRCALL
4598epilogProcessor(XML_Parser parser,
4599 const char *s,
4600 const char *end,
4601 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004602{
4603 processor = epilogProcessor;
4604 eventPtr = s;
4605 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004606 const char *next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004607 int tok = XmlPrologTok(encoding, s, end, &next);
4608 eventEndPtr = next;
4609 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004610 /* report partial linebreak - it might be the last token */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004611 case -XML_TOK_PROLOG_S:
4612 if (defaultHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004613 reportDefault(parser, encoding, s, next);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004614 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00004615 return XML_ERROR_ABORTED;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004616 }
Fred Drake31d485c2004-08-03 07:06:22 +00004617 *nextPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004618 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004619 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00004620 *nextPtr = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004621 return XML_ERROR_NONE;
4622 case XML_TOK_PROLOG_S:
4623 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004624 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004625 break;
4626 case XML_TOK_PI:
4627 if (!reportProcessingInstruction(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004628 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004629 break;
4630 case XML_TOK_COMMENT:
4631 if (!reportComment(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004632 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004633 break;
4634 case XML_TOK_INVALID:
4635 eventPtr = next;
4636 return XML_ERROR_INVALID_TOKEN;
4637 case XML_TOK_PARTIAL:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004638 if (!ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004639 *nextPtr = s;
4640 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004641 }
4642 return XML_ERROR_UNCLOSED_TOKEN;
4643 case XML_TOK_PARTIAL_CHAR:
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004644 if (!ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004645 *nextPtr = s;
4646 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004647 }
4648 return XML_ERROR_PARTIAL_CHAR;
4649 default:
4650 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4651 }
4652 eventPtr = s = next;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004653 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00004654 case XML_SUSPENDED:
4655 *nextPtr = next;
4656 return XML_ERROR_NONE;
4657 case XML_FINISHED:
4658 return XML_ERROR_ABORTED;
4659 default: ;
4660 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004661 }
4662}
4663
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004664static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +00004665processInternalEntity(XML_Parser parser, ENTITY *entity,
4666 XML_Bool betweenDecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004667{
Fred Drake31d485c2004-08-03 07:06:22 +00004668 const char *textStart, *textEnd;
4669 const char *next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004670 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004671 OPEN_INTERNAL_ENTITY *openEntity;
4672
4673 if (freeInternalEntities) {
4674 openEntity = freeInternalEntities;
4675 freeInternalEntities = openEntity->next;
4676 }
4677 else {
4678 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4679 if (!openEntity)
4680 return XML_ERROR_NO_MEMORY;
4681 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004682 entity->open = XML_TRUE;
Fred Drake31d485c2004-08-03 07:06:22 +00004683 entity->processed = 0;
4684 openEntity->next = openInternalEntities;
4685 openInternalEntities = openEntity;
4686 openEntity->entity = entity;
4687 openEntity->startTagLevel = tagLevel;
4688 openEntity->betweenDecl = betweenDecl;
4689 openEntity->internalEventPtr = NULL;
4690 openEntity->internalEventEndPtr = NULL;
4691 textStart = (char *)entity->textPtr;
4692 textEnd = (char *)(entity->textPtr + entity->textLen);
4693
4694#ifdef XML_DTD
4695 if (entity->is_param) {
4696 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4697 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4698 next, &next, XML_FALSE);
4699 }
4700 else
4701#endif /* XML_DTD */
4702 result = doContent(parser, tagLevel, internalEncoding, textStart,
4703 textEnd, &next, XML_FALSE);
4704
4705 if (result == XML_ERROR_NONE) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004706 if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4707 entity->processed = (int)(next - textStart);
Fred Drake31d485c2004-08-03 07:06:22 +00004708 processor = internalEntityProcessor;
4709 }
4710 else {
4711 entity->open = XML_FALSE;
4712 openInternalEntities = openEntity->next;
4713 /* put openEntity back in list of free instances */
4714 openEntity->next = freeInternalEntities;
4715 freeInternalEntities = openEntity;
4716 }
4717 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004718 return result;
4719}
4720
Fred Drake31d485c2004-08-03 07:06:22 +00004721static enum XML_Error PTRCALL
4722internalEntityProcessor(XML_Parser parser,
4723 const char *s,
4724 const char *end,
4725 const char **nextPtr)
4726{
4727 ENTITY *entity;
4728 const char *textStart, *textEnd;
4729 const char *next;
4730 enum XML_Error result;
4731 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4732 if (!openEntity)
4733 return XML_ERROR_UNEXPECTED_STATE;
4734
4735 entity = openEntity->entity;
4736 textStart = ((char *)entity->textPtr) + entity->processed;
4737 textEnd = (char *)(entity->textPtr + entity->textLen);
4738
4739#ifdef XML_DTD
4740 if (entity->is_param) {
4741 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4742 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4743 next, &next, XML_FALSE);
4744 }
4745 else
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004746#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00004747 result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4748 textStart, textEnd, &next, XML_FALSE);
4749
4750 if (result != XML_ERROR_NONE)
4751 return result;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004752 else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4753 entity->processed = (int)(next - (char *)entity->textPtr);
Fred Drake31d485c2004-08-03 07:06:22 +00004754 return result;
4755 }
4756 else {
4757 entity->open = XML_FALSE;
4758 openInternalEntities = openEntity->next;
4759 /* put openEntity back in list of free instances */
4760 openEntity->next = freeInternalEntities;
4761 freeInternalEntities = openEntity;
4762 }
4763
4764#ifdef XML_DTD
4765 if (entity->is_param) {
4766 int tok;
4767 processor = prologProcessor;
4768 tok = XmlPrologTok(encoding, s, end, &next);
4769 return doProlog(parser, encoding, s, end, tok, next, nextPtr,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004770 (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00004771 }
4772 else
4773#endif /* XML_DTD */
4774 {
4775 processor = contentProcessor;
4776 /* see externalEntityContentProcessor vs contentProcessor */
4777 return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004778 nextPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00004779 }
4780}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004781
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004782static enum XML_Error PTRCALL
4783errorProcessor(XML_Parser parser,
4784 const char *s,
4785 const char *end,
4786 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004787{
4788 return errorCode;
4789}
4790
4791static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004792storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4793 const char *ptr, const char *end,
4794 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004795{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004796 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4797 end, pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004798 if (result)
4799 return result;
4800 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4801 poolChop(pool);
4802 if (!poolAppendChar(pool, XML_T('\0')))
4803 return XML_ERROR_NO_MEMORY;
4804 return XML_ERROR_NONE;
4805}
4806
4807static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004808appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4809 const char *ptr, const char *end,
4810 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004811{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004812 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004813 for (;;) {
4814 const char *next;
4815 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4816 switch (tok) {
4817 case XML_TOK_NONE:
4818 return XML_ERROR_NONE;
4819 case XML_TOK_INVALID:
4820 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004821 eventPtr = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004822 return XML_ERROR_INVALID_TOKEN;
4823 case XML_TOK_PARTIAL:
4824 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004825 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004826 return XML_ERROR_INVALID_TOKEN;
4827 case XML_TOK_CHAR_REF:
4828 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004829 XML_Char buf[XML_ENCODE_MAX];
4830 int i;
4831 int n = XmlCharRefNumber(enc, ptr);
4832 if (n < 0) {
4833 if (enc == encoding)
4834 eventPtr = ptr;
4835 return XML_ERROR_BAD_CHAR_REF;
4836 }
4837 if (!isCdata
4838 && n == 0x20 /* space */
4839 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4840 break;
4841 n = XmlEncode(n, (ICHAR *)buf);
4842 if (!n) {
4843 if (enc == encoding)
4844 eventPtr = ptr;
4845 return XML_ERROR_BAD_CHAR_REF;
4846 }
4847 for (i = 0; i < n; i++) {
4848 if (!poolAppendChar(pool, buf[i]))
4849 return XML_ERROR_NO_MEMORY;
4850 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004851 }
4852 break;
4853 case XML_TOK_DATA_CHARS:
4854 if (!poolAppend(pool, enc, ptr, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004855 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004856 break;
4857 case XML_TOK_TRAILING_CR:
4858 next = ptr + enc->minBytesPerChar;
4859 /* fall through */
4860 case XML_TOK_ATTRIBUTE_VALUE_S:
4861 case XML_TOK_DATA_NEWLINE:
4862 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004863 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004864 if (!poolAppendChar(pool, 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004865 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004866 break;
4867 case XML_TOK_ENTITY_REF:
4868 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004869 const XML_Char *name;
4870 ENTITY *entity;
4871 char checkEntityDecl;
4872 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
4873 ptr + enc->minBytesPerChar,
4874 next - enc->minBytesPerChar);
4875 if (ch) {
4876 if (!poolAppendChar(pool, ch))
4877 return XML_ERROR_NO_MEMORY;
4878 break;
4879 }
4880 name = poolStoreString(&temp2Pool, enc,
4881 ptr + enc->minBytesPerChar,
4882 next - enc->minBytesPerChar);
4883 if (!name)
4884 return XML_ERROR_NO_MEMORY;
4885 entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0);
4886 poolDiscard(&temp2Pool);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004887 /* First, determine if a check for an existing declaration is needed;
4888 if yes, check that the entity exists, and that it is internal.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004889 */
4890 if (pool == &dtd->pool) /* are we called from prolog? */
4891 checkEntityDecl =
4892#ifdef XML_DTD
4893 prologState.documentEntity &&
4894#endif /* XML_DTD */
4895 (dtd->standalone
4896 ? !openInternalEntities
4897 : !dtd->hasParamEntityRefs);
4898 else /* if (pool == &tempPool): we are called from content */
4899 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
4900 if (checkEntityDecl) {
4901 if (!entity)
4902 return XML_ERROR_UNDEFINED_ENTITY;
4903 else if (!entity->is_internal)
4904 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4905 }
4906 else if (!entity) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004907 /* Cannot report skipped entity here - see comments on
4908 skippedEntityHandler.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004909 if (skippedEntityHandler)
4910 skippedEntityHandler(handlerArg, name, 0);
4911 */
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004912 /* Cannot call the default handler because this would be
4913 out of sync with the call to the startElementHandler.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004914 if ((pool == &tempPool) && defaultHandler)
4915 reportDefault(parser, enc, ptr, next);
Thomas Wouters0e3f5912006-08-11 14:57:12 +00004916 */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004917 break;
4918 }
4919 if (entity->open) {
4920 if (enc == encoding)
4921 eventPtr = ptr;
4922 return XML_ERROR_RECURSIVE_ENTITY_REF;
4923 }
4924 if (entity->notation) {
4925 if (enc == encoding)
4926 eventPtr = ptr;
4927 return XML_ERROR_BINARY_ENTITY_REF;
4928 }
4929 if (!entity->textPtr) {
4930 if (enc == encoding)
4931 eventPtr = ptr;
4932 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
4933 }
4934 else {
4935 enum XML_Error result;
4936 const XML_Char *textEnd = entity->textPtr + entity->textLen;
4937 entity->open = XML_TRUE;
4938 result = appendAttributeValue(parser, internalEncoding, isCdata,
4939 (char *)entity->textPtr,
4940 (char *)textEnd, pool);
4941 entity->open = XML_FALSE;
4942 if (result)
4943 return result;
4944 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004945 }
4946 break;
4947 default:
4948 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004949 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004950 return XML_ERROR_UNEXPECTED_STATE;
4951 }
4952 ptr = next;
4953 }
4954 /* not reached */
4955}
4956
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004957static enum XML_Error
4958storeEntityValue(XML_Parser parser,
4959 const ENCODING *enc,
4960 const char *entityTextPtr,
4961 const char *entityTextEnd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004962{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004963 DTD * const dtd = _dtd; /* save one level of indirection */
4964 STRING_POOL *pool = &(dtd->entityValuePool);
4965 enum XML_Error result = XML_ERROR_NONE;
4966#ifdef XML_DTD
4967 int oldInEntityValue = prologState.inEntityValue;
4968 prologState.inEntityValue = 1;
4969#endif /* XML_DTD */
4970 /* never return Null for the value argument in EntityDeclHandler,
4971 since this would indicate an external entity; therefore we
4972 have to make sure that entityValuePool.start is not null */
4973 if (!pool->blocks) {
4974 if (!poolGrow(pool))
4975 return XML_ERROR_NO_MEMORY;
4976 }
4977
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004978 for (;;) {
4979 const char *next;
4980 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
4981 switch (tok) {
4982 case XML_TOK_PARAM_ENTITY_REF:
4983#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004984 if (isParamEntity || enc != encoding) {
4985 const XML_Char *name;
4986 ENTITY *entity;
4987 name = poolStoreString(&tempPool, enc,
4988 entityTextPtr + enc->minBytesPerChar,
4989 next - enc->minBytesPerChar);
4990 if (!name) {
4991 result = XML_ERROR_NO_MEMORY;
4992 goto endEntityValue;
4993 }
4994 entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
4995 poolDiscard(&tempPool);
4996 if (!entity) {
4997 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
4998 /* cannot report skipped entity here - see comments on
4999 skippedEntityHandler
5000 if (skippedEntityHandler)
5001 skippedEntityHandler(handlerArg, name, 0);
5002 */
5003 dtd->keepProcessing = dtd->standalone;
5004 goto endEntityValue;
5005 }
5006 if (entity->open) {
5007 if (enc == encoding)
5008 eventPtr = entityTextPtr;
5009 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5010 goto endEntityValue;
5011 }
5012 if (entity->systemId) {
5013 if (externalEntityRefHandler) {
5014 dtd->paramEntityRead = XML_FALSE;
5015 entity->open = XML_TRUE;
5016 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5017 0,
5018 entity->base,
5019 entity->systemId,
5020 entity->publicId)) {
5021 entity->open = XML_FALSE;
5022 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5023 goto endEntityValue;
5024 }
5025 entity->open = XML_FALSE;
5026 if (!dtd->paramEntityRead)
5027 dtd->keepProcessing = dtd->standalone;
5028 }
5029 else
5030 dtd->keepProcessing = dtd->standalone;
5031 }
5032 else {
5033 entity->open = XML_TRUE;
5034 result = storeEntityValue(parser,
5035 internalEncoding,
5036 (char *)entity->textPtr,
5037 (char *)(entity->textPtr
5038 + entity->textLen));
5039 entity->open = XML_FALSE;
5040 if (result)
5041 goto endEntityValue;
5042 }
5043 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005044 }
5045#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00005046 /* In the internal subset, PE references are not legal
5047 within markup declarations, e.g entity values in this case. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005048 eventPtr = entityTextPtr;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005049 result = XML_ERROR_PARAM_ENTITY_REF;
5050 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005051 case XML_TOK_NONE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005052 result = XML_ERROR_NONE;
5053 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005054 case XML_TOK_ENTITY_REF:
5055 case XML_TOK_DATA_CHARS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005056 if (!poolAppend(pool, enc, entityTextPtr, next)) {
5057 result = XML_ERROR_NO_MEMORY;
5058 goto endEntityValue;
5059 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005060 break;
5061 case XML_TOK_TRAILING_CR:
5062 next = entityTextPtr + enc->minBytesPerChar;
5063 /* fall through */
5064 case XML_TOK_DATA_NEWLINE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005065 if (pool->end == pool->ptr && !poolGrow(pool)) {
5066 result = XML_ERROR_NO_MEMORY;
5067 goto endEntityValue;
5068 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005069 *(pool->ptr)++ = 0xA;
5070 break;
5071 case XML_TOK_CHAR_REF:
5072 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005073 XML_Char buf[XML_ENCODE_MAX];
5074 int i;
5075 int n = XmlCharRefNumber(enc, entityTextPtr);
5076 if (n < 0) {
5077 if (enc == encoding)
5078 eventPtr = entityTextPtr;
5079 result = XML_ERROR_BAD_CHAR_REF;
5080 goto endEntityValue;
5081 }
5082 n = XmlEncode(n, (ICHAR *)buf);
5083 if (!n) {
5084 if (enc == encoding)
5085 eventPtr = entityTextPtr;
5086 result = XML_ERROR_BAD_CHAR_REF;
5087 goto endEntityValue;
5088 }
5089 for (i = 0; i < n; i++) {
5090 if (pool->end == pool->ptr && !poolGrow(pool)) {
5091 result = XML_ERROR_NO_MEMORY;
5092 goto endEntityValue;
5093 }
5094 *(pool->ptr)++ = buf[i];
5095 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005096 }
5097 break;
5098 case XML_TOK_PARTIAL:
5099 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005100 eventPtr = entityTextPtr;
5101 result = XML_ERROR_INVALID_TOKEN;
5102 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005103 case XML_TOK_INVALID:
5104 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005105 eventPtr = next;
5106 result = XML_ERROR_INVALID_TOKEN;
5107 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005108 default:
5109 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005110 eventPtr = entityTextPtr;
5111 result = XML_ERROR_UNEXPECTED_STATE;
5112 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005113 }
5114 entityTextPtr = next;
5115 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005116endEntityValue:
5117#ifdef XML_DTD
5118 prologState.inEntityValue = oldInEntityValue;
5119#endif /* XML_DTD */
5120 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005121}
5122
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005123static void FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005124normalizeLines(XML_Char *s)
5125{
5126 XML_Char *p;
5127 for (;; s++) {
5128 if (*s == XML_T('\0'))
5129 return;
5130 if (*s == 0xD)
5131 break;
5132 }
5133 p = s;
5134 do {
5135 if (*s == 0xD) {
5136 *p++ = 0xA;
5137 if (*++s == 0xA)
5138 s++;
5139 }
5140 else
5141 *p++ = *s++;
5142 } while (*s);
5143 *p = XML_T('\0');
5144}
5145
5146static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005147reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5148 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005149{
5150 const XML_Char *target;
5151 XML_Char *data;
5152 const char *tem;
5153 if (!processingInstructionHandler) {
5154 if (defaultHandler)
5155 reportDefault(parser, enc, start, end);
5156 return 1;
5157 }
5158 start += enc->minBytesPerChar * 2;
5159 tem = start + XmlNameLength(enc, start);
5160 target = poolStoreString(&tempPool, enc, start, tem);
5161 if (!target)
5162 return 0;
5163 poolFinish(&tempPool);
5164 data = poolStoreString(&tempPool, enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005165 XmlSkipS(enc, tem),
5166 end - enc->minBytesPerChar*2);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005167 if (!data)
5168 return 0;
5169 normalizeLines(data);
5170 processingInstructionHandler(handlerArg, target, data);
5171 poolClear(&tempPool);
5172 return 1;
5173}
5174
5175static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005176reportComment(XML_Parser parser, const ENCODING *enc,
5177 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005178{
5179 XML_Char *data;
5180 if (!commentHandler) {
5181 if (defaultHandler)
5182 reportDefault(parser, enc, start, end);
5183 return 1;
5184 }
5185 data = poolStoreString(&tempPool,
5186 enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005187 start + enc->minBytesPerChar * 4,
5188 end - enc->minBytesPerChar * 3);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005189 if (!data)
5190 return 0;
5191 normalizeLines(data);
5192 commentHandler(handlerArg, data);
5193 poolClear(&tempPool);
5194 return 1;
5195}
5196
5197static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005198reportDefault(XML_Parser parser, const ENCODING *enc,
5199 const char *s, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005200{
5201 if (MUST_CONVERT(enc, s)) {
5202 const char **eventPP;
5203 const char **eventEndPP;
5204 if (enc == encoding) {
5205 eventPP = &eventPtr;
5206 eventEndPP = &eventEndPtr;
5207 }
5208 else {
5209 eventPP = &(openInternalEntities->internalEventPtr);
5210 eventEndPP = &(openInternalEntities->internalEventEndPtr);
5211 }
5212 do {
5213 ICHAR *dataPtr = (ICHAR *)dataBuf;
5214 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5215 *eventEndPP = s;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005216 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005217 *eventPP = s;
5218 } while (s != end);
5219 }
5220 else
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005221 defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005222}
5223
5224
5225static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005226defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5227 XML_Bool isId, const XML_Char *value, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005228{
5229 DEFAULT_ATTRIBUTE *att;
5230 if (value || isId) {
5231 /* The handling of default attributes gets messed up if we have
5232 a default which duplicates a non-default. */
5233 int i;
5234 for (i = 0; i < type->nDefaultAtts; i++)
5235 if (attId == type->defaultAtts[i].id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005236 return 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005237 if (isId && !type->idAtt && !attId->xmlns)
5238 type->idAtt = attId;
5239 }
5240 if (type->nDefaultAtts == type->allocDefaultAtts) {
5241 if (type->allocDefaultAtts == 0) {
5242 type->allocDefaultAtts = 8;
Fred Drake08317ae2003-10-21 15:38:55 +00005243 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005244 * sizeof(DEFAULT_ATTRIBUTE));
5245 if (!type->defaultAtts)
5246 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005247 }
5248 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005249 DEFAULT_ATTRIBUTE *temp;
5250 int count = type->allocDefaultAtts * 2;
5251 temp = (DEFAULT_ATTRIBUTE *)
5252 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5253 if (temp == NULL)
5254 return 0;
5255 type->allocDefaultAtts = count;
5256 type->defaultAtts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005257 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005258 }
5259 att = type->defaultAtts + type->nDefaultAtts;
5260 att->id = attId;
5261 att->value = value;
5262 att->isCdata = isCdata;
5263 if (!isCdata)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005264 attId->maybeTokenized = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005265 type->nDefaultAtts += 1;
5266 return 1;
5267}
5268
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005269static int
5270setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005271{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005272 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005273 const XML_Char *name;
5274 for (name = elementType->name; *name; name++) {
5275 if (*name == XML_T(':')) {
5276 PREFIX *prefix;
5277 const XML_Char *s;
5278 for (s = elementType->name; s != name; s++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005279 if (!poolAppendChar(&dtd->pool, *s))
5280 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005281 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005282 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5283 return 0;
5284 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5285 sizeof(PREFIX));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005286 if (!prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005287 return 0;
5288 if (prefix->name == poolStart(&dtd->pool))
5289 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005290 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005291 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005292 elementType->prefix = prefix;
5293
5294 }
5295 }
5296 return 1;
5297}
5298
5299static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005300getAttributeId(XML_Parser parser, const ENCODING *enc,
5301 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005302{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005303 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005304 ATTRIBUTE_ID *id;
5305 const XML_Char *name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005306 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5307 return NULL;
5308 name = poolStoreString(&dtd->pool, enc, start, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005309 if (!name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005310 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005311 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005312 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005313 id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005314 if (!id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005315 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005316 if (id->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005317 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005318 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005319 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005320 if (!ns)
5321 ;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005322 else if (name[0] == XML_T('x')
5323 && name[1] == XML_T('m')
5324 && name[2] == XML_T('l')
5325 && name[3] == XML_T('n')
5326 && name[4] == XML_T('s')
5327 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
5328 if (name[5] == XML_T('\0'))
5329 id->prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005330 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005331 id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
5332 id->xmlns = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005333 }
5334 else {
5335 int i;
5336 for (i = 0; name[i]; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005337 /* attributes without prefix are *not* in the default namespace */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005338 if (name[i] == XML_T(':')) {
5339 int j;
5340 for (j = 0; j < i; j++) {
5341 if (!poolAppendChar(&dtd->pool, name[j]))
5342 return NULL;
5343 }
5344 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5345 return NULL;
5346 id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
5347 sizeof(PREFIX));
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00005348 if (!id->prefix)
5349 return NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005350 if (id->prefix->name == poolStart(&dtd->pool))
5351 poolFinish(&dtd->pool);
5352 else
5353 poolDiscard(&dtd->pool);
5354 break;
5355 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005356 }
5357 }
5358 }
5359 return id;
5360}
5361
5362#define CONTEXT_SEP XML_T('\f')
5363
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005364static const XML_Char *
5365getContext(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005366{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005367 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005368 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005369 XML_Bool needSep = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005370
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005371 if (dtd->defaultPrefix.binding) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005372 int i;
5373 int len;
5374 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005375 return NULL;
5376 len = dtd->defaultPrefix.binding->uriLen;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005377 if (namespaceSeparator)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005378 len--;
5379 for (i = 0; i < len; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005380 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5381 return NULL;
5382 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005383 }
5384
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005385 hashTableIterInit(&iter, &(dtd->prefixes));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005386 for (;;) {
5387 int i;
5388 int len;
5389 const XML_Char *s;
5390 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5391 if (!prefix)
5392 break;
5393 if (!prefix->binding)
5394 continue;
5395 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005396 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005397 for (s = prefix->name; *s; s++)
5398 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005399 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005400 if (!poolAppendChar(&tempPool, XML_T('=')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005401 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005402 len = prefix->binding->uriLen;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00005403 if (namespaceSeparator)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005404 len--;
5405 for (i = 0; i < len; i++)
5406 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005407 return NULL;
5408 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005409 }
5410
5411
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005412 hashTableIterInit(&iter, &(dtd->generalEntities));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005413 for (;;) {
5414 const XML_Char *s;
5415 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5416 if (!e)
5417 break;
5418 if (!e->open)
5419 continue;
5420 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005421 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005422 for (s = e->name; *s; s++)
5423 if (!poolAppendChar(&tempPool, *s))
5424 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005425 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005426 }
5427
5428 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005429 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005430 return tempPool.start;
5431}
5432
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005433static XML_Bool
5434setContext(XML_Parser parser, const XML_Char *context)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005435{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005436 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005437 const XML_Char *s = context;
5438
5439 while (*context != XML_T('\0')) {
5440 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5441 ENTITY *e;
5442 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005443 return XML_FALSE;
5444 e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005445 if (e)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005446 e->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005447 if (*s != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005448 s++;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005449 context = s;
5450 poolDiscard(&tempPool);
5451 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005452 else if (*s == XML_T('=')) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005453 PREFIX *prefix;
5454 if (poolLength(&tempPool) == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005455 prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005456 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005457 if (!poolAppendChar(&tempPool, XML_T('\0')))
5458 return XML_FALSE;
5459 prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
5460 sizeof(PREFIX));
5461 if (!prefix)
5462 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005463 if (prefix->name == poolStart(&tempPool)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005464 prefix->name = poolCopyString(&dtd->pool, prefix->name);
5465 if (!prefix->name)
5466 return XML_FALSE;
5467 }
5468 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005469 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005470 for (context = s + 1;
5471 *context != CONTEXT_SEP && *context != XML_T('\0');
5472 context++)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005473 if (!poolAppendChar(&tempPool, *context))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005474 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005475 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005476 return XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00005477 if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005478 &inheritedBindings) != XML_ERROR_NONE)
5479 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005480 poolDiscard(&tempPool);
5481 if (*context != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005482 ++context;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005483 s = context;
5484 }
5485 else {
5486 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005487 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005488 s++;
5489 }
5490 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005491 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005492}
5493
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005494static void FASTCALL
5495normalizePublicId(XML_Char *publicId)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005496{
5497 XML_Char *p = publicId;
5498 XML_Char *s;
5499 for (s = publicId; *s; s++) {
5500 switch (*s) {
5501 case 0x20:
5502 case 0xD:
5503 case 0xA:
5504 if (p != publicId && p[-1] != 0x20)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005505 *p++ = 0x20;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005506 break;
5507 default:
5508 *p++ = *s;
5509 }
5510 }
5511 if (p != publicId && p[-1] == 0x20)
5512 --p;
5513 *p = XML_T('\0');
5514}
5515
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005516static DTD *
5517dtdCreate(const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005518{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005519 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5520 if (p == NULL)
5521 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005522 poolInit(&(p->pool), ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005523 poolInit(&(p->entityValuePool), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005524 hashTableInit(&(p->generalEntities), ms);
5525 hashTableInit(&(p->elementTypes), ms);
5526 hashTableInit(&(p->attributeIds), ms);
5527 hashTableInit(&(p->prefixes), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005528#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005529 p->paramEntityRead = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005530 hashTableInit(&(p->paramEntities), ms);
5531#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005532 p->defaultPrefix.name = NULL;
5533 p->defaultPrefix.binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005534
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005535 p->in_eldecl = XML_FALSE;
5536 p->scaffIndex = NULL;
5537 p->scaffold = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005538 p->scaffLevel = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005539 p->scaffSize = 0;
5540 p->scaffCount = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005541 p->contentStringLen = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005542
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005543 p->keepProcessing = XML_TRUE;
5544 p->hasParamEntityRefs = XML_FALSE;
5545 p->standalone = XML_FALSE;
5546 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005547}
5548
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005549static void
5550dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005551{
5552 HASH_TABLE_ITER iter;
5553 hashTableIterInit(&iter, &(p->elementTypes));
5554 for (;;) {
5555 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5556 if (!e)
5557 break;
5558 if (e->allocDefaultAtts != 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005559 ms->free_fcn(e->defaultAtts);
5560 }
5561 hashTableClear(&(p->generalEntities));
5562#ifdef XML_DTD
5563 p->paramEntityRead = XML_FALSE;
5564 hashTableClear(&(p->paramEntities));
5565#endif /* XML_DTD */
5566 hashTableClear(&(p->elementTypes));
5567 hashTableClear(&(p->attributeIds));
5568 hashTableClear(&(p->prefixes));
5569 poolClear(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005570 poolClear(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005571 p->defaultPrefix.name = NULL;
5572 p->defaultPrefix.binding = NULL;
5573
5574 p->in_eldecl = XML_FALSE;
Fred Drake08317ae2003-10-21 15:38:55 +00005575
5576 ms->free_fcn(p->scaffIndex);
5577 p->scaffIndex = NULL;
5578 ms->free_fcn(p->scaffold);
5579 p->scaffold = NULL;
5580
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005581 p->scaffLevel = 0;
5582 p->scaffSize = 0;
5583 p->scaffCount = 0;
5584 p->contentStringLen = 0;
5585
5586 p->keepProcessing = XML_TRUE;
5587 p->hasParamEntityRefs = XML_FALSE;
5588 p->standalone = XML_FALSE;
5589}
5590
5591static void
5592dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5593{
5594 HASH_TABLE_ITER iter;
5595 hashTableIterInit(&iter, &(p->elementTypes));
5596 for (;;) {
5597 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5598 if (!e)
5599 break;
5600 if (e->allocDefaultAtts != 0)
5601 ms->free_fcn(e->defaultAtts);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005602 }
5603 hashTableDestroy(&(p->generalEntities));
5604#ifdef XML_DTD
5605 hashTableDestroy(&(p->paramEntities));
5606#endif /* XML_DTD */
5607 hashTableDestroy(&(p->elementTypes));
5608 hashTableDestroy(&(p->attributeIds));
5609 hashTableDestroy(&(p->prefixes));
5610 poolDestroy(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005611 poolDestroy(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005612 if (isDocEntity) {
Fred Drake08317ae2003-10-21 15:38:55 +00005613 ms->free_fcn(p->scaffIndex);
5614 ms->free_fcn(p->scaffold);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005615 }
5616 ms->free_fcn(p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005617}
5618
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005619/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5620 The new DTD has already been initialized.
5621*/
5622static int
5623dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005624{
5625 HASH_TABLE_ITER iter;
5626
5627 /* Copy the prefix table. */
5628
5629 hashTableIterInit(&iter, &(oldDtd->prefixes));
5630 for (;;) {
5631 const XML_Char *name;
5632 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5633 if (!oldP)
5634 break;
5635 name = poolCopyString(&(newDtd->pool), oldP->name);
5636 if (!name)
5637 return 0;
5638 if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
5639 return 0;
5640 }
5641
5642 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5643
5644 /* Copy the attribute id table. */
5645
5646 for (;;) {
5647 ATTRIBUTE_ID *newA;
5648 const XML_Char *name;
5649 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5650
5651 if (!oldA)
5652 break;
5653 /* Remember to allocate the scratch byte before the name. */
5654 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5655 return 0;
5656 name = poolCopyString(&(newDtd->pool), oldA->name);
5657 if (!name)
5658 return 0;
5659 ++name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005660 newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
5661 sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005662 if (!newA)
5663 return 0;
5664 newA->maybeTokenized = oldA->maybeTokenized;
5665 if (oldA->prefix) {
5666 newA->xmlns = oldA->xmlns;
5667 if (oldA->prefix == &oldDtd->defaultPrefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005668 newA->prefix = &newDtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005669 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005670 newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5671 oldA->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005672 }
5673 }
5674
5675 /* Copy the element type table. */
5676
5677 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5678
5679 for (;;) {
5680 int i;
5681 ELEMENT_TYPE *newE;
5682 const XML_Char *name;
5683 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5684 if (!oldE)
5685 break;
5686 name = poolCopyString(&(newDtd->pool), oldE->name);
5687 if (!name)
5688 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005689 newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
5690 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005691 if (!newE)
5692 return 0;
5693 if (oldE->nDefaultAtts) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005694 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5695 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5696 if (!newE->defaultAtts) {
5697 ms->free_fcn(newE);
5698 return 0;
5699 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005700 }
5701 if (oldE->idAtt)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005702 newE->idAtt = (ATTRIBUTE_ID *)
5703 lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005704 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5705 if (oldE->prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005706 newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
5707 oldE->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005708 for (i = 0; i < newE->nDefaultAtts; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005709 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5710 lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005711 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5712 if (oldE->defaultAtts[i].value) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005713 newE->defaultAtts[i].value
5714 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5715 if (!newE->defaultAtts[i].value)
5716 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005717 }
5718 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005719 newE->defaultAtts[i].value = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005720 }
5721 }
5722
5723 /* Copy the entity tables. */
5724 if (!copyEntityTable(&(newDtd->generalEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005725 &(newDtd->pool),
5726 &(oldDtd->generalEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005727 return 0;
5728
5729#ifdef XML_DTD
5730 if (!copyEntityTable(&(newDtd->paramEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005731 &(newDtd->pool),
5732 &(oldDtd->paramEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005733 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005734 newDtd->paramEntityRead = oldDtd->paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005735#endif /* XML_DTD */
5736
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005737 newDtd->keepProcessing = oldDtd->keepProcessing;
5738 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005739 newDtd->standalone = oldDtd->standalone;
5740
5741 /* Don't want deep copying for scaffolding */
5742 newDtd->in_eldecl = oldDtd->in_eldecl;
5743 newDtd->scaffold = oldDtd->scaffold;
5744 newDtd->contentStringLen = oldDtd->contentStringLen;
5745 newDtd->scaffSize = oldDtd->scaffSize;
5746 newDtd->scaffLevel = oldDtd->scaffLevel;
5747 newDtd->scaffIndex = oldDtd->scaffIndex;
5748
5749 return 1;
5750} /* End dtdCopy */
5751
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005752static int
5753copyEntityTable(HASH_TABLE *newTable,
5754 STRING_POOL *newPool,
5755 const HASH_TABLE *oldTable)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005756{
5757 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005758 const XML_Char *cachedOldBase = NULL;
5759 const XML_Char *cachedNewBase = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005760
5761 hashTableIterInit(&iter, oldTable);
5762
5763 for (;;) {
5764 ENTITY *newE;
5765 const XML_Char *name;
5766 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5767 if (!oldE)
5768 break;
5769 name = poolCopyString(newPool, oldE->name);
5770 if (!name)
5771 return 0;
5772 newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
5773 if (!newE)
5774 return 0;
5775 if (oldE->systemId) {
5776 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5777 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005778 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005779 newE->systemId = tem;
5780 if (oldE->base) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005781 if (oldE->base == cachedOldBase)
5782 newE->base = cachedNewBase;
5783 else {
5784 cachedOldBase = oldE->base;
5785 tem = poolCopyString(newPool, cachedOldBase);
5786 if (!tem)
5787 return 0;
5788 cachedNewBase = newE->base = tem;
5789 }
5790 }
5791 if (oldE->publicId) {
5792 tem = poolCopyString(newPool, oldE->publicId);
5793 if (!tem)
5794 return 0;
5795 newE->publicId = tem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005796 }
5797 }
5798 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005799 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5800 oldE->textLen);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005801 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005802 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005803 newE->textPtr = tem;
5804 newE->textLen = oldE->textLen;
5805 }
5806 if (oldE->notation) {
5807 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5808 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005809 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005810 newE->notation = tem;
5811 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005812 newE->is_param = oldE->is_param;
5813 newE->is_internal = oldE->is_internal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005814 }
5815 return 1;
5816}
5817
Fred Drake08317ae2003-10-21 15:38:55 +00005818#define INIT_POWER 6
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005819
Fred Drake08317ae2003-10-21 15:38:55 +00005820static XML_Bool FASTCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005821keyeq(KEY s1, KEY s2)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005822{
5823 for (; *s1 == *s2; s1++, s2++)
5824 if (*s1 == 0)
Fred Drake08317ae2003-10-21 15:38:55 +00005825 return XML_TRUE;
5826 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005827}
5828
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005829static unsigned long FASTCALL
5830hash(KEY s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005831{
5832 unsigned long h = 0;
5833 while (*s)
Fred Drake08317ae2003-10-21 15:38:55 +00005834 h = CHAR_HASH(h, *s++);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005835 return h;
5836}
5837
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005838static NAMED *
5839lookup(HASH_TABLE *table, KEY name, size_t createSize)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005840{
5841 size_t i;
5842 if (table->size == 0) {
5843 size_t tsize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005844 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005845 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005846 table->power = INIT_POWER;
5847 /* table->size is a power of 2 */
5848 table->size = (size_t)1 << INIT_POWER;
5849 tsize = table->size * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005850 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Fred Drake31d485c2004-08-03 07:06:22 +00005851 if (!table->v) {
5852 table->size = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005853 return NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00005854 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005855 memset(table->v, 0, tsize);
Fred Drake08317ae2003-10-21 15:38:55 +00005856 i = hash(name) & ((unsigned long)table->size - 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005857 }
5858 else {
5859 unsigned long h = hash(name);
Fred Drake08317ae2003-10-21 15:38:55 +00005860 unsigned long mask = (unsigned long)table->size - 1;
5861 unsigned char step = 0;
5862 i = h & mask;
5863 while (table->v[i]) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005864 if (keyeq(name, table->v[i]->name))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005865 return table->v[i];
Fred Drake08317ae2003-10-21 15:38:55 +00005866 if (!step)
5867 step = PROBE_STEP(h, mask, table->power);
5868 i < step ? (i += table->size - step) : (i -= step);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005869 }
5870 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005871 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005872
5873 /* check for overflow (table is half full) */
5874 if (table->used >> (table->power - 1)) {
5875 unsigned char newPower = table->power + 1;
5876 size_t newSize = (size_t)1 << newPower;
5877 unsigned long newMask = (unsigned long)newSize - 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005878 size_t tsize = newSize * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005879 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005880 if (!newV)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005881 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005882 memset(newV, 0, tsize);
5883 for (i = 0; i < table->size; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005884 if (table->v[i]) {
Fred Drake08317ae2003-10-21 15:38:55 +00005885 unsigned long newHash = hash(table->v[i]->name);
5886 size_t j = newHash & newMask;
5887 step = 0;
5888 while (newV[j]) {
5889 if (!step)
5890 step = PROBE_STEP(newHash, newMask, newPower);
5891 j < step ? (j += newSize - step) : (j -= step);
5892 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005893 newV[j] = table->v[i];
5894 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005895 table->mem->free_fcn(table->v);
5896 table->v = newV;
Fred Drake08317ae2003-10-21 15:38:55 +00005897 table->power = newPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005898 table->size = newSize;
Fred Drake08317ae2003-10-21 15:38:55 +00005899 i = h & newMask;
5900 step = 0;
5901 while (table->v[i]) {
5902 if (!step)
5903 step = PROBE_STEP(h, newMask, newPower);
5904 i < step ? (i += newSize - step) : (i -= step);
5905 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005906 }
5907 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005908 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005909 if (!table->v[i])
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005910 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005911 memset(table->v[i], 0, createSize);
5912 table->v[i]->name = name;
5913 (table->used)++;
5914 return table->v[i];
5915}
5916
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005917static void FASTCALL
5918hashTableClear(HASH_TABLE *table)
5919{
5920 size_t i;
5921 for (i = 0; i < table->size; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005922 table->mem->free_fcn(table->v[i]);
5923 table->v[i] = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005924 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005925 table->used = 0;
5926}
5927
5928static void FASTCALL
5929hashTableDestroy(HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005930{
5931 size_t i;
Fred Drake08317ae2003-10-21 15:38:55 +00005932 for (i = 0; i < table->size; i++)
5933 table->mem->free_fcn(table->v[i]);
5934 table->mem->free_fcn(table->v);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005935}
5936
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005937static void FASTCALL
5938hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005939{
Fred Drake08317ae2003-10-21 15:38:55 +00005940 p->power = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005941 p->size = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005942 p->used = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005943 p->v = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005944 p->mem = ms;
5945}
5946
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005947static void FASTCALL
5948hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005949{
5950 iter->p = table->v;
5951 iter->end = iter->p + table->size;
5952}
5953
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005954static NAMED * FASTCALL
5955hashTableIterNext(HASH_TABLE_ITER *iter)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005956{
5957 while (iter->p != iter->end) {
5958 NAMED *tem = *(iter->p)++;
5959 if (tem)
5960 return tem;
5961 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005962 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005963}
5964
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005965static void FASTCALL
5966poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005967{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005968 pool->blocks = NULL;
5969 pool->freeBlocks = NULL;
5970 pool->start = NULL;
5971 pool->ptr = NULL;
5972 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005973 pool->mem = ms;
5974}
5975
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005976static void FASTCALL
5977poolClear(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005978{
5979 if (!pool->freeBlocks)
5980 pool->freeBlocks = pool->blocks;
5981 else {
5982 BLOCK *p = pool->blocks;
5983 while (p) {
5984 BLOCK *tem = p->next;
5985 p->next = pool->freeBlocks;
5986 pool->freeBlocks = p;
5987 p = tem;
5988 }
5989 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005990 pool->blocks = NULL;
5991 pool->start = NULL;
5992 pool->ptr = NULL;
5993 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005994}
5995
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005996static void FASTCALL
5997poolDestroy(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005998{
5999 BLOCK *p = pool->blocks;
6000 while (p) {
6001 BLOCK *tem = p->next;
6002 pool->mem->free_fcn(p);
6003 p = tem;
6004 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006005 p = pool->freeBlocks;
6006 while (p) {
6007 BLOCK *tem = p->next;
6008 pool->mem->free_fcn(p);
6009 p = tem;
6010 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006011}
6012
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006013static XML_Char *
6014poolAppend(STRING_POOL *pool, const ENCODING *enc,
6015 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006016{
6017 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006018 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006019 for (;;) {
6020 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6021 if (ptr == end)
6022 break;
6023 if (!poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006024 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006025 }
6026 return pool->start;
6027}
6028
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006029static const XML_Char * FASTCALL
6030poolCopyString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006031{
6032 do {
6033 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006034 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006035 } while (*s++);
6036 s = pool->start;
6037 poolFinish(pool);
6038 return s;
6039}
6040
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006041static const XML_Char *
6042poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006043{
6044 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006045 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006046 for (; n > 0; --n, s++) {
6047 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006048 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006049 }
6050 s = pool->start;
6051 poolFinish(pool);
6052 return s;
6053}
6054
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006055static const XML_Char * FASTCALL
6056poolAppendString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006057{
6058 while (*s) {
6059 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006060 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006061 s++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006062 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006063 return pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006064}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006065
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006066static XML_Char *
6067poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6068 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006069{
6070 if (!poolAppend(pool, enc, ptr, end))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006071 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006072 if (pool->ptr == pool->end && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006073 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006074 *(pool->ptr)++ = 0;
6075 return pool->start;
6076}
6077
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006078static XML_Bool FASTCALL
6079poolGrow(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006080{
6081 if (pool->freeBlocks) {
6082 if (pool->start == 0) {
6083 pool->blocks = pool->freeBlocks;
6084 pool->freeBlocks = pool->freeBlocks->next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006085 pool->blocks->next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006086 pool->start = pool->blocks->s;
6087 pool->end = pool->start + pool->blocks->size;
6088 pool->ptr = pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006089 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006090 }
6091 if (pool->end - pool->start < pool->freeBlocks->size) {
6092 BLOCK *tem = pool->freeBlocks->next;
6093 pool->freeBlocks->next = pool->blocks;
6094 pool->blocks = pool->freeBlocks;
6095 pool->freeBlocks = tem;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006096 memcpy(pool->blocks->s, pool->start,
6097 (pool->end - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006098 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6099 pool->start = pool->blocks->s;
6100 pool->end = pool->start + pool->blocks->size;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006101 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006102 }
6103 }
6104 if (pool->blocks && pool->start == pool->blocks->s) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006105 int blockSize = (int)(pool->end - pool->start)*2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006106 pool->blocks = (BLOCK *)
6107 pool->mem->realloc_fcn(pool->blocks,
Fred Drake08317ae2003-10-21 15:38:55 +00006108 (offsetof(BLOCK, s)
6109 + blockSize * sizeof(XML_Char)));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006110 if (pool->blocks == NULL)
6111 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006112 pool->blocks->size = blockSize;
6113 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6114 pool->start = pool->blocks->s;
6115 pool->end = pool->start + blockSize;
6116 }
6117 else {
6118 BLOCK *tem;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006119 int blockSize = (int)(pool->end - pool->start);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006120 if (blockSize < INIT_BLOCK_SIZE)
6121 blockSize = INIT_BLOCK_SIZE;
6122 else
6123 blockSize *= 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006124 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
Fred Drake08317ae2003-10-21 15:38:55 +00006125 + blockSize * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006126 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006127 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006128 tem->size = blockSize;
6129 tem->next = pool->blocks;
6130 pool->blocks = tem;
6131 if (pool->ptr != pool->start)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006132 memcpy(tem->s, pool->start,
6133 (pool->ptr - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006134 pool->ptr = tem->s + (pool->ptr - pool->start);
6135 pool->start = tem->s;
6136 pool->end = tem->s + blockSize;
6137 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006138 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006139}
6140
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006141static int FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006142nextScaffoldPart(XML_Parser parser)
6143{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006144 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006145 CONTENT_SCAFFOLD * me;
6146 int next;
6147
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006148 if (!dtd->scaffIndex) {
6149 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6150 if (!dtd->scaffIndex)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006151 return -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006152 dtd->scaffIndex[0] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006153 }
6154
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006155 if (dtd->scaffCount >= dtd->scaffSize) {
6156 CONTENT_SCAFFOLD *temp;
6157 if (dtd->scaffold) {
6158 temp = (CONTENT_SCAFFOLD *)
6159 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6160 if (temp == NULL)
6161 return -1;
6162 dtd->scaffSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006163 }
6164 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006165 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6166 * sizeof(CONTENT_SCAFFOLD));
6167 if (temp == NULL)
6168 return -1;
6169 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006170 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006171 dtd->scaffold = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006172 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006173 next = dtd->scaffCount++;
6174 me = &dtd->scaffold[next];
6175 if (dtd->scaffLevel) {
6176 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006177 if (parent->lastchild) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006178 dtd->scaffold[parent->lastchild].nextsib = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006179 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006180 if (!parent->childcnt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006181 parent->firstchild = next;
6182 parent->lastchild = next;
6183 parent->childcnt++;
6184 }
6185 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6186 return next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006187}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006188
6189static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006190build_node(XML_Parser parser,
6191 int src_node,
6192 XML_Content *dest,
6193 XML_Content **contpos,
6194 XML_Char **strpos)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006195{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006196 DTD * const dtd = _dtd; /* save one level of indirection */
6197 dest->type = dtd->scaffold[src_node].type;
6198 dest->quant = dtd->scaffold[src_node].quant;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006199 if (dest->type == XML_CTYPE_NAME) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006200 const XML_Char *src;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006201 dest->name = *strpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006202 src = dtd->scaffold[src_node].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006203 for (;;) {
6204 *(*strpos)++ = *src;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006205 if (!*src)
6206 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006207 src++;
6208 }
6209 dest->numchildren = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006210 dest->children = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006211 }
6212 else {
6213 unsigned int i;
6214 int cn;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006215 dest->numchildren = dtd->scaffold[src_node].childcnt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006216 dest->children = *contpos;
6217 *contpos += dest->numchildren;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006218 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6219 i < dest->numchildren;
6220 i++, cn = dtd->scaffold[cn].nextsib) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006221 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6222 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006223 dest->name = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006224 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006225}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006226
6227static XML_Content *
6228build_model (XML_Parser parser)
6229{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006230 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006231 XML_Content *ret;
6232 XML_Content *cpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006233 XML_Char * str;
6234 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6235 + (dtd->contentStringLen * sizeof(XML_Char)));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006236
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006237 ret = (XML_Content *)MALLOC(allocsize);
6238 if (!ret)
6239 return NULL;
6240
6241 str = (XML_Char *) (&ret[dtd->scaffCount]);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006242 cpos = &ret[1];
6243
6244 build_node(parser, 0, ret, &cpos, &str);
6245 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006246}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006247
6248static ELEMENT_TYPE *
6249getElementType(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006250 const ENCODING *enc,
6251 const char *ptr,
6252 const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006253{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006254 DTD * const dtd = _dtd; /* save one level of indirection */
6255 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006256 ELEMENT_TYPE *ret;
6257
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006258 if (!name)
6259 return NULL;
6260 ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6261 if (!ret)
6262 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006263 if (ret->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006264 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006265 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006266 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006267 if (!setElementTypePrefix(parser, ret))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006268 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006269 }
6270 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006271}