blob: f35aa36ba8a7fce3bae90f31b20354435b15d2f2 [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
Neal Norwitz9652baa2006-05-02 07:27:47 +00005#include <stddef.h>
6#include <string.h> /* memset(), memcpy() */
7#include <assert.h>
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07008#include <limits.h> /* UINT_MAX */
9#include <time.h> /* time() */
Neal Norwitz9652baa2006-05-02 07:27:47 +000010
Gregory P. Smitha5df2902012-07-14 14:12:35 -070011#define XML_BUILDING_EXPAT 1
12
13#ifdef COMPILED_FROM_DSP
14#include "winconfig.h"
15#elif defined(MACOS_CLASSIC)
16#include "macconfig.h"
17#elif defined(__amigaos__)
18#include "amigaconfig.h"
19#elif defined(__WATCOMC__)
20#include "watcomconfig.h"
21#elif defined(HAVE_EXPAT_CONFIG_H)
22#include <expat_config.h>
23#endif /* ndef COMPILED_FROM_DSP */
24
25#include "ascii.h"
Fred Drake08317ae2003-10-21 15:38:55 +000026#include "expat.h"
27
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000028#ifdef XML_UNICODE
29#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
30#define XmlConvert XmlUtf16Convert
31#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
32#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
33#define XmlEncode XmlUtf16Encode
Gregory P. Smitha5df2902012-07-14 14:12:35 -070034/* Using pointer subtraction to convert to integer type. */
35#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000036typedef unsigned short ICHAR;
37#else
38#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
39#define XmlConvert XmlUtf8Convert
40#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
41#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
42#define XmlEncode XmlUtf8Encode
43#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
44typedef char ICHAR;
45#endif
46
47
48#ifndef XML_NS
49
50#define XmlInitEncodingNS XmlInitEncoding
51#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
52#undef XmlGetInternalEncodingNS
53#define XmlGetInternalEncodingNS XmlGetInternalEncoding
54#define XmlParseXmlDeclNS XmlParseXmlDecl
55
56#endif
57
Martin v. Löwisfc03a942003-01-25 22:41:29 +000058#ifdef XML_UNICODE
59
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000060#ifdef XML_UNICODE_WCHAR_T
Martin v. Löwisfc03a942003-01-25 22:41:29 +000061#define XML_T(x) (const wchar_t)x
62#define XML_L(x) L ## x
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000063#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +000064#define XML_T(x) (const unsigned short)x
65#define XML_L(x) x
66#endif
67
68#else
69
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000070#define XML_T(x) x
Martin v. Löwisfc03a942003-01-25 22:41:29 +000071#define XML_L(x) x
72
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000073#endif
74
75/* Round up n to be a multiple of sz, where sz is a power of 2. */
76#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
77
Fred Drake08317ae2003-10-21 15:38:55 +000078/* Handle the case where memmove() doesn't exist. */
79#ifndef HAVE_MEMMOVE
80#ifdef HAVE_BCOPY
81#define memmove(d,s,l) bcopy((s),(d),(l))
82#else
83#error memmove does not exist on this platform, nor is a substitute available
84#endif /* HAVE_BCOPY */
85#endif /* HAVE_MEMMOVE */
86
Martin v. Löwisfc03a942003-01-25 22:41:29 +000087#include "internal.h"
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +000088#include "xmltok.h"
89#include "xmlrole.h"
90
91typedef const XML_Char *KEY;
92
93typedef struct {
94 KEY name;
95} NAMED;
96
97typedef struct {
98 NAMED **v;
Fred Drake08317ae2003-10-21 15:38:55 +000099 unsigned char power;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000100 size_t size;
101 size_t used;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000102 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000103} HASH_TABLE;
104
Fred Drake08317ae2003-10-21 15:38:55 +0000105/* Basic character hash algorithm, taken from Python's string hash:
106 h = h * 1000003 ^ character, the constant being a prime number.
107
108*/
109#ifdef XML_UNICODE
110#define CHAR_HASH(h, c) \
111 (((h) * 0xF4243) ^ (unsigned short)(c))
112#else
113#define CHAR_HASH(h, c) \
114 (((h) * 0xF4243) ^ (unsigned char)(c))
115#endif
116
117/* For probing (after a collision) we need a step size relative prime
118 to the hash table size, which is a power of 2. We use double-hashing,
119 since we can calculate a second hash value cheaply by taking those bits
120 of the first hash value that were discarded (masked out) when the table
121 index was calculated: index = hash & mask, where mask = table->size - 1.
122 We limit the maximum step size to table->size / 4 (mask >> 2) and make
123 it odd, since odd numbers are always relative prime to a power of 2.
124*/
125#define SECOND_HASH(hash, mask, power) \
126 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
127#define PROBE_STEP(hash, mask, power) \
128 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
129
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000130typedef struct {
131 NAMED **p;
132 NAMED **end;
133} HASH_TABLE_ITER;
134
135#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
136#define INIT_DATA_BUF_SIZE 1024
137#define INIT_ATTS_SIZE 16
Fred Drake08317ae2003-10-21 15:38:55 +0000138#define INIT_ATTS_VERSION 0xFFFFFFFF
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000139#define INIT_BLOCK_SIZE 1024
140#define INIT_BUFFER_SIZE 1024
141
142#define EXPAND_SPARE 24
143
144typedef struct binding {
145 struct prefix *prefix;
146 struct binding *nextTagBinding;
147 struct binding *prevPrefixBinding;
148 const struct attribute_id *attId;
149 XML_Char *uri;
150 int uriLen;
151 int uriAlloc;
152} BINDING;
153
154typedef struct prefix {
155 const XML_Char *name;
156 BINDING *binding;
157} PREFIX;
158
159typedef struct {
160 const XML_Char *str;
161 const XML_Char *localPart;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000162 const XML_Char *prefix;
163 int strLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000164 int uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000165 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000166} TAG_NAME;
167
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000168/* TAG represents an open element.
169 The name of the element is stored in both the document and API
170 encodings. The memory buffer 'buf' is a separately-allocated
171 memory area which stores the name. During the XML_Parse()/
172 XMLParseBuffer() when the element is open, the memory for the 'raw'
173 version of the name (in the document encoding) is shared with the
174 document buffer. If the element is open across calls to
175 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
176 contain the 'raw' name as well.
177
178 A parser re-uses these structures, maintaining a list of allocated
179 TAG objects in a free list.
180*/
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000181typedef struct tag {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000182 struct tag *parent; /* parent of this element */
183 const char *rawName; /* tagName in the original encoding */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000184 int rawNameLength;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000185 TAG_NAME name; /* tagName in the API encoding */
186 char *buf; /* buffer for name components */
187 char *bufEnd; /* end of the buffer */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000188 BINDING *bindings;
189} TAG;
190
191typedef struct {
192 const XML_Char *name;
193 const XML_Char *textPtr;
Fred Drake31d485c2004-08-03 07:06:22 +0000194 int textLen; /* length in XML_Chars */
195 int processed; /* # of processed bytes - when suspended */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000196 const XML_Char *systemId;
197 const XML_Char *base;
198 const XML_Char *publicId;
199 const XML_Char *notation;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000200 XML_Bool open;
201 XML_Bool is_param;
202 XML_Bool is_internal; /* true if declared in internal subset outside PE */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000203} ENTITY;
204
205typedef struct {
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000206 enum XML_Content_Type type;
207 enum XML_Content_Quant quant;
208 const XML_Char * name;
209 int firstchild;
210 int lastchild;
211 int childcnt;
212 int nextsib;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000213} CONTENT_SCAFFOLD;
214
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000215#define INIT_SCAFFOLD_ELEMENTS 32
216
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000217typedef struct block {
218 struct block *next;
219 int size;
220 XML_Char s[1];
221} BLOCK;
222
223typedef struct {
224 BLOCK *blocks;
225 BLOCK *freeBlocks;
226 const XML_Char *end;
227 XML_Char *ptr;
228 XML_Char *start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000229 const XML_Memory_Handling_Suite *mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000230} STRING_POOL;
231
232/* The XML_Char before the name is used to determine whether
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000233 an attribute has been specified. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000234typedef struct attribute_id {
235 XML_Char *name;
236 PREFIX *prefix;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000237 XML_Bool maybeTokenized;
238 XML_Bool xmlns;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000239} ATTRIBUTE_ID;
240
241typedef struct {
242 const ATTRIBUTE_ID *id;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000243 XML_Bool isCdata;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000244 const XML_Char *value;
245} DEFAULT_ATTRIBUTE;
246
247typedef struct {
Fred Drake08317ae2003-10-21 15:38:55 +0000248 unsigned long version;
249 unsigned long hash;
250 const XML_Char *uriName;
251} NS_ATT;
252
253typedef struct {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000254 const XML_Char *name;
255 PREFIX *prefix;
256 const ATTRIBUTE_ID *idAtt;
257 int nDefaultAtts;
258 int allocDefaultAtts;
259 DEFAULT_ATTRIBUTE *defaultAtts;
260} ELEMENT_TYPE;
261
262typedef struct {
263 HASH_TABLE generalEntities;
264 HASH_TABLE elementTypes;
265 HASH_TABLE attributeIds;
266 HASH_TABLE prefixes;
267 STRING_POOL pool;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000268 STRING_POOL entityValuePool;
269 /* false once a parameter entity reference has been skipped */
270 XML_Bool keepProcessing;
271 /* true once an internal or external PE reference has been encountered;
272 this includes the reference to an external subset */
273 XML_Bool hasParamEntityRefs;
274 XML_Bool standalone;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000275#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000276 /* indicates if external PE has been read */
277 XML_Bool paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000278 HASH_TABLE paramEntities;
279#endif /* XML_DTD */
280 PREFIX defaultPrefix;
281 /* === scaffolding for building content model === */
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000282 XML_Bool in_eldecl;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000283 CONTENT_SCAFFOLD *scaffold;
284 unsigned contentStringLen;
285 unsigned scaffSize;
286 unsigned scaffCount;
287 int scaffLevel;
288 int *scaffIndex;
289} DTD;
290
291typedef struct open_internal_entity {
292 const char *internalEventPtr;
293 const char *internalEventEndPtr;
294 struct open_internal_entity *next;
295 ENTITY *entity;
Fred Drake31d485c2004-08-03 07:06:22 +0000296 int startTagLevel;
297 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000298} OPEN_INTERNAL_ENTITY;
299
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000300typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
301 const char *start,
302 const char *end,
303 const char **endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000304
305static Processor prologProcessor;
306static Processor prologInitProcessor;
307static Processor contentProcessor;
308static Processor cdataSectionProcessor;
309#ifdef XML_DTD
310static Processor ignoreSectionProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000311static Processor externalParEntProcessor;
312static Processor externalParEntInitProcessor;
313static Processor entityValueProcessor;
314static Processor entityValueInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000315#endif /* XML_DTD */
316static Processor epilogProcessor;
317static Processor errorProcessor;
318static Processor externalEntityInitProcessor;
319static Processor externalEntityInitProcessor2;
320static Processor externalEntityInitProcessor3;
321static Processor externalEntityContentProcessor;
Fred Drake31d485c2004-08-03 07:06:22 +0000322static Processor internalEntityProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000323
324static enum XML_Error
325handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
326static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000327processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Fred Drake31d485c2004-08-03 07:06:22 +0000328 const char *s, const char *next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000329static enum XML_Error
330initializeEncoding(XML_Parser parser);
331static enum XML_Error
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700332doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
333 const char *end, int tok, const char *next, const char **nextPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000334 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000335static enum XML_Error
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700336processInternalEntity(XML_Parser parser, ENTITY *entity,
Fred Drake31d485c2004-08-03 07:06:22 +0000337 XML_Bool betweenDecl);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000338static enum XML_Error
339doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700340 const char *start, const char *end, const char **endPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000341 XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000342static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000343doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000344 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000345#ifdef XML_DTD
346static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000347doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
Fred Drake31d485c2004-08-03 07:06:22 +0000348 const char *end, const char **nextPtr, XML_Bool haveMore);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000349#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000350
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000351static enum XML_Error
Fred Drake4faea012003-01-28 06:42:40 +0000352storeAtts(XML_Parser parser, const ENCODING *, const char *s,
353 TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000354static enum XML_Error
355addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
356 const XML_Char *uri, BINDING **bindingsPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000357static int
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700358defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
Fred Drake31d485c2004-08-03 07:06:22 +0000359 XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000360static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000361storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
362 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000363static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000364appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
365 const char *, const char *, STRING_POOL *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000366static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000367getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
368 const char *end);
369static int
370setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000371static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000372storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
373 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000374static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000375reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
376 const char *start, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000377static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000378reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
379 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000380static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000381reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
382 const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000383
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000384static const XML_Char * getContext(XML_Parser parser);
385static XML_Bool
386setContext(XML_Parser parser, const XML_Char *context);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000387
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000388static void FASTCALL normalizePublicId(XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000389
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000390static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
391/* do not call if parentParser != NULL */
392static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
393static void
394dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
395static int
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700396dtdCopy(XML_Parser oldParser,
397 DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000398static int
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700399copyEntityTable(XML_Parser oldParser,
400 HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000401static NAMED *
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700402lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000403static void FASTCALL
404hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
405static void FASTCALL hashTableClear(HASH_TABLE *);
406static void FASTCALL hashTableDestroy(HASH_TABLE *);
407static void FASTCALL
408hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
409static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000410
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000411static void FASTCALL
412poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
413static void FASTCALL poolClear(STRING_POOL *);
414static void FASTCALL poolDestroy(STRING_POOL *);
415static XML_Char *
416poolAppend(STRING_POOL *pool, const ENCODING *enc,
417 const char *ptr, const char *end);
418static XML_Char *
419poolStoreString(STRING_POOL *pool, const ENCODING *enc,
420 const char *ptr, const char *end);
421static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
422static const XML_Char * FASTCALL
423poolCopyString(STRING_POOL *pool, const XML_Char *s);
424static const XML_Char *
425poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
426static const XML_Char * FASTCALL
427poolAppendString(STRING_POOL *pool, const XML_Char *s);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000428
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000429static int FASTCALL nextScaffoldPart(XML_Parser parser);
430static XML_Content * build_model(XML_Parser parser);
431static ELEMENT_TYPE *
432getElementType(XML_Parser parser, const ENCODING *enc,
433 const char *ptr, const char *end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000434
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700435static unsigned long generate_hash_secret_salt(void);
436static XML_Bool startParsing(XML_Parser parser);
437
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000438static XML_Parser
439parserCreate(const XML_Char *encodingName,
440 const XML_Memory_Handling_Suite *memsuite,
441 const XML_Char *nameSep,
442 DTD *dtd);
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700443
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000444static void
445parserInit(XML_Parser parser, const XML_Char *encodingName);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000446
447#define poolStart(pool) ((pool)->start)
448#define poolEnd(pool) ((pool)->ptr)
449#define poolLength(pool) ((pool)->ptr - (pool)->start)
450#define poolChop(pool) ((void)--(pool->ptr))
451#define poolLastChar(pool) (((pool)->ptr)[-1])
452#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
453#define poolFinish(pool) ((pool)->start = (pool)->ptr)
454#define poolAppendChar(pool, c) \
455 (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
456 ? 0 \
457 : ((*((pool)->ptr)++ = c), 1))
458
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000459struct XML_ParserStruct {
460 /* The first member must be userData so that the XML_GetUserData
461 macro works. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000462 void *m_userData;
463 void *m_handlerArg;
464 char *m_buffer;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000465 const XML_Memory_Handling_Suite m_mem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000466 /* first character to be parsed */
467 const char *m_bufferPtr;
468 /* past last character to be parsed */
469 char *m_bufferEnd;
470 /* allocated end of buffer */
471 const char *m_bufferLim;
Trent Mickf08d6632006-06-19 23:21:25 +0000472 XML_Index m_parseEndByteIndex;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000473 const char *m_parseEndPtr;
474 XML_Char *m_dataBuf;
475 XML_Char *m_dataBufEnd;
476 XML_StartElementHandler m_startElementHandler;
477 XML_EndElementHandler m_endElementHandler;
478 XML_CharacterDataHandler m_characterDataHandler;
479 XML_ProcessingInstructionHandler m_processingInstructionHandler;
480 XML_CommentHandler m_commentHandler;
481 XML_StartCdataSectionHandler m_startCdataSectionHandler;
482 XML_EndCdataSectionHandler m_endCdataSectionHandler;
483 XML_DefaultHandler m_defaultHandler;
484 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
485 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
486 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
487 XML_NotationDeclHandler m_notationDeclHandler;
488 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
489 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
490 XML_NotStandaloneHandler m_notStandaloneHandler;
491 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000492 XML_Parser m_externalEntityRefHandlerArg;
493 XML_SkippedEntityHandler m_skippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000494 XML_UnknownEncodingHandler m_unknownEncodingHandler;
495 XML_ElementDeclHandler m_elementDeclHandler;
496 XML_AttlistDeclHandler m_attlistDeclHandler;
497 XML_EntityDeclHandler m_entityDeclHandler;
498 XML_XmlDeclHandler m_xmlDeclHandler;
499 const ENCODING *m_encoding;
500 INIT_ENCODING m_initEncoding;
501 const ENCODING *m_internalEncoding;
502 const XML_Char *m_protocolEncodingName;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000503 XML_Bool m_ns;
504 XML_Bool m_ns_triplets;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000505 void *m_unknownEncodingMem;
506 void *m_unknownEncodingData;
507 void *m_unknownEncodingHandlerData;
Fred Drake31d485c2004-08-03 07:06:22 +0000508 void (XMLCALL *m_unknownEncodingRelease)(void *);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000509 PROLOG_STATE m_prologState;
510 Processor *m_processor;
511 enum XML_Error m_errorCode;
512 const char *m_eventPtr;
513 const char *m_eventEndPtr;
514 const char *m_positionPtr;
515 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
Fred Drake31d485c2004-08-03 07:06:22 +0000516 OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000517 XML_Bool m_defaultExpandInternalEntities;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000518 int m_tagLevel;
519 ENTITY *m_declEntity;
520 const XML_Char *m_doctypeName;
521 const XML_Char *m_doctypeSysid;
522 const XML_Char *m_doctypePubid;
523 const XML_Char *m_declAttributeType;
524 const XML_Char *m_declNotationName;
525 const XML_Char *m_declNotationPublicId;
526 ELEMENT_TYPE *m_declElementType;
527 ATTRIBUTE_ID *m_declAttributeId;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000528 XML_Bool m_declAttributeIsCdata;
529 XML_Bool m_declAttributeIsId;
530 DTD *m_dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000531 const XML_Char *m_curBase;
532 TAG *m_tagStack;
533 TAG *m_freeTagList;
534 BINDING *m_inheritedBindings;
535 BINDING *m_freeBindingList;
536 int m_attsSize;
537 int m_nSpecifiedAtts;
538 int m_idAttIndex;
539 ATTRIBUTE *m_atts;
Fred Drake08317ae2003-10-21 15:38:55 +0000540 NS_ATT *m_nsAtts;
541 unsigned long m_nsAttsVersion;
542 unsigned char m_nsAttsPower;
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700543#ifdef XML_ATTR_INFO
544 XML_AttrInfo *m_attInfo;
545#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000546 POSITION m_position;
547 STRING_POOL m_tempPool;
548 STRING_POOL m_temp2Pool;
549 char *m_groupConnector;
Fred Drake08317ae2003-10-21 15:38:55 +0000550 unsigned int m_groupSize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000551 XML_Char m_namespaceSeparator;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000552 XML_Parser m_parentParser;
Fred Drake31d485c2004-08-03 07:06:22 +0000553 XML_ParsingStatus m_parsingStatus;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000554#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000555 XML_Bool m_isParamEntity;
556 XML_Bool m_useForeignDTD;
557 enum XML_ParamEntityParsing m_paramEntityParsing;
558#endif
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700559 unsigned long m_hash_secret_salt;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000560};
561
562#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
563#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
564#define FREE(p) (parser->m_mem.free_fcn((p)))
565
566#define userData (parser->m_userData)
567#define handlerArg (parser->m_handlerArg)
568#define startElementHandler (parser->m_startElementHandler)
569#define endElementHandler (parser->m_endElementHandler)
570#define characterDataHandler (parser->m_characterDataHandler)
571#define processingInstructionHandler \
572 (parser->m_processingInstructionHandler)
573#define commentHandler (parser->m_commentHandler)
574#define startCdataSectionHandler \
575 (parser->m_startCdataSectionHandler)
576#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
577#define defaultHandler (parser->m_defaultHandler)
578#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
579#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
580#define unparsedEntityDeclHandler \
581 (parser->m_unparsedEntityDeclHandler)
582#define notationDeclHandler (parser->m_notationDeclHandler)
583#define startNamespaceDeclHandler \
584 (parser->m_startNamespaceDeclHandler)
585#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
586#define notStandaloneHandler (parser->m_notStandaloneHandler)
587#define externalEntityRefHandler \
588 (parser->m_externalEntityRefHandler)
589#define externalEntityRefHandlerArg \
590 (parser->m_externalEntityRefHandlerArg)
591#define internalEntityRefHandler \
592 (parser->m_internalEntityRefHandler)
593#define skippedEntityHandler (parser->m_skippedEntityHandler)
594#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
595#define elementDeclHandler (parser->m_elementDeclHandler)
596#define attlistDeclHandler (parser->m_attlistDeclHandler)
597#define entityDeclHandler (parser->m_entityDeclHandler)
598#define xmlDeclHandler (parser->m_xmlDeclHandler)
599#define encoding (parser->m_encoding)
600#define initEncoding (parser->m_initEncoding)
601#define internalEncoding (parser->m_internalEncoding)
602#define unknownEncodingMem (parser->m_unknownEncodingMem)
603#define unknownEncodingData (parser->m_unknownEncodingData)
604#define unknownEncodingHandlerData \
605 (parser->m_unknownEncodingHandlerData)
606#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
607#define protocolEncodingName (parser->m_protocolEncodingName)
608#define ns (parser->m_ns)
609#define ns_triplets (parser->m_ns_triplets)
610#define prologState (parser->m_prologState)
611#define processor (parser->m_processor)
612#define errorCode (parser->m_errorCode)
613#define eventPtr (parser->m_eventPtr)
614#define eventEndPtr (parser->m_eventEndPtr)
615#define positionPtr (parser->m_positionPtr)
616#define position (parser->m_position)
617#define openInternalEntities (parser->m_openInternalEntities)
Fred Drake31d485c2004-08-03 07:06:22 +0000618#define freeInternalEntities (parser->m_freeInternalEntities)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000619#define defaultExpandInternalEntities \
620 (parser->m_defaultExpandInternalEntities)
621#define tagLevel (parser->m_tagLevel)
622#define buffer (parser->m_buffer)
623#define bufferPtr (parser->m_bufferPtr)
624#define bufferEnd (parser->m_bufferEnd)
625#define parseEndByteIndex (parser->m_parseEndByteIndex)
626#define parseEndPtr (parser->m_parseEndPtr)
627#define bufferLim (parser->m_bufferLim)
628#define dataBuf (parser->m_dataBuf)
629#define dataBufEnd (parser->m_dataBufEnd)
630#define _dtd (parser->m_dtd)
631#define curBase (parser->m_curBase)
632#define declEntity (parser->m_declEntity)
633#define doctypeName (parser->m_doctypeName)
634#define doctypeSysid (parser->m_doctypeSysid)
635#define doctypePubid (parser->m_doctypePubid)
636#define declAttributeType (parser->m_declAttributeType)
637#define declNotationName (parser->m_declNotationName)
638#define declNotationPublicId (parser->m_declNotationPublicId)
639#define declElementType (parser->m_declElementType)
640#define declAttributeId (parser->m_declAttributeId)
641#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
642#define declAttributeIsId (parser->m_declAttributeIsId)
643#define freeTagList (parser->m_freeTagList)
644#define freeBindingList (parser->m_freeBindingList)
645#define inheritedBindings (parser->m_inheritedBindings)
646#define tagStack (parser->m_tagStack)
647#define atts (parser->m_atts)
648#define attsSize (parser->m_attsSize)
649#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
650#define idAttIndex (parser->m_idAttIndex)
Fred Drake08317ae2003-10-21 15:38:55 +0000651#define nsAtts (parser->m_nsAtts)
652#define nsAttsVersion (parser->m_nsAttsVersion)
653#define nsAttsPower (parser->m_nsAttsPower)
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700654#define attInfo (parser->m_attInfo)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000655#define tempPool (parser->m_tempPool)
656#define temp2Pool (parser->m_temp2Pool)
657#define groupConnector (parser->m_groupConnector)
658#define groupSize (parser->m_groupSize)
659#define namespaceSeparator (parser->m_namespaceSeparator)
660#define parentParser (parser->m_parentParser)
Trent Mickf08d6632006-06-19 23:21:25 +0000661#define ps_parsing (parser->m_parsingStatus.parsing)
662#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000663#ifdef XML_DTD
664#define isParamEntity (parser->m_isParamEntity)
665#define useForeignDTD (parser->m_useForeignDTD)
666#define paramEntityParsing (parser->m_paramEntityParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000667#endif /* XML_DTD */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700668#define hash_secret_salt (parser->m_hash_secret_salt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000669
Fred Drake08317ae2003-10-21 15:38:55 +0000670XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000671XML_ParserCreate(const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000672{
673 return XML_ParserCreate_MM(encodingName, NULL, NULL);
674}
675
Fred Drake08317ae2003-10-21 15:38:55 +0000676XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000677XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000678{
679 XML_Char tmp[2];
680 *tmp = nsSep;
681 return XML_ParserCreate_MM(encodingName, NULL, tmp);
682}
683
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000684static const XML_Char implicitContext[] = {
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700685 ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
686 ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
687 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
688 ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
689 ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
690 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000691};
692
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700693static unsigned long
694generate_hash_secret_salt(void)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000695{
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700696 unsigned int seed = time(NULL) % UINT_MAX;
697 srand(seed);
698 return rand();
699}
700
701static XML_Bool /* only valid for root parser */
702startParsing(XML_Parser parser)
703{
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700704 /* hash functions must be initialized before setContext() is called */
705 if (hash_secret_salt == 0)
706 hash_secret_salt = generate_hash_secret_salt();
707 if (ns) {
708 /* implicit context only set for root parser, since child
709 parsers (i.e. external entity parsers) will inherit it
710 */
711 return setContext(parser, implicitContext);
712 }
713 return XML_TRUE;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700714}
715
716XML_Parser XMLCALL
717XML_ParserCreate_MM(const XML_Char *encodingName,
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700718 const XML_Memory_Handling_Suite *memsuite,
719 const XML_Char *nameSep)
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700720{
721 return parserCreate(encodingName, memsuite, nameSep, NULL);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000722}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000723
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000724static XML_Parser
725parserCreate(const XML_Char *encodingName,
726 const XML_Memory_Handling_Suite *memsuite,
727 const XML_Char *nameSep,
728 DTD *dtd)
729{
730 XML_Parser parser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000731
732 if (memsuite) {
733 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000734 parser = (XML_Parser)
735 memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
736 if (parser != NULL) {
737 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
738 mtemp->malloc_fcn = memsuite->malloc_fcn;
739 mtemp->realloc_fcn = memsuite->realloc_fcn;
740 mtemp->free_fcn = memsuite->free_fcn;
741 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000742 }
743 else {
744 XML_Memory_Handling_Suite *mtemp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000745 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
746 if (parser != NULL) {
747 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
748 mtemp->malloc_fcn = malloc;
749 mtemp->realloc_fcn = realloc;
750 mtemp->free_fcn = free;
751 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000752 }
753
754 if (!parser)
755 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000756
757 buffer = NULL;
758 bufferLim = NULL;
759
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000760 attsSize = INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000761 atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
762 if (atts == NULL) {
763 FREE(parser);
764 return NULL;
765 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700766#ifdef XML_ATTR_INFO
767 attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
768 if (attInfo == NULL) {
769 FREE(atts);
770 FREE(parser);
771 return NULL;
772 }
773#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000774 dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
775 if (dataBuf == NULL) {
776 FREE(atts);
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700777#ifdef XML_ATTR_INFO
778 FREE(attInfo);
779#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000780 FREE(parser);
781 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000782 }
783 dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
784
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000785 if (dtd)
786 _dtd = dtd;
787 else {
788 _dtd = dtdCreate(&parser->m_mem);
789 if (_dtd == NULL) {
790 FREE(dataBuf);
791 FREE(atts);
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700792#ifdef XML_ATTR_INFO
793 FREE(attInfo);
794#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000795 FREE(parser);
796 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000797 }
798 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000799
800 freeBindingList = NULL;
801 freeTagList = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000802 freeInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000803
804 groupSize = 0;
805 groupConnector = NULL;
806
807 unknownEncodingHandler = NULL;
808 unknownEncodingHandlerData = NULL;
809
Gregory P. Smitha5df2902012-07-14 14:12:35 -0700810 namespaceSeparator = ASCII_EXCL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000811 ns = XML_FALSE;
812 ns_triplets = XML_FALSE;
813
Fred Drake08317ae2003-10-21 15:38:55 +0000814 nsAtts = NULL;
815 nsAttsVersion = 0;
816 nsAttsPower = 0;
817
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000818 poolInit(&tempPool, &(parser->m_mem));
819 poolInit(&temp2Pool, &(parser->m_mem));
820 parserInit(parser, encodingName);
821
822 if (encodingName && !protocolEncodingName) {
823 XML_ParserFree(parser);
824 return NULL;
825 }
826
827 if (nameSep) {
828 ns = XML_TRUE;
829 internalEncoding = XmlGetInternalEncodingNS();
830 namespaceSeparator = *nameSep;
831 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000832 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000833 internalEncoding = XmlGetInternalEncoding();
834 }
835
836 return parser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000837}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000838
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000839static void
840parserInit(XML_Parser parser, const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000841{
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000842 processor = prologInitProcessor;
843 XmlPrologStateInit(&prologState);
844 protocolEncodingName = (encodingName != NULL
845 ? poolCopyString(&tempPool, encodingName)
846 : NULL);
847 curBase = NULL;
848 XmlInitEncoding(&initEncoding, &encoding, 0);
849 userData = NULL;
850 handlerArg = NULL;
851 startElementHandler = NULL;
852 endElementHandler = NULL;
853 characterDataHandler = NULL;
854 processingInstructionHandler = NULL;
855 commentHandler = NULL;
856 startCdataSectionHandler = NULL;
857 endCdataSectionHandler = NULL;
858 defaultHandler = NULL;
859 startDoctypeDeclHandler = NULL;
860 endDoctypeDeclHandler = NULL;
861 unparsedEntityDeclHandler = NULL;
862 notationDeclHandler = NULL;
863 startNamespaceDeclHandler = NULL;
864 endNamespaceDeclHandler = NULL;
865 notStandaloneHandler = NULL;
866 externalEntityRefHandler = NULL;
867 externalEntityRefHandlerArg = parser;
868 skippedEntityHandler = NULL;
869 elementDeclHandler = NULL;
870 attlistDeclHandler = NULL;
871 entityDeclHandler = NULL;
872 xmlDeclHandler = NULL;
873 bufferPtr = buffer;
874 bufferEnd = buffer;
875 parseEndByteIndex = 0;
876 parseEndPtr = NULL;
877 declElementType = NULL;
878 declAttributeId = NULL;
879 declEntity = NULL;
880 doctypeName = NULL;
881 doctypeSysid = NULL;
882 doctypePubid = NULL;
883 declAttributeType = NULL;
884 declNotationName = NULL;
885 declNotationPublicId = NULL;
886 declAttributeIsCdata = XML_FALSE;
887 declAttributeIsId = XML_FALSE;
888 memset(&position, 0, sizeof(POSITION));
889 errorCode = XML_ERROR_NONE;
890 eventPtr = NULL;
891 eventEndPtr = NULL;
892 positionPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +0000893 openInternalEntities = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000894 defaultExpandInternalEntities = XML_TRUE;
895 tagLevel = 0;
896 tagStack = NULL;
897 inheritedBindings = NULL;
898 nSpecifiedAtts = 0;
899 unknownEncodingMem = NULL;
900 unknownEncodingRelease = NULL;
901 unknownEncodingData = NULL;
902 parentParser = NULL;
Trent Mickf08d6632006-06-19 23:21:25 +0000903 ps_parsing = XML_INITIALIZED;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000904#ifdef XML_DTD
905 isParamEntity = XML_FALSE;
906 useForeignDTD = XML_FALSE;
907 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
908#endif
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700909 hash_secret_salt = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000910}
911
912/* moves list of bindings to freeBindingList */
913static void FASTCALL
914moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
915{
916 while (bindings) {
917 BINDING *b = bindings;
918 bindings = bindings->nextTagBinding;
919 b->nextTagBinding = freeBindingList;
920 freeBindingList = b;
921 }
922}
923
Fred Drake08317ae2003-10-21 15:38:55 +0000924XML_Bool XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000925XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
926{
927 TAG *tStk;
Fred Drake31d485c2004-08-03 07:06:22 +0000928 OPEN_INTERNAL_ENTITY *openEntityList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000929 if (parentParser)
930 return XML_FALSE;
931 /* move tagStack to freeTagList */
932 tStk = tagStack;
933 while (tStk) {
934 TAG *tag = tStk;
935 tStk = tStk->parent;
936 tag->parent = freeTagList;
937 moveToFreeBindingList(parser, tag->bindings);
938 tag->bindings = NULL;
939 freeTagList = tag;
940 }
Fred Drake31d485c2004-08-03 07:06:22 +0000941 /* move openInternalEntities to freeInternalEntities */
942 openEntityList = openInternalEntities;
943 while (openEntityList) {
944 OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
945 openEntityList = openEntity->next;
946 openEntity->next = freeInternalEntities;
947 freeInternalEntities = openEntity;
948 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000949 moveToFreeBindingList(parser, inheritedBindings);
Fred Drake08317ae2003-10-21 15:38:55 +0000950 FREE(unknownEncodingMem);
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000951 if (unknownEncodingRelease)
952 unknownEncodingRelease(unknownEncodingData);
953 poolClear(&tempPool);
954 poolClear(&temp2Pool);
955 parserInit(parser, encodingName);
956 dtdReset(_dtd, &parser->m_mem);
Gregory P. Smithc8ff4602012-03-14 15:28:10 -0700957 return XML_TRUE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000958}
959
Fred Drake08317ae2003-10-21 15:38:55 +0000960enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000961XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
962{
963 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
964 XXX There's no way for the caller to determine which of the
965 XXX possible error cases caused the XML_STATUS_ERROR return.
966 */
Trent Mickf08d6632006-06-19 23:21:25 +0000967 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000968 return XML_STATUS_ERROR;
969 if (encodingName == NULL)
970 protocolEncodingName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000971 else {
972 protocolEncodingName = poolCopyString(&tempPool, encodingName);
973 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000974 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000975 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000976 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000977}
978
Fred Drake08317ae2003-10-21 15:38:55 +0000979XML_Parser XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000980XML_ExternalEntityParserCreate(XML_Parser oldParser,
981 const XML_Char *context,
982 const XML_Char *encodingName)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000983{
984 XML_Parser parser = oldParser;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000985 DTD *newDtd = NULL;
986 DTD *oldDtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000987 XML_StartElementHandler oldStartElementHandler = startElementHandler;
988 XML_EndElementHandler oldEndElementHandler = endElementHandler;
989 XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000990 XML_ProcessingInstructionHandler oldProcessingInstructionHandler
991 = processingInstructionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000992 XML_CommentHandler oldCommentHandler = commentHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000993 XML_StartCdataSectionHandler oldStartCdataSectionHandler
994 = startCdataSectionHandler;
995 XML_EndCdataSectionHandler oldEndCdataSectionHandler
996 = endCdataSectionHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +0000997 XML_DefaultHandler oldDefaultHandler = defaultHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +0000998 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
999 = unparsedEntityDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001000 XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001001 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
1002 = startNamespaceDeclHandler;
1003 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
1004 = endNamespaceDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001005 XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001006 XML_ExternalEntityRefHandler oldExternalEntityRefHandler
1007 = externalEntityRefHandler;
1008 XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
1009 XML_UnknownEncodingHandler oldUnknownEncodingHandler
1010 = unknownEncodingHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001011 XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
1012 XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
1013 XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
1014 XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
1015 ELEMENT_TYPE * oldDeclElementType = declElementType;
1016
1017 void *oldUserData = userData;
1018 void *oldHandlerArg = handlerArg;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001019 XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
1020 XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001021#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001022 enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
1023 int oldInEntityValue = prologState.inEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001024#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001025 XML_Bool oldns_triplets = ns_triplets;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001026 /* Note that the new parser shares the same hash secret as the old
1027 parser, so that dtdCopy and copyEntityTable can lookup values
1028 from hash tables associated with either parser without us having
1029 to worry which hash secrets each table has.
1030 */
1031 unsigned long oldhash_secret_salt = hash_secret_salt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001032
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001033#ifdef XML_DTD
1034 if (!context)
1035 newDtd = oldDtd;
1036#endif /* XML_DTD */
1037
1038 /* Note that the magical uses of the pre-processor to make field
1039 access look more like C++ require that `parser' be overwritten
1040 here. This makes this function more painful to follow than it
1041 would be otherwise.
1042 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001043 if (ns) {
1044 XML_Char tmp[2];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001045 *tmp = namespaceSeparator;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001046 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001047 }
1048 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001049 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001050 }
1051
1052 if (!parser)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001053 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001054
1055 startElementHandler = oldStartElementHandler;
1056 endElementHandler = oldEndElementHandler;
1057 characterDataHandler = oldCharacterDataHandler;
1058 processingInstructionHandler = oldProcessingInstructionHandler;
1059 commentHandler = oldCommentHandler;
1060 startCdataSectionHandler = oldStartCdataSectionHandler;
1061 endCdataSectionHandler = oldEndCdataSectionHandler;
1062 defaultHandler = oldDefaultHandler;
1063 unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1064 notationDeclHandler = oldNotationDeclHandler;
1065 startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1066 endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1067 notStandaloneHandler = oldNotStandaloneHandler;
1068 externalEntityRefHandler = oldExternalEntityRefHandler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001069 skippedEntityHandler = oldSkippedEntityHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001070 unknownEncodingHandler = oldUnknownEncodingHandler;
1071 elementDeclHandler = oldElementDeclHandler;
1072 attlistDeclHandler = oldAttlistDeclHandler;
1073 entityDeclHandler = oldEntityDeclHandler;
1074 xmlDeclHandler = oldXmlDeclHandler;
1075 declElementType = oldDeclElementType;
1076 userData = oldUserData;
1077 if (oldUserData == oldHandlerArg)
1078 handlerArg = userData;
1079 else
1080 handlerArg = parser;
1081 if (oldExternalEntityRefHandlerArg != oldParser)
1082 externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1083 defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1084 ns_triplets = oldns_triplets;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001085 hash_secret_salt = oldhash_secret_salt;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001086 parentParser = oldParser;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001087#ifdef XML_DTD
1088 paramEntityParsing = oldParamEntityParsing;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001089 prologState.inEntityValue = oldInEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001090 if (context) {
1091#endif /* XML_DTD */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001092 if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001093 || !setContext(parser, context)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001094 XML_ParserFree(parser);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001095 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001096 }
1097 processor = externalEntityInitProcessor;
1098#ifdef XML_DTD
1099 }
1100 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001101 /* The DTD instance referenced by _dtd is shared between the document's
1102 root parser and external PE parsers, therefore one does not need to
1103 call setContext. In addition, one also *must* not call setContext,
1104 because this would overwrite existing prefix->binding pointers in
1105 _dtd with ones that get destroyed with the external PE parser.
1106 This would leave those prefixes with dangling pointers.
1107 */
1108 isParamEntity = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001109 XmlPrologStateInitExternalEntity(&prologState);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001110 processor = externalParEntInitProcessor;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001111 }
1112#endif /* XML_DTD */
1113 return parser;
1114}
1115
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001116static void FASTCALL
1117destroyBindings(BINDING *bindings, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001118{
1119 for (;;) {
1120 BINDING *b = bindings;
1121 if (!b)
1122 break;
1123 bindings = b->nextTagBinding;
1124 FREE(b->uri);
1125 FREE(b);
1126 }
1127}
1128
Fred Drake08317ae2003-10-21 15:38:55 +00001129void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001130XML_ParserFree(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001131{
Fred Drake31d485c2004-08-03 07:06:22 +00001132 TAG *tagList;
1133 OPEN_INTERNAL_ENTITY *entityList;
1134 if (parser == NULL)
1135 return;
1136 /* free tagStack and freeTagList */
1137 tagList = tagStack;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001138 for (;;) {
1139 TAG *p;
Fred Drake31d485c2004-08-03 07:06:22 +00001140 if (tagList == NULL) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001141 if (freeTagList == NULL)
1142 break;
Fred Drake31d485c2004-08-03 07:06:22 +00001143 tagList = freeTagList;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001144 freeTagList = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001145 }
Fred Drake31d485c2004-08-03 07:06:22 +00001146 p = tagList;
1147 tagList = tagList->parent;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001148 FREE(p->buf);
1149 destroyBindings(p->bindings, parser);
1150 FREE(p);
1151 }
Fred Drake31d485c2004-08-03 07:06:22 +00001152 /* free openInternalEntities and freeInternalEntities */
1153 entityList = openInternalEntities;
1154 for (;;) {
1155 OPEN_INTERNAL_ENTITY *openEntity;
1156 if (entityList == NULL) {
1157 if (freeInternalEntities == NULL)
1158 break;
1159 entityList = freeInternalEntities;
1160 freeInternalEntities = NULL;
1161 }
1162 openEntity = entityList;
1163 entityList = entityList->next;
1164 FREE(openEntity);
1165 }
1166
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001167 destroyBindings(freeBindingList, parser);
1168 destroyBindings(inheritedBindings, parser);
1169 poolDestroy(&tempPool);
1170 poolDestroy(&temp2Pool);
1171#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001172 /* external parameter entity parsers share the DTD structure
1173 parser->m_dtd with the root parser, so we must not destroy it
1174 */
1175 if (!isParamEntity && _dtd)
1176#else
1177 if (_dtd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001178#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001179 dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001180 FREE((void *)atts);
Gregory P. Smitha5df2902012-07-14 14:12:35 -07001181#ifdef XML_ATTR_INFO
1182 FREE((void *)attInfo);
1183#endif
Fred Drake08317ae2003-10-21 15:38:55 +00001184 FREE(groupConnector);
1185 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001186 FREE(dataBuf);
Fred Drake08317ae2003-10-21 15:38:55 +00001187 FREE(nsAtts);
1188 FREE(unknownEncodingMem);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001189 if (unknownEncodingRelease)
1190 unknownEncodingRelease(unknownEncodingData);
1191 FREE(parser);
1192}
1193
Fred Drake08317ae2003-10-21 15:38:55 +00001194void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001195XML_UseParserAsHandlerArg(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001196{
1197 handlerArg = parser;
1198}
1199
Fred Drake08317ae2003-10-21 15:38:55 +00001200enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001201XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1202{
1203#ifdef XML_DTD
1204 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Trent Mickf08d6632006-06-19 23:21:25 +00001205 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001206 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1207 useForeignDTD = useDTD;
1208 return XML_ERROR_NONE;
1209#else
1210 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1211#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001212}
1213
Fred Drake08317ae2003-10-21 15:38:55 +00001214void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001215XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1216{
1217 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Trent Mickf08d6632006-06-19 23:21:25 +00001218 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001219 return;
1220 ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1221}
1222
Fred Drake08317ae2003-10-21 15:38:55 +00001223void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001224XML_SetUserData(XML_Parser parser, void *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001225{
1226 if (handlerArg == userData)
1227 handlerArg = userData = p;
1228 else
1229 userData = p;
1230}
1231
Fred Drake08317ae2003-10-21 15:38:55 +00001232enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001233XML_SetBase(XML_Parser parser, const XML_Char *p)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001234{
1235 if (p) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001236 p = poolCopyString(&_dtd->pool, p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001237 if (!p)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001238 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001239 curBase = p;
1240 }
1241 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001242 curBase = NULL;
1243 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001244}
1245
Fred Drake08317ae2003-10-21 15:38:55 +00001246const XML_Char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001247XML_GetBase(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001248{
1249 return curBase;
1250}
1251
Fred Drake08317ae2003-10-21 15:38:55 +00001252int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001253XML_GetSpecifiedAttributeCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001254{
1255 return nSpecifiedAtts;
1256}
1257
Fred Drake08317ae2003-10-21 15:38:55 +00001258int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001259XML_GetIdAttributeIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001260{
1261 return idAttIndex;
1262}
1263
Gregory P. Smitha5df2902012-07-14 14:12:35 -07001264#ifdef XML_ATTR_INFO
1265const XML_AttrInfo * XMLCALL
1266XML_GetAttributeInfo(XML_Parser parser)
1267{
1268 return attInfo;
1269}
1270#endif
1271
Fred Drake08317ae2003-10-21 15:38:55 +00001272void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001273XML_SetElementHandler(XML_Parser parser,
1274 XML_StartElementHandler start,
1275 XML_EndElementHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001276{
1277 startElementHandler = start;
1278 endElementHandler = end;
1279}
1280
Fred Drake08317ae2003-10-21 15:38:55 +00001281void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001282XML_SetStartElementHandler(XML_Parser parser,
1283 XML_StartElementHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001284 startElementHandler = start;
1285}
1286
Fred Drake08317ae2003-10-21 15:38:55 +00001287void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001288XML_SetEndElementHandler(XML_Parser parser,
1289 XML_EndElementHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001290 endElementHandler = end;
1291}
1292
Fred Drake08317ae2003-10-21 15:38:55 +00001293void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001294XML_SetCharacterDataHandler(XML_Parser parser,
1295 XML_CharacterDataHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001296{
1297 characterDataHandler = handler;
1298}
1299
Fred Drake08317ae2003-10-21 15:38:55 +00001300void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001301XML_SetProcessingInstructionHandler(XML_Parser parser,
1302 XML_ProcessingInstructionHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001303{
1304 processingInstructionHandler = handler;
1305}
1306
Fred Drake08317ae2003-10-21 15:38:55 +00001307void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001308XML_SetCommentHandler(XML_Parser parser,
1309 XML_CommentHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001310{
1311 commentHandler = handler;
1312}
1313
Fred Drake08317ae2003-10-21 15:38:55 +00001314void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001315XML_SetCdataSectionHandler(XML_Parser parser,
1316 XML_StartCdataSectionHandler start,
1317 XML_EndCdataSectionHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001318{
1319 startCdataSectionHandler = start;
1320 endCdataSectionHandler = end;
1321}
1322
Fred Drake08317ae2003-10-21 15:38:55 +00001323void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001324XML_SetStartCdataSectionHandler(XML_Parser parser,
1325 XML_StartCdataSectionHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001326 startCdataSectionHandler = start;
1327}
1328
Fred Drake08317ae2003-10-21 15:38:55 +00001329void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001330XML_SetEndCdataSectionHandler(XML_Parser parser,
1331 XML_EndCdataSectionHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001332 endCdataSectionHandler = end;
1333}
1334
Fred Drake08317ae2003-10-21 15:38:55 +00001335void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001336XML_SetDefaultHandler(XML_Parser parser,
1337 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001338{
1339 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001340 defaultExpandInternalEntities = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001341}
1342
Fred Drake08317ae2003-10-21 15:38:55 +00001343void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001344XML_SetDefaultHandlerExpand(XML_Parser parser,
1345 XML_DefaultHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001346{
1347 defaultHandler = handler;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001348 defaultExpandInternalEntities = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001349}
1350
Fred Drake08317ae2003-10-21 15:38:55 +00001351void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001352XML_SetDoctypeDeclHandler(XML_Parser parser,
1353 XML_StartDoctypeDeclHandler start,
1354 XML_EndDoctypeDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001355{
1356 startDoctypeDeclHandler = start;
1357 endDoctypeDeclHandler = end;
1358}
1359
Fred Drake08317ae2003-10-21 15:38:55 +00001360void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001361XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1362 XML_StartDoctypeDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001363 startDoctypeDeclHandler = start;
1364}
1365
Fred Drake08317ae2003-10-21 15:38:55 +00001366void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001367XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1368 XML_EndDoctypeDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001369 endDoctypeDeclHandler = end;
1370}
1371
Fred Drake08317ae2003-10-21 15:38:55 +00001372void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001373XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1374 XML_UnparsedEntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001375{
1376 unparsedEntityDeclHandler = handler;
1377}
1378
Fred Drake08317ae2003-10-21 15:38:55 +00001379void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001380XML_SetNotationDeclHandler(XML_Parser parser,
1381 XML_NotationDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001382{
1383 notationDeclHandler = handler;
1384}
1385
Fred Drake08317ae2003-10-21 15:38:55 +00001386void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001387XML_SetNamespaceDeclHandler(XML_Parser parser,
1388 XML_StartNamespaceDeclHandler start,
1389 XML_EndNamespaceDeclHandler end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001390{
1391 startNamespaceDeclHandler = start;
1392 endNamespaceDeclHandler = end;
1393}
1394
Fred Drake08317ae2003-10-21 15:38:55 +00001395void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001396XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1397 XML_StartNamespaceDeclHandler start) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001398 startNamespaceDeclHandler = start;
1399}
1400
Fred Drake08317ae2003-10-21 15:38:55 +00001401void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001402XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1403 XML_EndNamespaceDeclHandler end) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001404 endNamespaceDeclHandler = end;
1405}
1406
Fred Drake08317ae2003-10-21 15:38:55 +00001407void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001408XML_SetNotStandaloneHandler(XML_Parser parser,
1409 XML_NotStandaloneHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001410{
1411 notStandaloneHandler = handler;
1412}
1413
Fred Drake08317ae2003-10-21 15:38:55 +00001414void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001415XML_SetExternalEntityRefHandler(XML_Parser parser,
1416 XML_ExternalEntityRefHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001417{
1418 externalEntityRefHandler = handler;
1419}
1420
Fred Drake08317ae2003-10-21 15:38:55 +00001421void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001422XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001423{
1424 if (arg)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001425 externalEntityRefHandlerArg = (XML_Parser)arg;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001426 else
1427 externalEntityRefHandlerArg = parser;
1428}
1429
Fred Drake08317ae2003-10-21 15:38:55 +00001430void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001431XML_SetSkippedEntityHandler(XML_Parser parser,
1432 XML_SkippedEntityHandler handler)
1433{
1434 skippedEntityHandler = handler;
1435}
1436
Fred Drake08317ae2003-10-21 15:38:55 +00001437void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001438XML_SetUnknownEncodingHandler(XML_Parser parser,
1439 XML_UnknownEncodingHandler handler,
1440 void *data)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001441{
1442 unknownEncodingHandler = handler;
1443 unknownEncodingHandlerData = data;
1444}
1445
Fred Drake08317ae2003-10-21 15:38:55 +00001446void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001447XML_SetElementDeclHandler(XML_Parser parser,
1448 XML_ElementDeclHandler eldecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001449{
1450 elementDeclHandler = eldecl;
1451}
1452
Fred Drake08317ae2003-10-21 15:38:55 +00001453void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001454XML_SetAttlistDeclHandler(XML_Parser parser,
1455 XML_AttlistDeclHandler attdecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001456{
1457 attlistDeclHandler = attdecl;
1458}
1459
Fred Drake08317ae2003-10-21 15:38:55 +00001460void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001461XML_SetEntityDeclHandler(XML_Parser parser,
1462 XML_EntityDeclHandler handler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001463{
1464 entityDeclHandler = handler;
1465}
1466
Fred Drake08317ae2003-10-21 15:38:55 +00001467void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001468XML_SetXmlDeclHandler(XML_Parser parser,
1469 XML_XmlDeclHandler handler) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001470 xmlDeclHandler = handler;
1471}
1472
Fred Drake08317ae2003-10-21 15:38:55 +00001473int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001474XML_SetParamEntityParsing(XML_Parser parser,
1475 enum XML_ParamEntityParsing peParsing)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001476{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001477 /* block after XML_Parse()/XML_ParseBuffer() has been called */
Trent Mickf08d6632006-06-19 23:21:25 +00001478 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001479 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001480#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001481 paramEntityParsing = peParsing;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001482 return 1;
1483#else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001484 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001485#endif
1486}
1487
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001488int XMLCALL
1489XML_SetHashSalt(XML_Parser parser,
1490 unsigned long hash_salt)
1491{
1492 /* block after XML_Parse()/XML_ParseBuffer() has been called */
1493 if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1494 return 0;
1495 hash_secret_salt = hash_salt;
1496 return 1;
1497}
1498
Fred Drake08317ae2003-10-21 15:38:55 +00001499enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001500XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001501{
Trent Mickf08d6632006-06-19 23:21:25 +00001502 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001503 case XML_SUSPENDED:
1504 errorCode = XML_ERROR_SUSPENDED;
1505 return XML_STATUS_ERROR;
1506 case XML_FINISHED:
1507 errorCode = XML_ERROR_FINISHED;
1508 return XML_STATUS_ERROR;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001509 case XML_INITIALIZED:
1510 if (parentParser == NULL && !startParsing(parser)) {
1511 errorCode = XML_ERROR_NO_MEMORY;
1512 return XML_STATUS_ERROR;
1513 }
Fred Drake31d485c2004-08-03 07:06:22 +00001514 default:
Trent Mickf08d6632006-06-19 23:21:25 +00001515 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001516 }
1517
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001518 if (len == 0) {
Trent Mickf08d6632006-06-19 23:21:25 +00001519 ps_finalBuffer = (XML_Bool)isFinal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001520 if (!isFinal)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001521 return XML_STATUS_OK;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001522 positionPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001523 parseEndPtr = bufferEnd;
1524
1525 /* If data are left over from last buffer, and we now know that these
1526 data are the final chunk of input, then we have to check them again
Trent Mickf08d6632006-06-19 23:21:25 +00001527 to detect errors based on that fact.
Fred Drake31d485c2004-08-03 07:06:22 +00001528 */
1529 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1530
1531 if (errorCode == XML_ERROR_NONE) {
Trent Mickf08d6632006-06-19 23:21:25 +00001532 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001533 case XML_SUSPENDED:
1534 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1535 positionPtr = bufferPtr;
1536 return XML_STATUS_SUSPENDED;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07001537 case XML_INITIALIZED:
Fred Drake31d485c2004-08-03 07:06:22 +00001538 case XML_PARSING:
Trent Mickf08d6632006-06-19 23:21:25 +00001539 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001540 /* fall through */
1541 default:
1542 return XML_STATUS_OK;
1543 }
1544 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001545 eventEndPtr = eventPtr;
1546 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001547 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001548 }
1549#ifndef XML_CONTEXT_BYTES
1550 else if (bufferPtr == bufferEnd) {
1551 const char *end;
1552 int nLeftOver;
Fred Drake31d485c2004-08-03 07:06:22 +00001553 enum XML_Error result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001554 parseEndByteIndex += len;
1555 positionPtr = s;
Trent Mickf08d6632006-06-19 23:21:25 +00001556 ps_finalBuffer = (XML_Bool)isFinal;
Fred Drake31d485c2004-08-03 07:06:22 +00001557
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001558 errorCode = processor(parser, s, parseEndPtr = s + len, &end);
Fred Drake31d485c2004-08-03 07:06:22 +00001559
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001560 if (errorCode != XML_ERROR_NONE) {
1561 eventEndPtr = eventPtr;
1562 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001563 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001564 }
Fred Drake31d485c2004-08-03 07:06:22 +00001565 else {
Trent Mickf08d6632006-06-19 23:21:25 +00001566 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001567 case XML_SUSPENDED:
1568 result = XML_STATUS_SUSPENDED;
1569 break;
1570 case XML_INITIALIZED:
1571 case XML_PARSING:
Fred Drake31d485c2004-08-03 07:06:22 +00001572 if (isFinal) {
Trent Mickf08d6632006-06-19 23:21:25 +00001573 ps_parsing = XML_FINISHED;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001574 return XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001575 }
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001576 /* fall through */
1577 default:
1578 result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001579 }
1580 }
1581
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001582 XmlUpdatePosition(encoding, positionPtr, end, &position);
1583 nLeftOver = s + len - end;
1584 if (nLeftOver) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001585 if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1586 /* FIXME avoid integer overflow */
1587 char *temp;
1588 temp = (buffer == NULL
1589 ? (char *)MALLOC(len * 2)
1590 : (char *)REALLOC(buffer, len * 2));
1591 if (temp == NULL) {
1592 errorCode = XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001593 eventPtr = eventEndPtr = NULL;
1594 processor = errorProcessor;
1595 return XML_STATUS_ERROR;
1596 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07001597 buffer = temp;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001598 bufferLim = buffer + len * 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001599 }
1600 memcpy(buffer, end, nLeftOver);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001601 }
Trent Mickf08d6632006-06-19 23:21:25 +00001602 bufferPtr = buffer;
1603 bufferEnd = buffer + nLeftOver;
1604 positionPtr = bufferPtr;
1605 parseEndPtr = bufferEnd;
1606 eventPtr = bufferPtr;
1607 eventEndPtr = bufferPtr;
Fred Drake31d485c2004-08-03 07:06:22 +00001608 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001609 }
1610#endif /* not defined XML_CONTEXT_BYTES */
1611 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001612 void *buff = XML_GetBuffer(parser, len);
1613 if (buff == NULL)
1614 return XML_STATUS_ERROR;
1615 else {
1616 memcpy(buff, s, len);
1617 return XML_ParseBuffer(parser, len, isFinal);
1618 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001619 }
1620}
1621
Fred Drake08317ae2003-10-21 15:38:55 +00001622enum XML_Status XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001623XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001624{
Fred Drake31d485c2004-08-03 07:06:22 +00001625 const char *start;
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001626 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001627
Trent Mickf08d6632006-06-19 23:21:25 +00001628 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001629 case XML_SUSPENDED:
1630 errorCode = XML_ERROR_SUSPENDED;
1631 return XML_STATUS_ERROR;
1632 case XML_FINISHED:
1633 errorCode = XML_ERROR_FINISHED;
1634 return XML_STATUS_ERROR;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07001635 case XML_INITIALIZED:
1636 if (parentParser == NULL && !startParsing(parser)) {
1637 errorCode = XML_ERROR_NO_MEMORY;
1638 return XML_STATUS_ERROR;
1639 }
Fred Drake31d485c2004-08-03 07:06:22 +00001640 default:
Trent Mickf08d6632006-06-19 23:21:25 +00001641 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001642 }
1643
1644 start = bufferPtr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001645 positionPtr = start;
1646 bufferEnd += len;
Fred Drake31d485c2004-08-03 07:06:22 +00001647 parseEndPtr = bufferEnd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001648 parseEndByteIndex += len;
Trent Mickf08d6632006-06-19 23:21:25 +00001649 ps_finalBuffer = (XML_Bool)isFinal;
Fred Drake31d485c2004-08-03 07:06:22 +00001650
1651 errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1652
1653 if (errorCode != XML_ERROR_NONE) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001654 eventEndPtr = eventPtr;
1655 processor = errorProcessor;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001656 return XML_STATUS_ERROR;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001657 }
Fred Drake31d485c2004-08-03 07:06:22 +00001658 else {
Trent Mickf08d6632006-06-19 23:21:25 +00001659 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001660 case XML_SUSPENDED:
1661 result = XML_STATUS_SUSPENDED;
1662 break;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07001663 case XML_INITIALIZED:
Fred Drake31d485c2004-08-03 07:06:22 +00001664 case XML_PARSING:
1665 if (isFinal) {
Trent Mickf08d6632006-06-19 23:21:25 +00001666 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001667 return result;
1668 }
1669 default: ; /* should not happen */
1670 }
1671 }
1672
1673 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1674 positionPtr = bufferPtr;
1675 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001676}
1677
Fred Drake08317ae2003-10-21 15:38:55 +00001678void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001679XML_GetBuffer(XML_Parser parser, int len)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001680{
Trent Mickf08d6632006-06-19 23:21:25 +00001681 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001682 case XML_SUSPENDED:
1683 errorCode = XML_ERROR_SUSPENDED;
1684 return NULL;
1685 case XML_FINISHED:
1686 errorCode = XML_ERROR_FINISHED;
1687 return NULL;
1688 default: ;
1689 }
1690
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001691 if (len > bufferLim - bufferEnd) {
1692 /* FIXME avoid integer overflow */
Trent Mickf08d6632006-06-19 23:21:25 +00001693 int neededSize = len + (int)(bufferEnd - bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001694#ifdef XML_CONTEXT_BYTES
Trent Mickf08d6632006-06-19 23:21:25 +00001695 int keep = (int)(bufferPtr - buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001696
1697 if (keep > XML_CONTEXT_BYTES)
1698 keep = XML_CONTEXT_BYTES;
1699 neededSize += keep;
1700#endif /* defined XML_CONTEXT_BYTES */
1701 if (neededSize <= bufferLim - buffer) {
1702#ifdef XML_CONTEXT_BYTES
1703 if (keep < bufferPtr - buffer) {
Trent Mickf08d6632006-06-19 23:21:25 +00001704 int offset = (int)(bufferPtr - buffer) - keep;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001705 memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1706 bufferEnd -= offset;
1707 bufferPtr -= offset;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001708 }
1709#else
1710 memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1711 bufferEnd = buffer + (bufferEnd - bufferPtr);
1712 bufferPtr = buffer;
1713#endif /* not defined XML_CONTEXT_BYTES */
1714 }
1715 else {
1716 char *newBuf;
Trent Mickf08d6632006-06-19 23:21:25 +00001717 int bufferSize = (int)(bufferLim - bufferPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001718 if (bufferSize == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001719 bufferSize = INIT_BUFFER_SIZE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001720 do {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001721 bufferSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001722 } while (bufferSize < neededSize);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001723 newBuf = (char *)MALLOC(bufferSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001724 if (newBuf == 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001725 errorCode = XML_ERROR_NO_MEMORY;
1726 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001727 }
1728 bufferLim = newBuf + bufferSize;
1729#ifdef XML_CONTEXT_BYTES
1730 if (bufferPtr) {
Trent Mickf08d6632006-06-19 23:21:25 +00001731 int keep = (int)(bufferPtr - buffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001732 if (keep > XML_CONTEXT_BYTES)
1733 keep = XML_CONTEXT_BYTES;
1734 memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1735 FREE(buffer);
1736 buffer = newBuf;
1737 bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1738 bufferPtr = buffer + keep;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001739 }
1740 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001741 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1742 bufferPtr = buffer = newBuf;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001743 }
1744#else
1745 if (bufferPtr) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001746 memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1747 FREE(buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001748 }
1749 bufferEnd = newBuf + (bufferEnd - bufferPtr);
1750 bufferPtr = buffer = newBuf;
1751#endif /* not defined XML_CONTEXT_BYTES */
1752 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07001753 eventPtr = eventEndPtr = NULL;
1754 positionPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001755 }
1756 return bufferEnd;
1757}
1758
Fred Drake31d485c2004-08-03 07:06:22 +00001759enum XML_Status XMLCALL
1760XML_StopParser(XML_Parser parser, XML_Bool resumable)
1761{
Trent Mickf08d6632006-06-19 23:21:25 +00001762 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001763 case XML_SUSPENDED:
1764 if (resumable) {
1765 errorCode = XML_ERROR_SUSPENDED;
1766 return XML_STATUS_ERROR;
1767 }
Trent Mickf08d6632006-06-19 23:21:25 +00001768 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001769 break;
1770 case XML_FINISHED:
1771 errorCode = XML_ERROR_FINISHED;
1772 return XML_STATUS_ERROR;
1773 default:
1774 if (resumable) {
1775#ifdef XML_DTD
1776 if (isParamEntity) {
1777 errorCode = XML_ERROR_SUSPEND_PE;
1778 return XML_STATUS_ERROR;
1779 }
1780#endif
Trent Mickf08d6632006-06-19 23:21:25 +00001781 ps_parsing = XML_SUSPENDED;
Fred Drake31d485c2004-08-03 07:06:22 +00001782 }
1783 else
Trent Mickf08d6632006-06-19 23:21:25 +00001784 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001785 }
1786 return XML_STATUS_OK;
1787}
1788
1789enum XML_Status XMLCALL
1790XML_ResumeParser(XML_Parser parser)
1791{
Neal Norwitz52ca0dd2006-01-07 21:21:16 +00001792 enum XML_Status result = XML_STATUS_OK;
Fred Drake31d485c2004-08-03 07:06:22 +00001793
Trent Mickf08d6632006-06-19 23:21:25 +00001794 if (ps_parsing != XML_SUSPENDED) {
Fred Drake31d485c2004-08-03 07:06:22 +00001795 errorCode = XML_ERROR_NOT_SUSPENDED;
1796 return XML_STATUS_ERROR;
1797 }
Trent Mickf08d6632006-06-19 23:21:25 +00001798 ps_parsing = XML_PARSING;
Fred Drake31d485c2004-08-03 07:06:22 +00001799
1800 errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1801
1802 if (errorCode != XML_ERROR_NONE) {
1803 eventEndPtr = eventPtr;
1804 processor = errorProcessor;
1805 return XML_STATUS_ERROR;
1806 }
1807 else {
Trent Mickf08d6632006-06-19 23:21:25 +00001808 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00001809 case XML_SUSPENDED:
1810 result = XML_STATUS_SUSPENDED;
1811 break;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07001812 case XML_INITIALIZED:
Fred Drake31d485c2004-08-03 07:06:22 +00001813 case XML_PARSING:
Trent Mickf08d6632006-06-19 23:21:25 +00001814 if (ps_finalBuffer) {
1815 ps_parsing = XML_FINISHED;
Fred Drake31d485c2004-08-03 07:06:22 +00001816 return result;
1817 }
1818 default: ;
1819 }
1820 }
1821
1822 XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1823 positionPtr = bufferPtr;
1824 return result;
1825}
1826
1827void XMLCALL
1828XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1829{
1830 assert(status != NULL);
1831 *status = parser->m_parsingStatus;
1832}
1833
Fred Drake08317ae2003-10-21 15:38:55 +00001834enum XML_Error XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001835XML_GetErrorCode(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001836{
1837 return errorCode;
1838}
1839
Trent Mickf08d6632006-06-19 23:21:25 +00001840XML_Index XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001841XML_GetCurrentByteIndex(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001842{
1843 if (eventPtr)
1844 return parseEndByteIndex - (parseEndPtr - eventPtr);
1845 return -1;
1846}
1847
Fred Drake08317ae2003-10-21 15:38:55 +00001848int XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001849XML_GetCurrentByteCount(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001850{
1851 if (eventEndPtr && eventPtr)
Trent Mickf08d6632006-06-19 23:21:25 +00001852 return (int)(eventEndPtr - eventPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001853 return 0;
1854}
1855
Fred Drake08317ae2003-10-21 15:38:55 +00001856const char * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001857XML_GetInputContext(XML_Parser parser, int *offset, int *size)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001858{
1859#ifdef XML_CONTEXT_BYTES
1860 if (eventPtr && buffer) {
Trent Mickf08d6632006-06-19 23:21:25 +00001861 *offset = (int)(eventPtr - buffer);
1862 *size = (int)(bufferEnd - buffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001863 return buffer;
1864 }
1865#endif /* defined XML_CONTEXT_BYTES */
1866 return (char *) 0;
1867}
1868
Trent Mickf08d6632006-06-19 23:21:25 +00001869XML_Size XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001870XML_GetCurrentLineNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001871{
Fred Drake31d485c2004-08-03 07:06:22 +00001872 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001873 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1874 positionPtr = eventPtr;
1875 }
1876 return position.lineNumber + 1;
1877}
1878
Trent Mickf08d6632006-06-19 23:21:25 +00001879XML_Size XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001880XML_GetCurrentColumnNumber(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001881{
Fred Drake31d485c2004-08-03 07:06:22 +00001882 if (eventPtr && eventPtr >= positionPtr) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001883 XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1884 positionPtr = eventPtr;
1885 }
1886 return position.columnNumber;
1887}
1888
Fred Drake08317ae2003-10-21 15:38:55 +00001889void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001890XML_FreeContentModel(XML_Parser parser, XML_Content *model)
1891{
1892 FREE(model);
1893}
1894
Fred Drake08317ae2003-10-21 15:38:55 +00001895void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001896XML_MemMalloc(XML_Parser parser, size_t size)
1897{
1898 return MALLOC(size);
1899}
1900
Fred Drake08317ae2003-10-21 15:38:55 +00001901void * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001902XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1903{
1904 return REALLOC(ptr, size);
1905}
1906
Fred Drake08317ae2003-10-21 15:38:55 +00001907void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001908XML_MemFree(XML_Parser parser, void *ptr)
1909{
1910 FREE(ptr);
1911}
1912
Fred Drake08317ae2003-10-21 15:38:55 +00001913void XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001914XML_DefaultCurrent(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001915{
1916 if (defaultHandler) {
1917 if (openInternalEntities)
1918 reportDefault(parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001919 internalEncoding,
1920 openInternalEntities->internalEventPtr,
1921 openInternalEntities->internalEventEndPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001922 else
1923 reportDefault(parser, encoding, eventPtr, eventEndPtr);
1924 }
1925}
1926
Fred Drake08317ae2003-10-21 15:38:55 +00001927const XML_LChar * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001928XML_ErrorString(enum XML_Error code)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001929{
Trent Mickf08d6632006-06-19 23:21:25 +00001930 static const XML_LChar* const message[] = {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001931 0,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001932 XML_L("out of memory"),
1933 XML_L("syntax error"),
1934 XML_L("no element found"),
1935 XML_L("not well-formed (invalid token)"),
1936 XML_L("unclosed token"),
1937 XML_L("partial character"),
1938 XML_L("mismatched tag"),
1939 XML_L("duplicate attribute"),
1940 XML_L("junk after document element"),
1941 XML_L("illegal parameter entity reference"),
1942 XML_L("undefined entity"),
1943 XML_L("recursive entity reference"),
1944 XML_L("asynchronous entity"),
1945 XML_L("reference to invalid character number"),
1946 XML_L("reference to binary entity"),
1947 XML_L("reference to external entity in attribute"),
Trent Mickf08d6632006-06-19 23:21:25 +00001948 XML_L("XML or text declaration not at start of entity"),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001949 XML_L("unknown encoding"),
1950 XML_L("encoding specified in XML declaration is incorrect"),
1951 XML_L("unclosed CDATA section"),
1952 XML_L("error in processing external entity reference"),
1953 XML_L("document is not standalone"),
1954 XML_L("unexpected parser state - please send a bug report"),
1955 XML_L("entity declared in parameter entity"),
1956 XML_L("requested feature requires XML_DTD support in Expat"),
Fred Drake08317ae2003-10-21 15:38:55 +00001957 XML_L("cannot change setting once parsing has begun"),
Fred Drake31d485c2004-08-03 07:06:22 +00001958 XML_L("unbound prefix"),
1959 XML_L("must not undeclare prefix"),
1960 XML_L("incomplete markup in parameter entity"),
1961 XML_L("XML declaration not well-formed"),
1962 XML_L("text declaration not well-formed"),
1963 XML_L("illegal character(s) in public id"),
1964 XML_L("parser suspended"),
1965 XML_L("parser not suspended"),
1966 XML_L("parsing aborted"),
1967 XML_L("parsing finished"),
Trent Mickf08d6632006-06-19 23:21:25 +00001968 XML_L("cannot suspend in external parameter entity"),
1969 XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1970 XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1971 XML_L("prefix must not be bound to one of the reserved namespace names")
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001972 };
1973 if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1974 return message[code];
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001975 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001976}
1977
Fred Drake08317ae2003-10-21 15:38:55 +00001978const XML_LChar * XMLCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001979XML_ExpatVersion(void) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001980
1981 /* V1 is used to string-ize the version number. However, it would
1982 string-ize the actual version macro *names* unless we get them
1983 substituted before being passed to V1. CPP is defined to expand
1984 a macro, then rescan for more expansions. Thus, we use V2 to expand
1985 the version macros, then CPP will expand the resulting V1() macro
1986 with the correct numerals. */
1987 /* ### I'm assuming cpp is portable in this respect... */
1988
1989#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
1990#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
1991
1992 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
1993
1994#undef V1
1995#undef V2
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00001996}
1997
Fred Drake08317ae2003-10-21 15:38:55 +00001998XML_Expat_Version XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00001999XML_ExpatVersionInfo(void)
2000{
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002001 XML_Expat_Version version;
2002
2003 version.major = XML_MAJOR_VERSION;
2004 version.minor = XML_MINOR_VERSION;
2005 version.micro = XML_MICRO_VERSION;
2006
2007 return version;
2008}
2009
Fred Drake08317ae2003-10-21 15:38:55 +00002010const XML_Feature * XMLCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002011XML_GetFeatureList(void)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002012{
Trent Mickf08d6632006-06-19 23:21:25 +00002013 static const XML_Feature features[] = {
2014 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2015 sizeof(XML_Char)},
2016 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2017 sizeof(XML_LChar)},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002018#ifdef XML_UNICODE
Fred Drake08317ae2003-10-21 15:38:55 +00002019 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002020#endif
2021#ifdef XML_UNICODE_WCHAR_T
Fred Drake08317ae2003-10-21 15:38:55 +00002022 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002023#endif
2024#ifdef XML_DTD
Fred Drake08317ae2003-10-21 15:38:55 +00002025 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002026#endif
2027#ifdef XML_CONTEXT_BYTES
2028 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2029 XML_CONTEXT_BYTES},
2030#endif
2031#ifdef XML_MIN_SIZE
Fred Drake08317ae2003-10-21 15:38:55 +00002032 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002033#endif
Trent Mickf08d6632006-06-19 23:21:25 +00002034#ifdef XML_NS
2035 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
2036#endif
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002037#ifdef XML_LARGE_SIZE
2038 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
2039#endif
2040#ifdef XML_ATTR_INFO
2041 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
2042#endif
Fred Drake08317ae2003-10-21 15:38:55 +00002043 {XML_FEATURE_END, NULL, 0}
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002044 };
2045
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002046 return features;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002047}
2048
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002049/* Initially tag->rawName always points into the parse buffer;
2050 for those TAG instances opened while the current parse buffer was
2051 processed, and not yet closed, we need to store tag->rawName in a more
2052 permanent location, since the parse buffer is about to be discarded.
2053*/
2054static XML_Bool
2055storeRawNames(XML_Parser parser)
2056{
2057 TAG *tag = tagStack;
2058 while (tag) {
2059 int bufSize;
2060 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2061 char *rawNameBuf = tag->buf + nameLen;
2062 /* Stop if already stored. Since tagStack is a stack, we can stop
2063 at the first entry that has already been copied; everything
2064 below it in the stack is already been accounted for in a
2065 previous call to this function.
2066 */
2067 if (tag->rawName == rawNameBuf)
2068 break;
2069 /* For re-use purposes we need to ensure that the
2070 size of tag->buf is a multiple of sizeof(XML_Char).
2071 */
2072 bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2073 if (bufSize > tag->bufEnd - tag->buf) {
2074 char *temp = (char *)REALLOC(tag->buf, bufSize);
2075 if (temp == NULL)
2076 return XML_FALSE;
2077 /* if tag->name.str points to tag->buf (only when namespace
2078 processing is off) then we have to update it
2079 */
2080 if (tag->name.str == (XML_Char *)tag->buf)
2081 tag->name.str = (XML_Char *)temp;
2082 /* if tag->name.localPart is set (when namespace processing is on)
2083 then update it as well, since it will always point into tag->buf
2084 */
2085 if (tag->name.localPart)
2086 tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2087 (XML_Char *)tag->buf);
2088 tag->buf = temp;
2089 tag->bufEnd = temp + bufSize;
2090 rawNameBuf = temp + nameLen;
2091 }
2092 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2093 tag->rawName = rawNameBuf;
2094 tag = tag->parent;
2095 }
2096 return XML_TRUE;
2097}
2098
2099static enum XML_Error PTRCALL
2100contentProcessor(XML_Parser parser,
2101 const char *start,
2102 const char *end,
2103 const char **endPtr)
2104{
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002105 enum XML_Error result = doContent(parser, 0, encoding, start, end,
Trent Mickf08d6632006-06-19 23:21:25 +00002106 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00002107 if (result == XML_ERROR_NONE) {
2108 if (!storeRawNames(parser))
2109 return XML_ERROR_NO_MEMORY;
2110 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002111 return result;
2112}
2113
2114static enum XML_Error PTRCALL
2115externalEntityInitProcessor(XML_Parser parser,
2116 const char *start,
2117 const char *end,
2118 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002119{
2120 enum XML_Error result = initializeEncoding(parser);
2121 if (result != XML_ERROR_NONE)
2122 return result;
2123 processor = externalEntityInitProcessor2;
2124 return externalEntityInitProcessor2(parser, start, end, endPtr);
2125}
2126
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002127static enum XML_Error PTRCALL
2128externalEntityInitProcessor2(XML_Parser parser,
2129 const char *start,
2130 const char *end,
2131 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002132{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002133 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002134 int tok = XmlContentTok(encoding, start, end, &next);
2135 switch (tok) {
2136 case XML_TOK_BOM:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002137 /* If we are at the end of the buffer, this would cause the next stage,
2138 i.e. externalEntityInitProcessor3, to pass control directly to
2139 doContent (by detecting XML_TOK_NONE) without processing any xml text
2140 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2141 */
Trent Mickf08d6632006-06-19 23:21:25 +00002142 if (next == end && !ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002143 *endPtr = next;
2144 return XML_ERROR_NONE;
2145 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002146 start = next;
2147 break;
2148 case XML_TOK_PARTIAL:
Trent Mickf08d6632006-06-19 23:21:25 +00002149 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002150 *endPtr = start;
2151 return XML_ERROR_NONE;
2152 }
2153 eventPtr = start;
2154 return XML_ERROR_UNCLOSED_TOKEN;
2155 case XML_TOK_PARTIAL_CHAR:
Trent Mickf08d6632006-06-19 23:21:25 +00002156 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002157 *endPtr = start;
2158 return XML_ERROR_NONE;
2159 }
2160 eventPtr = start;
2161 return XML_ERROR_PARTIAL_CHAR;
2162 }
2163 processor = externalEntityInitProcessor3;
2164 return externalEntityInitProcessor3(parser, start, end, endPtr);
2165}
2166
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002167static enum XML_Error PTRCALL
2168externalEntityInitProcessor3(XML_Parser parser,
2169 const char *start,
2170 const char *end,
2171 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002172{
Fred Drake31d485c2004-08-03 07:06:22 +00002173 int tok;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002174 const char *next = start; /* XmlContentTok doesn't always set the last arg */
Fred Drake31d485c2004-08-03 07:06:22 +00002175 eventPtr = start;
2176 tok = XmlContentTok(encoding, start, end, &next);
2177 eventEndPtr = next;
2178
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002179 switch (tok) {
2180 case XML_TOK_XML_DECL:
2181 {
Fred Drake31d485c2004-08-03 07:06:22 +00002182 enum XML_Error result;
2183 result = processXmlDecl(parser, 1, start, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002184 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002185 return result;
Trent Mickf08d6632006-06-19 23:21:25 +00002186 switch (ps_parsing) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002187 case XML_SUSPENDED:
Fred Drake31d485c2004-08-03 07:06:22 +00002188 *endPtr = next;
2189 return XML_ERROR_NONE;
2190 case XML_FINISHED:
2191 return XML_ERROR_ABORTED;
2192 default:
2193 start = next;
2194 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002195 }
2196 break;
2197 case XML_TOK_PARTIAL:
Trent Mickf08d6632006-06-19 23:21:25 +00002198 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002199 *endPtr = start;
2200 return XML_ERROR_NONE;
2201 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002202 return XML_ERROR_UNCLOSED_TOKEN;
2203 case XML_TOK_PARTIAL_CHAR:
Trent Mickf08d6632006-06-19 23:21:25 +00002204 if (!ps_finalBuffer) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002205 *endPtr = start;
2206 return XML_ERROR_NONE;
2207 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002208 return XML_ERROR_PARTIAL_CHAR;
2209 }
2210 processor = externalEntityContentProcessor;
2211 tagLevel = 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002212 return externalEntityContentProcessor(parser, start, end, endPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002213}
2214
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002215static enum XML_Error PTRCALL
2216externalEntityContentProcessor(XML_Parser parser,
2217 const char *start,
2218 const char *end,
2219 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002220{
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002221 enum XML_Error result = doContent(parser, 1, encoding, start, end,
Trent Mickf08d6632006-06-19 23:21:25 +00002222 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00002223 if (result == XML_ERROR_NONE) {
2224 if (!storeRawNames(parser))
2225 return XML_ERROR_NO_MEMORY;
2226 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002227 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002228}
2229
2230static enum XML_Error
2231doContent(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002232 int startTagLevel,
2233 const ENCODING *enc,
2234 const char *s,
2235 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00002236 const char **nextPtr,
2237 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002238{
Fred Drake31d485c2004-08-03 07:06:22 +00002239 /* save one level of indirection */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002240 DTD * const dtd = _dtd;
Fred Drake31d485c2004-08-03 07:06:22 +00002241
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002242 const char **eventPP;
2243 const char **eventEndPP;
2244 if (enc == encoding) {
2245 eventPP = &eventPtr;
2246 eventEndPP = &eventEndPtr;
2247 }
2248 else {
2249 eventPP = &(openInternalEntities->internalEventPtr);
2250 eventEndPP = &(openInternalEntities->internalEventEndPtr);
2251 }
2252 *eventPP = s;
Fred Drake31d485c2004-08-03 07:06:22 +00002253
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002254 for (;;) {
2255 const char *next = s; /* XmlContentTok doesn't always set the last arg */
2256 int tok = XmlContentTok(enc, s, end, &next);
2257 *eventEndPP = next;
2258 switch (tok) {
2259 case XML_TOK_TRAILING_CR:
Fred Drake31d485c2004-08-03 07:06:22 +00002260 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002261 *nextPtr = s;
2262 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002263 }
2264 *eventEndPP = end;
2265 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002266 XML_Char c = 0xA;
2267 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002268 }
2269 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002270 reportDefault(parser, enc, s, end);
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002271 /* We are at the end of the final buffer, should we check for
2272 XML_SUSPENDED, XML_FINISHED?
Fred Drake31d485c2004-08-03 07:06:22 +00002273 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002274 if (startTagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002275 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002276 if (tagLevel != startTagLevel)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002277 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002278 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002279 return XML_ERROR_NONE;
2280 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00002281 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002282 *nextPtr = s;
2283 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002284 }
2285 if (startTagLevel > 0) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002286 if (tagLevel != startTagLevel)
2287 return XML_ERROR_ASYNC_ENTITY;
Fred Drake31d485c2004-08-03 07:06:22 +00002288 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002289 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002290 }
2291 return XML_ERROR_NO_ELEMENTS;
2292 case XML_TOK_INVALID:
2293 *eventPP = next;
2294 return XML_ERROR_INVALID_TOKEN;
2295 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00002296 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002297 *nextPtr = s;
2298 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002299 }
2300 return XML_ERROR_UNCLOSED_TOKEN;
2301 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00002302 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002303 *nextPtr = s;
2304 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002305 }
2306 return XML_ERROR_PARTIAL_CHAR;
2307 case XML_TOK_ENTITY_REF:
2308 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002309 const XML_Char *name;
2310 ENTITY *entity;
2311 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2312 s + enc->minBytesPerChar,
2313 next - enc->minBytesPerChar);
2314 if (ch) {
2315 if (characterDataHandler)
2316 characterDataHandler(handlerArg, &ch, 1);
2317 else if (defaultHandler)
2318 reportDefault(parser, enc, s, next);
2319 break;
2320 }
2321 name = poolStoreString(&dtd->pool, enc,
2322 s + enc->minBytesPerChar,
2323 next - enc->minBytesPerChar);
2324 if (!name)
2325 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002326 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002327 poolDiscard(&dtd->pool);
2328 /* First, determine if a check for an existing declaration is needed;
2329 if yes, check that the entity exists, and that it is internal,
2330 otherwise call the skipped entity or default handler.
2331 */
2332 if (!dtd->hasParamEntityRefs || dtd->standalone) {
2333 if (!entity)
2334 return XML_ERROR_UNDEFINED_ENTITY;
2335 else if (!entity->is_internal)
2336 return XML_ERROR_ENTITY_DECLARED_IN_PE;
2337 }
2338 else if (!entity) {
2339 if (skippedEntityHandler)
2340 skippedEntityHandler(handlerArg, name, 0);
2341 else if (defaultHandler)
2342 reportDefault(parser, enc, s, next);
2343 break;
2344 }
2345 if (entity->open)
2346 return XML_ERROR_RECURSIVE_ENTITY_REF;
2347 if (entity->notation)
2348 return XML_ERROR_BINARY_ENTITY_REF;
2349 if (entity->textPtr) {
2350 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002351 if (!defaultExpandInternalEntities) {
2352 if (skippedEntityHandler)
2353 skippedEntityHandler(handlerArg, entity->name, 0);
2354 else if (defaultHandler)
2355 reportDefault(parser, enc, s, next);
2356 break;
2357 }
Fred Drake31d485c2004-08-03 07:06:22 +00002358 result = processInternalEntity(parser, entity, XML_FALSE);
2359 if (result != XML_ERROR_NONE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002360 return result;
2361 }
2362 else if (externalEntityRefHandler) {
2363 const XML_Char *context;
2364 entity->open = XML_TRUE;
2365 context = getContext(parser);
2366 entity->open = XML_FALSE;
2367 if (!context)
2368 return XML_ERROR_NO_MEMORY;
Fred Drake31d485c2004-08-03 07:06:22 +00002369 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002370 context,
2371 entity->base,
2372 entity->systemId,
2373 entity->publicId))
2374 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2375 poolDiscard(&tempPool);
2376 }
2377 else if (defaultHandler)
2378 reportDefault(parser, enc, s, next);
2379 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002380 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002381 case XML_TOK_START_TAG_NO_ATTS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002382 /* fall through */
2383 case XML_TOK_START_TAG_WITH_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002384 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002385 TAG *tag;
2386 enum XML_Error result;
2387 XML_Char *toPtr;
2388 if (freeTagList) {
2389 tag = freeTagList;
2390 freeTagList = freeTagList->parent;
2391 }
2392 else {
2393 tag = (TAG *)MALLOC(sizeof(TAG));
2394 if (!tag)
2395 return XML_ERROR_NO_MEMORY;
2396 tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2397 if (!tag->buf) {
2398 FREE(tag);
2399 return XML_ERROR_NO_MEMORY;
2400 }
2401 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2402 }
2403 tag->bindings = NULL;
2404 tag->parent = tagStack;
2405 tagStack = tag;
2406 tag->name.localPart = NULL;
2407 tag->name.prefix = NULL;
2408 tag->rawName = s + enc->minBytesPerChar;
2409 tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2410 ++tagLevel;
2411 {
2412 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2413 const char *fromPtr = tag->rawName;
2414 toPtr = (XML_Char *)tag->buf;
2415 for (;;) {
2416 int bufSize;
2417 int convLen;
2418 XmlConvert(enc,
2419 &fromPtr, rawNameEnd,
2420 (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
Trent Mickf08d6632006-06-19 23:21:25 +00002421 convLen = (int)(toPtr - (XML_Char *)tag->buf);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002422 if (fromPtr == rawNameEnd) {
2423 tag->name.strLen = convLen;
2424 break;
2425 }
Trent Mickf08d6632006-06-19 23:21:25 +00002426 bufSize = (int)(tag->bufEnd - tag->buf) << 1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002427 {
2428 char *temp = (char *)REALLOC(tag->buf, bufSize);
2429 if (temp == NULL)
2430 return XML_ERROR_NO_MEMORY;
2431 tag->buf = temp;
2432 tag->bufEnd = temp + bufSize;
2433 toPtr = (XML_Char *)temp + convLen;
2434 }
2435 }
2436 }
2437 tag->name.str = (XML_Char *)tag->buf;
2438 *toPtr = XML_T('\0');
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002439 result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2440 if (result)
2441 return result;
2442 if (startElementHandler)
2443 startElementHandler(handlerArg, tag->name.str,
2444 (const XML_Char **)atts);
2445 else if (defaultHandler)
2446 reportDefault(parser, enc, s, next);
2447 poolClear(&tempPool);
2448 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002449 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002450 case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002451 /* fall through */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002452 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2453 {
2454 const char *rawName = s + enc->minBytesPerChar;
2455 enum XML_Error result;
2456 BINDING *bindings = NULL;
2457 XML_Bool noElmHandlers = XML_TRUE;
2458 TAG_NAME name;
2459 name.str = poolStoreString(&tempPool, enc, rawName,
2460 rawName + XmlNameLength(enc, rawName));
2461 if (!name.str)
2462 return XML_ERROR_NO_MEMORY;
2463 poolFinish(&tempPool);
Fred Drake4faea012003-01-28 06:42:40 +00002464 result = storeAtts(parser, enc, s, &name, &bindings);
2465 if (result)
2466 return result;
2467 poolFinish(&tempPool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002468 if (startElementHandler) {
2469 startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2470 noElmHandlers = XML_FALSE;
2471 }
2472 if (endElementHandler) {
2473 if (startElementHandler)
2474 *eventPP = *eventEndPP;
2475 endElementHandler(handlerArg, name.str);
2476 noElmHandlers = XML_FALSE;
2477 }
2478 if (noElmHandlers && defaultHandler)
2479 reportDefault(parser, enc, s, next);
2480 poolClear(&tempPool);
2481 while (bindings) {
2482 BINDING *b = bindings;
2483 if (endNamespaceDeclHandler)
2484 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2485 bindings = bindings->nextTagBinding;
2486 b->nextTagBinding = freeBindingList;
2487 freeBindingList = b;
2488 b->prefix->binding = b->prevPrefixBinding;
2489 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002490 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002491 if (tagLevel == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002492 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002493 break;
2494 case XML_TOK_END_TAG:
2495 if (tagLevel == startTagLevel)
2496 return XML_ERROR_ASYNC_ENTITY;
2497 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002498 int len;
2499 const char *rawName;
2500 TAG *tag = tagStack;
2501 tagStack = tag->parent;
2502 tag->parent = freeTagList;
2503 freeTagList = tag;
2504 rawName = s + enc->minBytesPerChar*2;
2505 len = XmlNameLength(enc, rawName);
2506 if (len != tag->rawNameLength
2507 || memcmp(tag->rawName, rawName, len) != 0) {
2508 *eventPP = rawName;
2509 return XML_ERROR_TAG_MISMATCH;
2510 }
2511 --tagLevel;
2512 if (endElementHandler) {
2513 const XML_Char *localPart;
2514 const XML_Char *prefix;
2515 XML_Char *uri;
2516 localPart = tag->name.localPart;
2517 if (ns && localPart) {
2518 /* localPart and prefix may have been overwritten in
2519 tag->name.str, since this points to the binding->uri
2520 buffer which gets re-used; so we have to add them again
2521 */
2522 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2523 /* don't need to check for space - already done in storeAtts() */
2524 while (*localPart) *uri++ = *localPart++;
2525 prefix = (XML_Char *)tag->name.prefix;
2526 if (ns_triplets && prefix) {
2527 *uri++ = namespaceSeparator;
2528 while (*prefix) *uri++ = *prefix++;
2529 }
2530 *uri = XML_T('\0');
2531 }
2532 endElementHandler(handlerArg, tag->name.str);
2533 }
2534 else if (defaultHandler)
2535 reportDefault(parser, enc, s, next);
2536 while (tag->bindings) {
2537 BINDING *b = tag->bindings;
2538 if (endNamespaceDeclHandler)
2539 endNamespaceDeclHandler(handlerArg, b->prefix->name);
2540 tag->bindings = tag->bindings->nextTagBinding;
2541 b->nextTagBinding = freeBindingList;
2542 freeBindingList = b;
2543 b->prefix->binding = b->prevPrefixBinding;
2544 }
2545 if (tagLevel == 0)
2546 return epilogProcessor(parser, next, end, nextPtr);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002547 }
2548 break;
2549 case XML_TOK_CHAR_REF:
2550 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002551 int n = XmlCharRefNumber(enc, s);
2552 if (n < 0)
2553 return XML_ERROR_BAD_CHAR_REF;
2554 if (characterDataHandler) {
2555 XML_Char buf[XML_ENCODE_MAX];
2556 characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2557 }
2558 else if (defaultHandler)
2559 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002560 }
2561 break;
2562 case XML_TOK_XML_DECL:
2563 return XML_ERROR_MISPLACED_XML_PI;
2564 case XML_TOK_DATA_NEWLINE:
2565 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002566 XML_Char c = 0xA;
2567 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002568 }
2569 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002570 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002571 break;
2572 case XML_TOK_CDATA_SECT_OPEN:
2573 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002574 enum XML_Error result;
2575 if (startCdataSectionHandler)
2576 startCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002577#if 0
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002578 /* Suppose you doing a transformation on a document that involves
2579 changing only the character data. You set up a defaultHandler
2580 and a characterDataHandler. The defaultHandler simply copies
2581 characters through. The characterDataHandler does the
2582 transformation and writes the characters out escaping them as
2583 necessary. This case will fail to work if we leave out the
2584 following two lines (because & and < inside CDATA sections will
2585 be incorrectly escaped).
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002586
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002587 However, now we have a start/endCdataSectionHandler, so it seems
2588 easier to let the user deal with this.
2589 */
2590 else if (characterDataHandler)
2591 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002592#endif
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002593 else if (defaultHandler)
2594 reportDefault(parser, enc, s, next);
Fred Drake31d485c2004-08-03 07:06:22 +00002595 result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2596 if (result != XML_ERROR_NONE)
2597 return result;
2598 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002599 processor = cdataSectionProcessor;
2600 return result;
2601 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002602 }
2603 break;
2604 case XML_TOK_TRAILING_RSQB:
Fred Drake31d485c2004-08-03 07:06:22 +00002605 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002606 *nextPtr = s;
2607 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002608 }
2609 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002610 if (MUST_CONVERT(enc, s)) {
2611 ICHAR *dataPtr = (ICHAR *)dataBuf;
2612 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2613 characterDataHandler(handlerArg, dataBuf,
Trent Mickf08d6632006-06-19 23:21:25 +00002614 (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002615 }
2616 else
2617 characterDataHandler(handlerArg,
2618 (XML_Char *)s,
Trent Mickf08d6632006-06-19 23:21:25 +00002619 (int)((XML_Char *)end - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002620 }
2621 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002622 reportDefault(parser, enc, s, end);
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002623 /* We are at the end of the final buffer, should we check for
2624 XML_SUSPENDED, XML_FINISHED?
Fred Drake31d485c2004-08-03 07:06:22 +00002625 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002626 if (startTagLevel == 0) {
2627 *eventPP = end;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002628 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002629 }
2630 if (tagLevel != startTagLevel) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002631 *eventPP = end;
2632 return XML_ERROR_ASYNC_ENTITY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002633 }
Fred Drake31d485c2004-08-03 07:06:22 +00002634 *nextPtr = end;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002635 return XML_ERROR_NONE;
2636 case XML_TOK_DATA_CHARS:
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002637 {
2638 XML_CharacterDataHandler charDataHandler = characterDataHandler;
2639 if (charDataHandler) {
2640 if (MUST_CONVERT(enc, s)) {
2641 for (;;) {
2642 ICHAR *dataPtr = (ICHAR *)dataBuf;
2643 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2644 *eventEndPP = s;
2645 charDataHandler(handlerArg, dataBuf,
2646 (int)(dataPtr - (ICHAR *)dataBuf));
2647 if (s == next)
2648 break;
2649 *eventPP = s;
2650 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002651 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002652 else
2653 charDataHandler(handlerArg,
2654 (XML_Char *)s,
2655 (int)((XML_Char *)next - (XML_Char *)s));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002656 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002657 else if (defaultHandler)
2658 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002659 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002660 break;
2661 case XML_TOK_PI:
2662 if (!reportProcessingInstruction(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002663 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002664 break;
2665 case XML_TOK_COMMENT:
2666 if (!reportComment(parser, enc, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002667 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002668 break;
2669 default:
2670 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002671 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002672 break;
2673 }
2674 *eventPP = s = next;
Trent Mickf08d6632006-06-19 23:21:25 +00002675 switch (ps_parsing) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002676 case XML_SUSPENDED:
Fred Drake31d485c2004-08-03 07:06:22 +00002677 *nextPtr = next;
2678 return XML_ERROR_NONE;
2679 case XML_FINISHED:
2680 return XML_ERROR_ABORTED;
2681 default: ;
2682 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002683 }
2684 /* not reached */
2685}
2686
Fred Drake4faea012003-01-28 06:42:40 +00002687/* Precondition: all arguments must be non-NULL;
2688 Purpose:
2689 - normalize attributes
2690 - check attributes for well-formedness
2691 - generate namespace aware attribute names (URI, prefix)
2692 - build list of attributes for startElementHandler
2693 - default attributes
2694 - process namespace declarations (check and report them)
2695 - generate namespace aware element name (URI, prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002696*/
2697static enum XML_Error
2698storeAtts(XML_Parser parser, const ENCODING *enc,
2699 const char *attStr, TAG_NAME *tagNamePtr,
2700 BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002701{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002702 DTD * const dtd = _dtd; /* save one level of indirection */
Fred Drake08317ae2003-10-21 15:38:55 +00002703 ELEMENT_TYPE *elementType;
2704 int nDefaultAtts;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002705 const XML_Char **appAtts; /* the attribute list for the application */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002706 int attIndex = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002707 int prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002708 int i;
2709 int n;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002710 XML_Char *uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002711 int nPrefixes = 0;
2712 BINDING *binding;
2713 const XML_Char *localPart;
2714
2715 /* lookup the element type name */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002716 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
Fred Drake4faea012003-01-28 06:42:40 +00002717 if (!elementType) {
2718 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2719 if (!name)
2720 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002721 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
Fred Drake4faea012003-01-28 06:42:40 +00002722 sizeof(ELEMENT_TYPE));
2723 if (!elementType)
2724 return XML_ERROR_NO_MEMORY;
2725 if (ns && !setElementTypePrefix(parser, elementType))
2726 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002727 }
Fred Drake4faea012003-01-28 06:42:40 +00002728 nDefaultAtts = elementType->nDefaultAtts;
2729
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002730 /* get the attributes from the tokenizer */
2731 n = XmlGetAttributes(enc, attStr, attsSize, atts);
2732 if (n + nDefaultAtts > attsSize) {
2733 int oldAttsSize = attsSize;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002734 ATTRIBUTE *temp;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002735#ifdef XML_ATTR_INFO
2736 XML_AttrInfo *temp2;
2737#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002738 attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002739 temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2740 if (temp == NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002741 return XML_ERROR_NO_MEMORY;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002742 atts = temp;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002743#ifdef XML_ATTR_INFO
2744 temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
2745 if (temp2 == NULL)
2746 return XML_ERROR_NO_MEMORY;
2747 attInfo = temp2;
2748#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002749 if (n > oldAttsSize)
2750 XmlGetAttributes(enc, attStr, n, atts);
2751 }
Fred Drake4faea012003-01-28 06:42:40 +00002752
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002753 appAtts = (const XML_Char **)atts;
2754 for (i = 0; i < n; i++) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002755 ATTRIBUTE *currAtt = &atts[i];
2756#ifdef XML_ATTR_INFO
2757 XML_AttrInfo *currAttInfo = &attInfo[i];
2758#endif
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002759 /* add the name and value to the attribute list */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002760 ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
2761 currAtt->name
2762 + XmlNameLength(enc, currAtt->name));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002763 if (!attId)
2764 return XML_ERROR_NO_MEMORY;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002765#ifdef XML_ATTR_INFO
2766 currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
2767 currAttInfo->nameEnd = currAttInfo->nameStart +
2768 XmlNameLength(enc, currAtt->name);
2769 currAttInfo->valueStart = parseEndByteIndex -
2770 (parseEndPtr - currAtt->valuePtr);
2771 currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
2772#endif
Fred Drake08317ae2003-10-21 15:38:55 +00002773 /* Detect duplicate attributes by their QNames. This does not work when
2774 namespace processing is turned on and different prefixes for the same
2775 namespace are used. For this case we have a check further down.
2776 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002777 if ((attId->name)[-1]) {
2778 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002779 eventPtr = atts[i].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002780 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2781 }
2782 (attId->name)[-1] = 1;
2783 appAtts[attIndex++] = attId->name;
2784 if (!atts[i].normalized) {
2785 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002786 XML_Bool isCdata = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002787
2788 /* figure out whether declared as other than CDATA */
2789 if (attId->maybeTokenized) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002790 int j;
2791 for (j = 0; j < nDefaultAtts; j++) {
2792 if (attId == elementType->defaultAtts[j].id) {
2793 isCdata = elementType->defaultAtts[j].isCdata;
2794 break;
2795 }
2796 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002797 }
2798
2799 /* normalize the attribute value */
2800 result = storeAttributeValue(parser, enc, isCdata,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002801 atts[i].valuePtr, atts[i].valueEnd,
2802 &tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002803 if (result)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002804 return result;
Fred Drake4faea012003-01-28 06:42:40 +00002805 appAtts[attIndex] = poolStart(&tempPool);
2806 poolFinish(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002807 }
Fred Drake4faea012003-01-28 06:42:40 +00002808 else {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002809 /* the value did not need normalizing */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002810 appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2811 atts[i].valueEnd);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002812 if (appAtts[attIndex] == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002813 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002814 poolFinish(&tempPool);
2815 }
2816 /* handle prefixed attribute names */
Fred Drake4faea012003-01-28 06:42:40 +00002817 if (attId->prefix) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002818 if (attId->xmlns) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002819 /* deal with namespace declarations here */
2820 enum XML_Error result = addBinding(parser, attId->prefix, attId,
2821 appAtts[attIndex], bindingsPtr);
2822 if (result)
2823 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002824 --attIndex;
2825 }
2826 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002827 /* deal with other prefixed names later */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002828 attIndex++;
2829 nPrefixes++;
2830 (attId->name)[-1] = 2;
2831 }
2832 }
2833 else
2834 attIndex++;
2835 }
Fred Drake4faea012003-01-28 06:42:40 +00002836
2837 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2838 nSpecifiedAtts = attIndex;
2839 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2840 for (i = 0; i < attIndex; i += 2)
2841 if (appAtts[i] == elementType->idAtt->name) {
2842 idAttIndex = i;
2843 break;
2844 }
2845 }
2846 else
2847 idAttIndex = -1;
2848
2849 /* do attribute defaulting */
2850 for (i = 0; i < nDefaultAtts; i++) {
2851 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2852 if (!(da->id->name)[-1] && da->value) {
2853 if (da->id->prefix) {
2854 if (da->id->xmlns) {
2855 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2856 da->value, bindingsPtr);
2857 if (result)
2858 return result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002859 }
2860 else {
Fred Drake4faea012003-01-28 06:42:40 +00002861 (da->id->name)[-1] = 2;
2862 nPrefixes++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002863 appAtts[attIndex++] = da->id->name;
2864 appAtts[attIndex++] = da->value;
2865 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002866 }
Fred Drake4faea012003-01-28 06:42:40 +00002867 else {
2868 (da->id->name)[-1] = 1;
2869 appAtts[attIndex++] = da->id->name;
2870 appAtts[attIndex++] = da->value;
2871 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002872 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002873 }
Fred Drake4faea012003-01-28 06:42:40 +00002874 appAtts[attIndex] = 0;
2875
Fred Drake08317ae2003-10-21 15:38:55 +00002876 /* expand prefixed attribute names, check for duplicates,
2877 and clear flags that say whether attributes were specified */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002878 i = 0;
2879 if (nPrefixes) {
Fred Drake08317ae2003-10-21 15:38:55 +00002880 int j; /* hash table index */
2881 unsigned long version = nsAttsVersion;
2882 int nsAttsSize = (int)1 << nsAttsPower;
2883 /* size of hash table must be at least 2 * (# of prefixed attributes) */
2884 if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
2885 NS_ATT *temp;
2886 /* hash table size must also be a power of 2 and >= 8 */
2887 while (nPrefixes >> nsAttsPower++);
2888 if (nsAttsPower < 3)
2889 nsAttsPower = 3;
2890 nsAttsSize = (int)1 << nsAttsPower;
2891 temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2892 if (!temp)
2893 return XML_ERROR_NO_MEMORY;
2894 nsAtts = temp;
2895 version = 0; /* force re-initialization of nsAtts hash table */
2896 }
2897 /* using a version flag saves us from initializing nsAtts every time */
2898 if (!version) { /* initialize version flags when version wraps around */
2899 version = INIT_ATTS_VERSION;
2900 for (j = nsAttsSize; j != 0; )
2901 nsAtts[--j].version = version;
2902 }
2903 nsAttsVersion = --version;
2904
2905 /* expand prefixed names and check for duplicates */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002906 for (; i < attIndex; i += 2) {
Fred Drake08317ae2003-10-21 15:38:55 +00002907 const XML_Char *s = appAtts[i];
2908 if (s[-1] == 2) { /* prefixed */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002909 ATTRIBUTE_ID *id;
Fred Drake08317ae2003-10-21 15:38:55 +00002910 const BINDING *b;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002911 unsigned long uriHash = hash_secret_salt;
Fred Drake08317ae2003-10-21 15:38:55 +00002912 ((XML_Char *)s)[-1] = 0; /* clear flag */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002913 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
Fred Drake08317ae2003-10-21 15:38:55 +00002914 b = id->prefix->binding;
2915 if (!b)
2916 return XML_ERROR_UNBOUND_PREFIX;
2917
2918 /* as we expand the name we also calculate its hash value */
2919 for (j = 0; j < b->uriLen; j++) {
2920 const XML_Char c = b->uri[j];
2921 if (!poolAppendChar(&tempPool, c))
2922 return XML_ERROR_NO_MEMORY;
2923 uriHash = CHAR_HASH(uriHash, c);
2924 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002925 while (*s++ != XML_T(ASCII_COLON))
Fred Drake08317ae2003-10-21 15:38:55 +00002926 ;
2927 do { /* copies null terminator */
2928 const XML_Char c = *s;
2929 if (!poolAppendChar(&tempPool, *s))
2930 return XML_ERROR_NO_MEMORY;
2931 uriHash = CHAR_HASH(uriHash, c);
2932 } while (*s++);
2933
2934 { /* Check hash table for duplicate of expanded name (uriName).
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07002935 Derived from code in lookup(parser, HASH_TABLE *table, ...).
Fred Drake08317ae2003-10-21 15:38:55 +00002936 */
2937 unsigned char step = 0;
2938 unsigned long mask = nsAttsSize - 1;
2939 j = uriHash & mask; /* index into hash table */
2940 while (nsAtts[j].version == version) {
2941 /* for speed we compare stored hash values first */
2942 if (uriHash == nsAtts[j].hash) {
2943 const XML_Char *s1 = poolStart(&tempPool);
2944 const XML_Char *s2 = nsAtts[j].uriName;
2945 /* s1 is null terminated, but not s2 */
2946 for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2947 if (*s1 == 0)
2948 return XML_ERROR_DUPLICATE_ATTRIBUTE;
2949 }
2950 if (!step)
2951 step = PROBE_STEP(uriHash, mask, nsAttsPower);
Trent Mickf08d6632006-06-19 23:21:25 +00002952 j < step ? (j += nsAttsSize - step) : (j -= step);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002953 }
Fred Drake08317ae2003-10-21 15:38:55 +00002954 }
2955
2956 if (ns_triplets) { /* append namespace separator and prefix */
2957 tempPool.ptr[-1] = namespaceSeparator;
2958 s = b->prefix->name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002959 do {
2960 if (!poolAppendChar(&tempPool, *s))
2961 return XML_ERROR_NO_MEMORY;
2962 } while (*s++);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002963 }
Fred Drake08317ae2003-10-21 15:38:55 +00002964
2965 /* store expanded name in attribute list */
2966 s = poolStart(&tempPool);
2967 poolFinish(&tempPool);
2968 appAtts[i] = s;
2969
2970 /* fill empty slot with new version, uriName and hash value */
2971 nsAtts[j].version = version;
2972 nsAtts[j].hash = uriHash;
2973 nsAtts[j].uriName = s;
2974
Trent Mickf08d6632006-06-19 23:21:25 +00002975 if (!--nPrefixes) {
2976 i += 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00002977 break;
Trent Mickf08d6632006-06-19 23:21:25 +00002978 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002979 }
Fred Drake08317ae2003-10-21 15:38:55 +00002980 else /* not prefixed */
2981 ((XML_Char *)s)[-1] = 0; /* clear flag */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002982 }
2983 }
Fred Drake08317ae2003-10-21 15:38:55 +00002984 /* clear flags for the remaining attributes */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002985 for (; i < attIndex; i += 2)
2986 ((XML_Char *)(appAtts[i]))[-1] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002987 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
2988 binding->attId->name[-1] = 0;
Fred Drake4faea012003-01-28 06:42:40 +00002989
Fred Drake08317ae2003-10-21 15:38:55 +00002990 if (!ns)
2991 return XML_ERROR_NONE;
2992
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002993 /* expand the element type name */
2994 if (elementType->prefix) {
2995 binding = elementType->prefix->binding;
2996 if (!binding)
Fred Drake08317ae2003-10-21 15:38:55 +00002997 return XML_ERROR_UNBOUND_PREFIX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00002998 localPart = tagNamePtr->str;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07002999 while (*localPart++ != XML_T(ASCII_COLON))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003000 ;
3001 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003002 else if (dtd->defaultPrefix.binding) {
3003 binding = dtd->defaultPrefix.binding;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003004 localPart = tagNamePtr->str;
3005 }
3006 else
3007 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003008 prefixLen = 0;
Fred Drake08317ae2003-10-21 15:38:55 +00003009 if (ns_triplets && binding->prefix->name) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003010 for (; binding->prefix->name[prefixLen++];)
Trent Mickf08d6632006-06-19 23:21:25 +00003011 ; /* prefixLen includes null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003012 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003013 tagNamePtr->localPart = localPart;
3014 tagNamePtr->uriLen = binding->uriLen;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003015 tagNamePtr->prefix = binding->prefix->name;
3016 tagNamePtr->prefixLen = prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003017 for (i = 0; localPart[i++];)
Trent Mickf08d6632006-06-19 23:21:25 +00003018 ; /* i includes null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003019 n = i + binding->uriLen + prefixLen;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003020 if (n > binding->uriAlloc) {
3021 TAG *p;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003022 uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003023 if (!uri)
3024 return XML_ERROR_NO_MEMORY;
3025 binding->uriAlloc = n + EXPAND_SPARE;
3026 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3027 for (p = tagStack; p; p = p->parent)
3028 if (p->name.str == binding->uri)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003029 p->name.str = uri;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003030 FREE(binding->uri);
3031 binding->uri = uri;
3032 }
Trent Mickf08d6632006-06-19 23:21:25 +00003033 /* if namespaceSeparator != '\0' then uri includes it already */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003034 uri = binding->uri + binding->uriLen;
3035 memcpy(uri, localPart, i * sizeof(XML_Char));
Trent Mickf08d6632006-06-19 23:21:25 +00003036 /* we always have a namespace separator between localPart and prefix */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003037 if (prefixLen) {
Trent Mickf08d6632006-06-19 23:21:25 +00003038 uri += i - 1;
3039 *uri = namespaceSeparator; /* replace null terminator */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003040 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3041 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003042 tagNamePtr->str = binding->uri;
3043 return XML_ERROR_NONE;
3044}
3045
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003046/* addBinding() overwrites the value of prefix->binding without checking.
3047 Therefore one must keep track of the old value outside of addBinding().
3048*/
3049static enum XML_Error
3050addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3051 const XML_Char *uri, BINDING **bindingsPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003052{
Trent Mickf08d6632006-06-19 23:21:25 +00003053 static const XML_Char xmlNamespace[] = {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003054 ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3055 ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3056 ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
3057 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
3058 ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3059 ASCII_e, '\0'
Trent Mickf08d6632006-06-19 23:21:25 +00003060 };
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003061 static const int xmlLen =
Trent Mickf08d6632006-06-19 23:21:25 +00003062 (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3063 static const XML_Char xmlnsNamespace[] = {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003064 ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3065 ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3066 ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
3067 ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
3068 ASCII_SLASH, '\0'
Trent Mickf08d6632006-06-19 23:21:25 +00003069 };
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003070 static const int xmlnsLen =
Trent Mickf08d6632006-06-19 23:21:25 +00003071 (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3072
3073 XML_Bool mustBeXML = XML_FALSE;
3074 XML_Bool isXML = XML_TRUE;
3075 XML_Bool isXMLNS = XML_TRUE;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003076
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003077 BINDING *b;
3078 int len;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003079
Fred Drake31d485c2004-08-03 07:06:22 +00003080 /* 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 +00003081 if (*uri == XML_T('\0') && prefix->name)
Fred Drake31d485c2004-08-03 07:06:22 +00003082 return XML_ERROR_UNDECLARING_PREFIX;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003083
Trent Mickf08d6632006-06-19 23:21:25 +00003084 if (prefix->name
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003085 && prefix->name[0] == XML_T(ASCII_x)
3086 && prefix->name[1] == XML_T(ASCII_m)
3087 && prefix->name[2] == XML_T(ASCII_l)) {
Trent Mickf08d6632006-06-19 23:21:25 +00003088
3089 /* Not allowed to bind xmlns */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003090 if (prefix->name[3] == XML_T(ASCII_n)
3091 && prefix->name[4] == XML_T(ASCII_s)
Trent Mickf08d6632006-06-19 23:21:25 +00003092 && prefix->name[5] == XML_T('\0'))
3093 return XML_ERROR_RESERVED_PREFIX_XMLNS;
3094
3095 if (prefix->name[3] == XML_T('\0'))
3096 mustBeXML = XML_TRUE;
3097 }
3098
3099 for (len = 0; uri[len]; len++) {
3100 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3101 isXML = XML_FALSE;
3102
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003103 if (!mustBeXML && isXMLNS
Trent Mickf08d6632006-06-19 23:21:25 +00003104 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3105 isXMLNS = XML_FALSE;
3106 }
3107 isXML = isXML && len == xmlLen;
3108 isXMLNS = isXMLNS && len == xmlnsLen;
3109
3110 if (mustBeXML != isXML)
3111 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3112 : XML_ERROR_RESERVED_NAMESPACE_URI;
3113
3114 if (isXMLNS)
3115 return XML_ERROR_RESERVED_NAMESPACE_URI;
3116
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003117 if (namespaceSeparator)
3118 len++;
3119 if (freeBindingList) {
3120 b = freeBindingList;
3121 if (len > b->uriAlloc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003122 XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3123 sizeof(XML_Char) * (len + EXPAND_SPARE));
3124 if (temp == NULL)
3125 return XML_ERROR_NO_MEMORY;
3126 b->uri = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003127 b->uriAlloc = len + EXPAND_SPARE;
3128 }
3129 freeBindingList = b->nextTagBinding;
3130 }
3131 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003132 b = (BINDING *)MALLOC(sizeof(BINDING));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003133 if (!b)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003134 return XML_ERROR_NO_MEMORY;
3135 b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003136 if (!b->uri) {
3137 FREE(b);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003138 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003139 }
3140 b->uriAlloc = len + EXPAND_SPARE;
3141 }
3142 b->uriLen = len;
3143 memcpy(b->uri, uri, len * sizeof(XML_Char));
3144 if (namespaceSeparator)
3145 b->uri[len - 1] = namespaceSeparator;
3146 b->prefix = prefix;
3147 b->attId = attId;
3148 b->prevPrefixBinding = prefix->binding;
Fred Drake08317ae2003-10-21 15:38:55 +00003149 /* NULL binding when default namespace undeclared */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003150 if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3151 prefix->binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003152 else
3153 prefix->binding = b;
3154 b->nextTagBinding = *bindingsPtr;
3155 *bindingsPtr = b;
Fred Drake31d485c2004-08-03 07:06:22 +00003156 /* if attId == NULL then we are not starting a namespace scope */
3157 if (attId && startNamespaceDeclHandler)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003158 startNamespaceDeclHandler(handlerArg, prefix->name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003159 prefix->binding ? uri : 0);
3160 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003161}
3162
3163/* The idea here is to avoid using stack for each CDATA section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003164 the whole file is parsed with one call.
3165*/
3166static enum XML_Error PTRCALL
3167cdataSectionProcessor(XML_Parser parser,
3168 const char *start,
3169 const char *end,
3170 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003171{
Fred Drake31d485c2004-08-03 07:06:22 +00003172 enum XML_Error result = doCdataSection(parser, encoding, &start, end,
Trent Mickf08d6632006-06-19 23:21:25 +00003173 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00003174 if (result != XML_ERROR_NONE)
3175 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003176 if (start) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003177 if (parentParser) { /* we are parsing an external entity */
3178 processor = externalEntityContentProcessor;
3179 return externalEntityContentProcessor(parser, start, end, endPtr);
3180 }
3181 else {
3182 processor = contentProcessor;
3183 return contentProcessor(parser, start, end, endPtr);
3184 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003185 }
3186 return result;
3187}
3188
Fred Drake31d485c2004-08-03 07:06:22 +00003189/* startPtr gets set to non-null if the section is closed, and to null if
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003190 the section is not yet closed.
3191*/
3192static enum XML_Error
3193doCdataSection(XML_Parser parser,
3194 const ENCODING *enc,
3195 const char **startPtr,
3196 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003197 const char **nextPtr,
3198 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003199{
3200 const char *s = *startPtr;
3201 const char **eventPP;
3202 const char **eventEndPP;
3203 if (enc == encoding) {
3204 eventPP = &eventPtr;
3205 *eventPP = s;
3206 eventEndPP = &eventEndPtr;
3207 }
3208 else {
3209 eventPP = &(openInternalEntities->internalEventPtr);
3210 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3211 }
3212 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003213 *startPtr = NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00003214
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003215 for (;;) {
3216 const char *next;
3217 int tok = XmlCdataSectionTok(enc, s, end, &next);
3218 *eventEndPP = next;
3219 switch (tok) {
3220 case XML_TOK_CDATA_SECT_CLOSE:
3221 if (endCdataSectionHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003222 endCdataSectionHandler(handlerArg);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003223#if 0
3224 /* see comment under XML_TOK_CDATA_SECT_OPEN */
3225 else if (characterDataHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003226 characterDataHandler(handlerArg, dataBuf, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003227#endif
3228 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003229 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003230 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003231 *nextPtr = next;
Trent Mickf08d6632006-06-19 23:21:25 +00003232 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00003233 return XML_ERROR_ABORTED;
3234 else
3235 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003236 case XML_TOK_DATA_NEWLINE:
3237 if (characterDataHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003238 XML_Char c = 0xA;
3239 characterDataHandler(handlerArg, &c, 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003240 }
3241 else if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003242 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003243 break;
3244 case XML_TOK_DATA_CHARS:
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003245 {
3246 XML_CharacterDataHandler charDataHandler = characterDataHandler;
3247 if (charDataHandler) {
3248 if (MUST_CONVERT(enc, s)) {
3249 for (;;) {
3250 ICHAR *dataPtr = (ICHAR *)dataBuf;
3251 XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3252 *eventEndPP = next;
3253 charDataHandler(handlerArg, dataBuf,
3254 (int)(dataPtr - (ICHAR *)dataBuf));
3255 if (s == next)
3256 break;
3257 *eventPP = s;
3258 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003259 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003260 else
3261 charDataHandler(handlerArg,
3262 (XML_Char *)s,
3263 (int)((XML_Char *)next - (XML_Char *)s));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003264 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003265 else if (defaultHandler)
3266 reportDefault(parser, enc, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003267 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003268 break;
3269 case XML_TOK_INVALID:
3270 *eventPP = next;
3271 return XML_ERROR_INVALID_TOKEN;
3272 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003273 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003274 *nextPtr = s;
3275 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003276 }
3277 return XML_ERROR_PARTIAL_CHAR;
3278 case XML_TOK_PARTIAL:
3279 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003280 if (haveMore) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003281 *nextPtr = s;
3282 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003283 }
3284 return XML_ERROR_UNCLOSED_CDATA_SECTION;
3285 default:
3286 *eventPP = next;
3287 return XML_ERROR_UNEXPECTED_STATE;
3288 }
Fred Drake31d485c2004-08-03 07:06:22 +00003289
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003290 *eventPP = s = next;
Trent Mickf08d6632006-06-19 23:21:25 +00003291 switch (ps_parsing) {
Fred Drake31d485c2004-08-03 07:06:22 +00003292 case XML_SUSPENDED:
3293 *nextPtr = next;
3294 return XML_ERROR_NONE;
3295 case XML_FINISHED:
3296 return XML_ERROR_ABORTED;
3297 default: ;
3298 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003299 }
3300 /* not reached */
3301}
3302
3303#ifdef XML_DTD
3304
3305/* The idea here is to avoid using stack for each IGNORE section when
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003306 the whole file is parsed with one call.
3307*/
3308static enum XML_Error PTRCALL
3309ignoreSectionProcessor(XML_Parser parser,
3310 const char *start,
3311 const char *end,
3312 const char **endPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003313{
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003314 enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
Trent Mickf08d6632006-06-19 23:21:25 +00003315 endPtr, (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00003316 if (result != XML_ERROR_NONE)
3317 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003318 if (start) {
3319 processor = prologProcessor;
3320 return prologProcessor(parser, start, end, endPtr);
3321 }
3322 return result;
3323}
3324
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003325/* startPtr gets set to non-null is the section is closed, and to null
3326 if the section is not yet closed.
3327*/
3328static enum XML_Error
3329doIgnoreSection(XML_Parser parser,
3330 const ENCODING *enc,
3331 const char **startPtr,
3332 const char *end,
Fred Drake31d485c2004-08-03 07:06:22 +00003333 const char **nextPtr,
3334 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003335{
3336 const char *next;
3337 int tok;
3338 const char *s = *startPtr;
3339 const char **eventPP;
3340 const char **eventEndPP;
3341 if (enc == encoding) {
3342 eventPP = &eventPtr;
3343 *eventPP = s;
3344 eventEndPP = &eventEndPtr;
3345 }
3346 else {
3347 eventPP = &(openInternalEntities->internalEventPtr);
3348 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3349 }
3350 *eventPP = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003351 *startPtr = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003352 tok = XmlIgnoreSectionTok(enc, s, end, &next);
3353 *eventEndPP = next;
3354 switch (tok) {
3355 case XML_TOK_IGNORE_SECT:
3356 if (defaultHandler)
3357 reportDefault(parser, enc, s, next);
3358 *startPtr = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003359 *nextPtr = next;
Trent Mickf08d6632006-06-19 23:21:25 +00003360 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00003361 return XML_ERROR_ABORTED;
3362 else
3363 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003364 case XML_TOK_INVALID:
3365 *eventPP = next;
3366 return XML_ERROR_INVALID_TOKEN;
3367 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003368 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003369 *nextPtr = s;
3370 return XML_ERROR_NONE;
3371 }
3372 return XML_ERROR_PARTIAL_CHAR;
3373 case XML_TOK_PARTIAL:
3374 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00003375 if (haveMore) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003376 *nextPtr = s;
3377 return XML_ERROR_NONE;
3378 }
3379 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3380 default:
3381 *eventPP = next;
3382 return XML_ERROR_UNEXPECTED_STATE;
3383 }
3384 /* not reached */
3385}
3386
3387#endif /* XML_DTD */
3388
3389static enum XML_Error
3390initializeEncoding(XML_Parser parser)
3391{
3392 const char *s;
3393#ifdef XML_UNICODE
3394 char encodingBuf[128];
3395 if (!protocolEncodingName)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003396 s = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003397 else {
3398 int i;
3399 for (i = 0; protocolEncodingName[i]; i++) {
3400 if (i == sizeof(encodingBuf) - 1
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003401 || (protocolEncodingName[i] & ~0x7f) != 0) {
3402 encodingBuf[0] = '\0';
3403 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003404 }
3405 encodingBuf[i] = (char)protocolEncodingName[i];
3406 }
3407 encodingBuf[i] = '\0';
3408 s = encodingBuf;
3409 }
3410#else
3411 s = protocolEncodingName;
3412#endif
3413 if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3414 return XML_ERROR_NONE;
3415 return handleUnknownEncoding(parser, protocolEncodingName);
3416}
3417
3418static enum XML_Error
3419processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003420 const char *s, const char *next)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003421{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003422 const char *encodingName = NULL;
3423 const XML_Char *storedEncName = NULL;
3424 const ENCODING *newEncoding = NULL;
3425 const char *version = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003426 const char *versionend;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003427 const XML_Char *storedversion = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003428 int standalone = -1;
3429 if (!(ns
3430 ? XmlParseXmlDeclNS
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003431 : XmlParseXmlDecl)(isGeneralTextEntity,
3432 encoding,
3433 s,
3434 next,
3435 &eventPtr,
3436 &version,
3437 &versionend,
3438 &encodingName,
3439 &newEncoding,
Fred Drake31d485c2004-08-03 07:06:22 +00003440 &standalone)) {
3441 if (isGeneralTextEntity)
3442 return XML_ERROR_TEXT_DECL;
3443 else
3444 return XML_ERROR_XML_DECL;
3445 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003446 if (!isGeneralTextEntity && standalone == 1) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003447 _dtd->standalone = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003448#ifdef XML_DTD
3449 if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3450 paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3451#endif /* XML_DTD */
3452 }
3453 if (xmlDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003454 if (encodingName != NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003455 storedEncName = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003456 encoding,
3457 encodingName,
3458 encodingName
3459 + XmlNameLength(encoding, encodingName));
3460 if (!storedEncName)
3461 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003462 poolFinish(&temp2Pool);
3463 }
3464 if (version) {
3465 storedversion = poolStoreString(&temp2Pool,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003466 encoding,
3467 version,
3468 versionend - encoding->minBytesPerChar);
3469 if (!storedversion)
3470 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003471 }
3472 xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3473 }
3474 else if (defaultHandler)
3475 reportDefault(parser, encoding, s, next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003476 if (protocolEncodingName == NULL) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003477 if (newEncoding) {
3478 if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003479 eventPtr = encodingName;
3480 return XML_ERROR_INCORRECT_ENCODING;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003481 }
3482 encoding = newEncoding;
3483 }
3484 else if (encodingName) {
3485 enum XML_Error result;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003486 if (!storedEncName) {
3487 storedEncName = poolStoreString(
3488 &temp2Pool, encoding, encodingName,
3489 encodingName + XmlNameLength(encoding, encodingName));
3490 if (!storedEncName)
3491 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003492 }
3493 result = handleUnknownEncoding(parser, storedEncName);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003494 poolClear(&temp2Pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003495 if (result == XML_ERROR_UNKNOWN_ENCODING)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003496 eventPtr = encodingName;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003497 return result;
3498 }
3499 }
3500
3501 if (storedEncName || storedversion)
3502 poolClear(&temp2Pool);
3503
3504 return XML_ERROR_NONE;
3505}
3506
3507static enum XML_Error
3508handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3509{
3510 if (unknownEncodingHandler) {
3511 XML_Encoding info;
3512 int i;
3513 for (i = 0; i < 256; i++)
3514 info.map[i] = -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003515 info.convert = NULL;
3516 info.data = NULL;
3517 info.release = NULL;
3518 if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3519 &info)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003520 ENCODING *enc;
3521 unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3522 if (!unknownEncodingMem) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003523 if (info.release)
3524 info.release(info.data);
3525 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003526 }
3527 enc = (ns
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003528 ? XmlInitUnknownEncodingNS
3529 : XmlInitUnknownEncoding)(unknownEncodingMem,
3530 info.map,
3531 info.convert,
3532 info.data);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003533 if (enc) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003534 unknownEncodingData = info.data;
3535 unknownEncodingRelease = info.release;
3536 encoding = enc;
3537 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003538 }
3539 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003540 if (info.release != NULL)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003541 info.release(info.data);
3542 }
3543 return XML_ERROR_UNKNOWN_ENCODING;
3544}
3545
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003546static enum XML_Error PTRCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003547prologInitProcessor(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003548 const char *s,
3549 const char *end,
3550 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003551{
3552 enum XML_Error result = initializeEncoding(parser);
3553 if (result != XML_ERROR_NONE)
3554 return result;
3555 processor = prologProcessor;
3556 return prologProcessor(parser, s, end, nextPtr);
3557}
3558
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003559#ifdef XML_DTD
3560
3561static enum XML_Error PTRCALL
3562externalParEntInitProcessor(XML_Parser parser,
3563 const char *s,
3564 const char *end,
3565 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003566{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003567 enum XML_Error result = initializeEncoding(parser);
3568 if (result != XML_ERROR_NONE)
3569 return result;
3570
3571 /* we know now that XML_Parse(Buffer) has been called,
3572 so we consider the external parameter entity read */
3573 _dtd->paramEntityRead = XML_TRUE;
3574
3575 if (prologState.inEntityValue) {
3576 processor = entityValueInitProcessor;
3577 return entityValueInitProcessor(parser, s, end, nextPtr);
3578 }
3579 else {
3580 processor = externalParEntProcessor;
3581 return externalParEntProcessor(parser, s, end, nextPtr);
3582 }
3583}
3584
3585static enum XML_Error PTRCALL
3586entityValueInitProcessor(XML_Parser parser,
3587 const char *s,
3588 const char *end,
3589 const char **nextPtr)
3590{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003591 int tok;
Fred Drake31d485c2004-08-03 07:06:22 +00003592 const char *start = s;
3593 const char *next = start;
3594 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003595
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003596 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003597 tok = XmlPrologTok(encoding, start, end, &next);
Fred Drake31d485c2004-08-03 07:06:22 +00003598 eventEndPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003599 if (tok <= 0) {
Trent Mickf08d6632006-06-19 23:21:25 +00003600 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Fred Drake31d485c2004-08-03 07:06:22 +00003601 *nextPtr = s;
3602 return XML_ERROR_NONE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003603 }
3604 switch (tok) {
3605 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003606 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003607 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003608 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003609 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003610 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003611 case XML_TOK_NONE: /* start == end */
3612 default:
3613 break;
3614 }
Fred Drake31d485c2004-08-03 07:06:22 +00003615 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003616 return storeEntityValue(parser, encoding, s, end);
3617 }
3618 else if (tok == XML_TOK_XML_DECL) {
Fred Drake31d485c2004-08-03 07:06:22 +00003619 enum XML_Error result;
3620 result = processXmlDecl(parser, 0, start, next);
3621 if (result != XML_ERROR_NONE)
3622 return result;
Trent Mickf08d6632006-06-19 23:21:25 +00003623 switch (ps_parsing) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003624 case XML_SUSPENDED:
Fred Drake31d485c2004-08-03 07:06:22 +00003625 *nextPtr = next;
3626 return XML_ERROR_NONE;
3627 case XML_FINISHED:
3628 return XML_ERROR_ABORTED;
3629 default:
3630 *nextPtr = next;
3631 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003632 /* stop scanning for text declaration - we found one */
3633 processor = entityValueProcessor;
3634 return entityValueProcessor(parser, next, end, nextPtr);
3635 }
3636 /* If we are at the end of the buffer, this would cause XmlPrologTok to
3637 return XML_TOK_NONE on the next call, which would then cause the
3638 function to exit with *nextPtr set to s - that is what we want for other
3639 tokens, but not for the BOM - we would rather like to skip it;
3640 then, when this routine is entered the next time, XmlPrologTok will
3641 return XML_TOK_INVALID, since the BOM is still in the buffer
3642 */
Trent Mickf08d6632006-06-19 23:21:25 +00003643 else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003644 *nextPtr = next;
3645 return XML_ERROR_NONE;
3646 }
3647 start = next;
Fred Drake31d485c2004-08-03 07:06:22 +00003648 eventPtr = start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003649 }
3650}
3651
3652static enum XML_Error PTRCALL
3653externalParEntProcessor(XML_Parser parser,
3654 const char *s,
3655 const char *end,
3656 const char **nextPtr)
3657{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003658 const char *next = s;
3659 int tok;
3660
Fred Drake31d485c2004-08-03 07:06:22 +00003661 tok = XmlPrologTok(encoding, s, end, &next);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003662 if (tok <= 0) {
Trent Mickf08d6632006-06-19 23:21:25 +00003663 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003664 *nextPtr = s;
3665 return XML_ERROR_NONE;
3666 }
3667 switch (tok) {
3668 case XML_TOK_INVALID:
3669 return XML_ERROR_INVALID_TOKEN;
3670 case XML_TOK_PARTIAL:
3671 return XML_ERROR_UNCLOSED_TOKEN;
3672 case XML_TOK_PARTIAL_CHAR:
3673 return XML_ERROR_PARTIAL_CHAR;
3674 case XML_TOK_NONE: /* start == end */
3675 default:
3676 break;
3677 }
3678 }
3679 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3680 However, when parsing an external subset, doProlog will not accept a BOM
3681 as valid, and report a syntax error, so we have to skip the BOM
3682 */
3683 else if (tok == XML_TOK_BOM) {
3684 s = next;
3685 tok = XmlPrologTok(encoding, s, end, &next);
3686 }
3687
3688 processor = prologProcessor;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003689 return doProlog(parser, encoding, s, end, tok, next,
Trent Mickf08d6632006-06-19 23:21:25 +00003690 nextPtr, (XML_Bool)!ps_finalBuffer);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003691}
3692
3693static enum XML_Error PTRCALL
3694entityValueProcessor(XML_Parser parser,
3695 const char *s,
3696 const char *end,
3697 const char **nextPtr)
3698{
3699 const char *start = s;
3700 const char *next = s;
3701 const ENCODING *enc = encoding;
3702 int tok;
3703
3704 for (;;) {
3705 tok = XmlPrologTok(enc, start, end, &next);
3706 if (tok <= 0) {
Trent Mickf08d6632006-06-19 23:21:25 +00003707 if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003708 *nextPtr = s;
3709 return XML_ERROR_NONE;
3710 }
3711 switch (tok) {
3712 case XML_TOK_INVALID:
Fred Drake31d485c2004-08-03 07:06:22 +00003713 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003714 case XML_TOK_PARTIAL:
Fred Drake31d485c2004-08-03 07:06:22 +00003715 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003716 case XML_TOK_PARTIAL_CHAR:
Fred Drake31d485c2004-08-03 07:06:22 +00003717 return XML_ERROR_PARTIAL_CHAR;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003718 case XML_TOK_NONE: /* start == end */
3719 default:
3720 break;
3721 }
Fred Drake31d485c2004-08-03 07:06:22 +00003722 /* found end of entity value - can store it now */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003723 return storeEntityValue(parser, enc, s, end);
3724 }
3725 start = next;
3726 }
3727}
3728
3729#endif /* XML_DTD */
3730
3731static enum XML_Error PTRCALL
3732prologProcessor(XML_Parser parser,
3733 const char *s,
3734 const char *end,
3735 const char **nextPtr)
3736{
3737 const char *next = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003738 int tok = XmlPrologTok(encoding, s, end, &next);
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003739 return doProlog(parser, encoding, s, end, tok, next,
Trent Mickf08d6632006-06-19 23:21:25 +00003740 nextPtr, (XML_Bool)!ps_finalBuffer);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003741}
3742
3743static enum XML_Error
3744doProlog(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003745 const ENCODING *enc,
3746 const char *s,
3747 const char *end,
3748 int tok,
3749 const char *next,
Fred Drake31d485c2004-08-03 07:06:22 +00003750 const char **nextPtr,
3751 XML_Bool haveMore)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003752{
3753#ifdef XML_DTD
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003754 static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003755#endif /* XML_DTD */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003756 static const XML_Char atypeCDATA[] =
3757 { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
3758 static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
3759 static const XML_Char atypeIDREF[] =
3760 { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
3761 static const XML_Char atypeIDREFS[] =
3762 { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
3763 static const XML_Char atypeENTITY[] =
3764 { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
3765 static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
3766 ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003767 static const XML_Char atypeNMTOKEN[] = {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003768 ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
3769 static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
3770 ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
3771 static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
3772 ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
3773 static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
3774 static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003775
Fred Drake31d485c2004-08-03 07:06:22 +00003776 /* save one level of indirection */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003777 DTD * const dtd = _dtd;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003778
3779 const char **eventPP;
3780 const char **eventEndPP;
3781 enum XML_Content_Quant quant;
3782
3783 if (enc == encoding) {
3784 eventPP = &eventPtr;
3785 eventEndPP = &eventEndPtr;
3786 }
3787 else {
3788 eventPP = &(openInternalEntities->internalEventPtr);
3789 eventEndPP = &(openInternalEntities->internalEventEndPtr);
3790 }
Fred Drake31d485c2004-08-03 07:06:22 +00003791
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003792 for (;;) {
3793 int role;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003794 XML_Bool handleDefault = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003795 *eventPP = s;
3796 *eventEndPP = next;
3797 if (tok <= 0) {
Fred Drake31d485c2004-08-03 07:06:22 +00003798 if (haveMore && tok != XML_TOK_INVALID) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003799 *nextPtr = s;
3800 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003801 }
3802 switch (tok) {
3803 case XML_TOK_INVALID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003804 *eventPP = next;
3805 return XML_ERROR_INVALID_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003806 case XML_TOK_PARTIAL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003807 return XML_ERROR_UNCLOSED_TOKEN;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003808 case XML_TOK_PARTIAL_CHAR:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003809 return XML_ERROR_PARTIAL_CHAR;
Matthias Klose0d948ac2010-01-22 00:39:04 +00003810 case -XML_TOK_PROLOG_S:
3811 tok = -tok;
3812 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003813 case XML_TOK_NONE:
3814#ifdef XML_DTD
Fred Drake31d485c2004-08-03 07:06:22 +00003815 /* for internal PE NOT referenced between declarations */
3816 if (enc != encoding && !openInternalEntities->betweenDecl) {
3817 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003818 return XML_ERROR_NONE;
Fred Drake31d485c2004-08-03 07:06:22 +00003819 }
3820 /* WFC: PE Between Declarations - must check that PE contains
3821 complete markup, not only for external PEs, but also for
3822 internal PEs if the reference occurs between declarations.
3823 */
3824 if (isParamEntity || enc != encoding) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003825 if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3826 == XML_ROLE_ERROR)
Fred Drake31d485c2004-08-03 07:06:22 +00003827 return XML_ERROR_INCOMPLETE_PE;
3828 *nextPtr = s;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003829 return XML_ERROR_NONE;
3830 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003831#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003832 return XML_ERROR_NO_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003833 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003834 tok = -tok;
3835 next = end;
3836 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003837 }
3838 }
3839 role = XmlTokenRole(&prologState, tok, s, next, enc);
3840 switch (role) {
3841 case XML_ROLE_XML_DECL:
3842 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003843 enum XML_Error result = processXmlDecl(parser, 0, s, next);
3844 if (result != XML_ERROR_NONE)
3845 return result;
3846 enc = encoding;
3847 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003848 }
3849 break;
3850 case XML_ROLE_DOCTYPE_NAME:
3851 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003852 doctypeName = poolStoreString(&tempPool, enc, s, next);
3853 if (!doctypeName)
3854 return XML_ERROR_NO_MEMORY;
3855 poolFinish(&tempPool);
3856 doctypePubid = NULL;
3857 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003858 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003859 doctypeSysid = NULL; /* always initialize to NULL */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003860 break;
3861 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3862 if (startDoctypeDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003863 startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3864 doctypePubid, 1);
3865 doctypeName = NULL;
3866 poolClear(&tempPool);
3867 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003868 }
3869 break;
3870#ifdef XML_DTD
3871 case XML_ROLE_TEXT_DECL:
3872 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003873 enum XML_Error result = processXmlDecl(parser, 1, s, next);
3874 if (result != XML_ERROR_NONE)
3875 return result;
3876 enc = encoding;
3877 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003878 }
3879 break;
3880#endif /* XML_DTD */
3881 case XML_ROLE_DOCTYPE_PUBLIC_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003882#ifdef XML_DTD
3883 useForeignDTD = XML_FALSE;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07003884 declEntity = (ENTITY *)lookup(parser,
3885 &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003886 externalSubsetName,
3887 sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003888 if (!declEntity)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003889 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003890#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00003891 dtd->hasParamEntityRefs = XML_TRUE;
3892 if (startDoctypeDeclHandler) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003893 XML_Char *pubId;
Fred Drake31d485c2004-08-03 07:06:22 +00003894 if (!XmlIsPublicId(enc, s, next, eventPP))
3895 return XML_ERROR_PUBLICID;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003896 pubId = poolStoreString(&tempPool, enc,
3897 s + enc->minBytesPerChar,
3898 next - enc->minBytesPerChar);
3899 if (!pubId)
Fred Drake31d485c2004-08-03 07:06:22 +00003900 return XML_ERROR_NO_MEMORY;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003901 normalizePublicId(pubId);
Fred Drake31d485c2004-08-03 07:06:22 +00003902 poolFinish(&tempPool);
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003903 doctypePubid = pubId;
Fred Drake31d485c2004-08-03 07:06:22 +00003904 handleDefault = XML_FALSE;
3905 goto alreadyChecked;
3906 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003907 /* fall through */
3908 case XML_ROLE_ENTITY_PUBLIC_ID:
3909 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00003910 return XML_ERROR_PUBLICID;
3911 alreadyChecked:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003912 if (dtd->keepProcessing && declEntity) {
3913 XML_Char *tem = poolStoreString(&dtd->pool,
3914 enc,
3915 s + enc->minBytesPerChar,
3916 next - enc->minBytesPerChar);
3917 if (!tem)
3918 return XML_ERROR_NO_MEMORY;
3919 normalizePublicId(tem);
3920 declEntity->publicId = tem;
3921 poolFinish(&dtd->pool);
3922 if (entityDeclHandler)
3923 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003924 }
3925 break;
3926 case XML_ROLE_DOCTYPE_CLOSE:
3927 if (doctypeName) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003928 startDoctypeDeclHandler(handlerArg, doctypeName,
3929 doctypeSysid, doctypePubid, 0);
3930 poolClear(&tempPool);
3931 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003932 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003933 /* doctypeSysid will be non-NULL in the case of a previous
3934 XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3935 was not set, indicating an external subset
3936 */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003937#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003938 if (doctypeSysid || useForeignDTD) {
Trent Mickf08d6632006-06-19 23:21:25 +00003939 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3940 dtd->hasParamEntityRefs = XML_TRUE;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003941 if (paramEntityParsing && externalEntityRefHandler) {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07003942 ENTITY *entity = (ENTITY *)lookup(parser,
3943 &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003944 externalSubsetName,
3945 sizeof(ENTITY));
3946 if (!entity)
3947 return XML_ERROR_NO_MEMORY;
3948 if (useForeignDTD)
3949 entity->base = curBase;
3950 dtd->paramEntityRead = XML_FALSE;
3951 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3952 0,
3953 entity->base,
3954 entity->systemId,
3955 entity->publicId))
3956 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
Trent Mickf08d6632006-06-19 23:21:25 +00003957 if (dtd->paramEntityRead) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07003958 if (!dtd->standalone &&
3959 notStandaloneHandler &&
Trent Mickf08d6632006-06-19 23:21:25 +00003960 !notStandaloneHandler(handlerArg))
3961 return XML_ERROR_NOT_STANDALONE;
3962 }
3963 /* if we didn't read the foreign DTD then this means that there
3964 is no external subset and we must reset dtd->hasParamEntityRefs
3965 */
3966 else if (!doctypeSysid)
3967 dtd->hasParamEntityRefs = hadParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003968 /* end of DTD - no need to update dtd->keepProcessing */
3969 }
3970 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003971 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003972#endif /* XML_DTD */
3973 if (endDoctypeDeclHandler) {
3974 endDoctypeDeclHandler(handlerArg);
3975 handleDefault = XML_FALSE;
3976 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00003977 break;
3978 case XML_ROLE_INSTANCE_START:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003979#ifdef XML_DTD
3980 /* if there is no DOCTYPE declaration then now is the
3981 last chance to read the foreign DTD
3982 */
3983 if (useForeignDTD) {
Trent Mickf08d6632006-06-19 23:21:25 +00003984 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003985 dtd->hasParamEntityRefs = XML_TRUE;
3986 if (paramEntityParsing && externalEntityRefHandler) {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07003987 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00003988 externalSubsetName,
3989 sizeof(ENTITY));
3990 if (!entity)
3991 return XML_ERROR_NO_MEMORY;
3992 entity->base = curBase;
3993 dtd->paramEntityRead = XML_FALSE;
3994 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3995 0,
3996 entity->base,
3997 entity->systemId,
3998 entity->publicId))
3999 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
Trent Mickf08d6632006-06-19 23:21:25 +00004000 if (dtd->paramEntityRead) {
4001 if (!dtd->standalone &&
4002 notStandaloneHandler &&
4003 !notStandaloneHandler(handlerArg))
4004 return XML_ERROR_NOT_STANDALONE;
4005 }
4006 /* if we didn't read the foreign DTD then this means that there
4007 is no external subset and we must reset dtd->hasParamEntityRefs
4008 */
4009 else
4010 dtd->hasParamEntityRefs = hadParamEntityRefs;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004011 /* end of DTD - no need to update dtd->keepProcessing */
4012 }
4013 }
4014#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004015 processor = contentProcessor;
4016 return contentProcessor(parser, s, end, nextPtr);
4017 case XML_ROLE_ATTLIST_ELEMENT_NAME:
4018 declElementType = getElementType(parser, enc, s, next);
4019 if (!declElementType)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004020 return XML_ERROR_NO_MEMORY;
4021 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004022 case XML_ROLE_ATTRIBUTE_NAME:
4023 declAttributeId = getAttributeId(parser, enc, s, next);
4024 if (!declAttributeId)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004025 return XML_ERROR_NO_MEMORY;
4026 declAttributeIsCdata = XML_FALSE;
4027 declAttributeType = NULL;
4028 declAttributeIsId = XML_FALSE;
4029 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004030 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004031 declAttributeIsCdata = XML_TRUE;
4032 declAttributeType = atypeCDATA;
4033 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004034 case XML_ROLE_ATTRIBUTE_TYPE_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004035 declAttributeIsId = XML_TRUE;
4036 declAttributeType = atypeID;
4037 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004038 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004039 declAttributeType = atypeIDREF;
4040 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004041 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004042 declAttributeType = atypeIDREFS;
4043 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004044 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004045 declAttributeType = atypeENTITY;
4046 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004047 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004048 declAttributeType = atypeENTITIES;
4049 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004050 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004051 declAttributeType = atypeNMTOKEN;
4052 goto checkAttListDeclHandler;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004053 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004054 declAttributeType = atypeNMTOKENS;
4055 checkAttListDeclHandler:
4056 if (dtd->keepProcessing && attlistDeclHandler)
4057 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004058 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004059 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4060 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004061 if (dtd->keepProcessing && attlistDeclHandler) {
4062 const XML_Char *prefix;
4063 if (declAttributeType) {
4064 prefix = enumValueSep;
4065 }
4066 else {
4067 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4068 ? notationPrefix
4069 : enumValueStart);
4070 }
4071 if (!poolAppendString(&tempPool, prefix))
4072 return XML_ERROR_NO_MEMORY;
4073 if (!poolAppend(&tempPool, enc, s, next))
4074 return XML_ERROR_NO_MEMORY;
4075 declAttributeType = tempPool.start;
4076 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004077 }
4078 break;
4079 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4080 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004081 if (dtd->keepProcessing) {
4082 if (!defineAttribute(declElementType, declAttributeId,
Fred Drake08317ae2003-10-21 15:38:55 +00004083 declAttributeIsCdata, declAttributeIsId,
4084 0, parser))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004085 return XML_ERROR_NO_MEMORY;
4086 if (attlistDeclHandler && declAttributeType) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004087 if (*declAttributeType == XML_T(ASCII_LPAREN)
4088 || (*declAttributeType == XML_T(ASCII_N)
4089 && declAttributeType[1] == XML_T(ASCII_O))) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004090 /* Enumerated or Notation type */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004091 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004092 || !poolAppendChar(&tempPool, XML_T('\0')))
4093 return XML_ERROR_NO_MEMORY;
4094 declAttributeType = tempPool.start;
4095 poolFinish(&tempPool);
4096 }
4097 *eventEndPP = s;
4098 attlistDeclHandler(handlerArg, declElementType->name,
4099 declAttributeId->name, declAttributeType,
4100 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4101 poolClear(&tempPool);
4102 handleDefault = XML_FALSE;
4103 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004104 }
4105 break;
4106 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4107 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004108 if (dtd->keepProcessing) {
4109 const XML_Char *attVal;
Fred Drake08317ae2003-10-21 15:38:55 +00004110 enum XML_Error result =
4111 storeAttributeValue(parser, enc, declAttributeIsCdata,
4112 s + enc->minBytesPerChar,
4113 next - enc->minBytesPerChar,
4114 &dtd->pool);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004115 if (result)
4116 return result;
4117 attVal = poolStart(&dtd->pool);
4118 poolFinish(&dtd->pool);
4119 /* ID attributes aren't allowed to have a default */
4120 if (!defineAttribute(declElementType, declAttributeId,
4121 declAttributeIsCdata, XML_FALSE, attVal, parser))
4122 return XML_ERROR_NO_MEMORY;
4123 if (attlistDeclHandler && declAttributeType) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004124 if (*declAttributeType == XML_T(ASCII_LPAREN)
4125 || (*declAttributeType == XML_T(ASCII_N)
4126 && declAttributeType[1] == XML_T(ASCII_O))) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004127 /* Enumerated or Notation type */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004128 if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004129 || !poolAppendChar(&tempPool, XML_T('\0')))
4130 return XML_ERROR_NO_MEMORY;
4131 declAttributeType = tempPool.start;
4132 poolFinish(&tempPool);
4133 }
4134 *eventEndPP = s;
4135 attlistDeclHandler(handlerArg, declElementType->name,
4136 declAttributeId->name, declAttributeType,
4137 attVal,
4138 role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4139 poolClear(&tempPool);
4140 handleDefault = XML_FALSE;
4141 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004142 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004143 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004144 case XML_ROLE_ENTITY_VALUE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004145 if (dtd->keepProcessing) {
4146 enum XML_Error result = storeEntityValue(parser, enc,
4147 s + enc->minBytesPerChar,
4148 next - enc->minBytesPerChar);
4149 if (declEntity) {
4150 declEntity->textPtr = poolStart(&dtd->entityValuePool);
Trent Mickf08d6632006-06-19 23:21:25 +00004151 declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004152 poolFinish(&dtd->entityValuePool);
4153 if (entityDeclHandler) {
4154 *eventEndPP = s;
4155 entityDeclHandler(handlerArg,
4156 declEntity->name,
4157 declEntity->is_param,
4158 declEntity->textPtr,
4159 declEntity->textLen,
4160 curBase, 0, 0, 0);
4161 handleDefault = XML_FALSE;
4162 }
4163 }
4164 else
4165 poolDiscard(&dtd->entityValuePool);
4166 if (result != XML_ERROR_NONE)
4167 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004168 }
4169 break;
4170 case XML_ROLE_DOCTYPE_SYSTEM_ID:
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004171#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004172 useForeignDTD = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004173#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004174 dtd->hasParamEntityRefs = XML_TRUE;
4175 if (startDoctypeDeclHandler) {
4176 doctypeSysid = poolStoreString(&tempPool, enc,
4177 s + enc->minBytesPerChar,
4178 next - enc->minBytesPerChar);
4179 if (doctypeSysid == NULL)
4180 return XML_ERROR_NO_MEMORY;
4181 poolFinish(&tempPool);
4182 handleDefault = XML_FALSE;
4183 }
4184#ifdef XML_DTD
4185 else
4186 /* use externalSubsetName to make doctypeSysid non-NULL
4187 for the case where no startDoctypeDeclHandler is set */
4188 doctypeSysid = externalSubsetName;
4189#endif /* XML_DTD */
4190 if (!dtd->standalone
4191#ifdef XML_DTD
4192 && !paramEntityParsing
4193#endif /* XML_DTD */
4194 && notStandaloneHandler
4195 && !notStandaloneHandler(handlerArg))
4196 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004197#ifndef XML_DTD
4198 break;
4199#else /* XML_DTD */
4200 if (!declEntity) {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004201 declEntity = (ENTITY *)lookup(parser,
4202 &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004203 externalSubsetName,
4204 sizeof(ENTITY));
4205 if (!declEntity)
4206 return XML_ERROR_NO_MEMORY;
4207 declEntity->publicId = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004208 }
4209 /* fall through */
4210#endif /* XML_DTD */
4211 case XML_ROLE_ENTITY_SYSTEM_ID:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004212 if (dtd->keepProcessing && declEntity) {
4213 declEntity->systemId = poolStoreString(&dtd->pool, enc,
4214 s + enc->minBytesPerChar,
4215 next - enc->minBytesPerChar);
4216 if (!declEntity->systemId)
4217 return XML_ERROR_NO_MEMORY;
4218 declEntity->base = curBase;
4219 poolFinish(&dtd->pool);
4220 if (entityDeclHandler)
4221 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004222 }
4223 break;
4224 case XML_ROLE_ENTITY_COMPLETE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004225 if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4226 *eventEndPP = s;
4227 entityDeclHandler(handlerArg,
4228 declEntity->name,
4229 declEntity->is_param,
4230 0,0,
4231 declEntity->base,
4232 declEntity->systemId,
4233 declEntity->publicId,
4234 0);
4235 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004236 }
4237 break;
4238 case XML_ROLE_ENTITY_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004239 if (dtd->keepProcessing && declEntity) {
4240 declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4241 if (!declEntity->notation)
4242 return XML_ERROR_NO_MEMORY;
4243 poolFinish(&dtd->pool);
4244 if (unparsedEntityDeclHandler) {
4245 *eventEndPP = s;
4246 unparsedEntityDeclHandler(handlerArg,
4247 declEntity->name,
4248 declEntity->base,
4249 declEntity->systemId,
4250 declEntity->publicId,
4251 declEntity->notation);
4252 handleDefault = XML_FALSE;
4253 }
4254 else if (entityDeclHandler) {
4255 *eventEndPP = s;
4256 entityDeclHandler(handlerArg,
4257 declEntity->name,
4258 0,0,0,
4259 declEntity->base,
4260 declEntity->systemId,
4261 declEntity->publicId,
4262 declEntity->notation);
4263 handleDefault = XML_FALSE;
4264 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004265 }
4266 break;
4267 case XML_ROLE_GENERAL_ENTITY_NAME:
4268 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004269 if (XmlPredefinedEntityName(enc, s, next)) {
4270 declEntity = NULL;
4271 break;
4272 }
4273 if (dtd->keepProcessing) {
4274 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4275 if (!name)
4276 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004277 declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004278 sizeof(ENTITY));
4279 if (!declEntity)
4280 return XML_ERROR_NO_MEMORY;
4281 if (declEntity->name != name) {
4282 poolDiscard(&dtd->pool);
4283 declEntity = NULL;
4284 }
4285 else {
4286 poolFinish(&dtd->pool);
4287 declEntity->publicId = NULL;
4288 declEntity->is_param = XML_FALSE;
4289 /* if we have a parent parser or are reading an internal parameter
4290 entity, then the entity declaration is not considered "internal"
4291 */
4292 declEntity->is_internal = !(parentParser || openInternalEntities);
4293 if (entityDeclHandler)
4294 handleDefault = XML_FALSE;
4295 }
4296 }
4297 else {
4298 poolDiscard(&dtd->pool);
4299 declEntity = NULL;
4300 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004301 }
4302 break;
4303 case XML_ROLE_PARAM_ENTITY_NAME:
4304#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004305 if (dtd->keepProcessing) {
4306 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4307 if (!name)
4308 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004309 declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004310 name, sizeof(ENTITY));
4311 if (!declEntity)
4312 return XML_ERROR_NO_MEMORY;
4313 if (declEntity->name != name) {
4314 poolDiscard(&dtd->pool);
4315 declEntity = NULL;
4316 }
4317 else {
4318 poolFinish(&dtd->pool);
4319 declEntity->publicId = NULL;
4320 declEntity->is_param = XML_TRUE;
4321 /* if we have a parent parser or are reading an internal parameter
4322 entity, then the entity declaration is not considered "internal"
4323 */
4324 declEntity->is_internal = !(parentParser || openInternalEntities);
4325 if (entityDeclHandler)
4326 handleDefault = XML_FALSE;
4327 }
4328 }
4329 else {
4330 poolDiscard(&dtd->pool);
4331 declEntity = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004332 }
4333#else /* not XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004334 declEntity = NULL;
4335#endif /* XML_DTD */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004336 break;
4337 case XML_ROLE_NOTATION_NAME:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004338 declNotationPublicId = NULL;
4339 declNotationName = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004340 if (notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004341 declNotationName = poolStoreString(&tempPool, enc, s, next);
4342 if (!declNotationName)
4343 return XML_ERROR_NO_MEMORY;
4344 poolFinish(&tempPool);
4345 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004346 }
4347 break;
4348 case XML_ROLE_NOTATION_PUBLIC_ID:
4349 if (!XmlIsPublicId(enc, s, next, eventPP))
Fred Drake31d485c2004-08-03 07:06:22 +00004350 return XML_ERROR_PUBLICID;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004351 if (declNotationName) { /* means notationDeclHandler != NULL */
4352 XML_Char *tem = poolStoreString(&tempPool,
4353 enc,
4354 s + enc->minBytesPerChar,
4355 next - enc->minBytesPerChar);
4356 if (!tem)
4357 return XML_ERROR_NO_MEMORY;
4358 normalizePublicId(tem);
4359 declNotationPublicId = tem;
4360 poolFinish(&tempPool);
4361 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004362 }
4363 break;
4364 case XML_ROLE_NOTATION_SYSTEM_ID:
4365 if (declNotationName && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004366 const XML_Char *systemId
4367 = poolStoreString(&tempPool, enc,
4368 s + enc->minBytesPerChar,
4369 next - enc->minBytesPerChar);
4370 if (!systemId)
4371 return XML_ERROR_NO_MEMORY;
4372 *eventEndPP = s;
4373 notationDeclHandler(handlerArg,
4374 declNotationName,
4375 curBase,
4376 systemId,
4377 declNotationPublicId);
4378 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004379 }
4380 poolClear(&tempPool);
4381 break;
4382 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4383 if (declNotationPublicId && notationDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004384 *eventEndPP = s;
4385 notationDeclHandler(handlerArg,
4386 declNotationName,
4387 curBase,
4388 0,
4389 declNotationPublicId);
4390 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004391 }
4392 poolClear(&tempPool);
4393 break;
4394 case XML_ROLE_ERROR:
4395 switch (tok) {
4396 case XML_TOK_PARAM_ENTITY_REF:
Fred Drake31d485c2004-08-03 07:06:22 +00004397 /* PE references in internal subset are
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004398 not allowed within declarations. */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004399 return XML_ERROR_PARAM_ENTITY_REF;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004400 case XML_TOK_XML_DECL:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004401 return XML_ERROR_MISPLACED_XML_PI;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004402 default:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004403 return XML_ERROR_SYNTAX;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004404 }
4405#ifdef XML_DTD
4406 case XML_ROLE_IGNORE_SECT:
4407 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004408 enum XML_Error result;
4409 if (defaultHandler)
4410 reportDefault(parser, enc, s, next);
4411 handleDefault = XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00004412 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4413 if (result != XML_ERROR_NONE)
4414 return result;
4415 else if (!next) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004416 processor = ignoreSectionProcessor;
4417 return result;
4418 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004419 }
4420 break;
4421#endif /* XML_DTD */
4422 case XML_ROLE_GROUP_OPEN:
4423 if (prologState.level >= groupSize) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004424 if (groupSize) {
4425 char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4426 if (temp == NULL)
4427 return XML_ERROR_NO_MEMORY;
4428 groupConnector = temp;
4429 if (dtd->scaffIndex) {
4430 int *temp = (int *)REALLOC(dtd->scaffIndex,
4431 groupSize * sizeof(int));
4432 if (temp == NULL)
4433 return XML_ERROR_NO_MEMORY;
4434 dtd->scaffIndex = temp;
4435 }
4436 }
4437 else {
4438 groupConnector = (char *)MALLOC(groupSize = 32);
4439 if (!groupConnector)
4440 return XML_ERROR_NO_MEMORY;
4441 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004442 }
4443 groupConnector[prologState.level] = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004444 if (dtd->in_eldecl) {
4445 int myindex = nextScaffoldPart(parser);
4446 if (myindex < 0)
4447 return XML_ERROR_NO_MEMORY;
4448 dtd->scaffIndex[dtd->scaffLevel] = myindex;
4449 dtd->scaffLevel++;
4450 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4451 if (elementDeclHandler)
4452 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004453 }
4454 break;
4455 case XML_ROLE_GROUP_SEQUENCE:
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004456 if (groupConnector[prologState.level] == ASCII_PIPE)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004457 return XML_ERROR_SYNTAX;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004458 groupConnector[prologState.level] = ASCII_COMMA;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004459 if (dtd->in_eldecl && elementDeclHandler)
4460 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004461 break;
4462 case XML_ROLE_GROUP_CHOICE:
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004463 if (groupConnector[prologState.level] == ASCII_COMMA)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004464 return XML_ERROR_SYNTAX;
4465 if (dtd->in_eldecl
4466 && !groupConnector[prologState.level]
4467 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4468 != XML_CTYPE_MIXED)
4469 ) {
4470 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4471 = XML_CTYPE_CHOICE;
4472 if (elementDeclHandler)
4473 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004474 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004475 groupConnector[prologState.level] = ASCII_PIPE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004476 break;
4477 case XML_ROLE_PARAM_ENTITY_REF:
4478#ifdef XML_DTD
4479 case XML_ROLE_INNER_PARAM_ENTITY_REF:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004480 dtd->hasParamEntityRefs = XML_TRUE;
4481 if (!paramEntityParsing)
4482 dtd->keepProcessing = dtd->standalone;
4483 else {
4484 const XML_Char *name;
4485 ENTITY *entity;
4486 name = poolStoreString(&dtd->pool, enc,
4487 s + enc->minBytesPerChar,
4488 next - enc->minBytesPerChar);
4489 if (!name)
4490 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07004491 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004492 poolDiscard(&dtd->pool);
4493 /* first, determine if a check for an existing declaration is needed;
4494 if yes, check that the entity exists, and that it is internal,
4495 otherwise call the skipped entity handler
4496 */
4497 if (prologState.documentEntity &&
4498 (dtd->standalone
4499 ? !openInternalEntities
4500 : !dtd->hasParamEntityRefs)) {
4501 if (!entity)
4502 return XML_ERROR_UNDEFINED_ENTITY;
4503 else if (!entity->is_internal)
4504 return XML_ERROR_ENTITY_DECLARED_IN_PE;
4505 }
4506 else if (!entity) {
4507 dtd->keepProcessing = dtd->standalone;
4508 /* cannot report skipped entities in declarations */
4509 if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4510 skippedEntityHandler(handlerArg, name, 1);
4511 handleDefault = XML_FALSE;
4512 }
4513 break;
4514 }
4515 if (entity->open)
4516 return XML_ERROR_RECURSIVE_ENTITY_REF;
4517 if (entity->textPtr) {
4518 enum XML_Error result;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004519 XML_Bool betweenDecl =
Fred Drake31d485c2004-08-03 07:06:22 +00004520 (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4521 result = processInternalEntity(parser, entity, betweenDecl);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004522 if (result != XML_ERROR_NONE)
4523 return result;
4524 handleDefault = XML_FALSE;
4525 break;
4526 }
4527 if (externalEntityRefHandler) {
4528 dtd->paramEntityRead = XML_FALSE;
4529 entity->open = XML_TRUE;
4530 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4531 0,
4532 entity->base,
4533 entity->systemId,
4534 entity->publicId)) {
4535 entity->open = XML_FALSE;
4536 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4537 }
4538 entity->open = XML_FALSE;
4539 handleDefault = XML_FALSE;
4540 if (!dtd->paramEntityRead) {
4541 dtd->keepProcessing = dtd->standalone;
4542 break;
4543 }
4544 }
4545 else {
4546 dtd->keepProcessing = dtd->standalone;
4547 break;
4548 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004549 }
4550#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004551 if (!dtd->standalone &&
4552 notStandaloneHandler &&
4553 !notStandaloneHandler(handlerArg))
4554 return XML_ERROR_NOT_STANDALONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004555 break;
4556
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004557 /* Element declaration stuff */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004558
4559 case XML_ROLE_ELEMENT_NAME:
4560 if (elementDeclHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004561 declElementType = getElementType(parser, enc, s, next);
4562 if (!declElementType)
4563 return XML_ERROR_NO_MEMORY;
4564 dtd->scaffLevel = 0;
4565 dtd->scaffCount = 0;
4566 dtd->in_eldecl = XML_TRUE;
4567 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004568 }
4569 break;
4570
4571 case XML_ROLE_CONTENT_ANY:
4572 case XML_ROLE_CONTENT_EMPTY:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004573 if (dtd->in_eldecl) {
4574 if (elementDeclHandler) {
4575 XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4576 if (!content)
4577 return XML_ERROR_NO_MEMORY;
4578 content->quant = XML_CQUANT_NONE;
4579 content->name = NULL;
4580 content->numchildren = 0;
4581 content->children = NULL;
4582 content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4583 XML_CTYPE_ANY :
4584 XML_CTYPE_EMPTY);
4585 *eventEndPP = s;
4586 elementDeclHandler(handlerArg, declElementType->name, content);
4587 handleDefault = XML_FALSE;
4588 }
4589 dtd->in_eldecl = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004590 }
4591 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004592
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004593 case XML_ROLE_CONTENT_PCDATA:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004594 if (dtd->in_eldecl) {
4595 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4596 = XML_CTYPE_MIXED;
4597 if (elementDeclHandler)
4598 handleDefault = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004599 }
4600 break;
4601
4602 case XML_ROLE_CONTENT_ELEMENT:
4603 quant = XML_CQUANT_NONE;
4604 goto elementContent;
4605 case XML_ROLE_CONTENT_ELEMENT_OPT:
4606 quant = XML_CQUANT_OPT;
4607 goto elementContent;
4608 case XML_ROLE_CONTENT_ELEMENT_REP:
4609 quant = XML_CQUANT_REP;
4610 goto elementContent;
4611 case XML_ROLE_CONTENT_ELEMENT_PLUS:
4612 quant = XML_CQUANT_PLUS;
4613 elementContent:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004614 if (dtd->in_eldecl) {
4615 ELEMENT_TYPE *el;
4616 const XML_Char *name;
4617 int nameLen;
4618 const char *nxt = (quant == XML_CQUANT_NONE
4619 ? next
4620 : next - enc->minBytesPerChar);
4621 int myindex = nextScaffoldPart(parser);
4622 if (myindex < 0)
4623 return XML_ERROR_NO_MEMORY;
4624 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4625 dtd->scaffold[myindex].quant = quant;
4626 el = getElementType(parser, enc, s, nxt);
4627 if (!el)
4628 return XML_ERROR_NO_MEMORY;
4629 name = el->name;
4630 dtd->scaffold[myindex].name = name;
4631 nameLen = 0;
4632 for (; name[nameLen++]; );
4633 dtd->contentStringLen += nameLen;
4634 if (elementDeclHandler)
4635 handleDefault = XML_FALSE;
4636 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004637 break;
4638
4639 case XML_ROLE_GROUP_CLOSE:
4640 quant = XML_CQUANT_NONE;
4641 goto closeGroup;
4642 case XML_ROLE_GROUP_CLOSE_OPT:
4643 quant = XML_CQUANT_OPT;
4644 goto closeGroup;
4645 case XML_ROLE_GROUP_CLOSE_REP:
4646 quant = XML_CQUANT_REP;
4647 goto closeGroup;
4648 case XML_ROLE_GROUP_CLOSE_PLUS:
4649 quant = XML_CQUANT_PLUS;
4650 closeGroup:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004651 if (dtd->in_eldecl) {
4652 if (elementDeclHandler)
4653 handleDefault = XML_FALSE;
4654 dtd->scaffLevel--;
4655 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4656 if (dtd->scaffLevel == 0) {
4657 if (!handleDefault) {
4658 XML_Content *model = build_model(parser);
4659 if (!model)
4660 return XML_ERROR_NO_MEMORY;
4661 *eventEndPP = s;
4662 elementDeclHandler(handlerArg, declElementType->name, model);
4663 }
4664 dtd->in_eldecl = XML_FALSE;
4665 dtd->contentStringLen = 0;
4666 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004667 }
4668 break;
4669 /* End element declaration stuff */
4670
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004671 case XML_ROLE_PI:
4672 if (!reportProcessingInstruction(parser, enc, s, next))
4673 return XML_ERROR_NO_MEMORY;
4674 handleDefault = XML_FALSE;
4675 break;
4676 case XML_ROLE_COMMENT:
4677 if (!reportComment(parser, enc, s, next))
4678 return XML_ERROR_NO_MEMORY;
4679 handleDefault = XML_FALSE;
4680 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004681 case XML_ROLE_NONE:
4682 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004683 case XML_TOK_BOM:
4684 handleDefault = XML_FALSE;
4685 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004686 }
4687 break;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004688 case XML_ROLE_DOCTYPE_NONE:
4689 if (startDoctypeDeclHandler)
4690 handleDefault = XML_FALSE;
4691 break;
4692 case XML_ROLE_ENTITY_NONE:
4693 if (dtd->keepProcessing && entityDeclHandler)
4694 handleDefault = XML_FALSE;
4695 break;
4696 case XML_ROLE_NOTATION_NONE:
4697 if (notationDeclHandler)
4698 handleDefault = XML_FALSE;
4699 break;
4700 case XML_ROLE_ATTLIST_NONE:
4701 if (dtd->keepProcessing && attlistDeclHandler)
4702 handleDefault = XML_FALSE;
4703 break;
4704 case XML_ROLE_ELEMENT_NONE:
4705 if (elementDeclHandler)
4706 handleDefault = XML_FALSE;
4707 break;
4708 } /* end of big switch */
4709
4710 if (handleDefault && defaultHandler)
4711 reportDefault(parser, enc, s, next);
4712
Trent Mickf08d6632006-06-19 23:21:25 +00004713 switch (ps_parsing) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004714 case XML_SUSPENDED:
Fred Drake31d485c2004-08-03 07:06:22 +00004715 *nextPtr = next;
4716 return XML_ERROR_NONE;
4717 case XML_FINISHED:
4718 return XML_ERROR_ABORTED;
4719 default:
4720 s = next;
4721 tok = XmlPrologTok(enc, s, end, &next);
4722 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004723 }
4724 /* not reached */
4725}
4726
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004727static enum XML_Error PTRCALL
4728epilogProcessor(XML_Parser parser,
4729 const char *s,
4730 const char *end,
4731 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004732{
4733 processor = epilogProcessor;
4734 eventPtr = s;
4735 for (;;) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004736 const char *next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004737 int tok = XmlPrologTok(encoding, s, end, &next);
4738 eventEndPtr = next;
4739 switch (tok) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004740 /* report partial linebreak - it might be the last token */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004741 case -XML_TOK_PROLOG_S:
4742 if (defaultHandler) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004743 reportDefault(parser, encoding, s, next);
Trent Mickf08d6632006-06-19 23:21:25 +00004744 if (ps_parsing == XML_FINISHED)
Fred Drake31d485c2004-08-03 07:06:22 +00004745 return XML_ERROR_ABORTED;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004746 }
Fred Drake31d485c2004-08-03 07:06:22 +00004747 *nextPtr = next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004748 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004749 case XML_TOK_NONE:
Fred Drake31d485c2004-08-03 07:06:22 +00004750 *nextPtr = s;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004751 return XML_ERROR_NONE;
4752 case XML_TOK_PROLOG_S:
4753 if (defaultHandler)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004754 reportDefault(parser, encoding, s, next);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004755 break;
4756 case XML_TOK_PI:
4757 if (!reportProcessingInstruction(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004758 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004759 break;
4760 case XML_TOK_COMMENT:
4761 if (!reportComment(parser, encoding, s, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004762 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004763 break;
4764 case XML_TOK_INVALID:
4765 eventPtr = next;
4766 return XML_ERROR_INVALID_TOKEN;
4767 case XML_TOK_PARTIAL:
Trent Mickf08d6632006-06-19 23:21:25 +00004768 if (!ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004769 *nextPtr = s;
4770 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004771 }
4772 return XML_ERROR_UNCLOSED_TOKEN;
4773 case XML_TOK_PARTIAL_CHAR:
Trent Mickf08d6632006-06-19 23:21:25 +00004774 if (!ps_finalBuffer) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004775 *nextPtr = s;
4776 return XML_ERROR_NONE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004777 }
4778 return XML_ERROR_PARTIAL_CHAR;
4779 default:
4780 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4781 }
4782 eventPtr = s = next;
Trent Mickf08d6632006-06-19 23:21:25 +00004783 switch (ps_parsing) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004784 case XML_SUSPENDED:
Fred Drake31d485c2004-08-03 07:06:22 +00004785 *nextPtr = next;
4786 return XML_ERROR_NONE;
4787 case XML_FINISHED:
4788 return XML_ERROR_ABORTED;
4789 default: ;
4790 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004791 }
4792}
4793
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004794static enum XML_Error
Fred Drake31d485c2004-08-03 07:06:22 +00004795processInternalEntity(XML_Parser parser, ENTITY *entity,
4796 XML_Bool betweenDecl)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004797{
Fred Drake31d485c2004-08-03 07:06:22 +00004798 const char *textStart, *textEnd;
4799 const char *next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004800 enum XML_Error result;
Fred Drake31d485c2004-08-03 07:06:22 +00004801 OPEN_INTERNAL_ENTITY *openEntity;
4802
4803 if (freeInternalEntities) {
4804 openEntity = freeInternalEntities;
4805 freeInternalEntities = openEntity->next;
4806 }
4807 else {
4808 openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4809 if (!openEntity)
4810 return XML_ERROR_NO_MEMORY;
4811 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004812 entity->open = XML_TRUE;
Fred Drake31d485c2004-08-03 07:06:22 +00004813 entity->processed = 0;
4814 openEntity->next = openInternalEntities;
4815 openInternalEntities = openEntity;
4816 openEntity->entity = entity;
4817 openEntity->startTagLevel = tagLevel;
4818 openEntity->betweenDecl = betweenDecl;
4819 openEntity->internalEventPtr = NULL;
4820 openEntity->internalEventEndPtr = NULL;
4821 textStart = (char *)entity->textPtr;
4822 textEnd = (char *)(entity->textPtr + entity->textLen);
4823
4824#ifdef XML_DTD
4825 if (entity->is_param) {
4826 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004827 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
Fred Drake31d485c2004-08-03 07:06:22 +00004828 next, &next, XML_FALSE);
4829 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004830 else
Fred Drake31d485c2004-08-03 07:06:22 +00004831#endif /* XML_DTD */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004832 result = doContent(parser, tagLevel, internalEncoding, textStart,
Fred Drake31d485c2004-08-03 07:06:22 +00004833 textEnd, &next, XML_FALSE);
4834
4835 if (result == XML_ERROR_NONE) {
Trent Mickf08d6632006-06-19 23:21:25 +00004836 if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4837 entity->processed = (int)(next - textStart);
Fred Drake31d485c2004-08-03 07:06:22 +00004838 processor = internalEntityProcessor;
4839 }
4840 else {
4841 entity->open = XML_FALSE;
4842 openInternalEntities = openEntity->next;
4843 /* put openEntity back in list of free instances */
4844 openEntity->next = freeInternalEntities;
4845 freeInternalEntities = openEntity;
4846 }
4847 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004848 return result;
4849}
4850
Fred Drake31d485c2004-08-03 07:06:22 +00004851static enum XML_Error PTRCALL
4852internalEntityProcessor(XML_Parser parser,
4853 const char *s,
4854 const char *end,
4855 const char **nextPtr)
4856{
4857 ENTITY *entity;
4858 const char *textStart, *textEnd;
4859 const char *next;
4860 enum XML_Error result;
4861 OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4862 if (!openEntity)
4863 return XML_ERROR_UNEXPECTED_STATE;
4864
4865 entity = openEntity->entity;
4866 textStart = ((char *)entity->textPtr) + entity->processed;
4867 textEnd = (char *)(entity->textPtr + entity->textLen);
4868
4869#ifdef XML_DTD
4870 if (entity->is_param) {
4871 int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004872 result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
Fred Drake31d485c2004-08-03 07:06:22 +00004873 next, &next, XML_FALSE);
4874 }
4875 else
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004876#endif /* XML_DTD */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004877 result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4878 textStart, textEnd, &next, XML_FALSE);
Fred Drake31d485c2004-08-03 07:06:22 +00004879
4880 if (result != XML_ERROR_NONE)
4881 return result;
Trent Mickf08d6632006-06-19 23:21:25 +00004882 else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4883 entity->processed = (int)(next - (char *)entity->textPtr);
Fred Drake31d485c2004-08-03 07:06:22 +00004884 return result;
4885 }
4886 else {
4887 entity->open = XML_FALSE;
4888 openInternalEntities = openEntity->next;
4889 /* put openEntity back in list of free instances */
4890 openEntity->next = freeInternalEntities;
4891 freeInternalEntities = openEntity;
4892 }
4893
4894#ifdef XML_DTD
4895 if (entity->is_param) {
4896 int tok;
4897 processor = prologProcessor;
4898 tok = XmlPrologTok(encoding, s, end, &next);
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004899 return doProlog(parser, encoding, s, end, tok, next, nextPtr,
Trent Mickf08d6632006-06-19 23:21:25 +00004900 (XML_Bool)!ps_finalBuffer);
Fred Drake31d485c2004-08-03 07:06:22 +00004901 }
4902 else
4903#endif /* XML_DTD */
4904 {
4905 processor = contentProcessor;
4906 /* see externalEntityContentProcessor vs contentProcessor */
4907 return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
Gregory P. Smitha5df2902012-07-14 14:12:35 -07004908 nextPtr, (XML_Bool)!ps_finalBuffer);
4909 }
Fred Drake31d485c2004-08-03 07:06:22 +00004910}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004911
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004912static enum XML_Error PTRCALL
4913errorProcessor(XML_Parser parser,
4914 const char *s,
4915 const char *end,
4916 const char **nextPtr)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004917{
4918 return errorCode;
4919}
4920
4921static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004922storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4923 const char *ptr, const char *end,
4924 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004925{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004926 enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4927 end, pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004928 if (result)
4929 return result;
4930 if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4931 poolChop(pool);
4932 if (!poolAppendChar(pool, XML_T('\0')))
4933 return XML_ERROR_NO_MEMORY;
4934 return XML_ERROR_NONE;
4935}
4936
4937static enum XML_Error
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004938appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4939 const char *ptr, const char *end,
4940 STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004941{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004942 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004943 for (;;) {
4944 const char *next;
4945 int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4946 switch (tok) {
4947 case XML_TOK_NONE:
4948 return XML_ERROR_NONE;
4949 case XML_TOK_INVALID:
4950 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004951 eventPtr = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004952 return XML_ERROR_INVALID_TOKEN;
4953 case XML_TOK_PARTIAL:
4954 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004955 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004956 return XML_ERROR_INVALID_TOKEN;
4957 case XML_TOK_CHAR_REF:
4958 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004959 XML_Char buf[XML_ENCODE_MAX];
4960 int i;
4961 int n = XmlCharRefNumber(enc, ptr);
4962 if (n < 0) {
4963 if (enc == encoding)
4964 eventPtr = ptr;
4965 return XML_ERROR_BAD_CHAR_REF;
4966 }
4967 if (!isCdata
4968 && n == 0x20 /* space */
4969 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4970 break;
4971 n = XmlEncode(n, (ICHAR *)buf);
4972 if (!n) {
4973 if (enc == encoding)
4974 eventPtr = ptr;
4975 return XML_ERROR_BAD_CHAR_REF;
4976 }
4977 for (i = 0; i < n; i++) {
4978 if (!poolAppendChar(pool, buf[i]))
4979 return XML_ERROR_NO_MEMORY;
4980 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004981 }
4982 break;
4983 case XML_TOK_DATA_CHARS:
4984 if (!poolAppend(pool, enc, ptr, next))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004985 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004986 break;
4987 case XML_TOK_TRAILING_CR:
4988 next = ptr + enc->minBytesPerChar;
4989 /* fall through */
4990 case XML_TOK_ATTRIBUTE_VALUE_S:
4991 case XML_TOK_DATA_NEWLINE:
4992 if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004993 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004994 if (!poolAppendChar(pool, 0x20))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004995 return XML_ERROR_NO_MEMORY;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00004996 break;
4997 case XML_TOK_ENTITY_REF:
4998 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00004999 const XML_Char *name;
5000 ENTITY *entity;
5001 char checkEntityDecl;
5002 XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
5003 ptr + enc->minBytesPerChar,
5004 next - enc->minBytesPerChar);
5005 if (ch) {
5006 if (!poolAppendChar(pool, ch))
5007 return XML_ERROR_NO_MEMORY;
5008 break;
5009 }
5010 name = poolStoreString(&temp2Pool, enc,
5011 ptr + enc->minBytesPerChar,
5012 next - enc->minBytesPerChar);
5013 if (!name)
5014 return XML_ERROR_NO_MEMORY;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005015 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005016 poolDiscard(&temp2Pool);
Trent Mickf08d6632006-06-19 23:21:25 +00005017 /* First, determine if a check for an existing declaration is needed;
5018 if yes, check that the entity exists, and that it is internal.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005019 */
5020 if (pool == &dtd->pool) /* are we called from prolog? */
5021 checkEntityDecl =
5022#ifdef XML_DTD
5023 prologState.documentEntity &&
5024#endif /* XML_DTD */
5025 (dtd->standalone
5026 ? !openInternalEntities
5027 : !dtd->hasParamEntityRefs);
5028 else /* if (pool == &tempPool): we are called from content */
5029 checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
5030 if (checkEntityDecl) {
5031 if (!entity)
5032 return XML_ERROR_UNDEFINED_ENTITY;
5033 else if (!entity->is_internal)
5034 return XML_ERROR_ENTITY_DECLARED_IN_PE;
5035 }
5036 else if (!entity) {
Trent Mickf08d6632006-06-19 23:21:25 +00005037 /* Cannot report skipped entity here - see comments on
5038 skippedEntityHandler.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005039 if (skippedEntityHandler)
5040 skippedEntityHandler(handlerArg, name, 0);
5041 */
Trent Mickf08d6632006-06-19 23:21:25 +00005042 /* Cannot call the default handler because this would be
5043 out of sync with the call to the startElementHandler.
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005044 if ((pool == &tempPool) && defaultHandler)
5045 reportDefault(parser, enc, ptr, next);
Trent Mickf08d6632006-06-19 23:21:25 +00005046 */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005047 break;
5048 }
5049 if (entity->open) {
5050 if (enc == encoding)
5051 eventPtr = ptr;
5052 return XML_ERROR_RECURSIVE_ENTITY_REF;
5053 }
5054 if (entity->notation) {
5055 if (enc == encoding)
5056 eventPtr = ptr;
5057 return XML_ERROR_BINARY_ENTITY_REF;
5058 }
5059 if (!entity->textPtr) {
5060 if (enc == encoding)
5061 eventPtr = ptr;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07005062 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005063 }
5064 else {
5065 enum XML_Error result;
5066 const XML_Char *textEnd = entity->textPtr + entity->textLen;
5067 entity->open = XML_TRUE;
5068 result = appendAttributeValue(parser, internalEncoding, isCdata,
5069 (char *)entity->textPtr,
5070 (char *)textEnd, pool);
5071 entity->open = XML_FALSE;
5072 if (result)
5073 return result;
5074 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005075 }
5076 break;
5077 default:
5078 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005079 eventPtr = ptr;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005080 return XML_ERROR_UNEXPECTED_STATE;
5081 }
5082 ptr = next;
5083 }
5084 /* not reached */
5085}
5086
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005087static enum XML_Error
5088storeEntityValue(XML_Parser parser,
5089 const ENCODING *enc,
5090 const char *entityTextPtr,
5091 const char *entityTextEnd)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005092{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005093 DTD * const dtd = _dtd; /* save one level of indirection */
5094 STRING_POOL *pool = &(dtd->entityValuePool);
5095 enum XML_Error result = XML_ERROR_NONE;
5096#ifdef XML_DTD
5097 int oldInEntityValue = prologState.inEntityValue;
5098 prologState.inEntityValue = 1;
5099#endif /* XML_DTD */
5100 /* never return Null for the value argument in EntityDeclHandler,
5101 since this would indicate an external entity; therefore we
5102 have to make sure that entityValuePool.start is not null */
5103 if (!pool->blocks) {
5104 if (!poolGrow(pool))
5105 return XML_ERROR_NO_MEMORY;
5106 }
5107
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005108 for (;;) {
5109 const char *next;
5110 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5111 switch (tok) {
5112 case XML_TOK_PARAM_ENTITY_REF:
5113#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005114 if (isParamEntity || enc != encoding) {
5115 const XML_Char *name;
5116 ENTITY *entity;
5117 name = poolStoreString(&tempPool, enc,
5118 entityTextPtr + enc->minBytesPerChar,
5119 next - enc->minBytesPerChar);
5120 if (!name) {
5121 result = XML_ERROR_NO_MEMORY;
5122 goto endEntityValue;
5123 }
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005124 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005125 poolDiscard(&tempPool);
5126 if (!entity) {
5127 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5128 /* cannot report skipped entity here - see comments on
5129 skippedEntityHandler
5130 if (skippedEntityHandler)
5131 skippedEntityHandler(handlerArg, name, 0);
5132 */
5133 dtd->keepProcessing = dtd->standalone;
5134 goto endEntityValue;
5135 }
5136 if (entity->open) {
5137 if (enc == encoding)
5138 eventPtr = entityTextPtr;
5139 result = XML_ERROR_RECURSIVE_ENTITY_REF;
5140 goto endEntityValue;
5141 }
5142 if (entity->systemId) {
5143 if (externalEntityRefHandler) {
5144 dtd->paramEntityRead = XML_FALSE;
5145 entity->open = XML_TRUE;
5146 if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5147 0,
5148 entity->base,
5149 entity->systemId,
5150 entity->publicId)) {
5151 entity->open = XML_FALSE;
5152 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5153 goto endEntityValue;
5154 }
5155 entity->open = XML_FALSE;
5156 if (!dtd->paramEntityRead)
5157 dtd->keepProcessing = dtd->standalone;
5158 }
5159 else
5160 dtd->keepProcessing = dtd->standalone;
5161 }
5162 else {
5163 entity->open = XML_TRUE;
5164 result = storeEntityValue(parser,
5165 internalEncoding,
5166 (char *)entity->textPtr,
5167 (char *)(entity->textPtr
5168 + entity->textLen));
5169 entity->open = XML_FALSE;
5170 if (result)
5171 goto endEntityValue;
5172 }
5173 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005174 }
5175#endif /* XML_DTD */
Fred Drake31d485c2004-08-03 07:06:22 +00005176 /* In the internal subset, PE references are not legal
5177 within markup declarations, e.g entity values in this case. */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005178 eventPtr = entityTextPtr;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005179 result = XML_ERROR_PARAM_ENTITY_REF;
5180 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005181 case XML_TOK_NONE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005182 result = XML_ERROR_NONE;
5183 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005184 case XML_TOK_ENTITY_REF:
5185 case XML_TOK_DATA_CHARS:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005186 if (!poolAppend(pool, enc, entityTextPtr, next)) {
5187 result = XML_ERROR_NO_MEMORY;
5188 goto endEntityValue;
5189 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005190 break;
5191 case XML_TOK_TRAILING_CR:
5192 next = entityTextPtr + enc->minBytesPerChar;
5193 /* fall through */
5194 case XML_TOK_DATA_NEWLINE:
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005195 if (pool->end == pool->ptr && !poolGrow(pool)) {
5196 result = XML_ERROR_NO_MEMORY;
5197 goto endEntityValue;
5198 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005199 *(pool->ptr)++ = 0xA;
5200 break;
5201 case XML_TOK_CHAR_REF:
5202 {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005203 XML_Char buf[XML_ENCODE_MAX];
5204 int i;
5205 int n = XmlCharRefNumber(enc, entityTextPtr);
5206 if (n < 0) {
5207 if (enc == encoding)
5208 eventPtr = entityTextPtr;
5209 result = XML_ERROR_BAD_CHAR_REF;
5210 goto endEntityValue;
5211 }
5212 n = XmlEncode(n, (ICHAR *)buf);
5213 if (!n) {
5214 if (enc == encoding)
5215 eventPtr = entityTextPtr;
5216 result = XML_ERROR_BAD_CHAR_REF;
5217 goto endEntityValue;
5218 }
5219 for (i = 0; i < n; i++) {
5220 if (pool->end == pool->ptr && !poolGrow(pool)) {
5221 result = XML_ERROR_NO_MEMORY;
5222 goto endEntityValue;
5223 }
5224 *(pool->ptr)++ = buf[i];
5225 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005226 }
5227 break;
5228 case XML_TOK_PARTIAL:
5229 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005230 eventPtr = entityTextPtr;
5231 result = XML_ERROR_INVALID_TOKEN;
5232 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005233 case XML_TOK_INVALID:
5234 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005235 eventPtr = next;
5236 result = XML_ERROR_INVALID_TOKEN;
5237 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005238 default:
5239 if (enc == encoding)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005240 eventPtr = entityTextPtr;
5241 result = XML_ERROR_UNEXPECTED_STATE;
5242 goto endEntityValue;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005243 }
5244 entityTextPtr = next;
5245 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005246endEntityValue:
5247#ifdef XML_DTD
5248 prologState.inEntityValue = oldInEntityValue;
5249#endif /* XML_DTD */
5250 return result;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005251}
5252
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005253static void FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005254normalizeLines(XML_Char *s)
5255{
5256 XML_Char *p;
5257 for (;; s++) {
5258 if (*s == XML_T('\0'))
5259 return;
5260 if (*s == 0xD)
5261 break;
5262 }
5263 p = s;
5264 do {
5265 if (*s == 0xD) {
5266 *p++ = 0xA;
5267 if (*++s == 0xA)
5268 s++;
5269 }
5270 else
5271 *p++ = *s++;
5272 } while (*s);
5273 *p = XML_T('\0');
5274}
5275
5276static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005277reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5278 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005279{
5280 const XML_Char *target;
5281 XML_Char *data;
5282 const char *tem;
5283 if (!processingInstructionHandler) {
5284 if (defaultHandler)
5285 reportDefault(parser, enc, start, end);
5286 return 1;
5287 }
5288 start += enc->minBytesPerChar * 2;
5289 tem = start + XmlNameLength(enc, start);
5290 target = poolStoreString(&tempPool, enc, start, tem);
5291 if (!target)
5292 return 0;
5293 poolFinish(&tempPool);
5294 data = poolStoreString(&tempPool, enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005295 XmlSkipS(enc, tem),
5296 end - enc->minBytesPerChar*2);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005297 if (!data)
5298 return 0;
5299 normalizeLines(data);
5300 processingInstructionHandler(handlerArg, target, data);
5301 poolClear(&tempPool);
5302 return 1;
5303}
5304
5305static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005306reportComment(XML_Parser parser, const ENCODING *enc,
5307 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005308{
5309 XML_Char *data;
5310 if (!commentHandler) {
5311 if (defaultHandler)
5312 reportDefault(parser, enc, start, end);
5313 return 1;
5314 }
5315 data = poolStoreString(&tempPool,
5316 enc,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005317 start + enc->minBytesPerChar * 4,
5318 end - enc->minBytesPerChar * 3);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005319 if (!data)
5320 return 0;
5321 normalizeLines(data);
5322 commentHandler(handlerArg, data);
5323 poolClear(&tempPool);
5324 return 1;
5325}
5326
5327static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005328reportDefault(XML_Parser parser, const ENCODING *enc,
5329 const char *s, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005330{
5331 if (MUST_CONVERT(enc, s)) {
5332 const char **eventPP;
5333 const char **eventEndPP;
5334 if (enc == encoding) {
5335 eventPP = &eventPtr;
5336 eventEndPP = &eventEndPtr;
5337 }
5338 else {
5339 eventPP = &(openInternalEntities->internalEventPtr);
5340 eventEndPP = &(openInternalEntities->internalEventEndPtr);
5341 }
5342 do {
5343 ICHAR *dataPtr = (ICHAR *)dataBuf;
5344 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5345 *eventEndPP = s;
Trent Mickf08d6632006-06-19 23:21:25 +00005346 defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005347 *eventPP = s;
5348 } while (s != end);
5349 }
5350 else
Trent Mickf08d6632006-06-19 23:21:25 +00005351 defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005352}
5353
5354
5355static int
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005356defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5357 XML_Bool isId, const XML_Char *value, XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005358{
5359 DEFAULT_ATTRIBUTE *att;
5360 if (value || isId) {
5361 /* The handling of default attributes gets messed up if we have
5362 a default which duplicates a non-default. */
5363 int i;
5364 for (i = 0; i < type->nDefaultAtts; i++)
5365 if (attId == type->defaultAtts[i].id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005366 return 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005367 if (isId && !type->idAtt && !attId->xmlns)
5368 type->idAtt = attId;
5369 }
5370 if (type->nDefaultAtts == type->allocDefaultAtts) {
5371 if (type->allocDefaultAtts == 0) {
5372 type->allocDefaultAtts = 8;
Fred Drake08317ae2003-10-21 15:38:55 +00005373 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005374 * sizeof(DEFAULT_ATTRIBUTE));
5375 if (!type->defaultAtts)
5376 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005377 }
5378 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005379 DEFAULT_ATTRIBUTE *temp;
5380 int count = type->allocDefaultAtts * 2;
5381 temp = (DEFAULT_ATTRIBUTE *)
5382 REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5383 if (temp == NULL)
5384 return 0;
5385 type->allocDefaultAtts = count;
5386 type->defaultAtts = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005387 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005388 }
5389 att = type->defaultAtts + type->nDefaultAtts;
5390 att->id = attId;
5391 att->value = value;
5392 att->isCdata = isCdata;
5393 if (!isCdata)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005394 attId->maybeTokenized = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005395 type->nDefaultAtts += 1;
5396 return 1;
5397}
5398
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005399static int
5400setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005401{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005402 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005403 const XML_Char *name;
5404 for (name = elementType->name; *name; name++) {
Gregory P. Smitha5df2902012-07-14 14:12:35 -07005405 if (*name == XML_T(ASCII_COLON)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005406 PREFIX *prefix;
5407 const XML_Char *s;
5408 for (s = elementType->name; s != name; s++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005409 if (!poolAppendChar(&dtd->pool, *s))
5410 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005411 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005412 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5413 return 0;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005414 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005415 sizeof(PREFIX));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005416 if (!prefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005417 return 0;
5418 if (prefix->name == poolStart(&dtd->pool))
5419 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005420 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005421 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005422 elementType->prefix = prefix;
5423
5424 }
5425 }
5426 return 1;
5427}
5428
5429static ATTRIBUTE_ID *
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005430getAttributeId(XML_Parser parser, const ENCODING *enc,
5431 const char *start, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005432{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005433 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005434 ATTRIBUTE_ID *id;
5435 const XML_Char *name;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005436 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5437 return NULL;
5438 name = poolStoreString(&dtd->pool, enc, start, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005439 if (!name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005440 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005441 /* skip quotation mark - its storage will be re-used (like in name[-1]) */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005442 ++name;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005443 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005444 if (!id)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005445 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005446 if (id->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005447 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005448 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005449 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005450 if (!ns)
5451 ;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07005452 else if (name[0] == XML_T(ASCII_x)
5453 && name[1] == XML_T(ASCII_m)
5454 && name[2] == XML_T(ASCII_l)
5455 && name[3] == XML_T(ASCII_n)
5456 && name[4] == XML_T(ASCII_s)
5457 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005458 if (name[5] == XML_T('\0'))
5459 id->prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005460 else
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005461 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005462 id->xmlns = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005463 }
5464 else {
5465 int i;
5466 for (i = 0; name[i]; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00005467 /* attributes without prefix are *not* in the default namespace */
Gregory P. Smitha5df2902012-07-14 14:12:35 -07005468 if (name[i] == XML_T(ASCII_COLON)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005469 int j;
5470 for (j = 0; j < i; j++) {
5471 if (!poolAppendChar(&dtd->pool, name[j]))
5472 return NULL;
5473 }
5474 if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5475 return NULL;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005476 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005477 sizeof(PREFIX));
5478 if (id->prefix->name == poolStart(&dtd->pool))
5479 poolFinish(&dtd->pool);
5480 else
5481 poolDiscard(&dtd->pool);
5482 break;
5483 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005484 }
5485 }
5486 }
5487 return id;
5488}
5489
Gregory P. Smitha5df2902012-07-14 14:12:35 -07005490#define CONTEXT_SEP XML_T(ASCII_FF)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005491
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005492static const XML_Char *
5493getContext(XML_Parser parser)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005494{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005495 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005496 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005497 XML_Bool needSep = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005498
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005499 if (dtd->defaultPrefix.binding) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005500 int i;
5501 int len;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07005502 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005503 return NULL;
5504 len = dtd->defaultPrefix.binding->uriLen;
Trent Mickf08d6632006-06-19 23:21:25 +00005505 if (namespaceSeparator)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005506 len--;
5507 for (i = 0; i < len; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005508 if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5509 return NULL;
5510 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005511 }
5512
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005513 hashTableIterInit(&iter, &(dtd->prefixes));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005514 for (;;) {
5515 int i;
5516 int len;
5517 const XML_Char *s;
5518 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5519 if (!prefix)
5520 break;
5521 if (!prefix->binding)
5522 continue;
5523 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005524 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005525 for (s = prefix->name; *s; s++)
5526 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005527 return NULL;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07005528 if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005529 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005530 len = prefix->binding->uriLen;
Trent Mickf08d6632006-06-19 23:21:25 +00005531 if (namespaceSeparator)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005532 len--;
5533 for (i = 0; i < len; i++)
5534 if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005535 return NULL;
5536 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005537 }
5538
5539
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005540 hashTableIterInit(&iter, &(dtd->generalEntities));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005541 for (;;) {
5542 const XML_Char *s;
5543 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5544 if (!e)
5545 break;
5546 if (!e->open)
5547 continue;
5548 if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005549 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005550 for (s = e->name; *s; s++)
5551 if (!poolAppendChar(&tempPool, *s))
5552 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005553 needSep = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005554 }
5555
5556 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005557 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005558 return tempPool.start;
5559}
5560
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005561static XML_Bool
5562setContext(XML_Parser parser, const XML_Char *context)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005563{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005564 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005565 const XML_Char *s = context;
5566
5567 while (*context != XML_T('\0')) {
5568 if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5569 ENTITY *e;
5570 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005571 return XML_FALSE;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005572 e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005573 if (e)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005574 e->open = XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005575 if (*s != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005576 s++;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005577 context = s;
5578 poolDiscard(&tempPool);
5579 }
Gregory P. Smitha5df2902012-07-14 14:12:35 -07005580 else if (*s == XML_T(ASCII_EQUALS)) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005581 PREFIX *prefix;
5582 if (poolLength(&tempPool) == 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005583 prefix = &dtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005584 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005585 if (!poolAppendChar(&tempPool, XML_T('\0')))
5586 return XML_FALSE;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005587 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005588 sizeof(PREFIX));
5589 if (!prefix)
5590 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005591 if (prefix->name == poolStart(&tempPool)) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005592 prefix->name = poolCopyString(&dtd->pool, prefix->name);
5593 if (!prefix->name)
5594 return XML_FALSE;
5595 }
5596 poolDiscard(&tempPool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005597 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005598 for (context = s + 1;
5599 *context != CONTEXT_SEP && *context != XML_T('\0');
5600 context++)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005601 if (!poolAppendChar(&tempPool, *context))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005602 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005603 if (!poolAppendChar(&tempPool, XML_T('\0')))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005604 return XML_FALSE;
Fred Drake31d485c2004-08-03 07:06:22 +00005605 if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005606 &inheritedBindings) != XML_ERROR_NONE)
5607 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005608 poolDiscard(&tempPool);
5609 if (*context != XML_T('\0'))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005610 ++context;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005611 s = context;
5612 }
5613 else {
5614 if (!poolAppendChar(&tempPool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005615 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005616 s++;
5617 }
5618 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005619 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005620}
5621
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005622static void FASTCALL
5623normalizePublicId(XML_Char *publicId)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005624{
5625 XML_Char *p = publicId;
5626 XML_Char *s;
5627 for (s = publicId; *s; s++) {
5628 switch (*s) {
5629 case 0x20:
5630 case 0xD:
5631 case 0xA:
5632 if (p != publicId && p[-1] != 0x20)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005633 *p++ = 0x20;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005634 break;
5635 default:
5636 *p++ = *s;
5637 }
5638 }
5639 if (p != publicId && p[-1] == 0x20)
5640 --p;
5641 *p = XML_T('\0');
5642}
5643
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005644static DTD *
5645dtdCreate(const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005646{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005647 DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5648 if (p == NULL)
5649 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005650 poolInit(&(p->pool), ms);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005651 poolInit(&(p->entityValuePool), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005652 hashTableInit(&(p->generalEntities), ms);
5653 hashTableInit(&(p->elementTypes), ms);
5654 hashTableInit(&(p->attributeIds), ms);
5655 hashTableInit(&(p->prefixes), ms);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005656#ifdef XML_DTD
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005657 p->paramEntityRead = XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005658 hashTableInit(&(p->paramEntities), ms);
5659#endif /* XML_DTD */
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005660 p->defaultPrefix.name = NULL;
5661 p->defaultPrefix.binding = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005662
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005663 p->in_eldecl = XML_FALSE;
5664 p->scaffIndex = NULL;
5665 p->scaffold = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005666 p->scaffLevel = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005667 p->scaffSize = 0;
5668 p->scaffCount = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005669 p->contentStringLen = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005670
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005671 p->keepProcessing = XML_TRUE;
5672 p->hasParamEntityRefs = XML_FALSE;
5673 p->standalone = XML_FALSE;
5674 return p;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005675}
5676
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005677static void
5678dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005679{
5680 HASH_TABLE_ITER iter;
5681 hashTableIterInit(&iter, &(p->elementTypes));
5682 for (;;) {
5683 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5684 if (!e)
5685 break;
5686 if (e->allocDefaultAtts != 0)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005687 ms->free_fcn(e->defaultAtts);
5688 }
5689 hashTableClear(&(p->generalEntities));
5690#ifdef XML_DTD
5691 p->paramEntityRead = XML_FALSE;
5692 hashTableClear(&(p->paramEntities));
5693#endif /* XML_DTD */
5694 hashTableClear(&(p->elementTypes));
5695 hashTableClear(&(p->attributeIds));
5696 hashTableClear(&(p->prefixes));
5697 poolClear(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005698 poolClear(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005699 p->defaultPrefix.name = NULL;
5700 p->defaultPrefix.binding = NULL;
5701
5702 p->in_eldecl = XML_FALSE;
Fred Drake08317ae2003-10-21 15:38:55 +00005703
5704 ms->free_fcn(p->scaffIndex);
5705 p->scaffIndex = NULL;
5706 ms->free_fcn(p->scaffold);
5707 p->scaffold = NULL;
5708
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005709 p->scaffLevel = 0;
5710 p->scaffSize = 0;
5711 p->scaffCount = 0;
5712 p->contentStringLen = 0;
5713
5714 p->keepProcessing = XML_TRUE;
5715 p->hasParamEntityRefs = XML_FALSE;
5716 p->standalone = XML_FALSE;
5717}
5718
5719static void
5720dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5721{
5722 HASH_TABLE_ITER iter;
5723 hashTableIterInit(&iter, &(p->elementTypes));
5724 for (;;) {
5725 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5726 if (!e)
5727 break;
5728 if (e->allocDefaultAtts != 0)
5729 ms->free_fcn(e->defaultAtts);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005730 }
5731 hashTableDestroy(&(p->generalEntities));
5732#ifdef XML_DTD
5733 hashTableDestroy(&(p->paramEntities));
5734#endif /* XML_DTD */
5735 hashTableDestroy(&(p->elementTypes));
5736 hashTableDestroy(&(p->attributeIds));
5737 hashTableDestroy(&(p->prefixes));
5738 poolDestroy(&(p->pool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005739 poolDestroy(&(p->entityValuePool));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005740 if (isDocEntity) {
Fred Drake08317ae2003-10-21 15:38:55 +00005741 ms->free_fcn(p->scaffIndex);
5742 ms->free_fcn(p->scaffold);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005743 }
5744 ms->free_fcn(p);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005745}
5746
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005747/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5748 The new DTD has already been initialized.
5749*/
5750static int
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005751dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005752{
5753 HASH_TABLE_ITER iter;
5754
5755 /* Copy the prefix table. */
5756
5757 hashTableIterInit(&iter, &(oldDtd->prefixes));
5758 for (;;) {
5759 const XML_Char *name;
5760 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5761 if (!oldP)
5762 break;
5763 name = poolCopyString(&(newDtd->pool), oldP->name);
5764 if (!name)
5765 return 0;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005766 if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005767 return 0;
5768 }
5769
5770 hashTableIterInit(&iter, &(oldDtd->attributeIds));
5771
5772 /* Copy the attribute id table. */
5773
5774 for (;;) {
5775 ATTRIBUTE_ID *newA;
5776 const XML_Char *name;
5777 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5778
5779 if (!oldA)
5780 break;
5781 /* Remember to allocate the scratch byte before the name. */
5782 if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5783 return 0;
5784 name = poolCopyString(&(newDtd->pool), oldA->name);
5785 if (!name)
5786 return 0;
5787 ++name;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005788 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005789 sizeof(ATTRIBUTE_ID));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005790 if (!newA)
5791 return 0;
5792 newA->maybeTokenized = oldA->maybeTokenized;
5793 if (oldA->prefix) {
5794 newA->xmlns = oldA->xmlns;
5795 if (oldA->prefix == &oldDtd->defaultPrefix)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005796 newA->prefix = &newDtd->defaultPrefix;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005797 else
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005798 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005799 oldA->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005800 }
5801 }
5802
5803 /* Copy the element type table. */
5804
5805 hashTableIterInit(&iter, &(oldDtd->elementTypes));
5806
5807 for (;;) {
5808 int i;
5809 ELEMENT_TYPE *newE;
5810 const XML_Char *name;
5811 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5812 if (!oldE)
5813 break;
5814 name = poolCopyString(&(newDtd->pool), oldE->name);
5815 if (!name)
5816 return 0;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005817 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005818 sizeof(ELEMENT_TYPE));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005819 if (!newE)
5820 return 0;
5821 if (oldE->nDefaultAtts) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005822 newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5823 ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5824 if (!newE->defaultAtts) {
5825 ms->free_fcn(newE);
5826 return 0;
5827 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005828 }
5829 if (oldE->idAtt)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005830 newE->idAtt = (ATTRIBUTE_ID *)
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005831 lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005832 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5833 if (oldE->prefix)
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005834 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005835 oldE->prefix->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005836 for (i = 0; i < newE->nDefaultAtts; i++) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005837 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005838 lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005839 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5840 if (oldE->defaultAtts[i].value) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005841 newE->defaultAtts[i].value
5842 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5843 if (!newE->defaultAtts[i].value)
5844 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005845 }
5846 else
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005847 newE->defaultAtts[i].value = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005848 }
5849 }
5850
5851 /* Copy the entity tables. */
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005852 if (!copyEntityTable(oldParser,
5853 &(newDtd->generalEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005854 &(newDtd->pool),
5855 &(oldDtd->generalEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005856 return 0;
5857
5858#ifdef XML_DTD
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005859 if (!copyEntityTable(oldParser,
5860 &(newDtd->paramEntities),
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005861 &(newDtd->pool),
5862 &(oldDtd->paramEntities)))
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005863 return 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005864 newDtd->paramEntityRead = oldDtd->paramEntityRead;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005865#endif /* XML_DTD */
5866
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005867 newDtd->keepProcessing = oldDtd->keepProcessing;
5868 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005869 newDtd->standalone = oldDtd->standalone;
5870
5871 /* Don't want deep copying for scaffolding */
5872 newDtd->in_eldecl = oldDtd->in_eldecl;
5873 newDtd->scaffold = oldDtd->scaffold;
5874 newDtd->contentStringLen = oldDtd->contentStringLen;
5875 newDtd->scaffSize = oldDtd->scaffSize;
5876 newDtd->scaffLevel = oldDtd->scaffLevel;
5877 newDtd->scaffIndex = oldDtd->scaffIndex;
5878
5879 return 1;
5880} /* End dtdCopy */
5881
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005882static int
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005883copyEntityTable(XML_Parser oldParser,
5884 HASH_TABLE *newTable,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005885 STRING_POOL *newPool,
5886 const HASH_TABLE *oldTable)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005887{
5888 HASH_TABLE_ITER iter;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005889 const XML_Char *cachedOldBase = NULL;
5890 const XML_Char *cachedNewBase = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005891
5892 hashTableIterInit(&iter, oldTable);
5893
5894 for (;;) {
5895 ENTITY *newE;
5896 const XML_Char *name;
5897 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5898 if (!oldE)
5899 break;
5900 name = poolCopyString(newPool, oldE->name);
5901 if (!name)
5902 return 0;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005903 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005904 if (!newE)
5905 return 0;
5906 if (oldE->systemId) {
5907 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5908 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005909 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005910 newE->systemId = tem;
5911 if (oldE->base) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005912 if (oldE->base == cachedOldBase)
5913 newE->base = cachedNewBase;
5914 else {
5915 cachedOldBase = oldE->base;
5916 tem = poolCopyString(newPool, cachedOldBase);
5917 if (!tem)
5918 return 0;
5919 cachedNewBase = newE->base = tem;
5920 }
5921 }
5922 if (oldE->publicId) {
5923 tem = poolCopyString(newPool, oldE->publicId);
5924 if (!tem)
5925 return 0;
5926 newE->publicId = tem;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005927 }
5928 }
5929 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005930 const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5931 oldE->textLen);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005932 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005933 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005934 newE->textPtr = tem;
5935 newE->textLen = oldE->textLen;
5936 }
5937 if (oldE->notation) {
5938 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5939 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005940 return 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005941 newE->notation = tem;
5942 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005943 newE->is_param = oldE->is_param;
5944 newE->is_internal = oldE->is_internal;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005945 }
5946 return 1;
5947}
5948
Fred Drake08317ae2003-10-21 15:38:55 +00005949#define INIT_POWER 6
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005950
Fred Drake08317ae2003-10-21 15:38:55 +00005951static XML_Bool FASTCALL
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005952keyeq(KEY s1, KEY s2)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005953{
5954 for (; *s1 == *s2; s1++, s2++)
5955 if (*s1 == 0)
Fred Drake08317ae2003-10-21 15:38:55 +00005956 return XML_TRUE;
5957 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005958}
5959
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005960static unsigned long FASTCALL
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005961hash(XML_Parser parser, KEY s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005962{
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005963 unsigned long h = hash_secret_salt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005964 while (*s)
Fred Drake08317ae2003-10-21 15:38:55 +00005965 h = CHAR_HASH(h, *s++);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005966 return h;
5967}
5968
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005969static NAMED *
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005970lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005971{
5972 size_t i;
5973 if (table->size == 0) {
5974 size_t tsize;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005975 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005976 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00005977 table->power = INIT_POWER;
5978 /* table->size is a power of 2 */
5979 table->size = (size_t)1 << INIT_POWER;
5980 tsize = table->size * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005981 table->v = (NAMED **)table->mem->malloc_fcn(tsize);
Fred Drake31d485c2004-08-03 07:06:22 +00005982 if (!table->v) {
5983 table->size = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005984 return NULL;
Fred Drake31d485c2004-08-03 07:06:22 +00005985 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005986 memset(table->v, 0, tsize);
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005987 i = hash(parser, name) & ((unsigned long)table->size - 1);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005988 }
5989 else {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07005990 unsigned long h = hash(parser, name);
Fred Drake08317ae2003-10-21 15:38:55 +00005991 unsigned long mask = (unsigned long)table->size - 1;
5992 unsigned char step = 0;
5993 i = h & mask;
5994 while (table->v[i]) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00005995 if (keyeq(name, table->v[i]->name))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00005996 return table->v[i];
Fred Drake08317ae2003-10-21 15:38:55 +00005997 if (!step)
5998 step = PROBE_STEP(h, mask, table->power);
5999 i < step ? (i += table->size - step) : (i -= step);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006000 }
6001 if (!createSize)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006002 return NULL;
Fred Drake08317ae2003-10-21 15:38:55 +00006003
6004 /* check for overflow (table is half full) */
6005 if (table->used >> (table->power - 1)) {
6006 unsigned char newPower = table->power + 1;
6007 size_t newSize = (size_t)1 << newPower;
6008 unsigned long newMask = (unsigned long)newSize - 1;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006009 size_t tsize = newSize * sizeof(NAMED *);
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006010 NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006011 if (!newV)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006012 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006013 memset(newV, 0, tsize);
6014 for (i = 0; i < table->size; i++)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006015 if (table->v[i]) {
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07006016 unsigned long newHash = hash(parser, table->v[i]->name);
Fred Drake08317ae2003-10-21 15:38:55 +00006017 size_t j = newHash & newMask;
6018 step = 0;
6019 while (newV[j]) {
6020 if (!step)
6021 step = PROBE_STEP(newHash, newMask, newPower);
6022 j < step ? (j += newSize - step) : (j -= step);
6023 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006024 newV[j] = table->v[i];
6025 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006026 table->mem->free_fcn(table->v);
6027 table->v = newV;
Fred Drake08317ae2003-10-21 15:38:55 +00006028 table->power = newPower;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006029 table->size = newSize;
Fred Drake08317ae2003-10-21 15:38:55 +00006030 i = h & newMask;
6031 step = 0;
6032 while (table->v[i]) {
6033 if (!step)
6034 step = PROBE_STEP(h, newMask, newPower);
6035 i < step ? (i += newSize - step) : (i -= step);
6036 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006037 }
6038 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006039 table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006040 if (!table->v[i])
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006041 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006042 memset(table->v[i], 0, createSize);
6043 table->v[i]->name = name;
6044 (table->used)++;
6045 return table->v[i];
6046}
6047
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006048static void FASTCALL
6049hashTableClear(HASH_TABLE *table)
6050{
6051 size_t i;
6052 for (i = 0; i < table->size; i++) {
Fred Drake08317ae2003-10-21 15:38:55 +00006053 table->mem->free_fcn(table->v[i]);
6054 table->v[i] = NULL;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006055 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006056 table->used = 0;
6057}
6058
6059static void FASTCALL
6060hashTableDestroy(HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006061{
6062 size_t i;
Fred Drake08317ae2003-10-21 15:38:55 +00006063 for (i = 0; i < table->size; i++)
6064 table->mem->free_fcn(table->v[i]);
6065 table->mem->free_fcn(table->v);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006066}
6067
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006068static void FASTCALL
6069hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006070{
Fred Drake08317ae2003-10-21 15:38:55 +00006071 p->power = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006072 p->size = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006073 p->used = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006074 p->v = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006075 p->mem = ms;
6076}
6077
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006078static void FASTCALL
6079hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006080{
6081 iter->p = table->v;
6082 iter->end = iter->p + table->size;
6083}
6084
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006085static NAMED * FASTCALL
6086hashTableIterNext(HASH_TABLE_ITER *iter)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006087{
6088 while (iter->p != iter->end) {
6089 NAMED *tem = *(iter->p)++;
6090 if (tem)
6091 return tem;
6092 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006093 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006094}
6095
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006096static void FASTCALL
6097poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006098{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006099 pool->blocks = NULL;
6100 pool->freeBlocks = NULL;
6101 pool->start = NULL;
6102 pool->ptr = NULL;
6103 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006104 pool->mem = ms;
6105}
6106
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006107static void FASTCALL
6108poolClear(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006109{
6110 if (!pool->freeBlocks)
6111 pool->freeBlocks = pool->blocks;
6112 else {
6113 BLOCK *p = pool->blocks;
6114 while (p) {
6115 BLOCK *tem = p->next;
6116 p->next = pool->freeBlocks;
6117 pool->freeBlocks = p;
6118 p = tem;
6119 }
6120 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006121 pool->blocks = NULL;
6122 pool->start = NULL;
6123 pool->ptr = NULL;
6124 pool->end = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006125}
6126
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006127static void FASTCALL
6128poolDestroy(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006129{
6130 BLOCK *p = pool->blocks;
6131 while (p) {
6132 BLOCK *tem = p->next;
6133 pool->mem->free_fcn(p);
6134 p = tem;
6135 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006136 p = pool->freeBlocks;
6137 while (p) {
6138 BLOCK *tem = p->next;
6139 pool->mem->free_fcn(p);
6140 p = tem;
6141 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006142}
6143
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006144static XML_Char *
6145poolAppend(STRING_POOL *pool, const ENCODING *enc,
6146 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006147{
6148 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006149 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006150 for (;;) {
6151 XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6152 if (ptr == end)
6153 break;
6154 if (!poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006155 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006156 }
6157 return pool->start;
6158}
6159
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006160static const XML_Char * FASTCALL
6161poolCopyString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006162{
6163 do {
6164 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006165 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006166 } while (*s++);
6167 s = pool->start;
6168 poolFinish(pool);
6169 return s;
6170}
6171
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006172static const XML_Char *
6173poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006174{
6175 if (!pool->ptr && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006176 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006177 for (; n > 0; --n, s++) {
6178 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006179 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006180 }
6181 s = pool->start;
6182 poolFinish(pool);
6183 return s;
6184}
6185
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006186static const XML_Char * FASTCALL
6187poolAppendString(STRING_POOL *pool, const XML_Char *s)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006188{
6189 while (*s) {
6190 if (!poolAppendChar(pool, *s))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006191 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006192 s++;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006193 }
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006194 return pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006195}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006196
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006197static XML_Char *
6198poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6199 const char *ptr, const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006200{
6201 if (!poolAppend(pool, enc, ptr, end))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006202 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006203 if (pool->ptr == pool->end && !poolGrow(pool))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006204 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006205 *(pool->ptr)++ = 0;
6206 return pool->start;
6207}
6208
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006209static XML_Bool FASTCALL
6210poolGrow(STRING_POOL *pool)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006211{
6212 if (pool->freeBlocks) {
6213 if (pool->start == 0) {
6214 pool->blocks = pool->freeBlocks;
6215 pool->freeBlocks = pool->freeBlocks->next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006216 pool->blocks->next = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006217 pool->start = pool->blocks->s;
6218 pool->end = pool->start + pool->blocks->size;
6219 pool->ptr = pool->start;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006220 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006221 }
6222 if (pool->end - pool->start < pool->freeBlocks->size) {
6223 BLOCK *tem = pool->freeBlocks->next;
6224 pool->freeBlocks->next = pool->blocks;
6225 pool->blocks = pool->freeBlocks;
6226 pool->freeBlocks = tem;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006227 memcpy(pool->blocks->s, pool->start,
6228 (pool->end - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006229 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6230 pool->start = pool->blocks->s;
6231 pool->end = pool->start + pool->blocks->size;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006232 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006233 }
6234 }
6235 if (pool->blocks && pool->start == pool->blocks->s) {
Trent Mickf08d6632006-06-19 23:21:25 +00006236 int blockSize = (int)(pool->end - pool->start)*2;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07006237 BLOCK *temp = (BLOCK *)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006238 pool->mem->realloc_fcn(pool->blocks,
Fred Drake08317ae2003-10-21 15:38:55 +00006239 (offsetof(BLOCK, s)
6240 + blockSize * sizeof(XML_Char)));
Gregory P. Smitha5df2902012-07-14 14:12:35 -07006241 if (temp == NULL)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006242 return XML_FALSE;
Gregory P. Smitha5df2902012-07-14 14:12:35 -07006243 pool->blocks = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006244 pool->blocks->size = blockSize;
6245 pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6246 pool->start = pool->blocks->s;
6247 pool->end = pool->start + blockSize;
6248 }
6249 else {
6250 BLOCK *tem;
Trent Mickf08d6632006-06-19 23:21:25 +00006251 int blockSize = (int)(pool->end - pool->start);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006252 if (blockSize < INIT_BLOCK_SIZE)
6253 blockSize = INIT_BLOCK_SIZE;
6254 else
6255 blockSize *= 2;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006256 tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
Fred Drake08317ae2003-10-21 15:38:55 +00006257 + blockSize * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006258 if (!tem)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006259 return XML_FALSE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006260 tem->size = blockSize;
6261 tem->next = pool->blocks;
6262 pool->blocks = tem;
6263 if (pool->ptr != pool->start)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006264 memcpy(tem->s, pool->start,
6265 (pool->ptr - pool->start) * sizeof(XML_Char));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006266 pool->ptr = tem->s + (pool->ptr - pool->start);
6267 pool->start = tem->s;
6268 pool->end = tem->s + blockSize;
6269 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006270 return XML_TRUE;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006271}
6272
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006273static int FASTCALL
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006274nextScaffoldPart(XML_Parser parser)
6275{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006276 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006277 CONTENT_SCAFFOLD * me;
6278 int next;
6279
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006280 if (!dtd->scaffIndex) {
6281 dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6282 if (!dtd->scaffIndex)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006283 return -1;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006284 dtd->scaffIndex[0] = 0;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006285 }
6286
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006287 if (dtd->scaffCount >= dtd->scaffSize) {
6288 CONTENT_SCAFFOLD *temp;
6289 if (dtd->scaffold) {
6290 temp = (CONTENT_SCAFFOLD *)
6291 REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6292 if (temp == NULL)
6293 return -1;
6294 dtd->scaffSize *= 2;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006295 }
6296 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006297 temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6298 * sizeof(CONTENT_SCAFFOLD));
6299 if (temp == NULL)
6300 return -1;
6301 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006302 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006303 dtd->scaffold = temp;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006304 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006305 next = dtd->scaffCount++;
6306 me = &dtd->scaffold[next];
6307 if (dtd->scaffLevel) {
6308 CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006309 if (parent->lastchild) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006310 dtd->scaffold[parent->lastchild].nextsib = next;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006311 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006312 if (!parent->childcnt)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006313 parent->firstchild = next;
6314 parent->lastchild = next;
6315 parent->childcnt++;
6316 }
6317 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6318 return next;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006319}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006320
6321static void
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006322build_node(XML_Parser parser,
6323 int src_node,
6324 XML_Content *dest,
6325 XML_Content **contpos,
6326 XML_Char **strpos)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006327{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006328 DTD * const dtd = _dtd; /* save one level of indirection */
6329 dest->type = dtd->scaffold[src_node].type;
6330 dest->quant = dtd->scaffold[src_node].quant;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006331 if (dest->type == XML_CTYPE_NAME) {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006332 const XML_Char *src;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006333 dest->name = *strpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006334 src = dtd->scaffold[src_node].name;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006335 for (;;) {
6336 *(*strpos)++ = *src;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006337 if (!*src)
6338 break;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006339 src++;
6340 }
6341 dest->numchildren = 0;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006342 dest->children = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006343 }
6344 else {
6345 unsigned int i;
6346 int cn;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006347 dest->numchildren = dtd->scaffold[src_node].childcnt;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006348 dest->children = *contpos;
6349 *contpos += dest->numchildren;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006350 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6351 i < dest->numchildren;
6352 i++, cn = dtd->scaffold[cn].nextsib) {
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006353 build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6354 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006355 dest->name = NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006356 }
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006357}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006358
6359static XML_Content *
6360build_model (XML_Parser parser)
6361{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006362 DTD * const dtd = _dtd; /* save one level of indirection */
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006363 XML_Content *ret;
6364 XML_Content *cpos;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006365 XML_Char * str;
6366 int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6367 + (dtd->contentStringLen * sizeof(XML_Char)));
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006368
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006369 ret = (XML_Content *)MALLOC(allocsize);
6370 if (!ret)
6371 return NULL;
6372
6373 str = (XML_Char *) (&ret[dtd->scaffCount]);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006374 cpos = &ret[1];
6375
6376 build_node(parser, 0, ret, &cpos, &str);
6377 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006378}
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006379
6380static ELEMENT_TYPE *
6381getElementType(XML_Parser parser,
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006382 const ENCODING *enc,
6383 const char *ptr,
6384 const char *end)
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006385{
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006386 DTD * const dtd = _dtd; /* save one level of indirection */
6387 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006388 ELEMENT_TYPE *ret;
6389
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006390 if (!name)
6391 return NULL;
Gregory P. Smithc8ff4602012-03-14 15:28:10 -07006392 ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006393 if (!ret)
6394 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006395 if (ret->name != name)
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006396 poolDiscard(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006397 else {
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006398 poolFinish(&dtd->pool);
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006399 if (!setElementTypePrefix(parser, ret))
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006400 return NULL;
Martin v. Löwis1dbb1ca2002-02-11 23:13:04 +00006401 }
6402 return ret;
Martin v. Löwisfc03a942003-01-25 22:41:29 +00006403}