xmlparse.c revision 1.7 1 1.1 tron /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2 1.1 tron See the file COPYING for copying permission.
3 1.7 christos
4 1.7 christos 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)
5 1.1 tron */
6 1.1 tron
7 1.7 christos #define _GNU_SOURCE /* syscall prototype */
8 1.7 christos
9 1.1 tron #include <stddef.h>
10 1.1 tron #include <string.h> /* memset(), memcpy() */
11 1.1 tron #include <assert.h>
12 1.3 spz #include <limits.h> /* UINT_MAX */
13 1.7 christos #include <stdio.h> /* fprintf */
14 1.7 christos #include <stdlib.h> /* getenv */
15 1.6 spz
16 1.7 christos #ifdef _WIN32
17 1.6 spz #define getpid GetCurrentProcessId
18 1.6 spz #else
19 1.6 spz #include <sys/time.h> /* gettimeofday() */
20 1.6 spz #include <sys/types.h> /* getpid() */
21 1.6 spz #include <unistd.h> /* getpid() */
22 1.6 spz #endif
23 1.1 tron
24 1.1 tron #define XML_BUILDING_EXPAT 1
25 1.1 tron
26 1.7 christos #ifdef _WIN32
27 1.1 tron #include "winconfig.h"
28 1.1 tron #elif defined(HAVE_EXPAT_CONFIG_H)
29 1.1 tron #include <expat_config.h>
30 1.7 christos #endif /* ndef _WIN32 */
31 1.1 tron
32 1.1 tron #include "ascii.h"
33 1.1 tron #include "expat.h"
34 1.7 christos #include "siphash.h"
35 1.1 tron
36 1.1 tron #ifdef XML_UNICODE
37 1.1 tron #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
38 1.1 tron #define XmlConvert XmlUtf16Convert
39 1.1 tron #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
40 1.1 tron #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
41 1.1 tron #define XmlEncode XmlUtf16Encode
42 1.1 tron /* Using pointer subtraction to convert to integer type. */
43 1.1 tron #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
44 1.1 tron typedef unsigned short ICHAR;
45 1.1 tron #else
46 1.1 tron #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
47 1.1 tron #define XmlConvert XmlUtf8Convert
48 1.1 tron #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
49 1.1 tron #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
50 1.1 tron #define XmlEncode XmlUtf8Encode
51 1.1 tron #define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
52 1.1 tron typedef char ICHAR;
53 1.1 tron #endif
54 1.1 tron
55 1.1 tron
56 1.1 tron #ifndef XML_NS
57 1.1 tron
58 1.1 tron #define XmlInitEncodingNS XmlInitEncoding
59 1.1 tron #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
60 1.1 tron #undef XmlGetInternalEncodingNS
61 1.1 tron #define XmlGetInternalEncodingNS XmlGetInternalEncoding
62 1.1 tron #define XmlParseXmlDeclNS XmlParseXmlDecl
63 1.1 tron
64 1.1 tron #endif
65 1.1 tron
66 1.1 tron #ifdef XML_UNICODE
67 1.1 tron
68 1.1 tron #ifdef XML_UNICODE_WCHAR_T
69 1.1 tron #define XML_T(x) (const wchar_t)x
70 1.1 tron #define XML_L(x) L ## x
71 1.1 tron #else
72 1.1 tron #define XML_T(x) (const unsigned short)x
73 1.1 tron #define XML_L(x) x
74 1.1 tron #endif
75 1.1 tron
76 1.1 tron #else
77 1.1 tron
78 1.1 tron #define XML_T(x) x
79 1.1 tron #define XML_L(x) x
80 1.1 tron
81 1.1 tron #endif
82 1.1 tron
83 1.1 tron /* Round up n to be a multiple of sz, where sz is a power of 2. */
84 1.1 tron #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
85 1.1 tron
86 1.1 tron /* Handle the case where memmove() doesn't exist. */
87 1.1 tron #ifndef HAVE_MEMMOVE
88 1.1 tron #ifdef HAVE_BCOPY
89 1.1 tron #define memmove(d,s,l) bcopy((s),(d),(l))
90 1.1 tron #else
91 1.1 tron #error memmove does not exist on this platform, nor is a substitute available
92 1.1 tron #endif /* HAVE_BCOPY */
93 1.1 tron #endif /* HAVE_MEMMOVE */
94 1.1 tron
95 1.1 tron #include "internal.h"
96 1.1 tron #include "xmltok.h"
97 1.1 tron #include "xmlrole.h"
98 1.1 tron
99 1.1 tron typedef const XML_Char *KEY;
100 1.1 tron
101 1.1 tron typedef struct {
102 1.1 tron KEY name;
103 1.1 tron } NAMED;
104 1.1 tron
105 1.1 tron typedef struct {
106 1.1 tron NAMED **v;
107 1.1 tron unsigned char power;
108 1.1 tron size_t size;
109 1.1 tron size_t used;
110 1.1 tron const XML_Memory_Handling_Suite *mem;
111 1.1 tron } HASH_TABLE;
112 1.1 tron
113 1.7 christos static size_t
114 1.7 christos keylen(KEY s);
115 1.1 tron
116 1.7 christos static void
117 1.7 christos copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
118 1.1 tron
119 1.1 tron /* For probing (after a collision) we need a step size relative prime
120 1.1 tron to the hash table size, which is a power of 2. We use double-hashing,
121 1.1 tron since we can calculate a second hash value cheaply by taking those bits
122 1.1 tron of the first hash value that were discarded (masked out) when the table
123 1.1 tron index was calculated: index = hash & mask, where mask = table->size - 1.
124 1.1 tron We limit the maximum step size to table->size / 4 (mask >> 2) and make
125 1.1 tron it odd, since odd numbers are always relative prime to a power of 2.
126 1.1 tron */
127 1.1 tron #define SECOND_HASH(hash, mask, power) \
128 1.1 tron ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
129 1.1 tron #define PROBE_STEP(hash, mask, power) \
130 1.1 tron ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
131 1.1 tron
132 1.1 tron typedef struct {
133 1.1 tron NAMED **p;
134 1.1 tron NAMED **end;
135 1.1 tron } HASH_TABLE_ITER;
136 1.1 tron
137 1.1 tron #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
138 1.1 tron #define INIT_DATA_BUF_SIZE 1024
139 1.1 tron #define INIT_ATTS_SIZE 16
140 1.1 tron #define INIT_ATTS_VERSION 0xFFFFFFFF
141 1.1 tron #define INIT_BLOCK_SIZE 1024
142 1.1 tron #define INIT_BUFFER_SIZE 1024
143 1.1 tron
144 1.1 tron #define EXPAND_SPARE 24
145 1.1 tron
146 1.1 tron typedef struct binding {
147 1.1 tron struct prefix *prefix;
148 1.1 tron struct binding *nextTagBinding;
149 1.1 tron struct binding *prevPrefixBinding;
150 1.1 tron const struct attribute_id *attId;
151 1.1 tron XML_Char *uri;
152 1.1 tron int uriLen;
153 1.1 tron int uriAlloc;
154 1.1 tron } BINDING;
155 1.1 tron
156 1.1 tron typedef struct prefix {
157 1.1 tron const XML_Char *name;
158 1.1 tron BINDING *binding;
159 1.1 tron } PREFIX;
160 1.1 tron
161 1.1 tron typedef struct {
162 1.1 tron const XML_Char *str;
163 1.1 tron const XML_Char *localPart;
164 1.1 tron const XML_Char *prefix;
165 1.1 tron int strLen;
166 1.1 tron int uriLen;
167 1.1 tron int prefixLen;
168 1.1 tron } TAG_NAME;
169 1.1 tron
170 1.1 tron /* TAG represents an open element.
171 1.1 tron The name of the element is stored in both the document and API
172 1.1 tron encodings. The memory buffer 'buf' is a separately-allocated
173 1.1 tron memory area which stores the name. During the XML_Parse()/
174 1.1 tron XMLParseBuffer() when the element is open, the memory for the 'raw'
175 1.1 tron version of the name (in the document encoding) is shared with the
176 1.1 tron document buffer. If the element is open across calls to
177 1.1 tron XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
178 1.1 tron contain the 'raw' name as well.
179 1.1 tron
180 1.1 tron A parser re-uses these structures, maintaining a list of allocated
181 1.1 tron TAG objects in a free list.
182 1.1 tron */
183 1.1 tron typedef struct tag {
184 1.1 tron struct tag *parent; /* parent of this element */
185 1.1 tron const char *rawName; /* tagName in the original encoding */
186 1.1 tron int rawNameLength;
187 1.1 tron TAG_NAME name; /* tagName in the API encoding */
188 1.1 tron char *buf; /* buffer for name components */
189 1.1 tron char *bufEnd; /* end of the buffer */
190 1.1 tron BINDING *bindings;
191 1.1 tron } TAG;
192 1.1 tron
193 1.1 tron typedef struct {
194 1.1 tron const XML_Char *name;
195 1.1 tron const XML_Char *textPtr;
196 1.1 tron int textLen; /* length in XML_Chars */
197 1.1 tron int processed; /* # of processed bytes - when suspended */
198 1.1 tron const XML_Char *systemId;
199 1.1 tron const XML_Char *base;
200 1.1 tron const XML_Char *publicId;
201 1.1 tron const XML_Char *notation;
202 1.1 tron XML_Bool open;
203 1.1 tron XML_Bool is_param;
204 1.1 tron XML_Bool is_internal; /* true if declared in internal subset outside PE */
205 1.1 tron } ENTITY;
206 1.1 tron
207 1.1 tron typedef struct {
208 1.1 tron enum XML_Content_Type type;
209 1.1 tron enum XML_Content_Quant quant;
210 1.1 tron const XML_Char * name;
211 1.1 tron int firstchild;
212 1.1 tron int lastchild;
213 1.1 tron int childcnt;
214 1.1 tron int nextsib;
215 1.1 tron } CONTENT_SCAFFOLD;
216 1.1 tron
217 1.1 tron #define INIT_SCAFFOLD_ELEMENTS 32
218 1.1 tron
219 1.1 tron typedef struct block {
220 1.1 tron struct block *next;
221 1.1 tron int size;
222 1.1 tron XML_Char s[1];
223 1.1 tron } BLOCK;
224 1.1 tron
225 1.1 tron typedef struct {
226 1.1 tron BLOCK *blocks;
227 1.1 tron BLOCK *freeBlocks;
228 1.1 tron const XML_Char *end;
229 1.1 tron XML_Char *ptr;
230 1.1 tron XML_Char *start;
231 1.1 tron const XML_Memory_Handling_Suite *mem;
232 1.1 tron } STRING_POOL;
233 1.1 tron
234 1.1 tron /* The XML_Char before the name is used to determine whether
235 1.1 tron an attribute has been specified. */
236 1.1 tron typedef struct attribute_id {
237 1.1 tron XML_Char *name;
238 1.1 tron PREFIX *prefix;
239 1.1 tron XML_Bool maybeTokenized;
240 1.1 tron XML_Bool xmlns;
241 1.1 tron } ATTRIBUTE_ID;
242 1.1 tron
243 1.1 tron typedef struct {
244 1.1 tron const ATTRIBUTE_ID *id;
245 1.1 tron XML_Bool isCdata;
246 1.1 tron const XML_Char *value;
247 1.1 tron } DEFAULT_ATTRIBUTE;
248 1.1 tron
249 1.1 tron typedef struct {
250 1.1 tron unsigned long version;
251 1.1 tron unsigned long hash;
252 1.1 tron const XML_Char *uriName;
253 1.1 tron } NS_ATT;
254 1.1 tron
255 1.1 tron typedef struct {
256 1.1 tron const XML_Char *name;
257 1.1 tron PREFIX *prefix;
258 1.1 tron const ATTRIBUTE_ID *idAtt;
259 1.1 tron int nDefaultAtts;
260 1.1 tron int allocDefaultAtts;
261 1.1 tron DEFAULT_ATTRIBUTE *defaultAtts;
262 1.1 tron } ELEMENT_TYPE;
263 1.1 tron
264 1.1 tron typedef struct {
265 1.1 tron HASH_TABLE generalEntities;
266 1.1 tron HASH_TABLE elementTypes;
267 1.1 tron HASH_TABLE attributeIds;
268 1.1 tron HASH_TABLE prefixes;
269 1.1 tron STRING_POOL pool;
270 1.1 tron STRING_POOL entityValuePool;
271 1.1 tron /* false once a parameter entity reference has been skipped */
272 1.1 tron XML_Bool keepProcessing;
273 1.1 tron /* true once an internal or external PE reference has been encountered;
274 1.1 tron this includes the reference to an external subset */
275 1.1 tron XML_Bool hasParamEntityRefs;
276 1.1 tron XML_Bool standalone;
277 1.1 tron #ifdef XML_DTD
278 1.1 tron /* indicates if external PE has been read */
279 1.1 tron XML_Bool paramEntityRead;
280 1.1 tron HASH_TABLE paramEntities;
281 1.1 tron #endif /* XML_DTD */
282 1.1 tron PREFIX defaultPrefix;
283 1.1 tron /* === scaffolding for building content model === */
284 1.1 tron XML_Bool in_eldecl;
285 1.1 tron CONTENT_SCAFFOLD *scaffold;
286 1.1 tron unsigned contentStringLen;
287 1.1 tron unsigned scaffSize;
288 1.1 tron unsigned scaffCount;
289 1.1 tron int scaffLevel;
290 1.1 tron int *scaffIndex;
291 1.1 tron } DTD;
292 1.1 tron
293 1.1 tron typedef struct open_internal_entity {
294 1.1 tron const char *internalEventPtr;
295 1.1 tron const char *internalEventEndPtr;
296 1.1 tron struct open_internal_entity *next;
297 1.1 tron ENTITY *entity;
298 1.1 tron int startTagLevel;
299 1.1 tron XML_Bool betweenDecl; /* WFC: PE Between Declarations */
300 1.1 tron } OPEN_INTERNAL_ENTITY;
301 1.1 tron
302 1.1 tron typedef enum XML_Error PTRCALL Processor(XML_Parser parser,
303 1.1 tron const char *start,
304 1.1 tron const char *end,
305 1.1 tron const char **endPtr);
306 1.1 tron
307 1.1 tron static Processor prologProcessor;
308 1.1 tron static Processor prologInitProcessor;
309 1.1 tron static Processor contentProcessor;
310 1.1 tron static Processor cdataSectionProcessor;
311 1.1 tron #ifdef XML_DTD
312 1.1 tron static Processor ignoreSectionProcessor;
313 1.1 tron static Processor externalParEntProcessor;
314 1.1 tron static Processor externalParEntInitProcessor;
315 1.1 tron static Processor entityValueProcessor;
316 1.1 tron static Processor entityValueInitProcessor;
317 1.1 tron #endif /* XML_DTD */
318 1.1 tron static Processor epilogProcessor;
319 1.1 tron static Processor errorProcessor;
320 1.1 tron static Processor externalEntityInitProcessor;
321 1.1 tron static Processor externalEntityInitProcessor2;
322 1.1 tron static Processor externalEntityInitProcessor3;
323 1.1 tron static Processor externalEntityContentProcessor;
324 1.1 tron static Processor internalEntityProcessor;
325 1.1 tron
326 1.1 tron static enum XML_Error
327 1.1 tron handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
328 1.1 tron static enum XML_Error
329 1.1 tron processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
330 1.1 tron const char *s, const char *next);
331 1.1 tron static enum XML_Error
332 1.1 tron initializeEncoding(XML_Parser parser);
333 1.1 tron static enum XML_Error
334 1.3 spz doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
335 1.3 spz const char *end, int tok, const char *next, const char **nextPtr,
336 1.1 tron XML_Bool haveMore);
337 1.1 tron static enum XML_Error
338 1.3 spz processInternalEntity(XML_Parser parser, ENTITY *entity,
339 1.1 tron XML_Bool betweenDecl);
340 1.1 tron static enum XML_Error
341 1.1 tron doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
342 1.3 spz const char *start, const char *end, const char **endPtr,
343 1.1 tron XML_Bool haveMore);
344 1.1 tron static enum XML_Error
345 1.1 tron doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
346 1.1 tron const char *end, const char **nextPtr, XML_Bool haveMore);
347 1.1 tron #ifdef XML_DTD
348 1.1 tron static enum XML_Error
349 1.1 tron doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
350 1.1 tron const char *end, const char **nextPtr, XML_Bool haveMore);
351 1.1 tron #endif /* XML_DTD */
352 1.1 tron
353 1.7 christos static void
354 1.7 christos freeBindings(XML_Parser parser, BINDING *bindings);
355 1.1 tron static enum XML_Error
356 1.1 tron storeAtts(XML_Parser parser, const ENCODING *, const char *s,
357 1.1 tron TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
358 1.1 tron static enum XML_Error
359 1.1 tron addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
360 1.1 tron const XML_Char *uri, BINDING **bindingsPtr);
361 1.1 tron static int
362 1.3 spz defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
363 1.1 tron XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
364 1.1 tron static enum XML_Error
365 1.1 tron storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
366 1.1 tron const char *, const char *, STRING_POOL *);
367 1.1 tron static enum XML_Error
368 1.1 tron appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
369 1.1 tron const char *, const char *, STRING_POOL *);
370 1.1 tron static ATTRIBUTE_ID *
371 1.1 tron getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
372 1.1 tron const char *end);
373 1.1 tron static int
374 1.1 tron setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
375 1.1 tron static enum XML_Error
376 1.1 tron storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
377 1.1 tron const char *end);
378 1.1 tron static int
379 1.1 tron reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
380 1.1 tron const char *start, const char *end);
381 1.1 tron static int
382 1.1 tron reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
383 1.1 tron const char *end);
384 1.1 tron static void
385 1.1 tron reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
386 1.1 tron const char *end);
387 1.1 tron
388 1.1 tron static const XML_Char * getContext(XML_Parser parser);
389 1.1 tron static XML_Bool
390 1.1 tron setContext(XML_Parser parser, const XML_Char *context);
391 1.1 tron
392 1.1 tron static void FASTCALL normalizePublicId(XML_Char *s);
393 1.1 tron
394 1.1 tron static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
395 1.1 tron /* do not call if parentParser != NULL */
396 1.1 tron static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
397 1.1 tron static void
398 1.1 tron dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
399 1.1 tron static int
400 1.3 spz dtdCopy(XML_Parser oldParser,
401 1.3 spz DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
402 1.1 tron static int
403 1.3 spz copyEntityTable(XML_Parser oldParser,
404 1.3 spz HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
405 1.1 tron static NAMED *
406 1.3 spz lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
407 1.1 tron static void FASTCALL
408 1.1 tron hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
409 1.1 tron static void FASTCALL hashTableClear(HASH_TABLE *);
410 1.1 tron static void FASTCALL hashTableDestroy(HASH_TABLE *);
411 1.1 tron static void FASTCALL
412 1.1 tron hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
413 1.1 tron static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
414 1.1 tron
415 1.1 tron static void FASTCALL
416 1.1 tron poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
417 1.1 tron static void FASTCALL poolClear(STRING_POOL *);
418 1.1 tron static void FASTCALL poolDestroy(STRING_POOL *);
419 1.1 tron static XML_Char *
420 1.1 tron poolAppend(STRING_POOL *pool, const ENCODING *enc,
421 1.1 tron const char *ptr, const char *end);
422 1.1 tron static XML_Char *
423 1.1 tron poolStoreString(STRING_POOL *pool, const ENCODING *enc,
424 1.1 tron const char *ptr, const char *end);
425 1.1 tron static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
426 1.1 tron static const XML_Char * FASTCALL
427 1.1 tron poolCopyString(STRING_POOL *pool, const XML_Char *s);
428 1.1 tron static const XML_Char *
429 1.1 tron poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
430 1.1 tron static const XML_Char * FASTCALL
431 1.1 tron poolAppendString(STRING_POOL *pool, const XML_Char *s);
432 1.1 tron
433 1.1 tron static int FASTCALL nextScaffoldPart(XML_Parser parser);
434 1.1 tron static XML_Content * build_model(XML_Parser parser);
435 1.1 tron static ELEMENT_TYPE *
436 1.1 tron getElementType(XML_Parser parser, const ENCODING *enc,
437 1.1 tron const char *ptr, const char *end);
438 1.1 tron
439 1.6 spz static unsigned long generate_hash_secret_salt(XML_Parser parser);
440 1.3 spz static XML_Bool startParsing(XML_Parser parser);
441 1.3 spz
442 1.1 tron static XML_Parser
443 1.1 tron parserCreate(const XML_Char *encodingName,
444 1.1 tron const XML_Memory_Handling_Suite *memsuite,
445 1.1 tron const XML_Char *nameSep,
446 1.1 tron DTD *dtd);
447 1.3 spz
448 1.1 tron static void
449 1.1 tron parserInit(XML_Parser parser, const XML_Char *encodingName);
450 1.1 tron
451 1.1 tron #define poolStart(pool) ((pool)->start)
452 1.1 tron #define poolEnd(pool) ((pool)->ptr)
453 1.1 tron #define poolLength(pool) ((pool)->ptr - (pool)->start)
454 1.1 tron #define poolChop(pool) ((void)--(pool->ptr))
455 1.1 tron #define poolLastChar(pool) (((pool)->ptr)[-1])
456 1.1 tron #define poolDiscard(pool) ((pool)->ptr = (pool)->start)
457 1.1 tron #define poolFinish(pool) ((pool)->start = (pool)->ptr)
458 1.1 tron #define poolAppendChar(pool, c) \
459 1.1 tron (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
460 1.1 tron ? 0 \
461 1.1 tron : ((*((pool)->ptr)++ = c), 1))
462 1.1 tron
463 1.1 tron struct XML_ParserStruct {
464 1.1 tron /* The first member must be userData so that the XML_GetUserData
465 1.1 tron macro works. */
466 1.1 tron void *m_userData;
467 1.1 tron void *m_handlerArg;
468 1.1 tron char *m_buffer;
469 1.1 tron const XML_Memory_Handling_Suite m_mem;
470 1.1 tron /* first character to be parsed */
471 1.1 tron const char *m_bufferPtr;
472 1.1 tron /* past last character to be parsed */
473 1.1 tron char *m_bufferEnd;
474 1.1 tron /* allocated end of buffer */
475 1.1 tron const char *m_bufferLim;
476 1.1 tron XML_Index m_parseEndByteIndex;
477 1.1 tron const char *m_parseEndPtr;
478 1.1 tron XML_Char *m_dataBuf;
479 1.1 tron XML_Char *m_dataBufEnd;
480 1.1 tron XML_StartElementHandler m_startElementHandler;
481 1.1 tron XML_EndElementHandler m_endElementHandler;
482 1.1 tron XML_CharacterDataHandler m_characterDataHandler;
483 1.1 tron XML_ProcessingInstructionHandler m_processingInstructionHandler;
484 1.1 tron XML_CommentHandler m_commentHandler;
485 1.1 tron XML_StartCdataSectionHandler m_startCdataSectionHandler;
486 1.1 tron XML_EndCdataSectionHandler m_endCdataSectionHandler;
487 1.1 tron XML_DefaultHandler m_defaultHandler;
488 1.1 tron XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
489 1.1 tron XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
490 1.1 tron XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
491 1.1 tron XML_NotationDeclHandler m_notationDeclHandler;
492 1.1 tron XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
493 1.1 tron XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
494 1.1 tron XML_NotStandaloneHandler m_notStandaloneHandler;
495 1.1 tron XML_ExternalEntityRefHandler m_externalEntityRefHandler;
496 1.1 tron XML_Parser m_externalEntityRefHandlerArg;
497 1.1 tron XML_SkippedEntityHandler m_skippedEntityHandler;
498 1.1 tron XML_UnknownEncodingHandler m_unknownEncodingHandler;
499 1.1 tron XML_ElementDeclHandler m_elementDeclHandler;
500 1.1 tron XML_AttlistDeclHandler m_attlistDeclHandler;
501 1.1 tron XML_EntityDeclHandler m_entityDeclHandler;
502 1.1 tron XML_XmlDeclHandler m_xmlDeclHandler;
503 1.1 tron const ENCODING *m_encoding;
504 1.1 tron INIT_ENCODING m_initEncoding;
505 1.1 tron const ENCODING *m_internalEncoding;
506 1.1 tron const XML_Char *m_protocolEncodingName;
507 1.1 tron XML_Bool m_ns;
508 1.1 tron XML_Bool m_ns_triplets;
509 1.1 tron void *m_unknownEncodingMem;
510 1.1 tron void *m_unknownEncodingData;
511 1.1 tron void *m_unknownEncodingHandlerData;
512 1.1 tron void (XMLCALL *m_unknownEncodingRelease)(void *);
513 1.1 tron PROLOG_STATE m_prologState;
514 1.1 tron Processor *m_processor;
515 1.1 tron enum XML_Error m_errorCode;
516 1.1 tron const char *m_eventPtr;
517 1.1 tron const char *m_eventEndPtr;
518 1.1 tron const char *m_positionPtr;
519 1.1 tron OPEN_INTERNAL_ENTITY *m_openInternalEntities;
520 1.1 tron OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
521 1.1 tron XML_Bool m_defaultExpandInternalEntities;
522 1.1 tron int m_tagLevel;
523 1.1 tron ENTITY *m_declEntity;
524 1.1 tron const XML_Char *m_doctypeName;
525 1.1 tron const XML_Char *m_doctypeSysid;
526 1.1 tron const XML_Char *m_doctypePubid;
527 1.1 tron const XML_Char *m_declAttributeType;
528 1.1 tron const XML_Char *m_declNotationName;
529 1.1 tron const XML_Char *m_declNotationPublicId;
530 1.1 tron ELEMENT_TYPE *m_declElementType;
531 1.1 tron ATTRIBUTE_ID *m_declAttributeId;
532 1.1 tron XML_Bool m_declAttributeIsCdata;
533 1.1 tron XML_Bool m_declAttributeIsId;
534 1.1 tron DTD *m_dtd;
535 1.1 tron const XML_Char *m_curBase;
536 1.1 tron TAG *m_tagStack;
537 1.1 tron TAG *m_freeTagList;
538 1.1 tron BINDING *m_inheritedBindings;
539 1.1 tron BINDING *m_freeBindingList;
540 1.1 tron int m_attsSize;
541 1.1 tron int m_nSpecifiedAtts;
542 1.1 tron int m_idAttIndex;
543 1.1 tron ATTRIBUTE *m_atts;
544 1.1 tron NS_ATT *m_nsAtts;
545 1.1 tron unsigned long m_nsAttsVersion;
546 1.1 tron unsigned char m_nsAttsPower;
547 1.3 spz #ifdef XML_ATTR_INFO
548 1.3 spz XML_AttrInfo *m_attInfo;
549 1.3 spz #endif
550 1.1 tron POSITION m_position;
551 1.1 tron STRING_POOL m_tempPool;
552 1.1 tron STRING_POOL m_temp2Pool;
553 1.1 tron char *m_groupConnector;
554 1.1 tron unsigned int m_groupSize;
555 1.1 tron XML_Char m_namespaceSeparator;
556 1.1 tron XML_Parser m_parentParser;
557 1.1 tron XML_ParsingStatus m_parsingStatus;
558 1.1 tron #ifdef XML_DTD
559 1.1 tron XML_Bool m_isParamEntity;
560 1.1 tron XML_Bool m_useForeignDTD;
561 1.1 tron enum XML_ParamEntityParsing m_paramEntityParsing;
562 1.1 tron #endif
563 1.3 spz unsigned long m_hash_secret_salt;
564 1.1 tron };
565 1.1 tron
566 1.1 tron #define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
567 1.1 tron #define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
568 1.1 tron #define FREE(p) (parser->m_mem.free_fcn((p)))
569 1.1 tron
570 1.1 tron #define userData (parser->m_userData)
571 1.1 tron #define handlerArg (parser->m_handlerArg)
572 1.1 tron #define startElementHandler (parser->m_startElementHandler)
573 1.1 tron #define endElementHandler (parser->m_endElementHandler)
574 1.1 tron #define characterDataHandler (parser->m_characterDataHandler)
575 1.1 tron #define processingInstructionHandler \
576 1.1 tron (parser->m_processingInstructionHandler)
577 1.1 tron #define commentHandler (parser->m_commentHandler)
578 1.1 tron #define startCdataSectionHandler \
579 1.1 tron (parser->m_startCdataSectionHandler)
580 1.1 tron #define endCdataSectionHandler (parser->m_endCdataSectionHandler)
581 1.1 tron #define defaultHandler (parser->m_defaultHandler)
582 1.1 tron #define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
583 1.1 tron #define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
584 1.1 tron #define unparsedEntityDeclHandler \
585 1.1 tron (parser->m_unparsedEntityDeclHandler)
586 1.1 tron #define notationDeclHandler (parser->m_notationDeclHandler)
587 1.1 tron #define startNamespaceDeclHandler \
588 1.1 tron (parser->m_startNamespaceDeclHandler)
589 1.1 tron #define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
590 1.1 tron #define notStandaloneHandler (parser->m_notStandaloneHandler)
591 1.1 tron #define externalEntityRefHandler \
592 1.1 tron (parser->m_externalEntityRefHandler)
593 1.1 tron #define externalEntityRefHandlerArg \
594 1.1 tron (parser->m_externalEntityRefHandlerArg)
595 1.1 tron #define internalEntityRefHandler \
596 1.1 tron (parser->m_internalEntityRefHandler)
597 1.1 tron #define skippedEntityHandler (parser->m_skippedEntityHandler)
598 1.1 tron #define unknownEncodingHandler (parser->m_unknownEncodingHandler)
599 1.1 tron #define elementDeclHandler (parser->m_elementDeclHandler)
600 1.1 tron #define attlistDeclHandler (parser->m_attlistDeclHandler)
601 1.1 tron #define entityDeclHandler (parser->m_entityDeclHandler)
602 1.1 tron #define xmlDeclHandler (parser->m_xmlDeclHandler)
603 1.1 tron #define encoding (parser->m_encoding)
604 1.1 tron #define initEncoding (parser->m_initEncoding)
605 1.1 tron #define internalEncoding (parser->m_internalEncoding)
606 1.1 tron #define unknownEncodingMem (parser->m_unknownEncodingMem)
607 1.1 tron #define unknownEncodingData (parser->m_unknownEncodingData)
608 1.1 tron #define unknownEncodingHandlerData \
609 1.1 tron (parser->m_unknownEncodingHandlerData)
610 1.1 tron #define unknownEncodingRelease (parser->m_unknownEncodingRelease)
611 1.1 tron #define protocolEncodingName (parser->m_protocolEncodingName)
612 1.1 tron #define ns (parser->m_ns)
613 1.1 tron #define ns_triplets (parser->m_ns_triplets)
614 1.1 tron #define prologState (parser->m_prologState)
615 1.1 tron #define processor (parser->m_processor)
616 1.1 tron #define errorCode (parser->m_errorCode)
617 1.1 tron #define eventPtr (parser->m_eventPtr)
618 1.1 tron #define eventEndPtr (parser->m_eventEndPtr)
619 1.1 tron #define positionPtr (parser->m_positionPtr)
620 1.1 tron #define position (parser->m_position)
621 1.1 tron #define openInternalEntities (parser->m_openInternalEntities)
622 1.1 tron #define freeInternalEntities (parser->m_freeInternalEntities)
623 1.1 tron #define defaultExpandInternalEntities \
624 1.1 tron (parser->m_defaultExpandInternalEntities)
625 1.1 tron #define tagLevel (parser->m_tagLevel)
626 1.1 tron #define buffer (parser->m_buffer)
627 1.1 tron #define bufferPtr (parser->m_bufferPtr)
628 1.1 tron #define bufferEnd (parser->m_bufferEnd)
629 1.1 tron #define parseEndByteIndex (parser->m_parseEndByteIndex)
630 1.1 tron #define parseEndPtr (parser->m_parseEndPtr)
631 1.1 tron #define bufferLim (parser->m_bufferLim)
632 1.1 tron #define dataBuf (parser->m_dataBuf)
633 1.1 tron #define dataBufEnd (parser->m_dataBufEnd)
634 1.1 tron #define _dtd (parser->m_dtd)
635 1.1 tron #define curBase (parser->m_curBase)
636 1.1 tron #define declEntity (parser->m_declEntity)
637 1.1 tron #define doctypeName (parser->m_doctypeName)
638 1.1 tron #define doctypeSysid (parser->m_doctypeSysid)
639 1.1 tron #define doctypePubid (parser->m_doctypePubid)
640 1.1 tron #define declAttributeType (parser->m_declAttributeType)
641 1.1 tron #define declNotationName (parser->m_declNotationName)
642 1.1 tron #define declNotationPublicId (parser->m_declNotationPublicId)
643 1.1 tron #define declElementType (parser->m_declElementType)
644 1.1 tron #define declAttributeId (parser->m_declAttributeId)
645 1.1 tron #define declAttributeIsCdata (parser->m_declAttributeIsCdata)
646 1.1 tron #define declAttributeIsId (parser->m_declAttributeIsId)
647 1.1 tron #define freeTagList (parser->m_freeTagList)
648 1.1 tron #define freeBindingList (parser->m_freeBindingList)
649 1.1 tron #define inheritedBindings (parser->m_inheritedBindings)
650 1.1 tron #define tagStack (parser->m_tagStack)
651 1.1 tron #define atts (parser->m_atts)
652 1.1 tron #define attsSize (parser->m_attsSize)
653 1.1 tron #define nSpecifiedAtts (parser->m_nSpecifiedAtts)
654 1.1 tron #define idAttIndex (parser->m_idAttIndex)
655 1.1 tron #define nsAtts (parser->m_nsAtts)
656 1.1 tron #define nsAttsVersion (parser->m_nsAttsVersion)
657 1.1 tron #define nsAttsPower (parser->m_nsAttsPower)
658 1.3 spz #define attInfo (parser->m_attInfo)
659 1.1 tron #define tempPool (parser->m_tempPool)
660 1.1 tron #define temp2Pool (parser->m_temp2Pool)
661 1.1 tron #define groupConnector (parser->m_groupConnector)
662 1.1 tron #define groupSize (parser->m_groupSize)
663 1.1 tron #define namespaceSeparator (parser->m_namespaceSeparator)
664 1.1 tron #define parentParser (parser->m_parentParser)
665 1.1 tron #define ps_parsing (parser->m_parsingStatus.parsing)
666 1.1 tron #define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
667 1.1 tron #ifdef XML_DTD
668 1.1 tron #define isParamEntity (parser->m_isParamEntity)
669 1.1 tron #define useForeignDTD (parser->m_useForeignDTD)
670 1.1 tron #define paramEntityParsing (parser->m_paramEntityParsing)
671 1.1 tron #endif /* XML_DTD */
672 1.3 spz #define hash_secret_salt (parser->m_hash_secret_salt)
673 1.1 tron
674 1.1 tron XML_Parser XMLCALL
675 1.1 tron XML_ParserCreate(const XML_Char *encodingName)
676 1.1 tron {
677 1.1 tron return XML_ParserCreate_MM(encodingName, NULL, NULL);
678 1.1 tron }
679 1.1 tron
680 1.1 tron XML_Parser XMLCALL
681 1.1 tron XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
682 1.1 tron {
683 1.1 tron XML_Char tmp[2];
684 1.1 tron *tmp = nsSep;
685 1.1 tron return XML_ParserCreate_MM(encodingName, NULL, tmp);
686 1.1 tron }
687 1.1 tron
688 1.1 tron static const XML_Char implicitContext[] = {
689 1.1 tron ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
690 1.3 spz ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
691 1.1 tron ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
692 1.1 tron ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
693 1.1 tron ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
694 1.1 tron ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
695 1.1 tron };
696 1.1 tron
697 1.7 christos
698 1.7 christos #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
699 1.7 christos # include <errno.h>
700 1.7 christos
701 1.7 christos # if defined(HAVE_GETRANDOM)
702 1.7 christos # include <sys/random.h> /* getrandom */
703 1.7 christos # else
704 1.7 christos # include <unistd.h> /* syscall */
705 1.7 christos # include <sys/syscall.h> /* SYS_getrandom */
706 1.7 christos # endif
707 1.7 christos
708 1.7 christos /* Obtain entropy on Linux 3.17+ */
709 1.7 christos static int
710 1.7 christos writeRandomBytes_getrandom(void * target, size_t count) {
711 1.7 christos int success = 0; /* full count bytes written? */
712 1.7 christos size_t bytesWrittenTotal = 0;
713 1.7 christos const unsigned int getrandomFlags = 0;
714 1.7 christos
715 1.7 christos do {
716 1.7 christos void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
717 1.7 christos const size_t bytesToWrite = count - bytesWrittenTotal;
718 1.7 christos
719 1.7 christos const int bytesWrittenMore =
720 1.7 christos #if defined(HAVE_GETRANDOM)
721 1.7 christos getrandom(currentTarget, bytesToWrite, getrandomFlags);
722 1.7 christos #else
723 1.7 christos syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
724 1.7 christos #endif
725 1.7 christos
726 1.7 christos if (bytesWrittenMore > 0) {
727 1.7 christos bytesWrittenTotal += bytesWrittenMore;
728 1.7 christos if (bytesWrittenTotal >= count)
729 1.7 christos success = 1;
730 1.7 christos }
731 1.7 christos } while (! success && (errno == EINTR || errno == EAGAIN));
732 1.7 christos
733 1.7 christos return success;
734 1.7 christos }
735 1.7 christos
736 1.7 christos #endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
737 1.7 christos
738 1.7 christos
739 1.7 christos #ifdef _WIN32
740 1.7 christos
741 1.7 christos typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
742 1.7 christos
743 1.7 christos /* Obtain entropy on Windows XP / Windows Server 2003 and later.
744 1.7 christos * Hint on RtlGenRandom and the following article from libsodioum.
745 1.7 christos *
746 1.7 christos * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
747 1.7 christos * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
748 1.7 christos */
749 1.7 christos static int
750 1.7 christos writeRandomBytes_RtlGenRandom(void * target, size_t count) {
751 1.7 christos int success = 0; /* full count bytes written? */
752 1.7 christos const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL");
753 1.7 christos
754 1.7 christos if (advapi32) {
755 1.7 christos const RTLGENRANDOM_FUNC RtlGenRandom
756 1.7 christos = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");
757 1.7 christos if (RtlGenRandom) {
758 1.7 christos if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {
759 1.7 christos success = 1;
760 1.7 christos }
761 1.7 christos }
762 1.7 christos FreeLibrary(advapi32);
763 1.7 christos }
764 1.7 christos
765 1.7 christos return success;
766 1.7 christos }
767 1.7 christos
768 1.7 christos #endif /* _WIN32 */
769 1.7 christos
770 1.7 christos
771 1.3 spz static unsigned long
772 1.6 spz gather_time_entropy(void)
773 1.6 spz {
774 1.7 christos #ifdef _WIN32
775 1.6 spz FILETIME ft;
776 1.6 spz GetSystemTimeAsFileTime(&ft); /* never fails */
777 1.6 spz return ft.dwHighDateTime ^ ft.dwLowDateTime;
778 1.6 spz #else
779 1.6 spz struct timeval tv;
780 1.6 spz int gettimeofday_res;
781 1.6 spz
782 1.6 spz gettimeofday_res = gettimeofday(&tv, NULL);
783 1.6 spz assert (gettimeofday_res == 0);
784 1.6 spz
785 1.6 spz /* Microseconds time is <20 bits entropy */
786 1.6 spz return tv.tv_usec;
787 1.6 spz #endif
788 1.6 spz }
789 1.6 spz
790 1.7 christos #if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD)
791 1.7 christos # include <bsd/stdlib.h>
792 1.7 christos #endif
793 1.7 christos
794 1.7 christos static unsigned long
795 1.7 christos ENTROPY_DEBUG(const char * label, unsigned long entropy) {
796 1.7 christos const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
797 1.7 christos if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
798 1.7 christos fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",
799 1.7 christos label,
800 1.7 christos (int)sizeof(entropy) * 2, entropy,
801 1.7 christos (unsigned long)sizeof(entropy));
802 1.7 christos }
803 1.7 christos return entropy;
804 1.7 christos }
805 1.7 christos
806 1.6 spz static unsigned long
807 1.6 spz generate_hash_secret_salt(XML_Parser parser)
808 1.3 spz {
809 1.7 christos unsigned long entropy;
810 1.7 christos (void)parser;
811 1.7 christos #if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__)
812 1.7 christos (void)gather_time_entropy;
813 1.7 christos arc4random_buf(&entropy, sizeof(entropy));
814 1.7 christos return ENTROPY_DEBUG("arc4random_buf", entropy);
815 1.7 christos #else
816 1.7 christos /* Try high quality providers first .. */
817 1.7 christos #ifdef _WIN32
818 1.7 christos if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {
819 1.7 christos return ENTROPY_DEBUG("RtlGenRandom", entropy);
820 1.7 christos }
821 1.7 christos #elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
822 1.7 christos if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) {
823 1.7 christos return ENTROPY_DEBUG("getrandom", entropy);
824 1.7 christos }
825 1.7 christos #endif
826 1.7 christos /* .. and self-made low quality for backup: */
827 1.7 christos
828 1.7 christos /* Process ID is 0 bits entropy if attacker has local access */
829 1.7 christos entropy = gather_time_entropy() ^ getpid();
830 1.6 spz
831 1.6 spz /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
832 1.6 spz if (sizeof(unsigned long) == 4) {
833 1.7 christos return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
834 1.6 spz } else {
835 1.7 christos return ENTROPY_DEBUG("fallback(8)",
836 1.7 christos entropy * (unsigned long)2305843009213693951);
837 1.6 spz }
838 1.7 christos #endif
839 1.7 christos }
840 1.7 christos
841 1.7 christos static unsigned long
842 1.7 christos get_hash_secret_salt(XML_Parser parser) {
843 1.7 christos if (parser->m_parentParser != NULL)
844 1.7 christos return get_hash_secret_salt(parser->m_parentParser);
845 1.7 christos return parser->m_hash_secret_salt;
846 1.3 spz }
847 1.3 spz
848 1.3 spz static XML_Bool /* only valid for root parser */
849 1.3 spz startParsing(XML_Parser parser)
850 1.3 spz {
851 1.3 spz /* hash functions must be initialized before setContext() is called */
852 1.3 spz if (hash_secret_salt == 0)
853 1.6 spz hash_secret_salt = generate_hash_secret_salt(parser);
854 1.3 spz if (ns) {
855 1.3 spz /* implicit context only set for root parser, since child
856 1.3 spz parsers (i.e. external entity parsers) will inherit it
857 1.3 spz */
858 1.3 spz return setContext(parser, implicitContext);
859 1.3 spz }
860 1.3 spz return XML_TRUE;
861 1.3 spz }
862 1.3 spz
863 1.1 tron XML_Parser XMLCALL
864 1.1 tron XML_ParserCreate_MM(const XML_Char *encodingName,
865 1.1 tron const XML_Memory_Handling_Suite *memsuite,
866 1.1 tron const XML_Char *nameSep)
867 1.1 tron {
868 1.3 spz return parserCreate(encodingName, memsuite, nameSep, NULL);
869 1.1 tron }
870 1.1 tron
871 1.1 tron static XML_Parser
872 1.1 tron parserCreate(const XML_Char *encodingName,
873 1.1 tron const XML_Memory_Handling_Suite *memsuite,
874 1.1 tron const XML_Char *nameSep,
875 1.1 tron DTD *dtd)
876 1.1 tron {
877 1.1 tron XML_Parser parser;
878 1.1 tron
879 1.1 tron if (memsuite) {
880 1.1 tron XML_Memory_Handling_Suite *mtemp;
881 1.1 tron parser = (XML_Parser)
882 1.1 tron memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
883 1.1 tron if (parser != NULL) {
884 1.1 tron mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
885 1.1 tron mtemp->malloc_fcn = memsuite->malloc_fcn;
886 1.1 tron mtemp->realloc_fcn = memsuite->realloc_fcn;
887 1.1 tron mtemp->free_fcn = memsuite->free_fcn;
888 1.1 tron }
889 1.1 tron }
890 1.1 tron else {
891 1.1 tron XML_Memory_Handling_Suite *mtemp;
892 1.1 tron parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
893 1.1 tron if (parser != NULL) {
894 1.1 tron mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
895 1.1 tron mtemp->malloc_fcn = malloc;
896 1.1 tron mtemp->realloc_fcn = realloc;
897 1.1 tron mtemp->free_fcn = free;
898 1.1 tron }
899 1.1 tron }
900 1.1 tron
901 1.1 tron if (!parser)
902 1.1 tron return parser;
903 1.1 tron
904 1.1 tron buffer = NULL;
905 1.1 tron bufferLim = NULL;
906 1.1 tron
907 1.1 tron attsSize = INIT_ATTS_SIZE;
908 1.1 tron atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
909 1.1 tron if (atts == NULL) {
910 1.1 tron FREE(parser);
911 1.1 tron return NULL;
912 1.1 tron }
913 1.3 spz #ifdef XML_ATTR_INFO
914 1.3 spz attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
915 1.3 spz if (attInfo == NULL) {
916 1.3 spz FREE(atts);
917 1.3 spz FREE(parser);
918 1.3 spz return NULL;
919 1.3 spz }
920 1.3 spz #endif
921 1.1 tron dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
922 1.1 tron if (dataBuf == NULL) {
923 1.1 tron FREE(atts);
924 1.3 spz #ifdef XML_ATTR_INFO
925 1.3 spz FREE(attInfo);
926 1.3 spz #endif
927 1.1 tron FREE(parser);
928 1.1 tron return NULL;
929 1.1 tron }
930 1.1 tron dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
931 1.1 tron
932 1.1 tron if (dtd)
933 1.1 tron _dtd = dtd;
934 1.1 tron else {
935 1.1 tron _dtd = dtdCreate(&parser->m_mem);
936 1.1 tron if (_dtd == NULL) {
937 1.1 tron FREE(dataBuf);
938 1.1 tron FREE(atts);
939 1.3 spz #ifdef XML_ATTR_INFO
940 1.3 spz FREE(attInfo);
941 1.3 spz #endif
942 1.1 tron FREE(parser);
943 1.1 tron return NULL;
944 1.1 tron }
945 1.1 tron }
946 1.1 tron
947 1.1 tron freeBindingList = NULL;
948 1.1 tron freeTagList = NULL;
949 1.1 tron freeInternalEntities = NULL;
950 1.1 tron
951 1.1 tron groupSize = 0;
952 1.1 tron groupConnector = NULL;
953 1.1 tron
954 1.1 tron unknownEncodingHandler = NULL;
955 1.1 tron unknownEncodingHandlerData = NULL;
956 1.1 tron
957 1.1 tron namespaceSeparator = ASCII_EXCL;
958 1.1 tron ns = XML_FALSE;
959 1.1 tron ns_triplets = XML_FALSE;
960 1.1 tron
961 1.1 tron nsAtts = NULL;
962 1.1 tron nsAttsVersion = 0;
963 1.1 tron nsAttsPower = 0;
964 1.1 tron
965 1.1 tron poolInit(&tempPool, &(parser->m_mem));
966 1.1 tron poolInit(&temp2Pool, &(parser->m_mem));
967 1.1 tron parserInit(parser, encodingName);
968 1.1 tron
969 1.1 tron if (encodingName && !protocolEncodingName) {
970 1.1 tron XML_ParserFree(parser);
971 1.1 tron return NULL;
972 1.1 tron }
973 1.1 tron
974 1.1 tron if (nameSep) {
975 1.1 tron ns = XML_TRUE;
976 1.1 tron internalEncoding = XmlGetInternalEncodingNS();
977 1.1 tron namespaceSeparator = *nameSep;
978 1.1 tron }
979 1.1 tron else {
980 1.1 tron internalEncoding = XmlGetInternalEncoding();
981 1.1 tron }
982 1.1 tron
983 1.1 tron return parser;
984 1.1 tron }
985 1.1 tron
986 1.1 tron static void
987 1.1 tron parserInit(XML_Parser parser, const XML_Char *encodingName)
988 1.1 tron {
989 1.1 tron processor = prologInitProcessor;
990 1.1 tron XmlPrologStateInit(&prologState);
991 1.1 tron protocolEncodingName = (encodingName != NULL
992 1.1 tron ? poolCopyString(&tempPool, encodingName)
993 1.1 tron : NULL);
994 1.1 tron curBase = NULL;
995 1.1 tron XmlInitEncoding(&initEncoding, &encoding, 0);
996 1.1 tron userData = NULL;
997 1.1 tron handlerArg = NULL;
998 1.1 tron startElementHandler = NULL;
999 1.1 tron endElementHandler = NULL;
1000 1.1 tron characterDataHandler = NULL;
1001 1.1 tron processingInstructionHandler = NULL;
1002 1.1 tron commentHandler = NULL;
1003 1.1 tron startCdataSectionHandler = NULL;
1004 1.1 tron endCdataSectionHandler = NULL;
1005 1.1 tron defaultHandler = NULL;
1006 1.1 tron startDoctypeDeclHandler = NULL;
1007 1.1 tron endDoctypeDeclHandler = NULL;
1008 1.1 tron unparsedEntityDeclHandler = NULL;
1009 1.1 tron notationDeclHandler = NULL;
1010 1.1 tron startNamespaceDeclHandler = NULL;
1011 1.1 tron endNamespaceDeclHandler = NULL;
1012 1.1 tron notStandaloneHandler = NULL;
1013 1.1 tron externalEntityRefHandler = NULL;
1014 1.1 tron externalEntityRefHandlerArg = parser;
1015 1.1 tron skippedEntityHandler = NULL;
1016 1.1 tron elementDeclHandler = NULL;
1017 1.1 tron attlistDeclHandler = NULL;
1018 1.1 tron entityDeclHandler = NULL;
1019 1.1 tron xmlDeclHandler = NULL;
1020 1.1 tron bufferPtr = buffer;
1021 1.1 tron bufferEnd = buffer;
1022 1.1 tron parseEndByteIndex = 0;
1023 1.1 tron parseEndPtr = NULL;
1024 1.1 tron declElementType = NULL;
1025 1.1 tron declAttributeId = NULL;
1026 1.1 tron declEntity = NULL;
1027 1.1 tron doctypeName = NULL;
1028 1.1 tron doctypeSysid = NULL;
1029 1.1 tron doctypePubid = NULL;
1030 1.1 tron declAttributeType = NULL;
1031 1.1 tron declNotationName = NULL;
1032 1.1 tron declNotationPublicId = NULL;
1033 1.1 tron declAttributeIsCdata = XML_FALSE;
1034 1.1 tron declAttributeIsId = XML_FALSE;
1035 1.1 tron memset(&position, 0, sizeof(POSITION));
1036 1.1 tron errorCode = XML_ERROR_NONE;
1037 1.1 tron eventPtr = NULL;
1038 1.1 tron eventEndPtr = NULL;
1039 1.1 tron positionPtr = NULL;
1040 1.1 tron openInternalEntities = NULL;
1041 1.1 tron defaultExpandInternalEntities = XML_TRUE;
1042 1.1 tron tagLevel = 0;
1043 1.1 tron tagStack = NULL;
1044 1.1 tron inheritedBindings = NULL;
1045 1.1 tron nSpecifiedAtts = 0;
1046 1.1 tron unknownEncodingMem = NULL;
1047 1.1 tron unknownEncodingRelease = NULL;
1048 1.1 tron unknownEncodingData = NULL;
1049 1.1 tron parentParser = NULL;
1050 1.1 tron ps_parsing = XML_INITIALIZED;
1051 1.1 tron #ifdef XML_DTD
1052 1.1 tron isParamEntity = XML_FALSE;
1053 1.1 tron useForeignDTD = XML_FALSE;
1054 1.1 tron paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
1055 1.1 tron #endif
1056 1.3 spz hash_secret_salt = 0;
1057 1.1 tron }
1058 1.1 tron
1059 1.1 tron /* moves list of bindings to freeBindingList */
1060 1.1 tron static void FASTCALL
1061 1.1 tron moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
1062 1.1 tron {
1063 1.1 tron while (bindings) {
1064 1.1 tron BINDING *b = bindings;
1065 1.1 tron bindings = bindings->nextTagBinding;
1066 1.1 tron b->nextTagBinding = freeBindingList;
1067 1.1 tron freeBindingList = b;
1068 1.1 tron }
1069 1.1 tron }
1070 1.1 tron
1071 1.1 tron XML_Bool XMLCALL
1072 1.1 tron XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
1073 1.1 tron {
1074 1.1 tron TAG *tStk;
1075 1.1 tron OPEN_INTERNAL_ENTITY *openEntityList;
1076 1.7 christos
1077 1.7 christos if (parser == NULL)
1078 1.7 christos return XML_FALSE;
1079 1.7 christos
1080 1.1 tron if (parentParser)
1081 1.1 tron return XML_FALSE;
1082 1.1 tron /* move tagStack to freeTagList */
1083 1.1 tron tStk = tagStack;
1084 1.1 tron while (tStk) {
1085 1.1 tron TAG *tag = tStk;
1086 1.1 tron tStk = tStk->parent;
1087 1.1 tron tag->parent = freeTagList;
1088 1.1 tron moveToFreeBindingList(parser, tag->bindings);
1089 1.1 tron tag->bindings = NULL;
1090 1.1 tron freeTagList = tag;
1091 1.1 tron }
1092 1.1 tron /* move openInternalEntities to freeInternalEntities */
1093 1.1 tron openEntityList = openInternalEntities;
1094 1.1 tron while (openEntityList) {
1095 1.1 tron OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
1096 1.1 tron openEntityList = openEntity->next;
1097 1.1 tron openEntity->next = freeInternalEntities;
1098 1.1 tron freeInternalEntities = openEntity;
1099 1.1 tron }
1100 1.1 tron moveToFreeBindingList(parser, inheritedBindings);
1101 1.1 tron FREE(unknownEncodingMem);
1102 1.1 tron if (unknownEncodingRelease)
1103 1.1 tron unknownEncodingRelease(unknownEncodingData);
1104 1.1 tron poolClear(&tempPool);
1105 1.1 tron poolClear(&temp2Pool);
1106 1.1 tron parserInit(parser, encodingName);
1107 1.1 tron dtdReset(_dtd, &parser->m_mem);
1108 1.3 spz return XML_TRUE;
1109 1.1 tron }
1110 1.1 tron
1111 1.1 tron enum XML_Status XMLCALL
1112 1.1 tron XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
1113 1.1 tron {
1114 1.7 christos if (parser == NULL)
1115 1.7 christos return XML_STATUS_ERROR;
1116 1.1 tron /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1117 1.1 tron XXX There's no way for the caller to determine which of the
1118 1.1 tron XXX possible error cases caused the XML_STATUS_ERROR return.
1119 1.1 tron */
1120 1.1 tron if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1121 1.1 tron return XML_STATUS_ERROR;
1122 1.1 tron if (encodingName == NULL)
1123 1.1 tron protocolEncodingName = NULL;
1124 1.1 tron else {
1125 1.1 tron protocolEncodingName = poolCopyString(&tempPool, encodingName);
1126 1.1 tron if (!protocolEncodingName)
1127 1.1 tron return XML_STATUS_ERROR;
1128 1.1 tron }
1129 1.1 tron return XML_STATUS_OK;
1130 1.1 tron }
1131 1.1 tron
1132 1.1 tron XML_Parser XMLCALL
1133 1.1 tron XML_ExternalEntityParserCreate(XML_Parser oldParser,
1134 1.1 tron const XML_Char *context,
1135 1.1 tron const XML_Char *encodingName)
1136 1.1 tron {
1137 1.1 tron XML_Parser parser = oldParser;
1138 1.1 tron DTD *newDtd = NULL;
1139 1.7 christos DTD *oldDtd;
1140 1.7 christos XML_StartElementHandler oldStartElementHandler;
1141 1.7 christos XML_EndElementHandler oldEndElementHandler;
1142 1.7 christos XML_CharacterDataHandler oldCharacterDataHandler;
1143 1.7 christos XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1144 1.7 christos XML_CommentHandler oldCommentHandler;
1145 1.7 christos XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1146 1.7 christos XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1147 1.7 christos XML_DefaultHandler oldDefaultHandler;
1148 1.7 christos XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1149 1.7 christos XML_NotationDeclHandler oldNotationDeclHandler;
1150 1.7 christos XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1151 1.7 christos XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1152 1.7 christos XML_NotStandaloneHandler oldNotStandaloneHandler;
1153 1.7 christos XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1154 1.7 christos XML_SkippedEntityHandler oldSkippedEntityHandler;
1155 1.7 christos XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1156 1.7 christos XML_ElementDeclHandler oldElementDeclHandler;
1157 1.7 christos XML_AttlistDeclHandler oldAttlistDeclHandler;
1158 1.7 christos XML_EntityDeclHandler oldEntityDeclHandler;
1159 1.7 christos XML_XmlDeclHandler oldXmlDeclHandler;
1160 1.7 christos ELEMENT_TYPE * oldDeclElementType;
1161 1.7 christos
1162 1.7 christos void *oldUserData;
1163 1.7 christos void *oldHandlerArg;
1164 1.7 christos XML_Bool oldDefaultExpandInternalEntities;
1165 1.7 christos XML_Parser oldExternalEntityRefHandlerArg;
1166 1.1 tron #ifdef XML_DTD
1167 1.7 christos enum XML_ParamEntityParsing oldParamEntityParsing;
1168 1.7 christos int oldInEntityValue;
1169 1.7 christos #endif
1170 1.7 christos XML_Bool oldns_triplets;
1171 1.7 christos /* Note that the new parser shares the same hash secret as the old
1172 1.7 christos parser, so that dtdCopy and copyEntityTable can lookup values
1173 1.7 christos from hash tables associated with either parser without us having
1174 1.7 christos to worry which hash secrets each table has.
1175 1.7 christos */
1176 1.7 christos unsigned long oldhash_secret_salt;
1177 1.7 christos
1178 1.7 christos /* Validate the oldParser parameter before we pull everything out of it */
1179 1.7 christos if (oldParser == NULL)
1180 1.7 christos return NULL;
1181 1.7 christos
1182 1.7 christos /* Stash the original parser contents on the stack */
1183 1.7 christos oldDtd = _dtd;
1184 1.7 christos oldStartElementHandler = startElementHandler;
1185 1.7 christos oldEndElementHandler = endElementHandler;
1186 1.7 christos oldCharacterDataHandler = characterDataHandler;
1187 1.7 christos oldProcessingInstructionHandler = processingInstructionHandler;
1188 1.7 christos oldCommentHandler = commentHandler;
1189 1.7 christos oldStartCdataSectionHandler = startCdataSectionHandler;
1190 1.7 christos oldEndCdataSectionHandler = endCdataSectionHandler;
1191 1.7 christos oldDefaultHandler = defaultHandler;
1192 1.7 christos oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
1193 1.7 christos oldNotationDeclHandler = notationDeclHandler;
1194 1.7 christos oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
1195 1.7 christos oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
1196 1.7 christos oldNotStandaloneHandler = notStandaloneHandler;
1197 1.7 christos oldExternalEntityRefHandler = externalEntityRefHandler;
1198 1.7 christos oldSkippedEntityHandler = skippedEntityHandler;
1199 1.7 christos oldUnknownEncodingHandler = unknownEncodingHandler;
1200 1.7 christos oldElementDeclHandler = elementDeclHandler;
1201 1.7 christos oldAttlistDeclHandler = attlistDeclHandler;
1202 1.7 christos oldEntityDeclHandler = entityDeclHandler;
1203 1.7 christos oldXmlDeclHandler = xmlDeclHandler;
1204 1.7 christos oldDeclElementType = declElementType;
1205 1.7 christos
1206 1.7 christos oldUserData = userData;
1207 1.7 christos oldHandlerArg = handlerArg;
1208 1.7 christos oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
1209 1.7 christos oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
1210 1.7 christos #ifdef XML_DTD
1211 1.7 christos oldParamEntityParsing = paramEntityParsing;
1212 1.7 christos oldInEntityValue = prologState.inEntityValue;
1213 1.1 tron #endif
1214 1.7 christos oldns_triplets = ns_triplets;
1215 1.3 spz /* Note that the new parser shares the same hash secret as the old
1216 1.3 spz parser, so that dtdCopy and copyEntityTable can lookup values
1217 1.3 spz from hash tables associated with either parser without us having
1218 1.3 spz to worry which hash secrets each table has.
1219 1.3 spz */
1220 1.7 christos oldhash_secret_salt = hash_secret_salt;
1221 1.1 tron
1222 1.1 tron #ifdef XML_DTD
1223 1.1 tron if (!context)
1224 1.1 tron newDtd = oldDtd;
1225 1.1 tron #endif /* XML_DTD */
1226 1.1 tron
1227 1.1 tron /* Note that the magical uses of the pre-processor to make field
1228 1.1 tron access look more like C++ require that `parser' be overwritten
1229 1.1 tron here. This makes this function more painful to follow than it
1230 1.1 tron would be otherwise.
1231 1.1 tron */
1232 1.1 tron if (ns) {
1233 1.1 tron XML_Char tmp[2];
1234 1.1 tron *tmp = namespaceSeparator;
1235 1.1 tron parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1236 1.1 tron }
1237 1.1 tron else {
1238 1.1 tron parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1239 1.1 tron }
1240 1.1 tron
1241 1.1 tron if (!parser)
1242 1.1 tron return NULL;
1243 1.1 tron
1244 1.1 tron startElementHandler = oldStartElementHandler;
1245 1.1 tron endElementHandler = oldEndElementHandler;
1246 1.1 tron characterDataHandler = oldCharacterDataHandler;
1247 1.1 tron processingInstructionHandler = oldProcessingInstructionHandler;
1248 1.1 tron commentHandler = oldCommentHandler;
1249 1.1 tron startCdataSectionHandler = oldStartCdataSectionHandler;
1250 1.1 tron endCdataSectionHandler = oldEndCdataSectionHandler;
1251 1.1 tron defaultHandler = oldDefaultHandler;
1252 1.1 tron unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1253 1.1 tron notationDeclHandler = oldNotationDeclHandler;
1254 1.1 tron startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1255 1.1 tron endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1256 1.1 tron notStandaloneHandler = oldNotStandaloneHandler;
1257 1.1 tron externalEntityRefHandler = oldExternalEntityRefHandler;
1258 1.1 tron skippedEntityHandler = oldSkippedEntityHandler;
1259 1.1 tron unknownEncodingHandler = oldUnknownEncodingHandler;
1260 1.1 tron elementDeclHandler = oldElementDeclHandler;
1261 1.1 tron attlistDeclHandler = oldAttlistDeclHandler;
1262 1.1 tron entityDeclHandler = oldEntityDeclHandler;
1263 1.1 tron xmlDeclHandler = oldXmlDeclHandler;
1264 1.1 tron declElementType = oldDeclElementType;
1265 1.1 tron userData = oldUserData;
1266 1.1 tron if (oldUserData == oldHandlerArg)
1267 1.1 tron handlerArg = userData;
1268 1.1 tron else
1269 1.1 tron handlerArg = parser;
1270 1.1 tron if (oldExternalEntityRefHandlerArg != oldParser)
1271 1.1 tron externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1272 1.1 tron defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1273 1.1 tron ns_triplets = oldns_triplets;
1274 1.3 spz hash_secret_salt = oldhash_secret_salt;
1275 1.1 tron parentParser = oldParser;
1276 1.1 tron #ifdef XML_DTD
1277 1.1 tron paramEntityParsing = oldParamEntityParsing;
1278 1.1 tron prologState.inEntityValue = oldInEntityValue;
1279 1.1 tron if (context) {
1280 1.1 tron #endif /* XML_DTD */
1281 1.3 spz if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
1282 1.1 tron || !setContext(parser, context)) {
1283 1.1 tron XML_ParserFree(parser);
1284 1.1 tron return NULL;
1285 1.1 tron }
1286 1.1 tron processor = externalEntityInitProcessor;
1287 1.1 tron #ifdef XML_DTD
1288 1.1 tron }
1289 1.1 tron else {
1290 1.1 tron /* The DTD instance referenced by _dtd is shared between the document's
1291 1.1 tron root parser and external PE parsers, therefore one does not need to
1292 1.1 tron call setContext. In addition, one also *must* not call setContext,
1293 1.1 tron because this would overwrite existing prefix->binding pointers in
1294 1.1 tron _dtd with ones that get destroyed with the external PE parser.
1295 1.1 tron This would leave those prefixes with dangling pointers.
1296 1.1 tron */
1297 1.1 tron isParamEntity = XML_TRUE;
1298 1.1 tron XmlPrologStateInitExternalEntity(&prologState);
1299 1.1 tron processor = externalParEntInitProcessor;
1300 1.1 tron }
1301 1.1 tron #endif /* XML_DTD */
1302 1.1 tron return parser;
1303 1.1 tron }
1304 1.1 tron
1305 1.1 tron static void FASTCALL
1306 1.1 tron destroyBindings(BINDING *bindings, XML_Parser parser)
1307 1.1 tron {
1308 1.1 tron for (;;) {
1309 1.1 tron BINDING *b = bindings;
1310 1.1 tron if (!b)
1311 1.1 tron break;
1312 1.1 tron bindings = b->nextTagBinding;
1313 1.1 tron FREE(b->uri);
1314 1.1 tron FREE(b);
1315 1.1 tron }
1316 1.1 tron }
1317 1.1 tron
1318 1.1 tron void XMLCALL
1319 1.1 tron XML_ParserFree(XML_Parser parser)
1320 1.1 tron {
1321 1.1 tron TAG *tagList;
1322 1.1 tron OPEN_INTERNAL_ENTITY *entityList;
1323 1.1 tron if (parser == NULL)
1324 1.1 tron return;
1325 1.1 tron /* free tagStack and freeTagList */
1326 1.1 tron tagList = tagStack;
1327 1.1 tron for (;;) {
1328 1.1 tron TAG *p;
1329 1.1 tron if (tagList == NULL) {
1330 1.1 tron if (freeTagList == NULL)
1331 1.1 tron break;
1332 1.1 tron tagList = freeTagList;
1333 1.1 tron freeTagList = NULL;
1334 1.1 tron }
1335 1.1 tron p = tagList;
1336 1.1 tron tagList = tagList->parent;
1337 1.1 tron FREE(p->buf);
1338 1.1 tron destroyBindings(p->bindings, parser);
1339 1.1 tron FREE(p);
1340 1.1 tron }
1341 1.1 tron /* free openInternalEntities and freeInternalEntities */
1342 1.1 tron entityList = openInternalEntities;
1343 1.1 tron for (;;) {
1344 1.1 tron OPEN_INTERNAL_ENTITY *openEntity;
1345 1.1 tron if (entityList == NULL) {
1346 1.1 tron if (freeInternalEntities == NULL)
1347 1.1 tron break;
1348 1.1 tron entityList = freeInternalEntities;
1349 1.1 tron freeInternalEntities = NULL;
1350 1.1 tron }
1351 1.1 tron openEntity = entityList;
1352 1.1 tron entityList = entityList->next;
1353 1.1 tron FREE(openEntity);
1354 1.1 tron }
1355 1.1 tron
1356 1.1 tron destroyBindings(freeBindingList, parser);
1357 1.1 tron destroyBindings(inheritedBindings, parser);
1358 1.1 tron poolDestroy(&tempPool);
1359 1.1 tron poolDestroy(&temp2Pool);
1360 1.1 tron #ifdef XML_DTD
1361 1.1 tron /* external parameter entity parsers share the DTD structure
1362 1.1 tron parser->m_dtd with the root parser, so we must not destroy it
1363 1.1 tron */
1364 1.1 tron if (!isParamEntity && _dtd)
1365 1.1 tron #else
1366 1.1 tron if (_dtd)
1367 1.1 tron #endif /* XML_DTD */
1368 1.1 tron dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1369 1.1 tron FREE((void *)atts);
1370 1.3 spz #ifdef XML_ATTR_INFO
1371 1.3 spz FREE((void *)attInfo);
1372 1.3 spz #endif
1373 1.1 tron FREE(groupConnector);
1374 1.1 tron FREE(buffer);
1375 1.1 tron FREE(dataBuf);
1376 1.1 tron FREE(nsAtts);
1377 1.1 tron FREE(unknownEncodingMem);
1378 1.1 tron if (unknownEncodingRelease)
1379 1.1 tron unknownEncodingRelease(unknownEncodingData);
1380 1.1 tron FREE(parser);
1381 1.1 tron }
1382 1.1 tron
1383 1.1 tron void XMLCALL
1384 1.1 tron XML_UseParserAsHandlerArg(XML_Parser parser)
1385 1.1 tron {
1386 1.7 christos if (parser != NULL)
1387 1.7 christos handlerArg = parser;
1388 1.1 tron }
1389 1.1 tron
1390 1.1 tron enum XML_Error XMLCALL
1391 1.1 tron XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1392 1.1 tron {
1393 1.7 christos if (parser == NULL)
1394 1.7 christos return XML_ERROR_INVALID_ARGUMENT;
1395 1.1 tron #ifdef XML_DTD
1396 1.1 tron /* block after XML_Parse()/XML_ParseBuffer() has been called */
1397 1.1 tron if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1398 1.1 tron return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1399 1.1 tron useForeignDTD = useDTD;
1400 1.1 tron return XML_ERROR_NONE;
1401 1.1 tron #else
1402 1.1 tron return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1403 1.1 tron #endif
1404 1.1 tron }
1405 1.1 tron
1406 1.1 tron void XMLCALL
1407 1.1 tron XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1408 1.1 tron {
1409 1.7 christos if (parser == NULL)
1410 1.7 christos return;
1411 1.1 tron /* block after XML_Parse()/XML_ParseBuffer() has been called */
1412 1.1 tron if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1413 1.1 tron return;
1414 1.1 tron ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1415 1.1 tron }
1416 1.1 tron
1417 1.1 tron void XMLCALL
1418 1.1 tron XML_SetUserData(XML_Parser parser, void *p)
1419 1.1 tron {
1420 1.7 christos if (parser == NULL)
1421 1.7 christos return;
1422 1.1 tron if (handlerArg == userData)
1423 1.1 tron handlerArg = userData = p;
1424 1.1 tron else
1425 1.1 tron userData = p;
1426 1.1 tron }
1427 1.1 tron
1428 1.1 tron enum XML_Status XMLCALL
1429 1.1 tron XML_SetBase(XML_Parser parser, const XML_Char *p)
1430 1.1 tron {
1431 1.7 christos if (parser == NULL)
1432 1.7 christos return XML_STATUS_ERROR;
1433 1.1 tron if (p) {
1434 1.1 tron p = poolCopyString(&_dtd->pool, p);
1435 1.1 tron if (!p)
1436 1.1 tron return XML_STATUS_ERROR;
1437 1.1 tron curBase = p;
1438 1.1 tron }
1439 1.1 tron else
1440 1.1 tron curBase = NULL;
1441 1.1 tron return XML_STATUS_OK;
1442 1.1 tron }
1443 1.1 tron
1444 1.1 tron const XML_Char * XMLCALL
1445 1.1 tron XML_GetBase(XML_Parser parser)
1446 1.1 tron {
1447 1.7 christos if (parser == NULL)
1448 1.7 christos return NULL;
1449 1.1 tron return curBase;
1450 1.1 tron }
1451 1.1 tron
1452 1.1 tron int XMLCALL
1453 1.1 tron XML_GetSpecifiedAttributeCount(XML_Parser parser)
1454 1.1 tron {
1455 1.7 christos if (parser == NULL)
1456 1.7 christos return -1;
1457 1.1 tron return nSpecifiedAtts;
1458 1.1 tron }
1459 1.1 tron
1460 1.1 tron int XMLCALL
1461 1.1 tron XML_GetIdAttributeIndex(XML_Parser parser)
1462 1.1 tron {
1463 1.7 christos if (parser == NULL)
1464 1.7 christos return -1;
1465 1.1 tron return idAttIndex;
1466 1.1 tron }
1467 1.1 tron
1468 1.3 spz #ifdef XML_ATTR_INFO
1469 1.3 spz const XML_AttrInfo * XMLCALL
1470 1.3 spz XML_GetAttributeInfo(XML_Parser parser)
1471 1.3 spz {
1472 1.7 christos if (parser == NULL)
1473 1.7 christos return NULL;
1474 1.3 spz return attInfo;
1475 1.3 spz }
1476 1.3 spz #endif
1477 1.3 spz
1478 1.1 tron void XMLCALL
1479 1.1 tron XML_SetElementHandler(XML_Parser parser,
1480 1.1 tron XML_StartElementHandler start,
1481 1.1 tron XML_EndElementHandler end)
1482 1.1 tron {
1483 1.7 christos if (parser == NULL)
1484 1.7 christos return;
1485 1.1 tron startElementHandler = start;
1486 1.1 tron endElementHandler = end;
1487 1.1 tron }
1488 1.1 tron
1489 1.1 tron void XMLCALL
1490 1.1 tron XML_SetStartElementHandler(XML_Parser parser,
1491 1.1 tron XML_StartElementHandler start) {
1492 1.7 christos if (parser != NULL)
1493 1.7 christos startElementHandler = start;
1494 1.1 tron }
1495 1.1 tron
1496 1.1 tron void XMLCALL
1497 1.1 tron XML_SetEndElementHandler(XML_Parser parser,
1498 1.1 tron XML_EndElementHandler end) {
1499 1.7 christos if (parser != NULL)
1500 1.7 christos endElementHandler = end;
1501 1.1 tron }
1502 1.1 tron
1503 1.1 tron void XMLCALL
1504 1.1 tron XML_SetCharacterDataHandler(XML_Parser parser,
1505 1.1 tron XML_CharacterDataHandler handler)
1506 1.1 tron {
1507 1.7 christos if (parser != NULL)
1508 1.7 christos characterDataHandler = handler;
1509 1.1 tron }
1510 1.1 tron
1511 1.1 tron void XMLCALL
1512 1.1 tron XML_SetProcessingInstructionHandler(XML_Parser parser,
1513 1.1 tron XML_ProcessingInstructionHandler handler)
1514 1.1 tron {
1515 1.7 christos if (parser != NULL)
1516 1.7 christos processingInstructionHandler = handler;
1517 1.1 tron }
1518 1.1 tron
1519 1.1 tron void XMLCALL
1520 1.1 tron XML_SetCommentHandler(XML_Parser parser,
1521 1.1 tron XML_CommentHandler handler)
1522 1.1 tron {
1523 1.7 christos if (parser != NULL)
1524 1.7 christos commentHandler = handler;
1525 1.1 tron }
1526 1.1 tron
1527 1.1 tron void XMLCALL
1528 1.1 tron XML_SetCdataSectionHandler(XML_Parser parser,
1529 1.1 tron XML_StartCdataSectionHandler start,
1530 1.1 tron XML_EndCdataSectionHandler end)
1531 1.1 tron {
1532 1.7 christos if (parser == NULL)
1533 1.7 christos return;
1534 1.1 tron startCdataSectionHandler = start;
1535 1.1 tron endCdataSectionHandler = end;
1536 1.1 tron }
1537 1.1 tron
1538 1.1 tron void XMLCALL
1539 1.1 tron XML_SetStartCdataSectionHandler(XML_Parser parser,
1540 1.1 tron XML_StartCdataSectionHandler start) {
1541 1.7 christos if (parser != NULL)
1542 1.7 christos startCdataSectionHandler = start;
1543 1.1 tron }
1544 1.1 tron
1545 1.1 tron void XMLCALL
1546 1.1 tron XML_SetEndCdataSectionHandler(XML_Parser parser,
1547 1.1 tron XML_EndCdataSectionHandler end) {
1548 1.7 christos if (parser != NULL)
1549 1.7 christos endCdataSectionHandler = end;
1550 1.1 tron }
1551 1.1 tron
1552 1.1 tron void XMLCALL
1553 1.1 tron XML_SetDefaultHandler(XML_Parser parser,
1554 1.1 tron XML_DefaultHandler handler)
1555 1.1 tron {
1556 1.7 christos if (parser == NULL)
1557 1.7 christos return;
1558 1.1 tron defaultHandler = handler;
1559 1.1 tron defaultExpandInternalEntities = XML_FALSE;
1560 1.1 tron }
1561 1.1 tron
1562 1.1 tron void XMLCALL
1563 1.1 tron XML_SetDefaultHandlerExpand(XML_Parser parser,
1564 1.1 tron XML_DefaultHandler handler)
1565 1.1 tron {
1566 1.7 christos if (parser == NULL)
1567 1.7 christos return;
1568 1.1 tron defaultHandler = handler;
1569 1.1 tron defaultExpandInternalEntities = XML_TRUE;
1570 1.1 tron }
1571 1.1 tron
1572 1.1 tron void XMLCALL
1573 1.1 tron XML_SetDoctypeDeclHandler(XML_Parser parser,
1574 1.1 tron XML_StartDoctypeDeclHandler start,
1575 1.1 tron XML_EndDoctypeDeclHandler end)
1576 1.1 tron {
1577 1.7 christos if (parser == NULL)
1578 1.7 christos return;
1579 1.1 tron startDoctypeDeclHandler = start;
1580 1.1 tron endDoctypeDeclHandler = end;
1581 1.1 tron }
1582 1.1 tron
1583 1.1 tron void XMLCALL
1584 1.1 tron XML_SetStartDoctypeDeclHandler(XML_Parser parser,
1585 1.1 tron XML_StartDoctypeDeclHandler start) {
1586 1.7 christos if (parser != NULL)
1587 1.7 christos startDoctypeDeclHandler = start;
1588 1.1 tron }
1589 1.1 tron
1590 1.1 tron void XMLCALL
1591 1.1 tron XML_SetEndDoctypeDeclHandler(XML_Parser parser,
1592 1.1 tron XML_EndDoctypeDeclHandler end) {
1593 1.7 christos if (parser != NULL)
1594 1.7 christos endDoctypeDeclHandler = end;
1595 1.1 tron }
1596 1.1 tron
1597 1.1 tron void XMLCALL
1598 1.1 tron XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1599 1.1 tron XML_UnparsedEntityDeclHandler handler)
1600 1.1 tron {
1601 1.7 christos if (parser != NULL)
1602 1.7 christos unparsedEntityDeclHandler = handler;
1603 1.1 tron }
1604 1.1 tron
1605 1.1 tron void XMLCALL
1606 1.1 tron XML_SetNotationDeclHandler(XML_Parser parser,
1607 1.1 tron XML_NotationDeclHandler handler)
1608 1.1 tron {
1609 1.7 christos if (parser != NULL)
1610 1.7 christos notationDeclHandler = handler;
1611 1.1 tron }
1612 1.1 tron
1613 1.1 tron void XMLCALL
1614 1.1 tron XML_SetNamespaceDeclHandler(XML_Parser parser,
1615 1.1 tron XML_StartNamespaceDeclHandler start,
1616 1.1 tron XML_EndNamespaceDeclHandler end)
1617 1.1 tron {
1618 1.7 christos if (parser == NULL)
1619 1.7 christos return;
1620 1.1 tron startNamespaceDeclHandler = start;
1621 1.1 tron endNamespaceDeclHandler = end;
1622 1.1 tron }
1623 1.1 tron
1624 1.1 tron void XMLCALL
1625 1.1 tron XML_SetStartNamespaceDeclHandler(XML_Parser parser,
1626 1.1 tron XML_StartNamespaceDeclHandler start) {
1627 1.7 christos if (parser != NULL)
1628 1.7 christos startNamespaceDeclHandler = start;
1629 1.1 tron }
1630 1.1 tron
1631 1.1 tron void XMLCALL
1632 1.1 tron XML_SetEndNamespaceDeclHandler(XML_Parser parser,
1633 1.1 tron XML_EndNamespaceDeclHandler end) {
1634 1.7 christos if (parser != NULL)
1635 1.7 christos endNamespaceDeclHandler = end;
1636 1.1 tron }
1637 1.1 tron
1638 1.1 tron void XMLCALL
1639 1.1 tron XML_SetNotStandaloneHandler(XML_Parser parser,
1640 1.1 tron XML_NotStandaloneHandler handler)
1641 1.1 tron {
1642 1.7 christos if (parser != NULL)
1643 1.7 christos notStandaloneHandler = handler;
1644 1.1 tron }
1645 1.1 tron
1646 1.1 tron void XMLCALL
1647 1.1 tron XML_SetExternalEntityRefHandler(XML_Parser parser,
1648 1.1 tron XML_ExternalEntityRefHandler handler)
1649 1.1 tron {
1650 1.7 christos if (parser != NULL)
1651 1.7 christos externalEntityRefHandler = handler;
1652 1.1 tron }
1653 1.1 tron
1654 1.1 tron void XMLCALL
1655 1.1 tron XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1656 1.1 tron {
1657 1.7 christos if (parser == NULL)
1658 1.7 christos return;
1659 1.1 tron if (arg)
1660 1.1 tron externalEntityRefHandlerArg = (XML_Parser)arg;
1661 1.1 tron else
1662 1.1 tron externalEntityRefHandlerArg = parser;
1663 1.1 tron }
1664 1.1 tron
1665 1.1 tron void XMLCALL
1666 1.1 tron XML_SetSkippedEntityHandler(XML_Parser parser,
1667 1.1 tron XML_SkippedEntityHandler handler)
1668 1.1 tron {
1669 1.7 christos if (parser != NULL)
1670 1.7 christos skippedEntityHandler = handler;
1671 1.1 tron }
1672 1.1 tron
1673 1.1 tron void XMLCALL
1674 1.1 tron XML_SetUnknownEncodingHandler(XML_Parser parser,
1675 1.1 tron XML_UnknownEncodingHandler handler,
1676 1.1 tron void *data)
1677 1.1 tron {
1678 1.7 christos if (parser == NULL)
1679 1.7 christos return;
1680 1.1 tron unknownEncodingHandler = handler;
1681 1.1 tron unknownEncodingHandlerData = data;
1682 1.1 tron }
1683 1.1 tron
1684 1.1 tron void XMLCALL
1685 1.1 tron XML_SetElementDeclHandler(XML_Parser parser,
1686 1.1 tron XML_ElementDeclHandler eldecl)
1687 1.1 tron {
1688 1.7 christos if (parser != NULL)
1689 1.7 christos elementDeclHandler = eldecl;
1690 1.1 tron }
1691 1.1 tron
1692 1.1 tron void XMLCALL
1693 1.1 tron XML_SetAttlistDeclHandler(XML_Parser parser,
1694 1.1 tron XML_AttlistDeclHandler attdecl)
1695 1.1 tron {
1696 1.7 christos if (parser != NULL)
1697 1.7 christos attlistDeclHandler = attdecl;
1698 1.1 tron }
1699 1.1 tron
1700 1.1 tron void XMLCALL
1701 1.1 tron XML_SetEntityDeclHandler(XML_Parser parser,
1702 1.1 tron XML_EntityDeclHandler handler)
1703 1.1 tron {
1704 1.7 christos if (parser != NULL)
1705 1.7 christos entityDeclHandler = handler;
1706 1.1 tron }
1707 1.1 tron
1708 1.1 tron void XMLCALL
1709 1.1 tron XML_SetXmlDeclHandler(XML_Parser parser,
1710 1.1 tron XML_XmlDeclHandler handler) {
1711 1.7 christos if (parser != NULL)
1712 1.7 christos xmlDeclHandler = handler;
1713 1.1 tron }
1714 1.1 tron
1715 1.1 tron int XMLCALL
1716 1.1 tron XML_SetParamEntityParsing(XML_Parser parser,
1717 1.1 tron enum XML_ParamEntityParsing peParsing)
1718 1.1 tron {
1719 1.7 christos if (parser == NULL)
1720 1.7 christos return 0;
1721 1.1 tron /* block after XML_Parse()/XML_ParseBuffer() has been called */
1722 1.1 tron if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1723 1.1 tron return 0;
1724 1.1 tron #ifdef XML_DTD
1725 1.1 tron paramEntityParsing = peParsing;
1726 1.1 tron return 1;
1727 1.1 tron #else
1728 1.1 tron return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1729 1.1 tron #endif
1730 1.1 tron }
1731 1.1 tron
1732 1.3 spz int XMLCALL
1733 1.3 spz XML_SetHashSalt(XML_Parser parser,
1734 1.3 spz unsigned long hash_salt)
1735 1.3 spz {
1736 1.7 christos if (parser == NULL)
1737 1.7 christos return 0;
1738 1.7 christos if (parser->m_parentParser)
1739 1.7 christos return XML_SetHashSalt(parser->m_parentParser, hash_salt);
1740 1.3 spz /* block after XML_Parse()/XML_ParseBuffer() has been called */
1741 1.3 spz if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1742 1.3 spz return 0;
1743 1.3 spz hash_secret_salt = hash_salt;
1744 1.3 spz return 1;
1745 1.3 spz }
1746 1.3 spz
1747 1.1 tron enum XML_Status XMLCALL
1748 1.1 tron XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1749 1.1 tron {
1750 1.7 christos if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
1751 1.7 christos errorCode = XML_ERROR_INVALID_ARGUMENT;
1752 1.7 christos return XML_STATUS_ERROR;
1753 1.7 christos }
1754 1.1 tron switch (ps_parsing) {
1755 1.1 tron case XML_SUSPENDED:
1756 1.1 tron errorCode = XML_ERROR_SUSPENDED;
1757 1.1 tron return XML_STATUS_ERROR;
1758 1.1 tron case XML_FINISHED:
1759 1.1 tron errorCode = XML_ERROR_FINISHED;
1760 1.1 tron return XML_STATUS_ERROR;
1761 1.3 spz case XML_INITIALIZED:
1762 1.3 spz if (parentParser == NULL && !startParsing(parser)) {
1763 1.3 spz errorCode = XML_ERROR_NO_MEMORY;
1764 1.3 spz return XML_STATUS_ERROR;
1765 1.3 spz }
1766 1.1 tron default:
1767 1.1 tron ps_parsing = XML_PARSING;
1768 1.1 tron }
1769 1.1 tron
1770 1.1 tron if (len == 0) {
1771 1.1 tron ps_finalBuffer = (XML_Bool)isFinal;
1772 1.1 tron if (!isFinal)
1773 1.1 tron return XML_STATUS_OK;
1774 1.1 tron positionPtr = bufferPtr;
1775 1.1 tron parseEndPtr = bufferEnd;
1776 1.1 tron
1777 1.1 tron /* If data are left over from last buffer, and we now know that these
1778 1.1 tron data are the final chunk of input, then we have to check them again
1779 1.1 tron to detect errors based on that fact.
1780 1.1 tron */
1781 1.1 tron errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1782 1.1 tron
1783 1.1 tron if (errorCode == XML_ERROR_NONE) {
1784 1.1 tron switch (ps_parsing) {
1785 1.1 tron case XML_SUSPENDED:
1786 1.1 tron XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1787 1.1 tron positionPtr = bufferPtr;
1788 1.1 tron return XML_STATUS_SUSPENDED;
1789 1.3 spz case XML_INITIALIZED:
1790 1.1 tron case XML_PARSING:
1791 1.1 tron ps_parsing = XML_FINISHED;
1792 1.1 tron /* fall through */
1793 1.1 tron default:
1794 1.1 tron return XML_STATUS_OK;
1795 1.1 tron }
1796 1.1 tron }
1797 1.1 tron eventEndPtr = eventPtr;
1798 1.1 tron processor = errorProcessor;
1799 1.1 tron return XML_STATUS_ERROR;
1800 1.1 tron }
1801 1.1 tron #ifndef XML_CONTEXT_BYTES
1802 1.1 tron else if (bufferPtr == bufferEnd) {
1803 1.1 tron const char *end;
1804 1.1 tron int nLeftOver;
1805 1.4 spz enum XML_Status result;
1806 1.7 christos /* Detect overflow (a+b > MAX <==> b > MAX-a) */
1807 1.7 christos if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) {
1808 1.7 christos errorCode = XML_ERROR_NO_MEMORY;
1809 1.7 christos eventPtr = eventEndPtr = NULL;
1810 1.7 christos processor = errorProcessor;
1811 1.7 christos return XML_STATUS_ERROR;
1812 1.7 christos }
1813 1.1 tron parseEndByteIndex += len;
1814 1.1 tron positionPtr = s;
1815 1.1 tron ps_finalBuffer = (XML_Bool)isFinal;
1816 1.1 tron
1817 1.1 tron errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1818 1.1 tron
1819 1.1 tron if (errorCode != XML_ERROR_NONE) {
1820 1.1 tron eventEndPtr = eventPtr;
1821 1.1 tron processor = errorProcessor;
1822 1.1 tron return XML_STATUS_ERROR;
1823 1.1 tron }
1824 1.1 tron else {
1825 1.1 tron switch (ps_parsing) {
1826 1.1 tron case XML_SUSPENDED:
1827 1.1 tron result = XML_STATUS_SUSPENDED;
1828 1.1 tron break;
1829 1.1 tron case XML_INITIALIZED:
1830 1.1 tron case XML_PARSING:
1831 1.1 tron if (isFinal) {
1832 1.1 tron ps_parsing = XML_FINISHED;
1833 1.3 spz return XML_STATUS_OK;
1834 1.1 tron }
1835 1.3 spz /* fall through */
1836 1.3 spz default:
1837 1.3 spz result = XML_STATUS_OK;
1838 1.1 tron }
1839 1.1 tron }
1840 1.1 tron
1841 1.1 tron XmlUpdatePosition(encoding, positionPtr, end, &position);
1842 1.1 tron nLeftOver = s + len - end;
1843 1.1 tron if (nLeftOver) {
1844 1.1 tron if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1845 1.7 christos /* avoid _signed_ integer overflow */
1846 1.7 christos char *temp = NULL;
1847 1.7 christos const int bytesToAllocate = (int)((unsigned)len * 2U);
1848 1.7 christos if (bytesToAllocate > 0) {
1849 1.7 christos temp = (buffer == NULL
1850 1.7 christos ? (char *)MALLOC(bytesToAllocate)
1851 1.7 christos : (char *)REALLOC(buffer, bytesToAllocate));
1852 1.7 christos }
1853 1.1 tron if (temp == NULL) {
1854 1.1 tron errorCode = XML_ERROR_NO_MEMORY;
1855 1.1 tron eventPtr = eventEndPtr = NULL;
1856 1.1 tron processor = errorProcessor;
1857 1.1 tron return XML_STATUS_ERROR;
1858 1.1 tron }
1859 1.3 spz buffer = temp;
1860 1.7 christos bufferLim = buffer + bytesToAllocate;
1861 1.1 tron }
1862 1.1 tron memcpy(buffer, end, nLeftOver);
1863 1.1 tron }
1864 1.1 tron bufferPtr = buffer;
1865 1.1 tron bufferEnd = buffer + nLeftOver;
1866 1.1 tron positionPtr = bufferPtr;
1867 1.1 tron parseEndPtr = bufferEnd;
1868 1.1 tron eventPtr = bufferPtr;
1869 1.1 tron eventEndPtr = bufferPtr;
1870 1.1 tron return result;
1871 1.1 tron }
1872 1.1 tron #endif /* not defined XML_CONTEXT_BYTES */
1873 1.1 tron else {
1874 1.1 tron void *buff = XML_GetBuffer(parser, len);
1875 1.1 tron if (buff == NULL)
1876 1.1 tron return XML_STATUS_ERROR;
1877 1.1 tron else {
1878 1.1 tron memcpy(buff, s, len);
1879 1.1 tron return XML_ParseBuffer(parser, len, isFinal);
1880 1.1 tron }
1881 1.1 tron }
1882 1.1 tron }
1883 1.1 tron
1884 1.1 tron enum XML_Status XMLCALL
1885 1.1 tron XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1886 1.1 tron {
1887 1.1 tron const char *start;
1888 1.1 tron enum XML_Status result = XML_STATUS_OK;
1889 1.1 tron
1890 1.7 christos if (parser == NULL)
1891 1.7 christos return XML_STATUS_ERROR;
1892 1.1 tron switch (ps_parsing) {
1893 1.1 tron case XML_SUSPENDED:
1894 1.1 tron errorCode = XML_ERROR_SUSPENDED;
1895 1.1 tron return XML_STATUS_ERROR;
1896 1.1 tron case XML_FINISHED:
1897 1.1 tron errorCode = XML_ERROR_FINISHED;
1898 1.1 tron return XML_STATUS_ERROR;
1899 1.3 spz case XML_INITIALIZED:
1900 1.3 spz if (parentParser == NULL && !startParsing(parser)) {
1901 1.3 spz errorCode = XML_ERROR_NO_MEMORY;
1902 1.3 spz return XML_STATUS_ERROR;
1903 1.3 spz }
1904 1.1 tron default:
1905 1.1 tron ps_parsing = XML_PARSING;
1906 1.1 tron }
1907 1.1 tron
1908 1.1 tron start = bufferPtr;
1909 1.1 tron positionPtr = start;
1910 1.1 tron bufferEnd += len;
1911 1.1 tron parseEndPtr = bufferEnd;
1912 1.1 tron parseEndByteIndex += len;
1913 1.1 tron ps_finalBuffer = (XML_Bool)isFinal;
1914 1.1 tron
1915 1.1 tron errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1916 1.1 tron
1917 1.1 tron if (errorCode != XML_ERROR_NONE) {
1918 1.1 tron eventEndPtr = eventPtr;
1919 1.1 tron processor = errorProcessor;
1920 1.1 tron return XML_STATUS_ERROR;
1921 1.1 tron }
1922 1.1 tron else {
1923 1.1 tron switch (ps_parsing) {
1924 1.1 tron case XML_SUSPENDED:
1925 1.1 tron result = XML_STATUS_SUSPENDED;
1926 1.1 tron break;
1927 1.3 spz case XML_INITIALIZED:
1928 1.1 tron case XML_PARSING:
1929 1.1 tron if (isFinal) {
1930 1.1 tron ps_parsing = XML_FINISHED;
1931 1.1 tron return result;
1932 1.1 tron }
1933 1.1 tron default: ; /* should not happen */
1934 1.1 tron }
1935 1.1 tron }
1936 1.1 tron
1937 1.1 tron XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1938 1.1 tron positionPtr = bufferPtr;
1939 1.1 tron return result;
1940 1.1 tron }
1941 1.1 tron
1942 1.1 tron void * XMLCALL
1943 1.1 tron XML_GetBuffer(XML_Parser parser, int len)
1944 1.1 tron {
1945 1.7 christos if (parser == NULL)
1946 1.7 christos return NULL;
1947 1.4 spz if (len < 0) {
1948 1.4 spz errorCode = XML_ERROR_NO_MEMORY;
1949 1.4 spz return NULL;
1950 1.4 spz }
1951 1.1 tron switch (ps_parsing) {
1952 1.1 tron case XML_SUSPENDED:
1953 1.1 tron errorCode = XML_ERROR_SUSPENDED;
1954 1.1 tron return NULL;
1955 1.1 tron case XML_FINISHED:
1956 1.1 tron errorCode = XML_ERROR_FINISHED;
1957 1.1 tron return NULL;
1958 1.1 tron default: ;
1959 1.1 tron }
1960 1.1 tron
1961 1.1 tron if (len > bufferLim - bufferEnd) {
1962 1.6 spz #ifdef XML_CONTEXT_BYTES
1963 1.6 spz int keep;
1964 1.6 spz #endif /* defined XML_CONTEXT_BYTES */
1965 1.5 spz /* Do not invoke signed arithmetic overflow: */
1966 1.5 spz int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
1967 1.4 spz if (neededSize < 0) {
1968 1.4 spz errorCode = XML_ERROR_NO_MEMORY;
1969 1.4 spz return NULL;
1970 1.4 spz }
1971 1.1 tron #ifdef XML_CONTEXT_BYTES
1972 1.6 spz keep = (int)(bufferPtr - buffer);
1973 1.1 tron if (keep > XML_CONTEXT_BYTES)
1974 1.1 tron keep = XML_CONTEXT_BYTES;
1975 1.1 tron neededSize += keep;
1976 1.1 tron #endif /* defined XML_CONTEXT_BYTES */
1977 1.1 tron if (neededSize <= bufferLim - buffer) {
1978 1.1 tron #ifdef XML_CONTEXT_BYTES
1979 1.1 tron if (keep < bufferPtr - buffer) {
1980 1.1 tron int offset = (int)(bufferPtr - buffer) - keep;
1981 1.1 tron memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1982 1.1 tron bufferEnd -= offset;
1983 1.1 tron bufferPtr -= offset;
1984 1.1 tron }
1985 1.1 tron #else
1986 1.1 tron memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1987 1.1 tron bufferEnd = buffer + (bufferEnd - bufferPtr);
1988 1.1 tron bufferPtr = buffer;
1989 1.1 tron #endif /* not defined XML_CONTEXT_BYTES */
1990 1.1 tron }
1991 1.1 tron else {
1992 1.1 tron char *newBuf;
1993 1.1 tron int bufferSize = (int)(bufferLim - bufferPtr);
1994 1.1 tron if (bufferSize == 0)
1995 1.1 tron bufferSize = INIT_BUFFER_SIZE;
1996 1.1 tron do {
1997 1.5 spz /* Do not invoke signed arithmetic overflow: */
1998 1.5 spz bufferSize = (int) (2U * (unsigned) bufferSize);
1999 1.4 spz } while (bufferSize < neededSize && bufferSize > 0);
2000 1.4 spz if (bufferSize <= 0) {
2001 1.4 spz errorCode = XML_ERROR_NO_MEMORY;
2002 1.4 spz return NULL;
2003 1.4 spz }
2004 1.1 tron newBuf = (char *)MALLOC(bufferSize);
2005 1.1 tron if (newBuf == 0) {
2006 1.1 tron errorCode = XML_ERROR_NO_MEMORY;
2007 1.1 tron return NULL;
2008 1.1 tron }
2009 1.1 tron bufferLim = newBuf + bufferSize;
2010 1.1 tron #ifdef XML_CONTEXT_BYTES
2011 1.1 tron if (bufferPtr) {
2012 1.1 tron int keep = (int)(bufferPtr - buffer);
2013 1.1 tron if (keep > XML_CONTEXT_BYTES)
2014 1.1 tron keep = XML_CONTEXT_BYTES;
2015 1.1 tron memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
2016 1.1 tron FREE(buffer);
2017 1.1 tron buffer = newBuf;
2018 1.1 tron bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
2019 1.1 tron bufferPtr = buffer + keep;
2020 1.1 tron }
2021 1.1 tron else {
2022 1.1 tron bufferEnd = newBuf + (bufferEnd - bufferPtr);
2023 1.1 tron bufferPtr = buffer = newBuf;
2024 1.1 tron }
2025 1.1 tron #else
2026 1.1 tron if (bufferPtr) {
2027 1.1 tron memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
2028 1.1 tron FREE(buffer);
2029 1.1 tron }
2030 1.1 tron bufferEnd = newBuf + (bufferEnd - bufferPtr);
2031 1.1 tron bufferPtr = buffer = newBuf;
2032 1.1 tron #endif /* not defined XML_CONTEXT_BYTES */
2033 1.1 tron }
2034 1.3 spz eventPtr = eventEndPtr = NULL;
2035 1.3 spz positionPtr = NULL;
2036 1.1 tron }
2037 1.1 tron return bufferEnd;
2038 1.1 tron }
2039 1.1 tron
2040 1.1 tron enum XML_Status XMLCALL
2041 1.1 tron XML_StopParser(XML_Parser parser, XML_Bool resumable)
2042 1.1 tron {
2043 1.7 christos if (parser == NULL)
2044 1.7 christos return XML_STATUS_ERROR;
2045 1.1 tron switch (ps_parsing) {
2046 1.1 tron case XML_SUSPENDED:
2047 1.1 tron if (resumable) {
2048 1.1 tron errorCode = XML_ERROR_SUSPENDED;
2049 1.1 tron return XML_STATUS_ERROR;
2050 1.1 tron }
2051 1.1 tron ps_parsing = XML_FINISHED;
2052 1.1 tron break;
2053 1.1 tron case XML_FINISHED:
2054 1.1 tron errorCode = XML_ERROR_FINISHED;
2055 1.1 tron return XML_STATUS_ERROR;
2056 1.1 tron default:
2057 1.1 tron if (resumable) {
2058 1.1 tron #ifdef XML_DTD
2059 1.1 tron if (isParamEntity) {
2060 1.1 tron errorCode = XML_ERROR_SUSPEND_PE;
2061 1.1 tron return XML_STATUS_ERROR;
2062 1.1 tron }
2063 1.1 tron #endif
2064 1.1 tron ps_parsing = XML_SUSPENDED;
2065 1.1 tron }
2066 1.1 tron else
2067 1.1 tron ps_parsing = XML_FINISHED;
2068 1.1 tron }
2069 1.1 tron return XML_STATUS_OK;
2070 1.1 tron }
2071 1.1 tron
2072 1.1 tron enum XML_Status XMLCALL
2073 1.1 tron XML_ResumeParser(XML_Parser parser)
2074 1.1 tron {
2075 1.1 tron enum XML_Status result = XML_STATUS_OK;
2076 1.1 tron
2077 1.7 christos if (parser == NULL)
2078 1.7 christos return XML_STATUS_ERROR;
2079 1.1 tron if (ps_parsing != XML_SUSPENDED) {
2080 1.1 tron errorCode = XML_ERROR_NOT_SUSPENDED;
2081 1.1 tron return XML_STATUS_ERROR;
2082 1.1 tron }
2083 1.1 tron ps_parsing = XML_PARSING;
2084 1.1 tron
2085 1.1 tron errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
2086 1.1 tron
2087 1.1 tron if (errorCode != XML_ERROR_NONE) {
2088 1.1 tron eventEndPtr = eventPtr;
2089 1.1 tron processor = errorProcessor;
2090 1.1 tron return XML_STATUS_ERROR;
2091 1.1 tron }
2092 1.1 tron else {
2093 1.1 tron switch (ps_parsing) {
2094 1.1 tron case XML_SUSPENDED:
2095 1.1 tron result = XML_STATUS_SUSPENDED;
2096 1.1 tron break;
2097 1.3 spz case XML_INITIALIZED:
2098 1.1 tron case XML_PARSING:
2099 1.1 tron if (ps_finalBuffer) {
2100 1.1 tron ps_parsing = XML_FINISHED;
2101 1.1 tron return result;
2102 1.1 tron }
2103 1.1 tron default: ;
2104 1.1 tron }
2105 1.1 tron }
2106 1.1 tron
2107 1.1 tron XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
2108 1.1 tron positionPtr = bufferPtr;
2109 1.1 tron return result;
2110 1.1 tron }
2111 1.1 tron
2112 1.1 tron void XMLCALL
2113 1.1 tron XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
2114 1.1 tron {
2115 1.7 christos if (parser == NULL)
2116 1.7 christos return;
2117 1.1 tron assert(status != NULL);
2118 1.1 tron *status = parser->m_parsingStatus;
2119 1.1 tron }
2120 1.1 tron
2121 1.1 tron enum XML_Error XMLCALL
2122 1.1 tron XML_GetErrorCode(XML_Parser parser)
2123 1.1 tron {
2124 1.7 christos if (parser == NULL)
2125 1.7 christos return XML_ERROR_INVALID_ARGUMENT;
2126 1.1 tron return errorCode;
2127 1.1 tron }
2128 1.1 tron
2129 1.1 tron XML_Index XMLCALL
2130 1.1 tron XML_GetCurrentByteIndex(XML_Parser parser)
2131 1.1 tron {
2132 1.7 christos if (parser == NULL)
2133 1.7 christos return -1;
2134 1.1 tron if (eventPtr)
2135 1.6 spz return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
2136 1.1 tron return -1;
2137 1.1 tron }
2138 1.1 tron
2139 1.1 tron int XMLCALL
2140 1.1 tron XML_GetCurrentByteCount(XML_Parser parser)
2141 1.1 tron {
2142 1.7 christos if (parser == NULL)
2143 1.7 christos return 0;
2144 1.1 tron if (eventEndPtr && eventPtr)
2145 1.1 tron return (int)(eventEndPtr - eventPtr);
2146 1.1 tron return 0;
2147 1.1 tron }
2148 1.1 tron
2149 1.1 tron const char * XMLCALL
2150 1.1 tron XML_GetInputContext(XML_Parser parser, int *offset, int *size)
2151 1.1 tron {
2152 1.1 tron #ifdef XML_CONTEXT_BYTES
2153 1.7 christos if (parser == NULL)
2154 1.7 christos return NULL;
2155 1.1 tron if (eventPtr && buffer) {
2156 1.7 christos if (offset != NULL)
2157 1.7 christos *offset = (int)(eventPtr - buffer);
2158 1.7 christos if (size != NULL)
2159 1.7 christos *size = (int)(bufferEnd - buffer);
2160 1.1 tron return buffer;
2161 1.1 tron }
2162 1.7 christos #else
2163 1.7 christos (void)parser;
2164 1.7 christos (void)offset;
2165 1.7 christos (void)size;
2166 1.1 tron #endif /* defined XML_CONTEXT_BYTES */
2167 1.1 tron return (char *) 0;
2168 1.1 tron }
2169 1.1 tron
2170 1.1 tron XML_Size XMLCALL
2171 1.1 tron XML_GetCurrentLineNumber(XML_Parser parser)
2172 1.1 tron {
2173 1.7 christos if (parser == NULL)
2174 1.7 christos return 0;
2175 1.1 tron if (eventPtr && eventPtr >= positionPtr) {
2176 1.1 tron XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
2177 1.1 tron positionPtr = eventPtr;
2178 1.1 tron }
2179 1.1 tron return position.lineNumber + 1;
2180 1.1 tron }
2181 1.1 tron
2182 1.1 tron XML_Size XMLCALL
2183 1.1 tron XML_GetCurrentColumnNumber(XML_Parser parser)
2184 1.1 tron {
2185 1.7 christos if (parser == NULL)
2186 1.7 christos return 0;
2187 1.1 tron if (eventPtr && eventPtr >= positionPtr) {
2188 1.1 tron XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
2189 1.1 tron positionPtr = eventPtr;
2190 1.1 tron }
2191 1.1 tron return position.columnNumber;
2192 1.1 tron }
2193 1.1 tron
2194 1.1 tron void XMLCALL
2195 1.1 tron XML_FreeContentModel(XML_Parser parser, XML_Content *model)
2196 1.1 tron {
2197 1.7 christos if (parser != NULL)
2198 1.7 christos FREE(model);
2199 1.1 tron }
2200 1.1 tron
2201 1.1 tron void * XMLCALL
2202 1.1 tron XML_MemMalloc(XML_Parser parser, size_t size)
2203 1.1 tron {
2204 1.7 christos if (parser == NULL)
2205 1.7 christos return NULL;
2206 1.1 tron return MALLOC(size);
2207 1.1 tron }
2208 1.1 tron
2209 1.1 tron void * XMLCALL
2210 1.1 tron XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
2211 1.1 tron {
2212 1.7 christos if (parser == NULL)
2213 1.7 christos return NULL;
2214 1.1 tron return REALLOC(ptr, size);
2215 1.1 tron }
2216 1.1 tron
2217 1.1 tron void XMLCALL
2218 1.1 tron XML_MemFree(XML_Parser parser, void *ptr)
2219 1.1 tron {
2220 1.7 christos if (parser != NULL)
2221 1.7 christos FREE(ptr);
2222 1.1 tron }
2223 1.1 tron
2224 1.1 tron void XMLCALL
2225 1.1 tron XML_DefaultCurrent(XML_Parser parser)
2226 1.1 tron {
2227 1.7 christos if (parser == NULL)
2228 1.7 christos return;
2229 1.1 tron if (defaultHandler) {
2230 1.1 tron if (openInternalEntities)
2231 1.1 tron reportDefault(parser,
2232 1.1 tron internalEncoding,
2233 1.1 tron openInternalEntities->internalEventPtr,
2234 1.1 tron openInternalEntities->internalEventEndPtr);
2235 1.1 tron else
2236 1.1 tron reportDefault(parser, encoding, eventPtr, eventEndPtr);
2237 1.1 tron }
2238 1.1 tron }
2239 1.1 tron
2240 1.1 tron const XML_LChar * XMLCALL
2241 1.1 tron XML_ErrorString(enum XML_Error code)
2242 1.1 tron {
2243 1.1 tron static const XML_LChar* const message[] = {
2244 1.1 tron 0,
2245 1.1 tron XML_L("out of memory"),
2246 1.1 tron XML_L("syntax error"),
2247 1.1 tron XML_L("no element found"),
2248 1.1 tron XML_L("not well-formed (invalid token)"),
2249 1.1 tron XML_L("unclosed token"),
2250 1.1 tron XML_L("partial character"),
2251 1.1 tron XML_L("mismatched tag"),
2252 1.1 tron XML_L("duplicate attribute"),
2253 1.1 tron XML_L("junk after document element"),
2254 1.1 tron XML_L("illegal parameter entity reference"),
2255 1.1 tron XML_L("undefined entity"),
2256 1.1 tron XML_L("recursive entity reference"),
2257 1.1 tron XML_L("asynchronous entity"),
2258 1.1 tron XML_L("reference to invalid character number"),
2259 1.1 tron XML_L("reference to binary entity"),
2260 1.1 tron XML_L("reference to external entity in attribute"),
2261 1.1 tron XML_L("XML or text declaration not at start of entity"),
2262 1.1 tron XML_L("unknown encoding"),
2263 1.1 tron XML_L("encoding specified in XML declaration is incorrect"),
2264 1.1 tron XML_L("unclosed CDATA section"),
2265 1.1 tron XML_L("error in processing external entity reference"),
2266 1.1 tron XML_L("document is not standalone"),
2267 1.1 tron XML_L("unexpected parser state - please send a bug report"),
2268 1.1 tron XML_L("entity declared in parameter entity"),
2269 1.1 tron XML_L("requested feature requires XML_DTD support in Expat"),
2270 1.1 tron XML_L("cannot change setting once parsing has begun"),
2271 1.1 tron XML_L("unbound prefix"),
2272 1.1 tron XML_L("must not undeclare prefix"),
2273 1.1 tron XML_L("incomplete markup in parameter entity"),
2274 1.1 tron XML_L("XML declaration not well-formed"),
2275 1.1 tron XML_L("text declaration not well-formed"),
2276 1.1 tron XML_L("illegal character(s) in public id"),
2277 1.1 tron XML_L("parser suspended"),
2278 1.1 tron XML_L("parser not suspended"),
2279 1.1 tron XML_L("parsing aborted"),
2280 1.1 tron XML_L("parsing finished"),
2281 1.1 tron XML_L("cannot suspend in external parameter entity"),
2282 1.1 tron XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
2283 1.1 tron XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
2284 1.1 tron XML_L("prefix must not be bound to one of the reserved namespace names")
2285 1.1 tron };
2286 1.1 tron if (code > 0 && code < sizeof(message)/sizeof(message[0]))
2287 1.1 tron return message[code];
2288 1.1 tron return NULL;
2289 1.1 tron }
2290 1.1 tron
2291 1.1 tron const XML_LChar * XMLCALL
2292 1.1 tron XML_ExpatVersion(void) {
2293 1.1 tron
2294 1.1 tron /* V1 is used to string-ize the version number. However, it would
2295 1.1 tron string-ize the actual version macro *names* unless we get them
2296 1.1 tron substituted before being passed to V1. CPP is defined to expand
2297 1.1 tron a macro, then rescan for more expansions. Thus, we use V2 to expand
2298 1.1 tron the version macros, then CPP will expand the resulting V1() macro
2299 1.1 tron with the correct numerals. */
2300 1.1 tron /* ### I'm assuming cpp is portable in this respect... */
2301 1.1 tron
2302 1.1 tron #define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
2303 1.1 tron #define V2(a,b,c) XML_L("expat_")V1(a,b,c)
2304 1.1 tron
2305 1.1 tron return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2306 1.1 tron
2307 1.1 tron #undef V1
2308 1.1 tron #undef V2
2309 1.1 tron }
2310 1.1 tron
2311 1.1 tron XML_Expat_Version XMLCALL
2312 1.1 tron XML_ExpatVersionInfo(void)
2313 1.1 tron {
2314 1.1 tron XML_Expat_Version version;
2315 1.1 tron
2316 1.1 tron version.major = XML_MAJOR_VERSION;
2317 1.1 tron version.minor = XML_MINOR_VERSION;
2318 1.1 tron version.micro = XML_MICRO_VERSION;
2319 1.1 tron
2320 1.1 tron return version;
2321 1.1 tron }
2322 1.1 tron
2323 1.1 tron const XML_Feature * XMLCALL
2324 1.1 tron XML_GetFeatureList(void)
2325 1.1 tron {
2326 1.1 tron static const XML_Feature features[] = {
2327 1.1 tron {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
2328 1.1 tron sizeof(XML_Char)},
2329 1.1 tron {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2330 1.1 tron sizeof(XML_LChar)},
2331 1.1 tron #ifdef XML_UNICODE
2332 1.1 tron {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
2333 1.1 tron #endif
2334 1.1 tron #ifdef XML_UNICODE_WCHAR_T
2335 1.1 tron {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
2336 1.1 tron #endif
2337 1.1 tron #ifdef XML_DTD
2338 1.1 tron {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
2339 1.1 tron #endif
2340 1.1 tron #ifdef XML_CONTEXT_BYTES
2341 1.1 tron {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
2342 1.1 tron XML_CONTEXT_BYTES},
2343 1.1 tron #endif
2344 1.1 tron #ifdef XML_MIN_SIZE
2345 1.1 tron {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
2346 1.1 tron #endif
2347 1.1 tron #ifdef XML_NS
2348 1.1 tron {XML_FEATURE_NS, XML_L("XML_NS"), 0},
2349 1.1 tron #endif
2350 1.1 tron #ifdef XML_LARGE_SIZE
2351 1.1 tron {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
2352 1.3 spz #endif
2353 1.3 spz #ifdef XML_ATTR_INFO
2354 1.3 spz {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
2355 1.3 spz #endif
2356 1.1 tron {XML_FEATURE_END, NULL, 0}
2357 1.1 tron };
2358 1.1 tron
2359 1.1 tron return features;
2360 1.1 tron }
2361 1.1 tron
2362 1.1 tron /* Initially tag->rawName always points into the parse buffer;
2363 1.1 tron for those TAG instances opened while the current parse buffer was
2364 1.1 tron processed, and not yet closed, we need to store tag->rawName in a more
2365 1.1 tron permanent location, since the parse buffer is about to be discarded.
2366 1.1 tron */
2367 1.1 tron static XML_Bool
2368 1.1 tron storeRawNames(XML_Parser parser)
2369 1.1 tron {
2370 1.1 tron TAG *tag = tagStack;
2371 1.1 tron while (tag) {
2372 1.1 tron int bufSize;
2373 1.1 tron int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2374 1.1 tron char *rawNameBuf = tag->buf + nameLen;
2375 1.1 tron /* Stop if already stored. Since tagStack is a stack, we can stop
2376 1.1 tron at the first entry that has already been copied; everything
2377 1.1 tron below it in the stack is already been accounted for in a
2378 1.1 tron previous call to this function.
2379 1.1 tron */
2380 1.1 tron if (tag->rawName == rawNameBuf)
2381 1.1 tron break;
2382 1.1 tron /* For re-use purposes we need to ensure that the
2383 1.1 tron size of tag->buf is a multiple of sizeof(XML_Char).
2384 1.1 tron */
2385 1.1 tron bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2386 1.1 tron if (bufSize > tag->bufEnd - tag->buf) {
2387 1.1 tron char *temp = (char *)REALLOC(tag->buf, bufSize);
2388 1.1 tron if (temp == NULL)
2389 1.1 tron return XML_FALSE;
2390 1.1 tron /* if tag->name.str points to tag->buf (only when namespace
2391 1.1 tron processing is off) then we have to update it
2392 1.1 tron */
2393 1.1 tron if (tag->name.str == (XML_Char *)tag->buf)
2394 1.1 tron tag->name.str = (XML_Char *)temp;
2395 1.1 tron /* if tag->name.localPart is set (when namespace processing is on)
2396 1.1 tron then update it as well, since it will always point into tag->buf
2397 1.1 tron */
2398 1.1 tron if (tag->name.localPart)
2399 1.1 tron tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2400 1.1 tron (XML_Char *)tag->buf);
2401 1.1 tron tag->buf = temp;
2402 1.1 tron tag->bufEnd = temp + bufSize;
2403 1.1 tron rawNameBuf = temp + nameLen;
2404 1.1 tron }
2405 1.1 tron memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2406 1.1 tron tag->rawName = rawNameBuf;
2407 1.1 tron tag = tag->parent;
2408 1.1 tron }
2409 1.1 tron return XML_TRUE;
2410 1.1 tron }
2411 1.1 tron
2412 1.1 tron static enum XML_Error PTRCALL
2413 1.1 tron contentProcessor(XML_Parser parser,
2414 1.1 tron const char *start,
2415 1.1 tron const char *end,
2416 1.1 tron const char **endPtr)
2417 1.1 tron {
2418 1.3 spz enum XML_Error result = doContent(parser, 0, encoding, start, end,
2419 1.1 tron endPtr, (XML_Bool)!ps_finalBuffer);
2420 1.1 tron if (result == XML_ERROR_NONE) {
2421 1.1 tron if (!storeRawNames(parser))
2422 1.1 tron return XML_ERROR_NO_MEMORY;
2423 1.1 tron }
2424 1.1 tron return result;
2425 1.1 tron }
2426 1.1 tron
2427 1.1 tron static enum XML_Error PTRCALL
2428 1.1 tron externalEntityInitProcessor(XML_Parser parser,
2429 1.1 tron const char *start,
2430 1.1 tron const char *end,
2431 1.1 tron const char **endPtr)
2432 1.1 tron {
2433 1.1 tron enum XML_Error result = initializeEncoding(parser);
2434 1.1 tron if (result != XML_ERROR_NONE)
2435 1.1 tron return result;
2436 1.1 tron processor = externalEntityInitProcessor2;
2437 1.1 tron return externalEntityInitProcessor2(parser, start, end, endPtr);
2438 1.1 tron }
2439 1.1 tron
2440 1.1 tron static enum XML_Error PTRCALL
2441 1.1 tron externalEntityInitProcessor2(XML_Parser parser,
2442 1.1 tron const char *start,
2443 1.1 tron const char *end,
2444 1.1 tron const char **endPtr)
2445 1.1 tron {
2446 1.1 tron const char *next = start; /* XmlContentTok doesn't always set the last arg */
2447 1.1 tron int tok = XmlContentTok(encoding, start, end, &next);
2448 1.1 tron switch (tok) {
2449 1.1 tron case XML_TOK_BOM:
2450 1.1 tron /* If we are at the end of the buffer, this would cause the next stage,
2451 1.1 tron i.e. externalEntityInitProcessor3, to pass control directly to
2452 1.1 tron doContent (by detecting XML_TOK_NONE) without processing any xml text
2453 1.1 tron declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2454 1.1 tron */
2455 1.1 tron if (next == end && !ps_finalBuffer) {
2456 1.1 tron *endPtr = next;
2457 1.1 tron return XML_ERROR_NONE;
2458 1.1 tron }
2459 1.1 tron start = next;
2460 1.1 tron break;
2461 1.1 tron case XML_TOK_PARTIAL:
2462 1.1 tron if (!ps_finalBuffer) {
2463 1.1 tron *endPtr = start;
2464 1.1 tron return XML_ERROR_NONE;
2465 1.1 tron }
2466 1.1 tron eventPtr = start;
2467 1.1 tron return XML_ERROR_UNCLOSED_TOKEN;
2468 1.1 tron case XML_TOK_PARTIAL_CHAR:
2469 1.1 tron if (!ps_finalBuffer) {
2470 1.1 tron *endPtr = start;
2471 1.1 tron return XML_ERROR_NONE;
2472 1.1 tron }
2473 1.1 tron eventPtr = start;
2474 1.1 tron return XML_ERROR_PARTIAL_CHAR;
2475 1.1 tron }
2476 1.1 tron processor = externalEntityInitProcessor3;
2477 1.1 tron return externalEntityInitProcessor3(parser, start, end, endPtr);
2478 1.1 tron }
2479 1.1 tron
2480 1.1 tron static enum XML_Error PTRCALL
2481 1.1 tron externalEntityInitProcessor3(XML_Parser parser,
2482 1.1 tron const char *start,
2483 1.1 tron const char *end,
2484 1.1 tron const char **endPtr)
2485 1.1 tron {
2486 1.1 tron int tok;
2487 1.1 tron const char *next = start; /* XmlContentTok doesn't always set the last arg */
2488 1.1 tron eventPtr = start;
2489 1.1 tron tok = XmlContentTok(encoding, start, end, &next);
2490 1.1 tron eventEndPtr = next;
2491 1.1 tron
2492 1.1 tron switch (tok) {
2493 1.1 tron case XML_TOK_XML_DECL:
2494 1.1 tron {
2495 1.1 tron enum XML_Error result;
2496 1.1 tron result = processXmlDecl(parser, 1, start, next);
2497 1.1 tron if (result != XML_ERROR_NONE)
2498 1.1 tron return result;
2499 1.1 tron switch (ps_parsing) {
2500 1.3 spz case XML_SUSPENDED:
2501 1.1 tron *endPtr = next;
2502 1.1 tron return XML_ERROR_NONE;
2503 1.1 tron case XML_FINISHED:
2504 1.1 tron return XML_ERROR_ABORTED;
2505 1.1 tron default:
2506 1.1 tron start = next;
2507 1.1 tron }
2508 1.1 tron }
2509 1.1 tron break;
2510 1.1 tron case XML_TOK_PARTIAL:
2511 1.1 tron if (!ps_finalBuffer) {
2512 1.1 tron *endPtr = start;
2513 1.1 tron return XML_ERROR_NONE;
2514 1.1 tron }
2515 1.1 tron return XML_ERROR_UNCLOSED_TOKEN;
2516 1.1 tron case XML_TOK_PARTIAL_CHAR:
2517 1.1 tron if (!ps_finalBuffer) {
2518 1.1 tron *endPtr = start;
2519 1.1 tron return XML_ERROR_NONE;
2520 1.1 tron }
2521 1.1 tron return XML_ERROR_PARTIAL_CHAR;
2522 1.1 tron }
2523 1.1 tron processor = externalEntityContentProcessor;
2524 1.1 tron tagLevel = 1;
2525 1.1 tron return externalEntityContentProcessor(parser, start, end, endPtr);
2526 1.1 tron }
2527 1.1 tron
2528 1.1 tron static enum XML_Error PTRCALL
2529 1.1 tron externalEntityContentProcessor(XML_Parser parser,
2530 1.1 tron const char *start,
2531 1.1 tron const char *end,
2532 1.1 tron const char **endPtr)
2533 1.1 tron {
2534 1.3 spz enum XML_Error result = doContent(parser, 1, encoding, start, end,
2535 1.1 tron endPtr, (XML_Bool)!ps_finalBuffer);
2536 1.1 tron if (result == XML_ERROR_NONE) {
2537 1.1 tron if (!storeRawNames(parser))
2538 1.1 tron return XML_ERROR_NO_MEMORY;
2539 1.1 tron }
2540 1.1 tron return result;
2541 1.1 tron }
2542 1.1 tron
2543 1.1 tron static enum XML_Error
2544 1.1 tron doContent(XML_Parser parser,
2545 1.1 tron int startTagLevel,
2546 1.1 tron const ENCODING *enc,
2547 1.1 tron const char *s,
2548 1.1 tron const char *end,
2549 1.1 tron const char **nextPtr,
2550 1.1 tron XML_Bool haveMore)
2551 1.1 tron {
2552 1.1 tron /* save one level of indirection */
2553 1.3 spz DTD * const dtd = _dtd;
2554 1.1 tron
2555 1.1 tron const char **eventPP;
2556 1.1 tron const char **eventEndPP;
2557 1.1 tron if (enc == encoding) {
2558 1.1 tron eventPP = &eventPtr;
2559 1.1 tron eventEndPP = &eventEndPtr;
2560 1.1 tron }
2561 1.1 tron else {
2562 1.1 tron eventPP = &(openInternalEntities->internalEventPtr);
2563 1.1 tron eventEndPP = &(openInternalEntities->internalEventEndPtr);
2564 1.1 tron }
2565 1.1 tron *eventPP = s;
2566 1.1 tron
2567 1.1 tron for (;;) {
2568 1.1 tron const char *next = s; /* XmlContentTok doesn't always set the last arg */
2569 1.1 tron int tok = XmlContentTok(enc, s, end, &next);
2570 1.1 tron *eventEndPP = next;
2571 1.1 tron switch (tok) {
2572 1.1 tron case XML_TOK_TRAILING_CR:
2573 1.1 tron if (haveMore) {
2574 1.1 tron *nextPtr = s;
2575 1.1 tron return XML_ERROR_NONE;
2576 1.1 tron }
2577 1.1 tron *eventEndPP = end;
2578 1.1 tron if (characterDataHandler) {
2579 1.1 tron XML_Char c = 0xA;
2580 1.1 tron characterDataHandler(handlerArg, &c, 1);
2581 1.1 tron }
2582 1.1 tron else if (defaultHandler)
2583 1.1 tron reportDefault(parser, enc, s, end);
2584 1.3 spz /* We are at the end of the final buffer, should we check for
2585 1.3 spz XML_SUSPENDED, XML_FINISHED?
2586 1.1 tron */
2587 1.1 tron if (startTagLevel == 0)
2588 1.1 tron return XML_ERROR_NO_ELEMENTS;
2589 1.1 tron if (tagLevel != startTagLevel)
2590 1.1 tron return XML_ERROR_ASYNC_ENTITY;
2591 1.1 tron *nextPtr = end;
2592 1.1 tron return XML_ERROR_NONE;
2593 1.1 tron case XML_TOK_NONE:
2594 1.1 tron if (haveMore) {
2595 1.1 tron *nextPtr = s;
2596 1.1 tron return XML_ERROR_NONE;
2597 1.1 tron }
2598 1.1 tron if (startTagLevel > 0) {
2599 1.1 tron if (tagLevel != startTagLevel)
2600 1.1 tron return XML_ERROR_ASYNC_ENTITY;
2601 1.1 tron *nextPtr = s;
2602 1.1 tron return XML_ERROR_NONE;
2603 1.1 tron }
2604 1.1 tron return XML_ERROR_NO_ELEMENTS;
2605 1.1 tron case XML_TOK_INVALID:
2606 1.1 tron *eventPP = next;
2607 1.1 tron return XML_ERROR_INVALID_TOKEN;
2608 1.1 tron case XML_TOK_PARTIAL:
2609 1.1 tron if (haveMore) {
2610 1.1 tron *nextPtr = s;
2611 1.1 tron return XML_ERROR_NONE;
2612 1.1 tron }
2613 1.1 tron return XML_ERROR_UNCLOSED_TOKEN;
2614 1.1 tron case XML_TOK_PARTIAL_CHAR:
2615 1.1 tron if (haveMore) {
2616 1.1 tron *nextPtr = s;
2617 1.1 tron return XML_ERROR_NONE;
2618 1.1 tron }
2619 1.1 tron return XML_ERROR_PARTIAL_CHAR;
2620 1.1 tron case XML_TOK_ENTITY_REF:
2621 1.1 tron {
2622 1.1 tron const XML_Char *name;
2623 1.1 tron ENTITY *entity;
2624 1.1 tron XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2625 1.1 tron s + enc->minBytesPerChar,
2626 1.1 tron next - enc->minBytesPerChar);
2627 1.1 tron if (ch) {
2628 1.1 tron if (characterDataHandler)
2629 1.1 tron characterDataHandler(handlerArg, &ch, 1);
2630 1.1 tron else if (defaultHandler)
2631 1.1 tron reportDefault(parser, enc, s, next);
2632 1.1 tron break;
2633 1.1 tron }
2634 1.1 tron name = poolStoreString(&dtd->pool, enc,
2635 1.1 tron s + enc->minBytesPerChar,
2636 1.1 tron next - enc->minBytesPerChar);
2637 1.1 tron if (!name)
2638 1.1 tron return XML_ERROR_NO_MEMORY;
2639 1.3 spz entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2640 1.1 tron poolDiscard(&dtd->pool);
2641 1.1 tron /* First, determine if a check for an existing declaration is needed;
2642 1.1 tron if yes, check that the entity exists, and that it is internal,
2643 1.1 tron otherwise call the skipped entity or default handler.
2644 1.1 tron */
2645 1.1 tron if (!dtd->hasParamEntityRefs || dtd->standalone) {
2646 1.1 tron if (!entity)
2647 1.1 tron return XML_ERROR_UNDEFINED_ENTITY;
2648 1.1 tron else if (!entity->is_internal)
2649 1.1 tron return XML_ERROR_ENTITY_DECLARED_IN_PE;
2650 1.1 tron }
2651 1.1 tron else if (!entity) {
2652 1.1 tron if (skippedEntityHandler)
2653 1.1 tron skippedEntityHandler(handlerArg, name, 0);
2654 1.1 tron else if (defaultHandler)
2655 1.1 tron reportDefault(parser, enc, s, next);
2656 1.1 tron break;
2657 1.1 tron }
2658 1.1 tron if (entity->open)
2659 1.1 tron return XML_ERROR_RECURSIVE_ENTITY_REF;
2660 1.1 tron if (entity->notation)
2661 1.1 tron return XML_ERROR_BINARY_ENTITY_REF;
2662 1.1 tron if (entity->textPtr) {
2663 1.1 tron enum XML_Error result;
2664 1.1 tron if (!defaultExpandInternalEntities) {
2665 1.1 tron if (skippedEntityHandler)
2666 1.1 tron skippedEntityHandler(handlerArg, entity->name, 0);
2667 1.1 tron else if (defaultHandler)
2668 1.1 tron reportDefault(parser, enc, s, next);
2669 1.1 tron break;
2670 1.1 tron }
2671 1.1 tron result = processInternalEntity(parser, entity, XML_FALSE);
2672 1.1 tron if (result != XML_ERROR_NONE)
2673 1.1 tron return result;
2674 1.1 tron }
2675 1.1 tron else if (externalEntityRefHandler) {
2676 1.1 tron const XML_Char *context;
2677 1.1 tron entity->open = XML_TRUE;
2678 1.1 tron context = getContext(parser);
2679 1.1 tron entity->open = XML_FALSE;
2680 1.1 tron if (!context)
2681 1.1 tron return XML_ERROR_NO_MEMORY;
2682 1.1 tron if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2683 1.1 tron context,
2684 1.1 tron entity->base,
2685 1.1 tron entity->systemId,
2686 1.1 tron entity->publicId))
2687 1.1 tron return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2688 1.1 tron poolDiscard(&tempPool);
2689 1.1 tron }
2690 1.1 tron else if (defaultHandler)
2691 1.1 tron reportDefault(parser, enc, s, next);
2692 1.1 tron break;
2693 1.1 tron }
2694 1.1 tron case XML_TOK_START_TAG_NO_ATTS:
2695 1.1 tron /* fall through */
2696 1.1 tron case XML_TOK_START_TAG_WITH_ATTS:
2697 1.1 tron {
2698 1.1 tron TAG *tag;
2699 1.1 tron enum XML_Error result;
2700 1.1 tron XML_Char *toPtr;
2701 1.1 tron if (freeTagList) {
2702 1.1 tron tag = freeTagList;
2703 1.1 tron freeTagList = freeTagList->parent;
2704 1.1 tron }
2705 1.1 tron else {
2706 1.1 tron tag = (TAG *)MALLOC(sizeof(TAG));
2707 1.1 tron if (!tag)
2708 1.1 tron return XML_ERROR_NO_MEMORY;
2709 1.1 tron tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2710 1.1 tron if (!tag->buf) {
2711 1.1 tron FREE(tag);
2712 1.1 tron return XML_ERROR_NO_MEMORY;
2713 1.1 tron }
2714 1.1 tron tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2715 1.1 tron }
2716 1.1 tron tag->bindings = NULL;
2717 1.1 tron tag->parent = tagStack;
2718 1.1 tron tagStack = tag;
2719 1.1 tron tag->name.localPart = NULL;
2720 1.1 tron tag->name.prefix = NULL;
2721 1.1 tron tag->rawName = s + enc->minBytesPerChar;
2722 1.1 tron tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2723 1.1 tron ++tagLevel;
2724 1.1 tron {
2725 1.1 tron const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2726 1.1 tron const char *fromPtr = tag->rawName;
2727 1.1 tron toPtr = (XML_Char *)tag->buf;
2728 1.1 tron for (;;) {
2729 1.1 tron int bufSize;
2730 1.1 tron int convLen;
2731 1.5 spz const enum XML_Convert_Result convert_res = XmlConvert(enc,
2732 1.1 tron &fromPtr, rawNameEnd,
2733 1.1 tron (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2734 1.1 tron convLen = (int)(toPtr - (XML_Char *)tag->buf);
2735 1.7 christos if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
2736 1.1 tron tag->name.strLen = convLen;
2737 1.1 tron break;
2738 1.1 tron }
2739 1.1 tron bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2740 1.1 tron {
2741 1.1 tron char *temp = (char *)REALLOC(tag->buf, bufSize);
2742 1.1 tron if (temp == NULL)
2743 1.1 tron return XML_ERROR_NO_MEMORY;
2744 1.1 tron tag->buf = temp;
2745 1.1 tron tag->bufEnd = temp + bufSize;
2746 1.1 tron toPtr = (XML_Char *)temp + convLen;
2747 1.1 tron }
2748 1.1 tron }
2749 1.1 tron }
2750 1.1 tron tag->name.str = (XML_Char *)tag->buf;
2751 1.1 tron *toPtr = XML_T('\0');
2752 1.1 tron result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2753 1.1 tron if (result)
2754 1.1 tron return result;
2755 1.1 tron if (startElementHandler)
2756 1.1 tron startElementHandler(handlerArg, tag->name.str,
2757 1.1 tron (const XML_Char **)atts);
2758 1.1 tron else if (defaultHandler)
2759 1.1 tron reportDefault(parser, enc, s, next);
2760 1.1 tron poolClear(&tempPool);
2761 1.1 tron break;
2762 1.1 tron }
2763 1.1 tron case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2764 1.1 tron /* fall through */
2765 1.1 tron case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2766 1.1 tron {
2767 1.1 tron const char *rawName = s + enc->minBytesPerChar;
2768 1.1 tron enum XML_Error result;
2769 1.1 tron BINDING *bindings = NULL;
2770 1.1 tron XML_Bool noElmHandlers = XML_TRUE;
2771 1.1 tron TAG_NAME name;
2772 1.1 tron name.str = poolStoreString(&tempPool, enc, rawName,
2773 1.1 tron rawName + XmlNameLength(enc, rawName));
2774 1.1 tron if (!name.str)
2775 1.1 tron return XML_ERROR_NO_MEMORY;
2776 1.1 tron poolFinish(&tempPool);
2777 1.1 tron result = storeAtts(parser, enc, s, &name, &bindings);
2778 1.7 christos if (result != XML_ERROR_NONE) {
2779 1.7 christos freeBindings(parser, bindings);
2780 1.1 tron return result;
2781 1.7 christos }
2782 1.1 tron poolFinish(&tempPool);
2783 1.1 tron if (startElementHandler) {
2784 1.1 tron startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2785 1.1 tron noElmHandlers = XML_FALSE;
2786 1.1 tron }
2787 1.1 tron if (endElementHandler) {
2788 1.1 tron if (startElementHandler)
2789 1.1 tron *eventPP = *eventEndPP;
2790 1.1 tron endElementHandler(handlerArg, name.str);
2791 1.1 tron noElmHandlers = XML_FALSE;
2792 1.1 tron }
2793 1.1 tron if (noElmHandlers && defaultHandler)
2794 1.1 tron reportDefault(parser, enc, s, next);
2795 1.1 tron poolClear(&tempPool);
2796 1.7 christos freeBindings(parser, bindings);
2797 1.1 tron }
2798 1.1 tron if (tagLevel == 0)
2799 1.1 tron return epilogProcessor(parser, next, end, nextPtr);
2800 1.1 tron break;
2801 1.1 tron case XML_TOK_END_TAG:
2802 1.1 tron if (tagLevel == startTagLevel)
2803 1.1 tron return XML_ERROR_ASYNC_ENTITY;
2804 1.1 tron else {
2805 1.1 tron int len;
2806 1.1 tron const char *rawName;
2807 1.1 tron TAG *tag = tagStack;
2808 1.1 tron tagStack = tag->parent;
2809 1.1 tron tag->parent = freeTagList;
2810 1.1 tron freeTagList = tag;
2811 1.1 tron rawName = s + enc->minBytesPerChar*2;
2812 1.1 tron len = XmlNameLength(enc, rawName);
2813 1.1 tron if (len != tag->rawNameLength
2814 1.1 tron || memcmp(tag->rawName, rawName, len) != 0) {
2815 1.1 tron *eventPP = rawName;
2816 1.1 tron return XML_ERROR_TAG_MISMATCH;
2817 1.1 tron }
2818 1.1 tron --tagLevel;
2819 1.1 tron if (endElementHandler) {
2820 1.1 tron const XML_Char *localPart;
2821 1.1 tron const XML_Char *prefix;
2822 1.1 tron XML_Char *uri;
2823 1.1 tron localPart = tag->name.localPart;
2824 1.1 tron if (ns && localPart) {
2825 1.1 tron /* localPart and prefix may have been overwritten in
2826 1.1 tron tag->name.str, since this points to the binding->uri
2827 1.1 tron buffer which gets re-used; so we have to add them again
2828 1.1 tron */
2829 1.1 tron uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2830 1.1 tron /* don't need to check for space - already done in storeAtts() */
2831 1.1 tron while (*localPart) *uri++ = *localPart++;
2832 1.1 tron prefix = (XML_Char *)tag->name.prefix;
2833 1.1 tron if (ns_triplets && prefix) {
2834 1.1 tron *uri++ = namespaceSeparator;
2835 1.1 tron while (*prefix) *uri++ = *prefix++;
2836 1.1 tron }
2837 1.1 tron *uri = XML_T('\0');
2838 1.1 tron }
2839 1.1 tron endElementHandler(handlerArg, tag->name.str);
2840 1.1 tron }
2841 1.1 tron else if (defaultHandler)
2842 1.1 tron reportDefault(parser, enc, s, next);
2843 1.1 tron while (tag->bindings) {
2844 1.1 tron BINDING *b = tag->bindings;
2845 1.1 tron if (endNamespaceDeclHandler)
2846 1.1 tron endNamespaceDeclHandler(handlerArg, b->prefix->name);
2847 1.1 tron tag->bindings = tag->bindings->nextTagBinding;
2848 1.1 tron b->nextTagBinding = freeBindingList;
2849 1.1 tron freeBindingList = b;
2850 1.1 tron b->prefix->binding = b->prevPrefixBinding;
2851 1.1 tron }
2852 1.1 tron if (tagLevel == 0)
2853 1.1 tron return epilogProcessor(parser, next, end, nextPtr);
2854 1.1 tron }
2855 1.1 tron break;
2856 1.1 tron case XML_TOK_CHAR_REF:
2857 1.1 tron {
2858 1.1 tron int n = XmlCharRefNumber(enc, s);
2859 1.1 tron if (n < 0)
2860 1.1 tron return XML_ERROR_BAD_CHAR_REF;
2861 1.1 tron if (characterDataHandler) {
2862 1.1 tron XML_Char buf[XML_ENCODE_MAX];
2863 1.1 tron characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2864 1.1 tron }
2865 1.1 tron else if (defaultHandler)
2866 1.1 tron reportDefault(parser, enc, s, next);
2867 1.1 tron }
2868 1.1 tron break;
2869 1.1 tron case XML_TOK_XML_DECL:
2870 1.1 tron return XML_ERROR_MISPLACED_XML_PI;
2871 1.1 tron case XML_TOK_DATA_NEWLINE:
2872 1.1 tron if (characterDataHandler) {
2873 1.1 tron XML_Char c = 0xA;
2874 1.1 tron characterDataHandler(handlerArg, &c, 1);
2875 1.1 tron }
2876 1.1 tron else if (defaultHandler)
2877 1.1 tron reportDefault(parser, enc, s, next);
2878 1.1 tron break;
2879 1.1 tron case XML_TOK_CDATA_SECT_OPEN:
2880 1.1 tron {
2881 1.1 tron enum XML_Error result;
2882 1.1 tron if (startCdataSectionHandler)
2883 1.1 tron startCdataSectionHandler(handlerArg);
2884 1.1 tron #if 0
2885 1.1 tron /* Suppose you doing a transformation on a document that involves
2886 1.1 tron changing only the character data. You set up a defaultHandler
2887 1.1 tron and a characterDataHandler. The defaultHandler simply copies
2888 1.1 tron characters through. The characterDataHandler does the
2889 1.1 tron transformation and writes the characters out escaping them as
2890 1.1 tron necessary. This case will fail to work if we leave out the
2891 1.1 tron following two lines (because & and < inside CDATA sections will
2892 1.1 tron be incorrectly escaped).
2893 1.1 tron
2894 1.1 tron However, now we have a start/endCdataSectionHandler, so it seems
2895 1.1 tron easier to let the user deal with this.
2896 1.1 tron */
2897 1.1 tron else if (characterDataHandler)
2898 1.1 tron characterDataHandler(handlerArg, dataBuf, 0);
2899 1.1 tron #endif
2900 1.1 tron else if (defaultHandler)
2901 1.1 tron reportDefault(parser, enc, s, next);
2902 1.1 tron result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2903 1.1 tron if (result != XML_ERROR_NONE)
2904 1.1 tron return result;
2905 1.1 tron else if (!next) {
2906 1.1 tron processor = cdataSectionProcessor;
2907 1.1 tron return result;
2908 1.1 tron }
2909 1.1 tron }
2910 1.1 tron break;
2911 1.1 tron case XML_TOK_TRAILING_RSQB:
2912 1.1 tron if (haveMore) {
2913 1.1 tron *nextPtr = s;
2914 1.1 tron return XML_ERROR_NONE;
2915 1.1 tron }
2916 1.1 tron if (characterDataHandler) {
2917 1.1 tron if (MUST_CONVERT(enc, s)) {
2918 1.1 tron ICHAR *dataPtr = (ICHAR *)dataBuf;
2919 1.1 tron XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2920 1.1 tron characterDataHandler(handlerArg, dataBuf,
2921 1.1 tron (int)(dataPtr - (ICHAR *)dataBuf));
2922 1.1 tron }
2923 1.1 tron else
2924 1.1 tron characterDataHandler(handlerArg,
2925 1.1 tron (XML_Char *)s,
2926 1.1 tron (int)((XML_Char *)end - (XML_Char *)s));
2927 1.1 tron }
2928 1.1 tron else if (defaultHandler)
2929 1.1 tron reportDefault(parser, enc, s, end);
2930 1.3 spz /* We are at the end of the final buffer, should we check for
2931 1.3 spz XML_SUSPENDED, XML_FINISHED?
2932 1.1 tron */
2933 1.1 tron if (startTagLevel == 0) {
2934 1.1 tron *eventPP = end;
2935 1.1 tron return XML_ERROR_NO_ELEMENTS;
2936 1.1 tron }
2937 1.1 tron if (tagLevel != startTagLevel) {
2938 1.1 tron *eventPP = end;
2939 1.1 tron return XML_ERROR_ASYNC_ENTITY;
2940 1.1 tron }
2941 1.1 tron *nextPtr = end;
2942 1.1 tron return XML_ERROR_NONE;
2943 1.3 spz case XML_TOK_DATA_CHARS:
2944 1.1 tron {
2945 1.1 tron XML_CharacterDataHandler charDataHandler = characterDataHandler;
2946 1.1 tron if (charDataHandler) {
2947 1.1 tron if (MUST_CONVERT(enc, s)) {
2948 1.1 tron for (;;) {
2949 1.1 tron ICHAR *dataPtr = (ICHAR *)dataBuf;
2950 1.5 spz const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2951 1.1 tron *eventEndPP = s;
2952 1.1 tron charDataHandler(handlerArg, dataBuf,
2953 1.1 tron (int)(dataPtr - (ICHAR *)dataBuf));
2954 1.5 spz if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
2955 1.1 tron break;
2956 1.1 tron *eventPP = s;
2957 1.1 tron }
2958 1.1 tron }
2959 1.1 tron else
2960 1.1 tron charDataHandler(handlerArg,
2961 1.1 tron (XML_Char *)s,
2962 1.1 tron (int)((XML_Char *)next - (XML_Char *)s));
2963 1.1 tron }
2964 1.1 tron else if (defaultHandler)
2965 1.1 tron reportDefault(parser, enc, s, next);
2966 1.1 tron }
2967 1.1 tron break;
2968 1.1 tron case XML_TOK_PI:
2969 1.1 tron if (!reportProcessingInstruction(parser, enc, s, next))
2970 1.1 tron return XML_ERROR_NO_MEMORY;
2971 1.1 tron break;
2972 1.1 tron case XML_TOK_COMMENT:
2973 1.1 tron if (!reportComment(parser, enc, s, next))
2974 1.1 tron return XML_ERROR_NO_MEMORY;
2975 1.1 tron break;
2976 1.1 tron default:
2977 1.1 tron if (defaultHandler)
2978 1.1 tron reportDefault(parser, enc, s, next);
2979 1.1 tron break;
2980 1.1 tron }
2981 1.1 tron *eventPP = s = next;
2982 1.1 tron switch (ps_parsing) {
2983 1.3 spz case XML_SUSPENDED:
2984 1.1 tron *nextPtr = next;
2985 1.1 tron return XML_ERROR_NONE;
2986 1.1 tron case XML_FINISHED:
2987 1.1 tron return XML_ERROR_ABORTED;
2988 1.1 tron default: ;
2989 1.1 tron }
2990 1.1 tron }
2991 1.1 tron /* not reached */
2992 1.1 tron }
2993 1.1 tron
2994 1.7 christos /* This function does not call free() on the allocated memory, merely
2995 1.7 christos * moving it to the parser's freeBindingList where it can be freed or
2996 1.7 christos * reused as appropriate.
2997 1.7 christos */
2998 1.7 christos static void
2999 1.7 christos freeBindings(XML_Parser parser, BINDING *bindings)
3000 1.7 christos {
3001 1.7 christos while (bindings) {
3002 1.7 christos BINDING *b = bindings;
3003 1.7 christos
3004 1.7 christos /* startNamespaceDeclHandler will have been called for this
3005 1.7 christos * binding in addBindings(), so call the end handler now.
3006 1.7 christos */
3007 1.7 christos if (endNamespaceDeclHandler)
3008 1.7 christos endNamespaceDeclHandler(handlerArg, b->prefix->name);
3009 1.7 christos
3010 1.7 christos bindings = bindings->nextTagBinding;
3011 1.7 christos b->nextTagBinding = freeBindingList;
3012 1.7 christos freeBindingList = b;
3013 1.7 christos b->prefix->binding = b->prevPrefixBinding;
3014 1.7 christos }
3015 1.7 christos }
3016 1.7 christos
3017 1.1 tron /* Precondition: all arguments must be non-NULL;
3018 1.1 tron Purpose:
3019 1.1 tron - normalize attributes
3020 1.1 tron - check attributes for well-formedness
3021 1.1 tron - generate namespace aware attribute names (URI, prefix)
3022 1.1 tron - build list of attributes for startElementHandler
3023 1.1 tron - default attributes
3024 1.1 tron - process namespace declarations (check and report them)
3025 1.1 tron - generate namespace aware element name (URI, prefix)
3026 1.1 tron */
3027 1.1 tron static enum XML_Error
3028 1.1 tron storeAtts(XML_Parser parser, const ENCODING *enc,
3029 1.1 tron const char *attStr, TAG_NAME *tagNamePtr,
3030 1.1 tron BINDING **bindingsPtr)
3031 1.1 tron {
3032 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
3033 1.1 tron ELEMENT_TYPE *elementType;
3034 1.1 tron int nDefaultAtts;
3035 1.1 tron const XML_Char **appAtts; /* the attribute list for the application */
3036 1.1 tron int attIndex = 0;
3037 1.1 tron int prefixLen;
3038 1.1 tron int i;
3039 1.1 tron int n;
3040 1.1 tron XML_Char *uri;
3041 1.1 tron int nPrefixes = 0;
3042 1.1 tron BINDING *binding;
3043 1.1 tron const XML_Char *localPart;
3044 1.1 tron
3045 1.1 tron /* lookup the element type name */
3046 1.3 spz elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
3047 1.1 tron if (!elementType) {
3048 1.1 tron const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
3049 1.1 tron if (!name)
3050 1.1 tron return XML_ERROR_NO_MEMORY;
3051 1.3 spz elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
3052 1.1 tron sizeof(ELEMENT_TYPE));
3053 1.1 tron if (!elementType)
3054 1.1 tron return XML_ERROR_NO_MEMORY;
3055 1.1 tron if (ns && !setElementTypePrefix(parser, elementType))
3056 1.1 tron return XML_ERROR_NO_MEMORY;
3057 1.1 tron }
3058 1.1 tron nDefaultAtts = elementType->nDefaultAtts;
3059 1.1 tron
3060 1.1 tron /* get the attributes from the tokenizer */
3061 1.1 tron n = XmlGetAttributes(enc, attStr, attsSize, atts);
3062 1.1 tron if (n + nDefaultAtts > attsSize) {
3063 1.1 tron int oldAttsSize = attsSize;
3064 1.1 tron ATTRIBUTE *temp;
3065 1.3 spz #ifdef XML_ATTR_INFO
3066 1.3 spz XML_AttrInfo *temp2;
3067 1.3 spz #endif
3068 1.1 tron attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
3069 1.1 tron temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
3070 1.1 tron if (temp == NULL)
3071 1.1 tron return XML_ERROR_NO_MEMORY;
3072 1.1 tron atts = temp;
3073 1.3 spz #ifdef XML_ATTR_INFO
3074 1.3 spz temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
3075 1.3 spz if (temp2 == NULL)
3076 1.3 spz return XML_ERROR_NO_MEMORY;
3077 1.3 spz attInfo = temp2;
3078 1.3 spz #endif
3079 1.1 tron if (n > oldAttsSize)
3080 1.1 tron XmlGetAttributes(enc, attStr, n, atts);
3081 1.1 tron }
3082 1.1 tron
3083 1.1 tron appAtts = (const XML_Char **)atts;
3084 1.1 tron for (i = 0; i < n; i++) {
3085 1.3 spz ATTRIBUTE *currAtt = &atts[i];
3086 1.3 spz #ifdef XML_ATTR_INFO
3087 1.3 spz XML_AttrInfo *currAttInfo = &attInfo[i];
3088 1.3 spz #endif
3089 1.1 tron /* add the name and value to the attribute list */
3090 1.3 spz ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
3091 1.3 spz currAtt->name
3092 1.3 spz + XmlNameLength(enc, currAtt->name));
3093 1.1 tron if (!attId)
3094 1.1 tron return XML_ERROR_NO_MEMORY;
3095 1.3 spz #ifdef XML_ATTR_INFO
3096 1.3 spz currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
3097 1.3 spz currAttInfo->nameEnd = currAttInfo->nameStart +
3098 1.3 spz XmlNameLength(enc, currAtt->name);
3099 1.3 spz currAttInfo->valueStart = parseEndByteIndex -
3100 1.3 spz (parseEndPtr - currAtt->valuePtr);
3101 1.3 spz currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
3102 1.3 spz #endif
3103 1.1 tron /* Detect duplicate attributes by their QNames. This does not work when
3104 1.1 tron namespace processing is turned on and different prefixes for the same
3105 1.1 tron namespace are used. For this case we have a check further down.
3106 1.1 tron */
3107 1.1 tron if ((attId->name)[-1]) {
3108 1.1 tron if (enc == encoding)
3109 1.1 tron eventPtr = atts[i].name;
3110 1.1 tron return XML_ERROR_DUPLICATE_ATTRIBUTE;
3111 1.1 tron }
3112 1.1 tron (attId->name)[-1] = 1;
3113 1.1 tron appAtts[attIndex++] = attId->name;
3114 1.1 tron if (!atts[i].normalized) {
3115 1.1 tron enum XML_Error result;
3116 1.1 tron XML_Bool isCdata = XML_TRUE;
3117 1.1 tron
3118 1.1 tron /* figure out whether declared as other than CDATA */
3119 1.1 tron if (attId->maybeTokenized) {
3120 1.1 tron int j;
3121 1.1 tron for (j = 0; j < nDefaultAtts; j++) {
3122 1.1 tron if (attId == elementType->defaultAtts[j].id) {
3123 1.1 tron isCdata = elementType->defaultAtts[j].isCdata;
3124 1.1 tron break;
3125 1.1 tron }
3126 1.1 tron }
3127 1.1 tron }
3128 1.1 tron
3129 1.1 tron /* normalize the attribute value */
3130 1.1 tron result = storeAttributeValue(parser, enc, isCdata,
3131 1.1 tron atts[i].valuePtr, atts[i].valueEnd,
3132 1.1 tron &tempPool);
3133 1.1 tron if (result)
3134 1.1 tron return result;
3135 1.1 tron appAtts[attIndex] = poolStart(&tempPool);
3136 1.1 tron poolFinish(&tempPool);
3137 1.1 tron }
3138 1.1 tron else {
3139 1.1 tron /* the value did not need normalizing */
3140 1.1 tron appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
3141 1.1 tron atts[i].valueEnd);
3142 1.1 tron if (appAtts[attIndex] == 0)
3143 1.1 tron return XML_ERROR_NO_MEMORY;
3144 1.1 tron poolFinish(&tempPool);
3145 1.1 tron }
3146 1.1 tron /* handle prefixed attribute names */
3147 1.1 tron if (attId->prefix) {
3148 1.1 tron if (attId->xmlns) {
3149 1.1 tron /* deal with namespace declarations here */
3150 1.1 tron enum XML_Error result = addBinding(parser, attId->prefix, attId,
3151 1.1 tron appAtts[attIndex], bindingsPtr);
3152 1.1 tron if (result)
3153 1.1 tron return result;
3154 1.1 tron --attIndex;
3155 1.1 tron }
3156 1.1 tron else {
3157 1.1 tron /* deal with other prefixed names later */
3158 1.1 tron attIndex++;
3159 1.1 tron nPrefixes++;
3160 1.1 tron (attId->name)[-1] = 2;
3161 1.1 tron }
3162 1.1 tron }
3163 1.1 tron else
3164 1.1 tron attIndex++;
3165 1.1 tron }
3166 1.1 tron
3167 1.1 tron /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
3168 1.1 tron nSpecifiedAtts = attIndex;
3169 1.1 tron if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
3170 1.1 tron for (i = 0; i < attIndex; i += 2)
3171 1.1 tron if (appAtts[i] == elementType->idAtt->name) {
3172 1.1 tron idAttIndex = i;
3173 1.1 tron break;
3174 1.1 tron }
3175 1.1 tron }
3176 1.1 tron else
3177 1.1 tron idAttIndex = -1;
3178 1.1 tron
3179 1.1 tron /* do attribute defaulting */
3180 1.1 tron for (i = 0; i < nDefaultAtts; i++) {
3181 1.1 tron const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
3182 1.1 tron if (!(da->id->name)[-1] && da->value) {
3183 1.1 tron if (da->id->prefix) {
3184 1.1 tron if (da->id->xmlns) {
3185 1.1 tron enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
3186 1.1 tron da->value, bindingsPtr);
3187 1.1 tron if (result)
3188 1.1 tron return result;
3189 1.1 tron }
3190 1.1 tron else {
3191 1.1 tron (da->id->name)[-1] = 2;
3192 1.1 tron nPrefixes++;
3193 1.1 tron appAtts[attIndex++] = da->id->name;
3194 1.1 tron appAtts[attIndex++] = da->value;
3195 1.1 tron }
3196 1.1 tron }
3197 1.1 tron else {
3198 1.1 tron (da->id->name)[-1] = 1;
3199 1.1 tron appAtts[attIndex++] = da->id->name;
3200 1.1 tron appAtts[attIndex++] = da->value;
3201 1.1 tron }
3202 1.1 tron }
3203 1.1 tron }
3204 1.1 tron appAtts[attIndex] = 0;
3205 1.1 tron
3206 1.1 tron /* expand prefixed attribute names, check for duplicates,
3207 1.1 tron and clear flags that say whether attributes were specified */
3208 1.1 tron i = 0;
3209 1.1 tron if (nPrefixes) {
3210 1.1 tron int j; /* hash table index */
3211 1.1 tron unsigned long version = nsAttsVersion;
3212 1.1 tron int nsAttsSize = (int)1 << nsAttsPower;
3213 1.1 tron /* size of hash table must be at least 2 * (# of prefixed attributes) */
3214 1.1 tron if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
3215 1.1 tron NS_ATT *temp;
3216 1.1 tron /* hash table size must also be a power of 2 and >= 8 */
3217 1.1 tron while (nPrefixes >> nsAttsPower++);
3218 1.1 tron if (nsAttsPower < 3)
3219 1.1 tron nsAttsPower = 3;
3220 1.1 tron nsAttsSize = (int)1 << nsAttsPower;
3221 1.1 tron temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
3222 1.1 tron if (!temp)
3223 1.1 tron return XML_ERROR_NO_MEMORY;
3224 1.1 tron nsAtts = temp;
3225 1.1 tron version = 0; /* force re-initialization of nsAtts hash table */
3226 1.1 tron }
3227 1.1 tron /* using a version flag saves us from initializing nsAtts every time */
3228 1.1 tron if (!version) { /* initialize version flags when version wraps around */
3229 1.1 tron version = INIT_ATTS_VERSION;
3230 1.1 tron for (j = nsAttsSize; j != 0; )
3231 1.1 tron nsAtts[--j].version = version;
3232 1.1 tron }
3233 1.1 tron nsAttsVersion = --version;
3234 1.1 tron
3235 1.1 tron /* expand prefixed names and check for duplicates */
3236 1.1 tron for (; i < attIndex; i += 2) {
3237 1.1 tron const XML_Char *s = appAtts[i];
3238 1.1 tron if (s[-1] == 2) { /* prefixed */
3239 1.1 tron ATTRIBUTE_ID *id;
3240 1.1 tron const BINDING *b;
3241 1.7 christos unsigned long uriHash;
3242 1.7 christos struct siphash sip_state;
3243 1.7 christos struct sipkey sip_key;
3244 1.7 christos
3245 1.7 christos copy_salt_to_sipkey(parser, &sip_key);
3246 1.7 christos sip24_init(&sip_state, &sip_key);
3247 1.7 christos
3248 1.1 tron ((XML_Char *)s)[-1] = 0; /* clear flag */
3249 1.3 spz id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
3250 1.4 spz if (!id || !id->prefix)
3251 1.4 spz return XML_ERROR_NO_MEMORY;
3252 1.1 tron b = id->prefix->binding;
3253 1.1 tron if (!b)
3254 1.1 tron return XML_ERROR_UNBOUND_PREFIX;
3255 1.1 tron
3256 1.1 tron for (j = 0; j < b->uriLen; j++) {
3257 1.1 tron const XML_Char c = b->uri[j];
3258 1.1 tron if (!poolAppendChar(&tempPool, c))
3259 1.1 tron return XML_ERROR_NO_MEMORY;
3260 1.1 tron }
3261 1.7 christos
3262 1.7 christos sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
3263 1.7 christos
3264 1.1 tron while (*s++ != XML_T(ASCII_COLON))
3265 1.1 tron ;
3266 1.7 christos
3267 1.7 christos sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
3268 1.7 christos
3269 1.1 tron do { /* copies null terminator */
3270 1.1 tron if (!poolAppendChar(&tempPool, *s))
3271 1.1 tron return XML_ERROR_NO_MEMORY;
3272 1.1 tron } while (*s++);
3273 1.1 tron
3274 1.7 christos uriHash = (unsigned long)sip24_final(&sip_state);
3275 1.7 christos
3276 1.1 tron { /* Check hash table for duplicate of expanded name (uriName).
3277 1.3 spz Derived from code in lookup(parser, HASH_TABLE *table, ...).
3278 1.1 tron */
3279 1.1 tron unsigned char step = 0;
3280 1.1 tron unsigned long mask = nsAttsSize - 1;
3281 1.1 tron j = uriHash & mask; /* index into hash table */
3282 1.1 tron while (nsAtts[j].version == version) {
3283 1.1 tron /* for speed we compare stored hash values first */
3284 1.1 tron if (uriHash == nsAtts[j].hash) {
3285 1.1 tron const XML_Char *s1 = poolStart(&tempPool);
3286 1.1 tron const XML_Char *s2 = nsAtts[j].uriName;
3287 1.1 tron /* s1 is null terminated, but not s2 */
3288 1.1 tron for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
3289 1.1 tron if (*s1 == 0)
3290 1.1 tron return XML_ERROR_DUPLICATE_ATTRIBUTE;
3291 1.1 tron }
3292 1.1 tron if (!step)
3293 1.1 tron step = PROBE_STEP(uriHash, mask, nsAttsPower);
3294 1.1 tron j < step ? (j += nsAttsSize - step) : (j -= step);
3295 1.1 tron }
3296 1.1 tron }
3297 1.1 tron
3298 1.1 tron if (ns_triplets) { /* append namespace separator and prefix */
3299 1.1 tron tempPool.ptr[-1] = namespaceSeparator;
3300 1.1 tron s = b->prefix->name;
3301 1.1 tron do {
3302 1.1 tron if (!poolAppendChar(&tempPool, *s))
3303 1.1 tron return XML_ERROR_NO_MEMORY;
3304 1.1 tron } while (*s++);
3305 1.1 tron }
3306 1.1 tron
3307 1.1 tron /* store expanded name in attribute list */
3308 1.1 tron s = poolStart(&tempPool);
3309 1.1 tron poolFinish(&tempPool);
3310 1.1 tron appAtts[i] = s;
3311 1.1 tron
3312 1.1 tron /* fill empty slot with new version, uriName and hash value */
3313 1.1 tron nsAtts[j].version = version;
3314 1.1 tron nsAtts[j].hash = uriHash;
3315 1.1 tron nsAtts[j].uriName = s;
3316 1.1 tron
3317 1.1 tron if (!--nPrefixes) {
3318 1.1 tron i += 2;
3319 1.1 tron break;
3320 1.1 tron }
3321 1.1 tron }
3322 1.1 tron else /* not prefixed */
3323 1.1 tron ((XML_Char *)s)[-1] = 0; /* clear flag */
3324 1.1 tron }
3325 1.1 tron }
3326 1.1 tron /* clear flags for the remaining attributes */
3327 1.1 tron for (; i < attIndex; i += 2)
3328 1.1 tron ((XML_Char *)(appAtts[i]))[-1] = 0;
3329 1.1 tron for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3330 1.1 tron binding->attId->name[-1] = 0;
3331 1.1 tron
3332 1.1 tron if (!ns)
3333 1.1 tron return XML_ERROR_NONE;
3334 1.1 tron
3335 1.1 tron /* expand the element type name */
3336 1.1 tron if (elementType->prefix) {
3337 1.1 tron binding = elementType->prefix->binding;
3338 1.1 tron if (!binding)
3339 1.1 tron return XML_ERROR_UNBOUND_PREFIX;
3340 1.1 tron localPart = tagNamePtr->str;
3341 1.1 tron while (*localPart++ != XML_T(ASCII_COLON))
3342 1.1 tron ;
3343 1.1 tron }
3344 1.1 tron else if (dtd->defaultPrefix.binding) {
3345 1.1 tron binding = dtd->defaultPrefix.binding;
3346 1.1 tron localPart = tagNamePtr->str;
3347 1.1 tron }
3348 1.1 tron else
3349 1.1 tron return XML_ERROR_NONE;
3350 1.1 tron prefixLen = 0;
3351 1.1 tron if (ns_triplets && binding->prefix->name) {
3352 1.1 tron for (; binding->prefix->name[prefixLen++];)
3353 1.1 tron ; /* prefixLen includes null terminator */
3354 1.1 tron }
3355 1.1 tron tagNamePtr->localPart = localPart;
3356 1.1 tron tagNamePtr->uriLen = binding->uriLen;
3357 1.1 tron tagNamePtr->prefix = binding->prefix->name;
3358 1.1 tron tagNamePtr->prefixLen = prefixLen;
3359 1.1 tron for (i = 0; localPart[i++];)
3360 1.1 tron ; /* i includes null terminator */
3361 1.1 tron n = i + binding->uriLen + prefixLen;
3362 1.1 tron if (n > binding->uriAlloc) {
3363 1.1 tron TAG *p;
3364 1.1 tron uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
3365 1.1 tron if (!uri)
3366 1.1 tron return XML_ERROR_NO_MEMORY;
3367 1.1 tron binding->uriAlloc = n + EXPAND_SPARE;
3368 1.1 tron memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3369 1.1 tron for (p = tagStack; p; p = p->parent)
3370 1.1 tron if (p->name.str == binding->uri)
3371 1.1 tron p->name.str = uri;
3372 1.1 tron FREE(binding->uri);
3373 1.1 tron binding->uri = uri;
3374 1.1 tron }
3375 1.1 tron /* if namespaceSeparator != '\0' then uri includes it already */
3376 1.1 tron uri = binding->uri + binding->uriLen;
3377 1.1 tron memcpy(uri, localPart, i * sizeof(XML_Char));
3378 1.1 tron /* we always have a namespace separator between localPart and prefix */
3379 1.1 tron if (prefixLen) {
3380 1.1 tron uri += i - 1;
3381 1.1 tron *uri = namespaceSeparator; /* replace null terminator */
3382 1.1 tron memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3383 1.1 tron }
3384 1.1 tron tagNamePtr->str = binding->uri;
3385 1.1 tron return XML_ERROR_NONE;
3386 1.1 tron }
3387 1.1 tron
3388 1.1 tron /* addBinding() overwrites the value of prefix->binding without checking.
3389 1.1 tron Therefore one must keep track of the old value outside of addBinding().
3390 1.1 tron */
3391 1.1 tron static enum XML_Error
3392 1.1 tron addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3393 1.1 tron const XML_Char *uri, BINDING **bindingsPtr)
3394 1.1 tron {
3395 1.1 tron static const XML_Char xmlNamespace[] = {
3396 1.1 tron ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3397 1.1 tron ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3398 1.3 spz ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
3399 1.1 tron ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
3400 1.1 tron ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3401 1.1 tron ASCII_e, '\0'
3402 1.1 tron };
3403 1.3 spz static const int xmlLen =
3404 1.1 tron (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3405 1.1 tron static const XML_Char xmlnsNamespace[] = {
3406 1.1 tron ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3407 1.1 tron ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3408 1.3 spz ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
3409 1.3 spz ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
3410 1.1 tron ASCII_SLASH, '\0'
3411 1.1 tron };
3412 1.3 spz static const int xmlnsLen =
3413 1.1 tron (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3414 1.1 tron
3415 1.1 tron XML_Bool mustBeXML = XML_FALSE;
3416 1.1 tron XML_Bool isXML = XML_TRUE;
3417 1.1 tron XML_Bool isXMLNS = XML_TRUE;
3418 1.3 spz
3419 1.1 tron BINDING *b;
3420 1.1 tron int len;
3421 1.1 tron
3422 1.1 tron /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3423 1.1 tron if (*uri == XML_T('\0') && prefix->name)
3424 1.1 tron return XML_ERROR_UNDECLARING_PREFIX;
3425 1.1 tron
3426 1.1 tron if (prefix->name
3427 1.1 tron && prefix->name[0] == XML_T(ASCII_x)
3428 1.1 tron && prefix->name[1] == XML_T(ASCII_m)
3429 1.1 tron && prefix->name[2] == XML_T(ASCII_l)) {
3430 1.1 tron
3431 1.1 tron /* Not allowed to bind xmlns */
3432 1.1 tron if (prefix->name[3] == XML_T(ASCII_n)
3433 1.1 tron && prefix->name[4] == XML_T(ASCII_s)
3434 1.1 tron && prefix->name[5] == XML_T('\0'))
3435 1.1 tron return XML_ERROR_RESERVED_PREFIX_XMLNS;
3436 1.1 tron
3437 1.1 tron if (prefix->name[3] == XML_T('\0'))
3438 1.1 tron mustBeXML = XML_TRUE;
3439 1.1 tron }
3440 1.1 tron
3441 1.1 tron for (len = 0; uri[len]; len++) {
3442 1.1 tron if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3443 1.1 tron isXML = XML_FALSE;
3444 1.1 tron
3445 1.3 spz if (!mustBeXML && isXMLNS
3446 1.1 tron && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3447 1.1 tron isXMLNS = XML_FALSE;
3448 1.1 tron }
3449 1.1 tron isXML = isXML && len == xmlLen;
3450 1.1 tron isXMLNS = isXMLNS && len == xmlnsLen;
3451 1.1 tron
3452 1.1 tron if (mustBeXML != isXML)
3453 1.1 tron return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3454 1.1 tron : XML_ERROR_RESERVED_NAMESPACE_URI;
3455 1.1 tron
3456 1.1 tron if (isXMLNS)
3457 1.1 tron return XML_ERROR_RESERVED_NAMESPACE_URI;
3458 1.1 tron
3459 1.1 tron if (namespaceSeparator)
3460 1.1 tron len++;
3461 1.1 tron if (freeBindingList) {
3462 1.1 tron b = freeBindingList;
3463 1.1 tron if (len > b->uriAlloc) {
3464 1.1 tron XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3465 1.1 tron sizeof(XML_Char) * (len + EXPAND_SPARE));
3466 1.1 tron if (temp == NULL)
3467 1.1 tron return XML_ERROR_NO_MEMORY;
3468 1.1 tron b->uri = temp;
3469 1.1 tron b->uriAlloc = len + EXPAND_SPARE;
3470 1.1 tron }
3471 1.1 tron freeBindingList = b->nextTagBinding;
3472 1.1 tron }
3473 1.1 tron else {
3474 1.1 tron b = (BINDING *)MALLOC(sizeof(BINDING));
3475 1.1 tron if (!b)
3476 1.1 tron return XML_ERROR_NO_MEMORY;
3477 1.1 tron b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3478 1.1 tron if (!b->uri) {
3479 1.1 tron FREE(b);
3480 1.1 tron return XML_ERROR_NO_MEMORY;
3481 1.1 tron }
3482 1.1 tron b->uriAlloc = len + EXPAND_SPARE;
3483 1.1 tron }
3484 1.1 tron b->uriLen = len;
3485 1.1 tron memcpy(b->uri, uri, len * sizeof(XML_Char));
3486 1.1 tron if (namespaceSeparator)
3487 1.1 tron b->uri[len - 1] = namespaceSeparator;
3488 1.1 tron b->prefix = prefix;
3489 1.1 tron b->attId = attId;
3490 1.1 tron b->prevPrefixBinding = prefix->binding;
3491 1.1 tron /* NULL binding when default namespace undeclared */
3492 1.1 tron if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3493 1.1 tron prefix->binding = NULL;
3494 1.1 tron else
3495 1.1 tron prefix->binding = b;
3496 1.1 tron b->nextTagBinding = *bindingsPtr;
3497 1.1 tron *bindingsPtr = b;
3498 1.1 tron /* if attId == NULL then we are not starting a namespace scope */
3499 1.1 tron if (attId && startNamespaceDeclHandler)
3500 1.1 tron startNamespaceDeclHandler(handlerArg, prefix->name,
3501 1.1 tron prefix->binding ? uri : 0);
3502 1.1 tron return XML_ERROR_NONE;
3503 1.1 tron }
3504 1.1 tron
3505 1.1 tron /* The idea here is to avoid using stack for each CDATA section when
3506 1.1 tron the whole file is parsed with one call.
3507 1.1 tron */
3508 1.1 tron static enum XML_Error PTRCALL
3509 1.1 tron cdataSectionProcessor(XML_Parser parser,
3510 1.1 tron const char *start,
3511 1.1 tron const char *end,
3512 1.1 tron const char **endPtr)
3513 1.1 tron {
3514 1.1 tron enum XML_Error result = doCdataSection(parser, encoding, &start, end,
3515 1.1 tron endPtr, (XML_Bool)!ps_finalBuffer);
3516 1.1 tron if (result != XML_ERROR_NONE)
3517 1.1 tron return result;
3518 1.1 tron if (start) {
3519 1.1 tron if (parentParser) { /* we are parsing an external entity */
3520 1.1 tron processor = externalEntityContentProcessor;
3521 1.1 tron return externalEntityContentProcessor(parser, start, end, endPtr);
3522 1.1 tron }
3523 1.1 tron else {
3524 1.1 tron processor = contentProcessor;
3525 1.1 tron return contentProcessor(parser, start, end, endPtr);
3526 1.1 tron }
3527 1.1 tron }
3528 1.1 tron return result;
3529 1.1 tron }
3530 1.1 tron
3531 1.1 tron /* startPtr gets set to non-null if the section is closed, and to null if
3532 1.1 tron the section is not yet closed.
3533 1.1 tron */
3534 1.1 tron static enum XML_Error
3535 1.1 tron doCdataSection(XML_Parser parser,
3536 1.1 tron const ENCODING *enc,
3537 1.1 tron const char **startPtr,
3538 1.1 tron const char *end,
3539 1.1 tron const char **nextPtr,
3540 1.1 tron XML_Bool haveMore)
3541 1.1 tron {
3542 1.1 tron const char *s = *startPtr;
3543 1.1 tron const char **eventPP;
3544 1.1 tron const char **eventEndPP;
3545 1.1 tron if (enc == encoding) {
3546 1.1 tron eventPP = &eventPtr;
3547 1.1 tron *eventPP = s;
3548 1.1 tron eventEndPP = &eventEndPtr;
3549 1.1 tron }
3550 1.1 tron else {
3551 1.1 tron eventPP = &(openInternalEntities->internalEventPtr);
3552 1.1 tron eventEndPP = &(openInternalEntities->internalEventEndPtr);
3553 1.1 tron }
3554 1.1 tron *eventPP = s;
3555 1.1 tron *startPtr = NULL;
3556 1.1 tron
3557 1.1 tron for (;;) {
3558 1.1 tron const char *next;
3559 1.1 tron int tok = XmlCdataSectionTok(enc, s, end, &next);
3560 1.1 tron *eventEndPP = next;
3561 1.1 tron switch (tok) {
3562 1.1 tron case XML_TOK_CDATA_SECT_CLOSE:
3563 1.1 tron if (endCdataSectionHandler)
3564 1.1 tron endCdataSectionHandler(handlerArg);
3565 1.1 tron #if 0
3566 1.1 tron /* see comment under XML_TOK_CDATA_SECT_OPEN */
3567 1.1 tron else if (characterDataHandler)
3568 1.1 tron characterDataHandler(handlerArg, dataBuf, 0);
3569 1.1 tron #endif
3570 1.1 tron else if (defaultHandler)
3571 1.1 tron reportDefault(parser, enc, s, next);
3572 1.1 tron *startPtr = next;
3573 1.1 tron *nextPtr = next;
3574 1.1 tron if (ps_parsing == XML_FINISHED)
3575 1.1 tron return XML_ERROR_ABORTED;
3576 1.1 tron else
3577 1.1 tron return XML_ERROR_NONE;
3578 1.1 tron case XML_TOK_DATA_NEWLINE:
3579 1.1 tron if (characterDataHandler) {
3580 1.1 tron XML_Char c = 0xA;
3581 1.1 tron characterDataHandler(handlerArg, &c, 1);
3582 1.1 tron }
3583 1.1 tron else if (defaultHandler)
3584 1.1 tron reportDefault(parser, enc, s, next);
3585 1.1 tron break;
3586 1.1 tron case XML_TOK_DATA_CHARS:
3587 1.1 tron {
3588 1.1 tron XML_CharacterDataHandler charDataHandler = characterDataHandler;
3589 1.1 tron if (charDataHandler) {
3590 1.1 tron if (MUST_CONVERT(enc, s)) {
3591 1.1 tron for (;;) {
3592 1.1 tron ICHAR *dataPtr = (ICHAR *)dataBuf;
3593 1.5 spz const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3594 1.1 tron *eventEndPP = next;
3595 1.1 tron charDataHandler(handlerArg, dataBuf,
3596 1.1 tron (int)(dataPtr - (ICHAR *)dataBuf));
3597 1.5 spz if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3598 1.1 tron break;
3599 1.1 tron *eventPP = s;
3600 1.1 tron }
3601 1.1 tron }
3602 1.1 tron else
3603 1.1 tron charDataHandler(handlerArg,
3604 1.1 tron (XML_Char *)s,
3605 1.1 tron (int)((XML_Char *)next - (XML_Char *)s));
3606 1.1 tron }
3607 1.1 tron else if (defaultHandler)
3608 1.1 tron reportDefault(parser, enc, s, next);
3609 1.1 tron }
3610 1.1 tron break;
3611 1.1 tron case XML_TOK_INVALID:
3612 1.1 tron *eventPP = next;
3613 1.1 tron return XML_ERROR_INVALID_TOKEN;
3614 1.1 tron case XML_TOK_PARTIAL_CHAR:
3615 1.1 tron if (haveMore) {
3616 1.1 tron *nextPtr = s;
3617 1.1 tron return XML_ERROR_NONE;
3618 1.1 tron }
3619 1.1 tron return XML_ERROR_PARTIAL_CHAR;
3620 1.1 tron case XML_TOK_PARTIAL:
3621 1.1 tron case XML_TOK_NONE:
3622 1.1 tron if (haveMore) {
3623 1.1 tron *nextPtr = s;
3624 1.1 tron return XML_ERROR_NONE;
3625 1.1 tron }
3626 1.1 tron return XML_ERROR_UNCLOSED_CDATA_SECTION;
3627 1.1 tron default:
3628 1.1 tron *eventPP = next;
3629 1.1 tron return XML_ERROR_UNEXPECTED_STATE;
3630 1.1 tron }
3631 1.1 tron
3632 1.1 tron *eventPP = s = next;
3633 1.1 tron switch (ps_parsing) {
3634 1.1 tron case XML_SUSPENDED:
3635 1.1 tron *nextPtr = next;
3636 1.1 tron return XML_ERROR_NONE;
3637 1.1 tron case XML_FINISHED:
3638 1.1 tron return XML_ERROR_ABORTED;
3639 1.1 tron default: ;
3640 1.1 tron }
3641 1.1 tron }
3642 1.1 tron /* not reached */
3643 1.1 tron }
3644 1.1 tron
3645 1.1 tron #ifdef XML_DTD
3646 1.1 tron
3647 1.1 tron /* The idea here is to avoid using stack for each IGNORE section when
3648 1.1 tron the whole file is parsed with one call.
3649 1.1 tron */
3650 1.1 tron static enum XML_Error PTRCALL
3651 1.1 tron ignoreSectionProcessor(XML_Parser parser,
3652 1.1 tron const char *start,
3653 1.1 tron const char *end,
3654 1.1 tron const char **endPtr)
3655 1.1 tron {
3656 1.3 spz enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
3657 1.1 tron endPtr, (XML_Bool)!ps_finalBuffer);
3658 1.1 tron if (result != XML_ERROR_NONE)
3659 1.1 tron return result;
3660 1.1 tron if (start) {
3661 1.1 tron processor = prologProcessor;
3662 1.1 tron return prologProcessor(parser, start, end, endPtr);
3663 1.1 tron }
3664 1.1 tron return result;
3665 1.1 tron }
3666 1.1 tron
3667 1.1 tron /* startPtr gets set to non-null is the section is closed, and to null
3668 1.1 tron if the section is not yet closed.
3669 1.1 tron */
3670 1.1 tron static enum XML_Error
3671 1.1 tron doIgnoreSection(XML_Parser parser,
3672 1.1 tron const ENCODING *enc,
3673 1.1 tron const char **startPtr,
3674 1.1 tron const char *end,
3675 1.1 tron const char **nextPtr,
3676 1.1 tron XML_Bool haveMore)
3677 1.1 tron {
3678 1.1 tron const char *next;
3679 1.1 tron int tok;
3680 1.1 tron const char *s = *startPtr;
3681 1.1 tron const char **eventPP;
3682 1.1 tron const char **eventEndPP;
3683 1.1 tron if (enc == encoding) {
3684 1.1 tron eventPP = &eventPtr;
3685 1.1 tron *eventPP = s;
3686 1.1 tron eventEndPP = &eventEndPtr;
3687 1.1 tron }
3688 1.1 tron else {
3689 1.1 tron eventPP = &(openInternalEntities->internalEventPtr);
3690 1.1 tron eventEndPP = &(openInternalEntities->internalEventEndPtr);
3691 1.1 tron }
3692 1.1 tron *eventPP = s;
3693 1.1 tron *startPtr = NULL;
3694 1.1 tron tok = XmlIgnoreSectionTok(enc, s, end, &next);
3695 1.1 tron *eventEndPP = next;
3696 1.1 tron switch (tok) {
3697 1.1 tron case XML_TOK_IGNORE_SECT:
3698 1.1 tron if (defaultHandler)
3699 1.1 tron reportDefault(parser, enc, s, next);
3700 1.1 tron *startPtr = next;
3701 1.1 tron *nextPtr = next;
3702 1.1 tron if (ps_parsing == XML_FINISHED)
3703 1.1 tron return XML_ERROR_ABORTED;
3704 1.1 tron else
3705 1.1 tron return XML_ERROR_NONE;
3706 1.1 tron case XML_TOK_INVALID:
3707 1.1 tron *eventPP = next;
3708 1.1 tron return XML_ERROR_INVALID_TOKEN;
3709 1.1 tron case XML_TOK_PARTIAL_CHAR:
3710 1.1 tron if (haveMore) {
3711 1.1 tron *nextPtr = s;
3712 1.1 tron return XML_ERROR_NONE;
3713 1.1 tron }
3714 1.1 tron return XML_ERROR_PARTIAL_CHAR;
3715 1.1 tron case XML_TOK_PARTIAL:
3716 1.1 tron case XML_TOK_NONE:
3717 1.1 tron if (haveMore) {
3718 1.1 tron *nextPtr = s;
3719 1.1 tron return XML_ERROR_NONE;
3720 1.1 tron }
3721 1.1 tron return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3722 1.1 tron default:
3723 1.1 tron *eventPP = next;
3724 1.1 tron return XML_ERROR_UNEXPECTED_STATE;
3725 1.1 tron }
3726 1.1 tron /* not reached */
3727 1.1 tron }
3728 1.1 tron
3729 1.1 tron #endif /* XML_DTD */
3730 1.1 tron
3731 1.1 tron static enum XML_Error
3732 1.1 tron initializeEncoding(XML_Parser parser)
3733 1.1 tron {
3734 1.1 tron const char *s;
3735 1.1 tron #ifdef XML_UNICODE
3736 1.1 tron char encodingBuf[128];
3737 1.1 tron if (!protocolEncodingName)
3738 1.1 tron s = NULL;
3739 1.1 tron else {
3740 1.1 tron int i;
3741 1.1 tron for (i = 0; protocolEncodingName[i]; i++) {
3742 1.1 tron if (i == sizeof(encodingBuf) - 1
3743 1.1 tron || (protocolEncodingName[i] & ~0x7f) != 0) {
3744 1.1 tron encodingBuf[0] = '\0';
3745 1.1 tron break;
3746 1.1 tron }
3747 1.1 tron encodingBuf[i] = (char)protocolEncodingName[i];
3748 1.1 tron }
3749 1.1 tron encodingBuf[i] = '\0';
3750 1.1 tron s = encodingBuf;
3751 1.1 tron }
3752 1.1 tron #else
3753 1.1 tron s = protocolEncodingName;
3754 1.1 tron #endif
3755 1.1 tron if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3756 1.1 tron return XML_ERROR_NONE;
3757 1.1 tron return handleUnknownEncoding(parser, protocolEncodingName);
3758 1.1 tron }
3759 1.1 tron
3760 1.1 tron static enum XML_Error
3761 1.1 tron processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3762 1.1 tron const char *s, const char *next)
3763 1.1 tron {
3764 1.1 tron const char *encodingName = NULL;
3765 1.1 tron const XML_Char *storedEncName = NULL;
3766 1.1 tron const ENCODING *newEncoding = NULL;
3767 1.1 tron const char *version = NULL;
3768 1.1 tron const char *versionend;
3769 1.1 tron const XML_Char *storedversion = NULL;
3770 1.1 tron int standalone = -1;
3771 1.1 tron if (!(ns
3772 1.1 tron ? XmlParseXmlDeclNS
3773 1.1 tron : XmlParseXmlDecl)(isGeneralTextEntity,
3774 1.1 tron encoding,
3775 1.1 tron s,
3776 1.1 tron next,
3777 1.1 tron &eventPtr,
3778 1.1 tron &version,
3779 1.1 tron &versionend,
3780 1.1 tron &encodingName,
3781 1.1 tron &newEncoding,
3782 1.1 tron &standalone)) {
3783 1.1 tron if (isGeneralTextEntity)
3784 1.1 tron return XML_ERROR_TEXT_DECL;
3785 1.1 tron else
3786 1.1 tron return XML_ERROR_XML_DECL;
3787 1.1 tron }
3788 1.1 tron if (!isGeneralTextEntity && standalone == 1) {
3789 1.1 tron _dtd->standalone = XML_TRUE;
3790 1.1 tron #ifdef XML_DTD
3791 1.1 tron if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3792 1.1 tron paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3793 1.1 tron #endif /* XML_DTD */
3794 1.1 tron }
3795 1.1 tron if (xmlDeclHandler) {
3796 1.1 tron if (encodingName != NULL) {
3797 1.1 tron storedEncName = poolStoreString(&temp2Pool,
3798 1.1 tron encoding,
3799 1.1 tron encodingName,
3800 1.1 tron encodingName
3801 1.1 tron + XmlNameLength(encoding, encodingName));
3802 1.1 tron if (!storedEncName)
3803 1.1 tron return XML_ERROR_NO_MEMORY;
3804 1.1 tron poolFinish(&temp2Pool);
3805 1.1 tron }
3806 1.1 tron if (version) {
3807 1.1 tron storedversion = poolStoreString(&temp2Pool,
3808 1.1 tron encoding,
3809 1.1 tron version,
3810 1.1 tron versionend - encoding->minBytesPerChar);
3811 1.1 tron if (!storedversion)
3812 1.1 tron return XML_ERROR_NO_MEMORY;
3813 1.1 tron }
3814 1.1 tron xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3815 1.1 tron }
3816 1.1 tron else if (defaultHandler)
3817 1.1 tron reportDefault(parser, encoding, s, next);
3818 1.1 tron if (protocolEncodingName == NULL) {
3819 1.1 tron if (newEncoding) {
3820 1.1 tron if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3821 1.1 tron eventPtr = encodingName;
3822 1.1 tron return XML_ERROR_INCORRECT_ENCODING;
3823 1.1 tron }
3824 1.1 tron encoding = newEncoding;
3825 1.1 tron }
3826 1.1 tron else if (encodingName) {
3827 1.1 tron enum XML_Error result;
3828 1.1 tron if (!storedEncName) {
3829 1.1 tron storedEncName = poolStoreString(
3830 1.1 tron &temp2Pool, encoding, encodingName,
3831 1.1 tron encodingName + XmlNameLength(encoding, encodingName));
3832 1.1 tron if (!storedEncName)
3833 1.1 tron return XML_ERROR_NO_MEMORY;
3834 1.1 tron }
3835 1.1 tron result = handleUnknownEncoding(parser, storedEncName);
3836 1.1 tron poolClear(&temp2Pool);
3837 1.1 tron if (result == XML_ERROR_UNKNOWN_ENCODING)
3838 1.1 tron eventPtr = encodingName;
3839 1.1 tron return result;
3840 1.1 tron }
3841 1.1 tron }
3842 1.1 tron
3843 1.1 tron if (storedEncName || storedversion)
3844 1.1 tron poolClear(&temp2Pool);
3845 1.1 tron
3846 1.1 tron return XML_ERROR_NONE;
3847 1.1 tron }
3848 1.1 tron
3849 1.1 tron static enum XML_Error
3850 1.1 tron handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3851 1.1 tron {
3852 1.1 tron if (unknownEncodingHandler) {
3853 1.1 tron XML_Encoding info;
3854 1.1 tron int i;
3855 1.1 tron for (i = 0; i < 256; i++)
3856 1.1 tron info.map[i] = -1;
3857 1.1 tron info.convert = NULL;
3858 1.1 tron info.data = NULL;
3859 1.1 tron info.release = NULL;
3860 1.1 tron if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3861 1.1 tron &info)) {
3862 1.1 tron ENCODING *enc;
3863 1.1 tron unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3864 1.1 tron if (!unknownEncodingMem) {
3865 1.1 tron if (info.release)
3866 1.1 tron info.release(info.data);
3867 1.1 tron return XML_ERROR_NO_MEMORY;
3868 1.1 tron }
3869 1.1 tron enc = (ns
3870 1.1 tron ? XmlInitUnknownEncodingNS
3871 1.1 tron : XmlInitUnknownEncoding)(unknownEncodingMem,
3872 1.1 tron info.map,
3873 1.1 tron info.convert,
3874 1.1 tron info.data);
3875 1.1 tron if (enc) {
3876 1.1 tron unknownEncodingData = info.data;
3877 1.1 tron unknownEncodingRelease = info.release;
3878 1.1 tron encoding = enc;
3879 1.1 tron return XML_ERROR_NONE;
3880 1.1 tron }
3881 1.1 tron }
3882 1.1 tron if (info.release != NULL)
3883 1.1 tron info.release(info.data);
3884 1.1 tron }
3885 1.1 tron return XML_ERROR_UNKNOWN_ENCODING;
3886 1.1 tron }
3887 1.1 tron
3888 1.1 tron static enum XML_Error PTRCALL
3889 1.1 tron prologInitProcessor(XML_Parser parser,
3890 1.1 tron const char *s,
3891 1.1 tron const char *end,
3892 1.1 tron const char **nextPtr)
3893 1.1 tron {
3894 1.1 tron enum XML_Error result = initializeEncoding(parser);
3895 1.1 tron if (result != XML_ERROR_NONE)
3896 1.1 tron return result;
3897 1.1 tron processor = prologProcessor;
3898 1.1 tron return prologProcessor(parser, s, end, nextPtr);
3899 1.1 tron }
3900 1.1 tron
3901 1.1 tron #ifdef XML_DTD
3902 1.1 tron
3903 1.1 tron static enum XML_Error PTRCALL
3904 1.1 tron externalParEntInitProcessor(XML_Parser parser,
3905 1.1 tron const char *s,
3906 1.1 tron const char *end,
3907 1.1 tron const char **nextPtr)
3908 1.1 tron {
3909 1.1 tron enum XML_Error result = initializeEncoding(parser);
3910 1.1 tron if (result != XML_ERROR_NONE)
3911 1.1 tron return result;
3912 1.1 tron
3913 1.1 tron /* we know now that XML_Parse(Buffer) has been called,
3914 1.1 tron so we consider the external parameter entity read */
3915 1.1 tron _dtd->paramEntityRead = XML_TRUE;
3916 1.1 tron
3917 1.1 tron if (prologState.inEntityValue) {
3918 1.1 tron processor = entityValueInitProcessor;
3919 1.1 tron return entityValueInitProcessor(parser, s, end, nextPtr);
3920 1.1 tron }
3921 1.1 tron else {
3922 1.1 tron processor = externalParEntProcessor;
3923 1.1 tron return externalParEntProcessor(parser, s, end, nextPtr);
3924 1.1 tron }
3925 1.1 tron }
3926 1.1 tron
3927 1.1 tron static enum XML_Error PTRCALL
3928 1.1 tron entityValueInitProcessor(XML_Parser parser,
3929 1.1 tron const char *s,
3930 1.1 tron const char *end,
3931 1.1 tron const char **nextPtr)
3932 1.1 tron {
3933 1.1 tron int tok;
3934 1.1 tron const char *start = s;
3935 1.1 tron const char *next = start;
3936 1.1 tron eventPtr = start;
3937 1.1 tron
3938 1.3 spz for (;;) {
3939 1.1 tron tok = XmlPrologTok(encoding, start, end, &next);
3940 1.1 tron eventEndPtr = next;
3941 1.1 tron if (tok <= 0) {
3942 1.1 tron if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3943 1.1 tron *nextPtr = s;
3944 1.1 tron return XML_ERROR_NONE;
3945 1.1 tron }
3946 1.1 tron switch (tok) {
3947 1.1 tron case XML_TOK_INVALID:
3948 1.1 tron return XML_ERROR_INVALID_TOKEN;
3949 1.1 tron case XML_TOK_PARTIAL:
3950 1.1 tron return XML_ERROR_UNCLOSED_TOKEN;
3951 1.1 tron case XML_TOK_PARTIAL_CHAR:
3952 1.1 tron return XML_ERROR_PARTIAL_CHAR;
3953 1.1 tron case XML_TOK_NONE: /* start == end */
3954 1.1 tron default:
3955 1.1 tron break;
3956 1.1 tron }
3957 1.1 tron /* found end of entity value - can store it now */
3958 1.1 tron return storeEntityValue(parser, encoding, s, end);
3959 1.1 tron }
3960 1.1 tron else if (tok == XML_TOK_XML_DECL) {
3961 1.1 tron enum XML_Error result;
3962 1.1 tron result = processXmlDecl(parser, 0, start, next);
3963 1.1 tron if (result != XML_ERROR_NONE)
3964 1.1 tron return result;
3965 1.1 tron switch (ps_parsing) {
3966 1.3 spz case XML_SUSPENDED:
3967 1.1 tron *nextPtr = next;
3968 1.1 tron return XML_ERROR_NONE;
3969 1.1 tron case XML_FINISHED:
3970 1.1 tron return XML_ERROR_ABORTED;
3971 1.1 tron default:
3972 1.1 tron *nextPtr = next;
3973 1.1 tron }
3974 1.1 tron /* stop scanning for text declaration - we found one */
3975 1.1 tron processor = entityValueProcessor;
3976 1.1 tron return entityValueProcessor(parser, next, end, nextPtr);
3977 1.1 tron }
3978 1.1 tron /* If we are at the end of the buffer, this would cause XmlPrologTok to
3979 1.1 tron return XML_TOK_NONE on the next call, which would then cause the
3980 1.1 tron function to exit with *nextPtr set to s - that is what we want for other
3981 1.1 tron tokens, but not for the BOM - we would rather like to skip it;
3982 1.1 tron then, when this routine is entered the next time, XmlPrologTok will
3983 1.1 tron return XML_TOK_INVALID, since the BOM is still in the buffer
3984 1.1 tron */
3985 1.1 tron else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
3986 1.1 tron *nextPtr = next;
3987 1.1 tron return XML_ERROR_NONE;
3988 1.1 tron }
3989 1.7 christos /* If we get this token, we have the start of what might be a
3990 1.7 christos normal tag, but not a declaration (i.e. it doesn't begin with
3991 1.7 christos "<!"). In a DTD context, that isn't legal.
3992 1.7 christos */
3993 1.7 christos else if (tok == XML_TOK_INSTANCE_START) {
3994 1.7 christos *nextPtr = next;
3995 1.7 christos return XML_ERROR_SYNTAX;
3996 1.7 christos }
3997 1.1 tron start = next;
3998 1.1 tron eventPtr = start;
3999 1.1 tron }
4000 1.1 tron }
4001 1.1 tron
4002 1.1 tron static enum XML_Error PTRCALL
4003 1.1 tron externalParEntProcessor(XML_Parser parser,
4004 1.1 tron const char *s,
4005 1.1 tron const char *end,
4006 1.1 tron const char **nextPtr)
4007 1.1 tron {
4008 1.1 tron const char *next = s;
4009 1.1 tron int tok;
4010 1.1 tron
4011 1.1 tron tok = XmlPrologTok(encoding, s, end, &next);
4012 1.1 tron if (tok <= 0) {
4013 1.1 tron if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
4014 1.1 tron *nextPtr = s;
4015 1.1 tron return XML_ERROR_NONE;
4016 1.1 tron }
4017 1.1 tron switch (tok) {
4018 1.1 tron case XML_TOK_INVALID:
4019 1.1 tron return XML_ERROR_INVALID_TOKEN;
4020 1.1 tron case XML_TOK_PARTIAL:
4021 1.1 tron return XML_ERROR_UNCLOSED_TOKEN;
4022 1.1 tron case XML_TOK_PARTIAL_CHAR:
4023 1.1 tron return XML_ERROR_PARTIAL_CHAR;
4024 1.1 tron case XML_TOK_NONE: /* start == end */
4025 1.1 tron default:
4026 1.1 tron break;
4027 1.1 tron }
4028 1.1 tron }
4029 1.1 tron /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
4030 1.1 tron However, when parsing an external subset, doProlog will not accept a BOM
4031 1.1 tron as valid, and report a syntax error, so we have to skip the BOM
4032 1.1 tron */
4033 1.1 tron else if (tok == XML_TOK_BOM) {
4034 1.1 tron s = next;
4035 1.1 tron tok = XmlPrologTok(encoding, s, end, &next);
4036 1.1 tron }
4037 1.1 tron
4038 1.1 tron processor = prologProcessor;
4039 1.3 spz return doProlog(parser, encoding, s, end, tok, next,
4040 1.1 tron nextPtr, (XML_Bool)!ps_finalBuffer);
4041 1.1 tron }
4042 1.1 tron
4043 1.1 tron static enum XML_Error PTRCALL
4044 1.1 tron entityValueProcessor(XML_Parser parser,
4045 1.1 tron const char *s,
4046 1.1 tron const char *end,
4047 1.1 tron const char **nextPtr)
4048 1.1 tron {
4049 1.1 tron const char *start = s;
4050 1.1 tron const char *next = s;
4051 1.1 tron const ENCODING *enc = encoding;
4052 1.1 tron int tok;
4053 1.1 tron
4054 1.1 tron for (;;) {
4055 1.1 tron tok = XmlPrologTok(enc, start, end, &next);
4056 1.1 tron if (tok <= 0) {
4057 1.1 tron if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
4058 1.1 tron *nextPtr = s;
4059 1.1 tron return XML_ERROR_NONE;
4060 1.1 tron }
4061 1.1 tron switch (tok) {
4062 1.1 tron case XML_TOK_INVALID:
4063 1.1 tron return XML_ERROR_INVALID_TOKEN;
4064 1.1 tron case XML_TOK_PARTIAL:
4065 1.1 tron return XML_ERROR_UNCLOSED_TOKEN;
4066 1.1 tron case XML_TOK_PARTIAL_CHAR:
4067 1.1 tron return XML_ERROR_PARTIAL_CHAR;
4068 1.1 tron case XML_TOK_NONE: /* start == end */
4069 1.1 tron default:
4070 1.1 tron break;
4071 1.1 tron }
4072 1.1 tron /* found end of entity value - can store it now */
4073 1.1 tron return storeEntityValue(parser, enc, s, end);
4074 1.1 tron }
4075 1.1 tron start = next;
4076 1.1 tron }
4077 1.1 tron }
4078 1.1 tron
4079 1.1 tron #endif /* XML_DTD */
4080 1.1 tron
4081 1.1 tron static enum XML_Error PTRCALL
4082 1.1 tron prologProcessor(XML_Parser parser,
4083 1.1 tron const char *s,
4084 1.1 tron const char *end,
4085 1.1 tron const char **nextPtr)
4086 1.1 tron {
4087 1.1 tron const char *next = s;
4088 1.1 tron int tok = XmlPrologTok(encoding, s, end, &next);
4089 1.3 spz return doProlog(parser, encoding, s, end, tok, next,
4090 1.1 tron nextPtr, (XML_Bool)!ps_finalBuffer);
4091 1.1 tron }
4092 1.1 tron
4093 1.1 tron static enum XML_Error
4094 1.1 tron doProlog(XML_Parser parser,
4095 1.1 tron const ENCODING *enc,
4096 1.1 tron const char *s,
4097 1.1 tron const char *end,
4098 1.1 tron int tok,
4099 1.1 tron const char *next,
4100 1.1 tron const char **nextPtr,
4101 1.1 tron XML_Bool haveMore)
4102 1.1 tron {
4103 1.1 tron #ifdef XML_DTD
4104 1.1 tron static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
4105 1.1 tron #endif /* XML_DTD */
4106 1.3 spz static const XML_Char atypeCDATA[] =
4107 1.1 tron { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
4108 1.1 tron static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
4109 1.1 tron static const XML_Char atypeIDREF[] =
4110 1.1 tron { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
4111 1.1 tron static const XML_Char atypeIDREFS[] =
4112 1.1 tron { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
4113 1.1 tron static const XML_Char atypeENTITY[] =
4114 1.1 tron { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
4115 1.1 tron static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
4116 1.1 tron ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
4117 1.1 tron static const XML_Char atypeNMTOKEN[] = {
4118 1.1 tron ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
4119 1.1 tron static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
4120 1.1 tron ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
4121 1.1 tron static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
4122 1.1 tron ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
4123 1.1 tron static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
4124 1.1 tron static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
4125 1.1 tron
4126 1.1 tron /* save one level of indirection */
4127 1.3 spz DTD * const dtd = _dtd;
4128 1.1 tron
4129 1.1 tron const char **eventPP;
4130 1.1 tron const char **eventEndPP;
4131 1.1 tron enum XML_Content_Quant quant;
4132 1.1 tron
4133 1.1 tron if (enc == encoding) {
4134 1.1 tron eventPP = &eventPtr;
4135 1.1 tron eventEndPP = &eventEndPtr;
4136 1.1 tron }
4137 1.1 tron else {
4138 1.1 tron eventPP = &(openInternalEntities->internalEventPtr);
4139 1.1 tron eventEndPP = &(openInternalEntities->internalEventEndPtr);
4140 1.1 tron }
4141 1.1 tron
4142 1.1 tron for (;;) {
4143 1.1 tron int role;
4144 1.1 tron XML_Bool handleDefault = XML_TRUE;
4145 1.1 tron *eventPP = s;
4146 1.1 tron *eventEndPP = next;
4147 1.1 tron if (tok <= 0) {
4148 1.1 tron if (haveMore && tok != XML_TOK_INVALID) {
4149 1.1 tron *nextPtr = s;
4150 1.1 tron return XML_ERROR_NONE;
4151 1.1 tron }
4152 1.1 tron switch (tok) {
4153 1.1 tron case XML_TOK_INVALID:
4154 1.1 tron *eventPP = next;
4155 1.1 tron return XML_ERROR_INVALID_TOKEN;
4156 1.1 tron case XML_TOK_PARTIAL:
4157 1.1 tron return XML_ERROR_UNCLOSED_TOKEN;
4158 1.1 tron case XML_TOK_PARTIAL_CHAR:
4159 1.1 tron return XML_ERROR_PARTIAL_CHAR;
4160 1.2 tron case -XML_TOK_PROLOG_S:
4161 1.3 spz tok = -tok;
4162 1.3 spz break;
4163 1.1 tron case XML_TOK_NONE:
4164 1.1 tron #ifdef XML_DTD
4165 1.1 tron /* for internal PE NOT referenced between declarations */
4166 1.1 tron if (enc != encoding && !openInternalEntities->betweenDecl) {
4167 1.1 tron *nextPtr = s;
4168 1.1 tron return XML_ERROR_NONE;
4169 1.1 tron }
4170 1.1 tron /* WFC: PE Between Declarations - must check that PE contains
4171 1.1 tron complete markup, not only for external PEs, but also for
4172 1.1 tron internal PEs if the reference occurs between declarations.
4173 1.1 tron */
4174 1.1 tron if (isParamEntity || enc != encoding) {
4175 1.1 tron if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
4176 1.1 tron == XML_ROLE_ERROR)
4177 1.1 tron return XML_ERROR_INCOMPLETE_PE;
4178 1.1 tron *nextPtr = s;
4179 1.1 tron return XML_ERROR_NONE;
4180 1.1 tron }
4181 1.1 tron #endif /* XML_DTD */
4182 1.1 tron return XML_ERROR_NO_ELEMENTS;
4183 1.1 tron default:
4184 1.1 tron tok = -tok;
4185 1.1 tron next = end;
4186 1.1 tron break;
4187 1.1 tron }
4188 1.1 tron }
4189 1.1 tron role = XmlTokenRole(&prologState, tok, s, next, enc);
4190 1.1 tron switch (role) {
4191 1.1 tron case XML_ROLE_XML_DECL:
4192 1.1 tron {
4193 1.1 tron enum XML_Error result = processXmlDecl(parser, 0, s, next);
4194 1.1 tron if (result != XML_ERROR_NONE)
4195 1.1 tron return result;
4196 1.1 tron enc = encoding;
4197 1.1 tron handleDefault = XML_FALSE;
4198 1.1 tron }
4199 1.1 tron break;
4200 1.1 tron case XML_ROLE_DOCTYPE_NAME:
4201 1.1 tron if (startDoctypeDeclHandler) {
4202 1.1 tron doctypeName = poolStoreString(&tempPool, enc, s, next);
4203 1.1 tron if (!doctypeName)
4204 1.1 tron return XML_ERROR_NO_MEMORY;
4205 1.1 tron poolFinish(&tempPool);
4206 1.1 tron doctypePubid = NULL;
4207 1.1 tron handleDefault = XML_FALSE;
4208 1.1 tron }
4209 1.1 tron doctypeSysid = NULL; /* always initialize to NULL */
4210 1.1 tron break;
4211 1.1 tron case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
4212 1.1 tron if (startDoctypeDeclHandler) {
4213 1.1 tron startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
4214 1.1 tron doctypePubid, 1);
4215 1.1 tron doctypeName = NULL;
4216 1.1 tron poolClear(&tempPool);
4217 1.1 tron handleDefault = XML_FALSE;
4218 1.1 tron }
4219 1.1 tron break;
4220 1.1 tron #ifdef XML_DTD
4221 1.1 tron case XML_ROLE_TEXT_DECL:
4222 1.1 tron {
4223 1.1 tron enum XML_Error result = processXmlDecl(parser, 1, s, next);
4224 1.1 tron if (result != XML_ERROR_NONE)
4225 1.1 tron return result;
4226 1.1 tron enc = encoding;
4227 1.1 tron handleDefault = XML_FALSE;
4228 1.1 tron }
4229 1.1 tron break;
4230 1.1 tron #endif /* XML_DTD */
4231 1.1 tron case XML_ROLE_DOCTYPE_PUBLIC_ID:
4232 1.1 tron #ifdef XML_DTD
4233 1.1 tron useForeignDTD = XML_FALSE;
4234 1.3 spz declEntity = (ENTITY *)lookup(parser,
4235 1.3 spz &dtd->paramEntities,
4236 1.1 tron externalSubsetName,
4237 1.1 tron sizeof(ENTITY));
4238 1.1 tron if (!declEntity)
4239 1.1 tron return XML_ERROR_NO_MEMORY;
4240 1.1 tron #endif /* XML_DTD */
4241 1.1 tron dtd->hasParamEntityRefs = XML_TRUE;
4242 1.1 tron if (startDoctypeDeclHandler) {
4243 1.3 spz XML_Char *pubId;
4244 1.1 tron if (!XmlIsPublicId(enc, s, next, eventPP))
4245 1.1 tron return XML_ERROR_PUBLICID;
4246 1.3 spz pubId = poolStoreString(&tempPool, enc,
4247 1.3 spz s + enc->minBytesPerChar,
4248 1.3 spz next - enc->minBytesPerChar);
4249 1.3 spz if (!pubId)
4250 1.1 tron return XML_ERROR_NO_MEMORY;
4251 1.3 spz normalizePublicId(pubId);
4252 1.1 tron poolFinish(&tempPool);
4253 1.3 spz doctypePubid = pubId;
4254 1.1 tron handleDefault = XML_FALSE;
4255 1.1 tron goto alreadyChecked;
4256 1.1 tron }
4257 1.1 tron /* fall through */
4258 1.1 tron case XML_ROLE_ENTITY_PUBLIC_ID:
4259 1.1 tron if (!XmlIsPublicId(enc, s, next, eventPP))
4260 1.1 tron return XML_ERROR_PUBLICID;
4261 1.1 tron alreadyChecked:
4262 1.1 tron if (dtd->keepProcessing && declEntity) {
4263 1.1 tron XML_Char *tem = poolStoreString(&dtd->pool,
4264 1.1 tron enc,
4265 1.1 tron s + enc->minBytesPerChar,
4266 1.1 tron next - enc->minBytesPerChar);
4267 1.1 tron if (!tem)
4268 1.1 tron return XML_ERROR_NO_MEMORY;
4269 1.1 tron normalizePublicId(tem);
4270 1.1 tron declEntity->publicId = tem;
4271 1.1 tron poolFinish(&dtd->pool);
4272 1.1 tron if (entityDeclHandler)
4273 1.1 tron handleDefault = XML_FALSE;
4274 1.1 tron }
4275 1.1 tron break;
4276 1.1 tron case XML_ROLE_DOCTYPE_CLOSE:
4277 1.1 tron if (doctypeName) {
4278 1.1 tron startDoctypeDeclHandler(handlerArg, doctypeName,
4279 1.1 tron doctypeSysid, doctypePubid, 0);
4280 1.1 tron poolClear(&tempPool);
4281 1.1 tron handleDefault = XML_FALSE;
4282 1.1 tron }
4283 1.1 tron /* doctypeSysid will be non-NULL in the case of a previous
4284 1.1 tron XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
4285 1.1 tron was not set, indicating an external subset
4286 1.1 tron */
4287 1.1 tron #ifdef XML_DTD
4288 1.1 tron if (doctypeSysid || useForeignDTD) {
4289 1.1 tron XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4290 1.1 tron dtd->hasParamEntityRefs = XML_TRUE;
4291 1.1 tron if (paramEntityParsing && externalEntityRefHandler) {
4292 1.3 spz ENTITY *entity = (ENTITY *)lookup(parser,
4293 1.3 spz &dtd->paramEntities,
4294 1.1 tron externalSubsetName,
4295 1.1 tron sizeof(ENTITY));
4296 1.1 tron if (!entity)
4297 1.1 tron return XML_ERROR_NO_MEMORY;
4298 1.1 tron if (useForeignDTD)
4299 1.1 tron entity->base = curBase;
4300 1.1 tron dtd->paramEntityRead = XML_FALSE;
4301 1.1 tron if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4302 1.1 tron 0,
4303 1.1 tron entity->base,
4304 1.1 tron entity->systemId,
4305 1.1 tron entity->publicId))
4306 1.1 tron return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4307 1.1 tron if (dtd->paramEntityRead) {
4308 1.3 spz if (!dtd->standalone &&
4309 1.3 spz notStandaloneHandler &&
4310 1.1 tron !notStandaloneHandler(handlerArg))
4311 1.1 tron return XML_ERROR_NOT_STANDALONE;
4312 1.1 tron }
4313 1.1 tron /* if we didn't read the foreign DTD then this means that there
4314 1.1 tron is no external subset and we must reset dtd->hasParamEntityRefs
4315 1.1 tron */
4316 1.1 tron else if (!doctypeSysid)
4317 1.1 tron dtd->hasParamEntityRefs = hadParamEntityRefs;
4318 1.1 tron /* end of DTD - no need to update dtd->keepProcessing */
4319 1.1 tron }
4320 1.1 tron useForeignDTD = XML_FALSE;
4321 1.1 tron }
4322 1.1 tron #endif /* XML_DTD */
4323 1.1 tron if (endDoctypeDeclHandler) {
4324 1.1 tron endDoctypeDeclHandler(handlerArg);
4325 1.1 tron handleDefault = XML_FALSE;
4326 1.1 tron }
4327 1.1 tron break;
4328 1.1 tron case XML_ROLE_INSTANCE_START:
4329 1.1 tron #ifdef XML_DTD
4330 1.1 tron /* if there is no DOCTYPE declaration then now is the
4331 1.1 tron last chance to read the foreign DTD
4332 1.1 tron */
4333 1.1 tron if (useForeignDTD) {
4334 1.1 tron XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4335 1.1 tron dtd->hasParamEntityRefs = XML_TRUE;
4336 1.1 tron if (paramEntityParsing && externalEntityRefHandler) {
4337 1.3 spz ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4338 1.1 tron externalSubsetName,
4339 1.1 tron sizeof(ENTITY));
4340 1.1 tron if (!entity)
4341 1.1 tron return XML_ERROR_NO_MEMORY;
4342 1.1 tron entity->base = curBase;
4343 1.1 tron dtd->paramEntityRead = XML_FALSE;
4344 1.1 tron if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4345 1.1 tron 0,
4346 1.1 tron entity->base,
4347 1.1 tron entity->systemId,
4348 1.1 tron entity->publicId))
4349 1.1 tron return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4350 1.1 tron if (dtd->paramEntityRead) {
4351 1.1 tron if (!dtd->standalone &&
4352 1.1 tron notStandaloneHandler &&
4353 1.1 tron !notStandaloneHandler(handlerArg))
4354 1.1 tron return XML_ERROR_NOT_STANDALONE;
4355 1.1 tron }
4356 1.1 tron /* if we didn't read the foreign DTD then this means that there
4357 1.1 tron is no external subset and we must reset dtd->hasParamEntityRefs
4358 1.1 tron */
4359 1.1 tron else
4360 1.1 tron dtd->hasParamEntityRefs = hadParamEntityRefs;
4361 1.1 tron /* end of DTD - no need to update dtd->keepProcessing */
4362 1.1 tron }
4363 1.1 tron }
4364 1.1 tron #endif /* XML_DTD */
4365 1.1 tron processor = contentProcessor;
4366 1.1 tron return contentProcessor(parser, s, end, nextPtr);
4367 1.1 tron case XML_ROLE_ATTLIST_ELEMENT_NAME:
4368 1.1 tron declElementType = getElementType(parser, enc, s, next);
4369 1.1 tron if (!declElementType)
4370 1.1 tron return XML_ERROR_NO_MEMORY;
4371 1.1 tron goto checkAttListDeclHandler;
4372 1.1 tron case XML_ROLE_ATTRIBUTE_NAME:
4373 1.1 tron declAttributeId = getAttributeId(parser, enc, s, next);
4374 1.1 tron if (!declAttributeId)
4375 1.1 tron return XML_ERROR_NO_MEMORY;
4376 1.1 tron declAttributeIsCdata = XML_FALSE;
4377 1.1 tron declAttributeType = NULL;
4378 1.1 tron declAttributeIsId = XML_FALSE;
4379 1.1 tron goto checkAttListDeclHandler;
4380 1.1 tron case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4381 1.1 tron declAttributeIsCdata = XML_TRUE;
4382 1.1 tron declAttributeType = atypeCDATA;
4383 1.1 tron goto checkAttListDeclHandler;
4384 1.1 tron case XML_ROLE_ATTRIBUTE_TYPE_ID:
4385 1.1 tron declAttributeIsId = XML_TRUE;
4386 1.1 tron declAttributeType = atypeID;
4387 1.1 tron goto checkAttListDeclHandler;
4388 1.1 tron case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4389 1.1 tron declAttributeType = atypeIDREF;
4390 1.1 tron goto checkAttListDeclHandler;
4391 1.1 tron case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4392 1.1 tron declAttributeType = atypeIDREFS;
4393 1.1 tron goto checkAttListDeclHandler;
4394 1.1 tron case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4395 1.1 tron declAttributeType = atypeENTITY;
4396 1.1 tron goto checkAttListDeclHandler;
4397 1.1 tron case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4398 1.1 tron declAttributeType = atypeENTITIES;
4399 1.1 tron goto checkAttListDeclHandler;
4400 1.1 tron case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4401 1.1 tron declAttributeType = atypeNMTOKEN;
4402 1.1 tron goto checkAttListDeclHandler;
4403 1.1 tron case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4404 1.1 tron declAttributeType = atypeNMTOKENS;
4405 1.1 tron checkAttListDeclHandler:
4406 1.1 tron if (dtd->keepProcessing && attlistDeclHandler)
4407 1.1 tron handleDefault = XML_FALSE;
4408 1.1 tron break;
4409 1.1 tron case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4410 1.1 tron case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4411 1.1 tron if (dtd->keepProcessing && attlistDeclHandler) {
4412 1.1 tron const XML_Char *prefix;
4413 1.1 tron if (declAttributeType) {
4414 1.1 tron prefix = enumValueSep;
4415 1.1 tron }
4416 1.1 tron else {
4417 1.1 tron prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4418 1.1 tron ? notationPrefix
4419 1.1 tron : enumValueStart);
4420 1.1 tron }
4421 1.1 tron if (!poolAppendString(&tempPool, prefix))
4422 1.1 tron return XML_ERROR_NO_MEMORY;
4423 1.1 tron if (!poolAppend(&tempPool, enc, s, next))
4424 1.1 tron return XML_ERROR_NO_MEMORY;
4425 1.1 tron declAttributeType = tempPool.start;
4426 1.1 tron handleDefault = XML_FALSE;
4427 1.1 tron }
4428 1.1 tron break;
4429 1.1 tron case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4430 1.1 tron case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4431 1.1 tron if (dtd->keepProcessing) {
4432 1.1 tron if (!defineAttribute(declElementType, declAttributeId,
4433 1.1 tron declAttributeIsCdata, declAttributeIsId,
4434 1.1 tron 0, parser))
4435 1.1 tron return XML_ERROR_NO_MEMORY;
4436 1.1 tron if (attlistDeclHandler && declAttributeType) {
4437 1.1 tron if (*declAttributeType == XML_T(ASCII_LPAREN)
4438 1.1 tron || (*declAttributeType == XML_T(ASCII_N)
4439 1.1 tron && declAttributeType[1] == XML_T(ASCII_O))) {
4440 1.1 tron /* Enumerated or Notation type */
4441 1.1 tron if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4442 1.1 tron || !poolAppendChar(&tempPool, XML_T('\0')))
4443 1.1 tron return XML_ERROR_NO_MEMORY;
4444 1.1 tron declAttributeType = tempPool.start;
4445 1.1 tron poolFinish(&tempPool);
4446 1.1 tron }
4447 1.1 tron *eventEndPP = s;
4448 1.1 tron attlistDeclHandler(handlerArg, declElementType->name,
4449 1.1 tron declAttributeId->name, declAttributeType,
4450 1.1 tron 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4451 1.1 tron poolClear(&tempPool);
4452 1.1 tron handleDefault = XML_FALSE;
4453 1.1 tron }
4454 1.1 tron }
4455 1.1 tron break;
4456 1.1 tron case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4457 1.1 tron case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4458 1.1 tron if (dtd->keepProcessing) {
4459 1.1 tron const XML_Char *attVal;
4460 1.1 tron enum XML_Error result =
4461 1.1 tron storeAttributeValue(parser, enc, declAttributeIsCdata,
4462 1.1 tron s + enc->minBytesPerChar,
4463 1.1 tron next - enc->minBytesPerChar,
4464 1.1 tron &dtd->pool);
4465 1.1 tron if (result)
4466 1.1 tron return result;
4467 1.1 tron attVal = poolStart(&dtd->pool);
4468 1.1 tron poolFinish(&dtd->pool);
4469 1.1 tron /* ID attributes aren't allowed to have a default */
4470 1.1 tron if (!defineAttribute(declElementType, declAttributeId,
4471 1.1 tron declAttributeIsCdata, XML_FALSE, attVal, parser))
4472 1.1 tron return XML_ERROR_NO_MEMORY;
4473 1.1 tron if (attlistDeclHandler && declAttributeType) {
4474 1.1 tron if (*declAttributeType == XML_T(ASCII_LPAREN)
4475 1.1 tron || (*declAttributeType == XML_T(ASCII_N)
4476 1.1 tron && declAttributeType[1] == XML_T(ASCII_O))) {
4477 1.1 tron /* Enumerated or Notation type */
4478 1.1 tron if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4479 1.1 tron || !poolAppendChar(&tempPool, XML_T('\0')))
4480 1.1 tron return XML_ERROR_NO_MEMORY;
4481 1.1 tron declAttributeType = tempPool.start;
4482 1.1 tron poolFinish(&tempPool);
4483 1.1 tron }
4484 1.1 tron *eventEndPP = s;
4485 1.1 tron attlistDeclHandler(handlerArg, declElementType->name,
4486 1.1 tron declAttributeId->name, declAttributeType,
4487 1.1 tron attVal,
4488 1.1 tron role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4489 1.1 tron poolClear(&tempPool);
4490 1.1 tron handleDefault = XML_FALSE;
4491 1.1 tron }
4492 1.1 tron }
4493 1.1 tron break;
4494 1.1 tron case XML_ROLE_ENTITY_VALUE:
4495 1.1 tron if (dtd->keepProcessing) {
4496 1.1 tron enum XML_Error result = storeEntityValue(parser, enc,
4497 1.1 tron s + enc->minBytesPerChar,
4498 1.1 tron next - enc->minBytesPerChar);
4499 1.1 tron if (declEntity) {
4500 1.1 tron declEntity->textPtr = poolStart(&dtd->entityValuePool);
4501 1.1 tron declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4502 1.1 tron poolFinish(&dtd->entityValuePool);
4503 1.1 tron if (entityDeclHandler) {
4504 1.1 tron *eventEndPP = s;
4505 1.1 tron entityDeclHandler(handlerArg,
4506 1.1 tron declEntity->name,
4507 1.1 tron declEntity->is_param,
4508 1.1 tron declEntity->textPtr,
4509 1.1 tron declEntity->textLen,
4510 1.1 tron curBase, 0, 0, 0);
4511 1.1 tron handleDefault = XML_FALSE;
4512 1.1 tron }
4513 1.1 tron }
4514 1.1 tron else
4515 1.1 tron poolDiscard(&dtd->entityValuePool);
4516 1.1 tron if (result != XML_ERROR_NONE)
4517 1.1 tron return result;
4518 1.1 tron }
4519 1.1 tron break;
4520 1.1 tron case XML_ROLE_DOCTYPE_SYSTEM_ID:
4521 1.1 tron #ifdef XML_DTD
4522 1.1 tron useForeignDTD = XML_FALSE;
4523 1.1 tron #endif /* XML_DTD */
4524 1.1 tron dtd->hasParamEntityRefs = XML_TRUE;
4525 1.1 tron if (startDoctypeDeclHandler) {
4526 1.1 tron doctypeSysid = poolStoreString(&tempPool, enc,
4527 1.1 tron s + enc->minBytesPerChar,
4528 1.1 tron next - enc->minBytesPerChar);
4529 1.1 tron if (doctypeSysid == NULL)
4530 1.1 tron return XML_ERROR_NO_MEMORY;
4531 1.1 tron poolFinish(&tempPool);
4532 1.1 tron handleDefault = XML_FALSE;
4533 1.1 tron }
4534 1.1 tron #ifdef XML_DTD
4535 1.1 tron else
4536 1.1 tron /* use externalSubsetName to make doctypeSysid non-NULL
4537 1.1 tron for the case where no startDoctypeDeclHandler is set */
4538 1.1 tron doctypeSysid = externalSubsetName;
4539 1.1 tron #endif /* XML_DTD */
4540 1.1 tron if (!dtd->standalone
4541 1.1 tron #ifdef XML_DTD
4542 1.1 tron && !paramEntityParsing
4543 1.1 tron #endif /* XML_DTD */
4544 1.1 tron && notStandaloneHandler
4545 1.1 tron && !notStandaloneHandler(handlerArg))
4546 1.1 tron return XML_ERROR_NOT_STANDALONE;
4547 1.1 tron #ifndef XML_DTD
4548 1.1 tron break;
4549 1.1 tron #else /* XML_DTD */
4550 1.1 tron if (!declEntity) {
4551 1.3 spz declEntity = (ENTITY *)lookup(parser,
4552 1.3 spz &dtd->paramEntities,
4553 1.1 tron externalSubsetName,
4554 1.1 tron sizeof(ENTITY));
4555 1.1 tron if (!declEntity)
4556 1.1 tron return XML_ERROR_NO_MEMORY;
4557 1.1 tron declEntity->publicId = NULL;
4558 1.1 tron }
4559 1.1 tron /* fall through */
4560 1.1 tron #endif /* XML_DTD */
4561 1.1 tron case XML_ROLE_ENTITY_SYSTEM_ID:
4562 1.1 tron if (dtd->keepProcessing && declEntity) {
4563 1.1 tron declEntity->systemId = poolStoreString(&dtd->pool, enc,
4564 1.1 tron s + enc->minBytesPerChar,
4565 1.1 tron next - enc->minBytesPerChar);
4566 1.1 tron if (!declEntity->systemId)
4567 1.1 tron return XML_ERROR_NO_MEMORY;
4568 1.1 tron declEntity->base = curBase;
4569 1.1 tron poolFinish(&dtd->pool);
4570 1.1 tron if (entityDeclHandler)
4571 1.1 tron handleDefault = XML_FALSE;
4572 1.1 tron }
4573 1.1 tron break;
4574 1.1 tron case XML_ROLE_ENTITY_COMPLETE:
4575 1.1 tron if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4576 1.1 tron *eventEndPP = s;
4577 1.1 tron entityDeclHandler(handlerArg,
4578 1.1 tron declEntity->name,
4579 1.1 tron declEntity->is_param,
4580 1.1 tron 0,0,
4581 1.1 tron declEntity->base,
4582 1.1 tron declEntity->systemId,
4583 1.1 tron declEntity->publicId,
4584 1.1 tron 0);
4585 1.1 tron handleDefault = XML_FALSE;
4586 1.1 tron }
4587 1.1 tron break;
4588 1.1 tron case XML_ROLE_ENTITY_NOTATION_NAME:
4589 1.1 tron if (dtd->keepProcessing && declEntity) {
4590 1.1 tron declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4591 1.1 tron if (!declEntity->notation)
4592 1.1 tron return XML_ERROR_NO_MEMORY;
4593 1.1 tron poolFinish(&dtd->pool);
4594 1.1 tron if (unparsedEntityDeclHandler) {
4595 1.1 tron *eventEndPP = s;
4596 1.1 tron unparsedEntityDeclHandler(handlerArg,
4597 1.1 tron declEntity->name,
4598 1.1 tron declEntity->base,
4599 1.1 tron declEntity->systemId,
4600 1.1 tron declEntity->publicId,
4601 1.1 tron declEntity->notation);
4602 1.1 tron handleDefault = XML_FALSE;
4603 1.1 tron }
4604 1.1 tron else if (entityDeclHandler) {
4605 1.1 tron *eventEndPP = s;
4606 1.1 tron entityDeclHandler(handlerArg,
4607 1.1 tron declEntity->name,
4608 1.1 tron 0,0,0,
4609 1.1 tron declEntity->base,
4610 1.1 tron declEntity->systemId,
4611 1.1 tron declEntity->publicId,
4612 1.1 tron declEntity->notation);
4613 1.1 tron handleDefault = XML_FALSE;
4614 1.1 tron }
4615 1.1 tron }
4616 1.1 tron break;
4617 1.1 tron case XML_ROLE_GENERAL_ENTITY_NAME:
4618 1.1 tron {
4619 1.1 tron if (XmlPredefinedEntityName(enc, s, next)) {
4620 1.1 tron declEntity = NULL;
4621 1.1 tron break;
4622 1.1 tron }
4623 1.1 tron if (dtd->keepProcessing) {
4624 1.1 tron const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4625 1.1 tron if (!name)
4626 1.1 tron return XML_ERROR_NO_MEMORY;
4627 1.3 spz declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
4628 1.1 tron sizeof(ENTITY));
4629 1.1 tron if (!declEntity)
4630 1.1 tron return XML_ERROR_NO_MEMORY;
4631 1.1 tron if (declEntity->name != name) {
4632 1.1 tron poolDiscard(&dtd->pool);
4633 1.1 tron declEntity = NULL;
4634 1.1 tron }
4635 1.1 tron else {
4636 1.1 tron poolFinish(&dtd->pool);
4637 1.1 tron declEntity->publicId = NULL;
4638 1.1 tron declEntity->is_param = XML_FALSE;
4639 1.1 tron /* if we have a parent parser or are reading an internal parameter
4640 1.1 tron entity, then the entity declaration is not considered "internal"
4641 1.1 tron */
4642 1.1 tron declEntity->is_internal = !(parentParser || openInternalEntities);
4643 1.1 tron if (entityDeclHandler)
4644 1.1 tron handleDefault = XML_FALSE;
4645 1.1 tron }
4646 1.1 tron }
4647 1.1 tron else {
4648 1.1 tron poolDiscard(&dtd->pool);
4649 1.1 tron declEntity = NULL;
4650 1.1 tron }
4651 1.1 tron }
4652 1.1 tron break;
4653 1.1 tron case XML_ROLE_PARAM_ENTITY_NAME:
4654 1.1 tron #ifdef XML_DTD
4655 1.1 tron if (dtd->keepProcessing) {
4656 1.1 tron const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4657 1.1 tron if (!name)
4658 1.1 tron return XML_ERROR_NO_MEMORY;
4659 1.3 spz declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4660 1.1 tron name, sizeof(ENTITY));
4661 1.1 tron if (!declEntity)
4662 1.1 tron return XML_ERROR_NO_MEMORY;
4663 1.1 tron if (declEntity->name != name) {
4664 1.1 tron poolDiscard(&dtd->pool);
4665 1.1 tron declEntity = NULL;
4666 1.1 tron }
4667 1.1 tron else {
4668 1.1 tron poolFinish(&dtd->pool);
4669 1.1 tron declEntity->publicId = NULL;
4670 1.1 tron declEntity->is_param = XML_TRUE;
4671 1.1 tron /* if we have a parent parser or are reading an internal parameter
4672 1.1 tron entity, then the entity declaration is not considered "internal"
4673 1.1 tron */
4674 1.1 tron declEntity->is_internal = !(parentParser || openInternalEntities);
4675 1.1 tron if (entityDeclHandler)
4676 1.1 tron handleDefault = XML_FALSE;
4677 1.1 tron }
4678 1.1 tron }
4679 1.1 tron else {
4680 1.1 tron poolDiscard(&dtd->pool);
4681 1.1 tron declEntity = NULL;
4682 1.1 tron }
4683 1.1 tron #else /* not XML_DTD */
4684 1.1 tron declEntity = NULL;
4685 1.1 tron #endif /* XML_DTD */
4686 1.1 tron break;
4687 1.1 tron case XML_ROLE_NOTATION_NAME:
4688 1.1 tron declNotationPublicId = NULL;
4689 1.1 tron declNotationName = NULL;
4690 1.1 tron if (notationDeclHandler) {
4691 1.1 tron declNotationName = poolStoreString(&tempPool, enc, s, next);
4692 1.1 tron if (!declNotationName)
4693 1.1 tron return XML_ERROR_NO_MEMORY;
4694 1.1 tron poolFinish(&tempPool);
4695 1.1 tron handleDefault = XML_FALSE;
4696 1.1 tron }
4697 1.1 tron break;
4698 1.1 tron case XML_ROLE_NOTATION_PUBLIC_ID:
4699 1.1 tron if (!XmlIsPublicId(enc, s, next, eventPP))
4700 1.1 tron return XML_ERROR_PUBLICID;
4701 1.1 tron if (declNotationName) { /* means notationDeclHandler != NULL */
4702 1.1 tron XML_Char *tem = poolStoreString(&tempPool,
4703 1.1 tron enc,
4704 1.1 tron s + enc->minBytesPerChar,
4705 1.1 tron next - enc->minBytesPerChar);
4706 1.1 tron if (!tem)
4707 1.1 tron return XML_ERROR_NO_MEMORY;
4708 1.1 tron normalizePublicId(tem);
4709 1.1 tron declNotationPublicId = tem;
4710 1.1 tron poolFinish(&tempPool);
4711 1.1 tron handleDefault = XML_FALSE;
4712 1.1 tron }
4713 1.1 tron break;
4714 1.1 tron case XML_ROLE_NOTATION_SYSTEM_ID:
4715 1.1 tron if (declNotationName && notationDeclHandler) {
4716 1.1 tron const XML_Char *systemId
4717 1.1 tron = poolStoreString(&tempPool, enc,
4718 1.1 tron s + enc->minBytesPerChar,
4719 1.1 tron next - enc->minBytesPerChar);
4720 1.1 tron if (!systemId)
4721 1.1 tron return XML_ERROR_NO_MEMORY;
4722 1.1 tron *eventEndPP = s;
4723 1.1 tron notationDeclHandler(handlerArg,
4724 1.1 tron declNotationName,
4725 1.1 tron curBase,
4726 1.1 tron systemId,
4727 1.1 tron declNotationPublicId);
4728 1.1 tron handleDefault = XML_FALSE;
4729 1.1 tron }
4730 1.1 tron poolClear(&tempPool);
4731 1.1 tron break;
4732 1.1 tron case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4733 1.1 tron if (declNotationPublicId && notationDeclHandler) {
4734 1.1 tron *eventEndPP = s;
4735 1.1 tron notationDeclHandler(handlerArg,
4736 1.1 tron declNotationName,
4737 1.1 tron curBase,
4738 1.1 tron 0,
4739 1.1 tron declNotationPublicId);
4740 1.1 tron handleDefault = XML_FALSE;
4741 1.1 tron }
4742 1.1 tron poolClear(&tempPool);
4743 1.1 tron break;
4744 1.1 tron case XML_ROLE_ERROR:
4745 1.1 tron switch (tok) {
4746 1.1 tron case XML_TOK_PARAM_ENTITY_REF:
4747 1.1 tron /* PE references in internal subset are
4748 1.3 spz not allowed within declarations. */
4749 1.1 tron return XML_ERROR_PARAM_ENTITY_REF;
4750 1.1 tron case XML_TOK_XML_DECL:
4751 1.1 tron return XML_ERROR_MISPLACED_XML_PI;
4752 1.1 tron default:
4753 1.1 tron return XML_ERROR_SYNTAX;
4754 1.1 tron }
4755 1.1 tron #ifdef XML_DTD
4756 1.1 tron case XML_ROLE_IGNORE_SECT:
4757 1.1 tron {
4758 1.1 tron enum XML_Error result;
4759 1.1 tron if (defaultHandler)
4760 1.1 tron reportDefault(parser, enc, s, next);
4761 1.1 tron handleDefault = XML_FALSE;
4762 1.1 tron result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4763 1.1 tron if (result != XML_ERROR_NONE)
4764 1.1 tron return result;
4765 1.1 tron else if (!next) {
4766 1.1 tron processor = ignoreSectionProcessor;
4767 1.1 tron return result;
4768 1.1 tron }
4769 1.1 tron }
4770 1.1 tron break;
4771 1.1 tron #endif /* XML_DTD */
4772 1.1 tron case XML_ROLE_GROUP_OPEN:
4773 1.1 tron if (prologState.level >= groupSize) {
4774 1.1 tron if (groupSize) {
4775 1.1 tron char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4776 1.1 tron if (temp == NULL)
4777 1.1 tron return XML_ERROR_NO_MEMORY;
4778 1.1 tron groupConnector = temp;
4779 1.1 tron if (dtd->scaffIndex) {
4780 1.1 tron int *temp = (int *)REALLOC(dtd->scaffIndex,
4781 1.1 tron groupSize * sizeof(int));
4782 1.1 tron if (temp == NULL)
4783 1.1 tron return XML_ERROR_NO_MEMORY;
4784 1.1 tron dtd->scaffIndex = temp;
4785 1.1 tron }
4786 1.1 tron }
4787 1.1 tron else {
4788 1.1 tron groupConnector = (char *)MALLOC(groupSize = 32);
4789 1.1 tron if (!groupConnector)
4790 1.1 tron return XML_ERROR_NO_MEMORY;
4791 1.1 tron }
4792 1.1 tron }
4793 1.1 tron groupConnector[prologState.level] = 0;
4794 1.1 tron if (dtd->in_eldecl) {
4795 1.1 tron int myindex = nextScaffoldPart(parser);
4796 1.1 tron if (myindex < 0)
4797 1.1 tron return XML_ERROR_NO_MEMORY;
4798 1.1 tron dtd->scaffIndex[dtd->scaffLevel] = myindex;
4799 1.1 tron dtd->scaffLevel++;
4800 1.1 tron dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4801 1.1 tron if (elementDeclHandler)
4802 1.1 tron handleDefault = XML_FALSE;
4803 1.1 tron }
4804 1.1 tron break;
4805 1.1 tron case XML_ROLE_GROUP_SEQUENCE:
4806 1.1 tron if (groupConnector[prologState.level] == ASCII_PIPE)
4807 1.1 tron return XML_ERROR_SYNTAX;
4808 1.1 tron groupConnector[prologState.level] = ASCII_COMMA;
4809 1.1 tron if (dtd->in_eldecl && elementDeclHandler)
4810 1.1 tron handleDefault = XML_FALSE;
4811 1.1 tron break;
4812 1.1 tron case XML_ROLE_GROUP_CHOICE:
4813 1.1 tron if (groupConnector[prologState.level] == ASCII_COMMA)
4814 1.1 tron return XML_ERROR_SYNTAX;
4815 1.1 tron if (dtd->in_eldecl
4816 1.1 tron && !groupConnector[prologState.level]
4817 1.1 tron && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4818 1.1 tron != XML_CTYPE_MIXED)
4819 1.1 tron ) {
4820 1.1 tron dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4821 1.1 tron = XML_CTYPE_CHOICE;
4822 1.1 tron if (elementDeclHandler)
4823 1.1 tron handleDefault = XML_FALSE;
4824 1.1 tron }
4825 1.1 tron groupConnector[prologState.level] = ASCII_PIPE;
4826 1.1 tron break;
4827 1.1 tron case XML_ROLE_PARAM_ENTITY_REF:
4828 1.1 tron #ifdef XML_DTD
4829 1.1 tron case XML_ROLE_INNER_PARAM_ENTITY_REF:
4830 1.1 tron dtd->hasParamEntityRefs = XML_TRUE;
4831 1.1 tron if (!paramEntityParsing)
4832 1.1 tron dtd->keepProcessing = dtd->standalone;
4833 1.1 tron else {
4834 1.1 tron const XML_Char *name;
4835 1.1 tron ENTITY *entity;
4836 1.1 tron name = poolStoreString(&dtd->pool, enc,
4837 1.1 tron s + enc->minBytesPerChar,
4838 1.1 tron next - enc->minBytesPerChar);
4839 1.1 tron if (!name)
4840 1.1 tron return XML_ERROR_NO_MEMORY;
4841 1.3 spz entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
4842 1.1 tron poolDiscard(&dtd->pool);
4843 1.1 tron /* first, determine if a check for an existing declaration is needed;
4844 1.1 tron if yes, check that the entity exists, and that it is internal,
4845 1.1 tron otherwise call the skipped entity handler
4846 1.1 tron */
4847 1.1 tron if (prologState.documentEntity &&
4848 1.1 tron (dtd->standalone
4849 1.1 tron ? !openInternalEntities
4850 1.1 tron : !dtd->hasParamEntityRefs)) {
4851 1.1 tron if (!entity)
4852 1.1 tron return XML_ERROR_UNDEFINED_ENTITY;
4853 1.1 tron else if (!entity->is_internal)
4854 1.1 tron return XML_ERROR_ENTITY_DECLARED_IN_PE;
4855 1.1 tron }
4856 1.1 tron else if (!entity) {
4857 1.1 tron dtd->keepProcessing = dtd->standalone;
4858 1.1 tron /* cannot report skipped entities in declarations */
4859 1.1 tron if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4860 1.1 tron skippedEntityHandler(handlerArg, name, 1);
4861 1.1 tron handleDefault = XML_FALSE;
4862 1.1 tron }
4863 1.1 tron break;
4864 1.1 tron }
4865 1.1 tron if (entity->open)
4866 1.1 tron return XML_ERROR_RECURSIVE_ENTITY_REF;
4867 1.1 tron if (entity->textPtr) {
4868 1.1 tron enum XML_Error result;
4869 1.3 spz XML_Bool betweenDecl =
4870 1.1 tron (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4871 1.1 tron result = processInternalEntity(parser, entity, betweenDecl);
4872 1.1 tron if (result != XML_ERROR_NONE)
4873 1.1 tron return result;
4874 1.1 tron handleDefault = XML_FALSE;
4875 1.1 tron break;
4876 1.1 tron }
4877 1.1 tron if (externalEntityRefHandler) {
4878 1.1 tron dtd->paramEntityRead = XML_FALSE;
4879 1.1 tron entity->open = XML_TRUE;
4880 1.1 tron if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4881 1.1 tron 0,
4882 1.1 tron entity->base,
4883 1.1 tron entity->systemId,
4884 1.1 tron entity->publicId)) {
4885 1.1 tron entity->open = XML_FALSE;
4886 1.1 tron return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4887 1.1 tron }
4888 1.1 tron entity->open = XML_FALSE;
4889 1.1 tron handleDefault = XML_FALSE;
4890 1.1 tron if (!dtd->paramEntityRead) {
4891 1.1 tron dtd->keepProcessing = dtd->standalone;
4892 1.1 tron break;
4893 1.1 tron }
4894 1.1 tron }
4895 1.1 tron else {
4896 1.1 tron dtd->keepProcessing = dtd->standalone;
4897 1.1 tron break;
4898 1.1 tron }
4899 1.1 tron }
4900 1.1 tron #endif /* XML_DTD */
4901 1.1 tron if (!dtd->standalone &&
4902 1.1 tron notStandaloneHandler &&
4903 1.1 tron !notStandaloneHandler(handlerArg))
4904 1.1 tron return XML_ERROR_NOT_STANDALONE;
4905 1.1 tron break;
4906 1.1 tron
4907 1.1 tron /* Element declaration stuff */
4908 1.1 tron
4909 1.1 tron case XML_ROLE_ELEMENT_NAME:
4910 1.1 tron if (elementDeclHandler) {
4911 1.1 tron declElementType = getElementType(parser, enc, s, next);
4912 1.1 tron if (!declElementType)
4913 1.1 tron return XML_ERROR_NO_MEMORY;
4914 1.1 tron dtd->scaffLevel = 0;
4915 1.1 tron dtd->scaffCount = 0;
4916 1.1 tron dtd->in_eldecl = XML_TRUE;
4917 1.1 tron handleDefault = XML_FALSE;
4918 1.1 tron }
4919 1.1 tron break;
4920 1.1 tron
4921 1.1 tron case XML_ROLE_CONTENT_ANY:
4922 1.1 tron case XML_ROLE_CONTENT_EMPTY:
4923 1.1 tron if (dtd->in_eldecl) {
4924 1.1 tron if (elementDeclHandler) {
4925 1.1 tron XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4926 1.1 tron if (!content)
4927 1.1 tron return XML_ERROR_NO_MEMORY;
4928 1.1 tron content->quant = XML_CQUANT_NONE;
4929 1.1 tron content->name = NULL;
4930 1.1 tron content->numchildren = 0;
4931 1.1 tron content->children = NULL;
4932 1.1 tron content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4933 1.1 tron XML_CTYPE_ANY :
4934 1.1 tron XML_CTYPE_EMPTY);
4935 1.1 tron *eventEndPP = s;
4936 1.1 tron elementDeclHandler(handlerArg, declElementType->name, content);
4937 1.1 tron handleDefault = XML_FALSE;
4938 1.1 tron }
4939 1.1 tron dtd->in_eldecl = XML_FALSE;
4940 1.1 tron }
4941 1.1 tron break;
4942 1.1 tron
4943 1.1 tron case XML_ROLE_CONTENT_PCDATA:
4944 1.1 tron if (dtd->in_eldecl) {
4945 1.1 tron dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4946 1.1 tron = XML_CTYPE_MIXED;
4947 1.1 tron if (elementDeclHandler)
4948 1.1 tron handleDefault = XML_FALSE;
4949 1.1 tron }
4950 1.1 tron break;
4951 1.1 tron
4952 1.1 tron case XML_ROLE_CONTENT_ELEMENT:
4953 1.1 tron quant = XML_CQUANT_NONE;
4954 1.1 tron goto elementContent;
4955 1.1 tron case XML_ROLE_CONTENT_ELEMENT_OPT:
4956 1.1 tron quant = XML_CQUANT_OPT;
4957 1.1 tron goto elementContent;
4958 1.1 tron case XML_ROLE_CONTENT_ELEMENT_REP:
4959 1.1 tron quant = XML_CQUANT_REP;
4960 1.1 tron goto elementContent;
4961 1.1 tron case XML_ROLE_CONTENT_ELEMENT_PLUS:
4962 1.1 tron quant = XML_CQUANT_PLUS;
4963 1.1 tron elementContent:
4964 1.1 tron if (dtd->in_eldecl) {
4965 1.1 tron ELEMENT_TYPE *el;
4966 1.1 tron const XML_Char *name;
4967 1.1 tron int nameLen;
4968 1.1 tron const char *nxt = (quant == XML_CQUANT_NONE
4969 1.1 tron ? next
4970 1.1 tron : next - enc->minBytesPerChar);
4971 1.1 tron int myindex = nextScaffoldPart(parser);
4972 1.1 tron if (myindex < 0)
4973 1.1 tron return XML_ERROR_NO_MEMORY;
4974 1.1 tron dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4975 1.1 tron dtd->scaffold[myindex].quant = quant;
4976 1.1 tron el = getElementType(parser, enc, s, nxt);
4977 1.1 tron if (!el)
4978 1.1 tron return XML_ERROR_NO_MEMORY;
4979 1.1 tron name = el->name;
4980 1.1 tron dtd->scaffold[myindex].name = name;
4981 1.1 tron nameLen = 0;
4982 1.1 tron for (; name[nameLen++]; );
4983 1.1 tron dtd->contentStringLen += nameLen;
4984 1.1 tron if (elementDeclHandler)
4985 1.1 tron handleDefault = XML_FALSE;
4986 1.1 tron }
4987 1.1 tron break;
4988 1.1 tron
4989 1.1 tron case XML_ROLE_GROUP_CLOSE:
4990 1.1 tron quant = XML_CQUANT_NONE;
4991 1.1 tron goto closeGroup;
4992 1.1 tron case XML_ROLE_GROUP_CLOSE_OPT:
4993 1.1 tron quant = XML_CQUANT_OPT;
4994 1.1 tron goto closeGroup;
4995 1.1 tron case XML_ROLE_GROUP_CLOSE_REP:
4996 1.1 tron quant = XML_CQUANT_REP;
4997 1.1 tron goto closeGroup;
4998 1.1 tron case XML_ROLE_GROUP_CLOSE_PLUS:
4999 1.1 tron quant = XML_CQUANT_PLUS;
5000 1.1 tron closeGroup:
5001 1.1 tron if (dtd->in_eldecl) {
5002 1.1 tron if (elementDeclHandler)
5003 1.1 tron handleDefault = XML_FALSE;
5004 1.1 tron dtd->scaffLevel--;
5005 1.1 tron dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
5006 1.1 tron if (dtd->scaffLevel == 0) {
5007 1.1 tron if (!handleDefault) {
5008 1.1 tron XML_Content *model = build_model(parser);
5009 1.1 tron if (!model)
5010 1.1 tron return XML_ERROR_NO_MEMORY;
5011 1.1 tron *eventEndPP = s;
5012 1.1 tron elementDeclHandler(handlerArg, declElementType->name, model);
5013 1.1 tron }
5014 1.1 tron dtd->in_eldecl = XML_FALSE;
5015 1.1 tron dtd->contentStringLen = 0;
5016 1.1 tron }
5017 1.1 tron }
5018 1.1 tron break;
5019 1.1 tron /* End element declaration stuff */
5020 1.1 tron
5021 1.1 tron case XML_ROLE_PI:
5022 1.1 tron if (!reportProcessingInstruction(parser, enc, s, next))
5023 1.1 tron return XML_ERROR_NO_MEMORY;
5024 1.1 tron handleDefault = XML_FALSE;
5025 1.1 tron break;
5026 1.1 tron case XML_ROLE_COMMENT:
5027 1.1 tron if (!reportComment(parser, enc, s, next))
5028 1.1 tron return XML_ERROR_NO_MEMORY;
5029 1.1 tron handleDefault = XML_FALSE;
5030 1.1 tron break;
5031 1.1 tron case XML_ROLE_NONE:
5032 1.1 tron switch (tok) {
5033 1.1 tron case XML_TOK_BOM:
5034 1.1 tron handleDefault = XML_FALSE;
5035 1.1 tron break;
5036 1.1 tron }
5037 1.1 tron break;
5038 1.1 tron case XML_ROLE_DOCTYPE_NONE:
5039 1.1 tron if (startDoctypeDeclHandler)
5040 1.1 tron handleDefault = XML_FALSE;
5041 1.1 tron break;
5042 1.1 tron case XML_ROLE_ENTITY_NONE:
5043 1.1 tron if (dtd->keepProcessing && entityDeclHandler)
5044 1.1 tron handleDefault = XML_FALSE;
5045 1.1 tron break;
5046 1.1 tron case XML_ROLE_NOTATION_NONE:
5047 1.1 tron if (notationDeclHandler)
5048 1.1 tron handleDefault = XML_FALSE;
5049 1.1 tron break;
5050 1.1 tron case XML_ROLE_ATTLIST_NONE:
5051 1.1 tron if (dtd->keepProcessing && attlistDeclHandler)
5052 1.1 tron handleDefault = XML_FALSE;
5053 1.1 tron break;
5054 1.1 tron case XML_ROLE_ELEMENT_NONE:
5055 1.1 tron if (elementDeclHandler)
5056 1.1 tron handleDefault = XML_FALSE;
5057 1.1 tron break;
5058 1.1 tron } /* end of big switch */
5059 1.1 tron
5060 1.1 tron if (handleDefault && defaultHandler)
5061 1.1 tron reportDefault(parser, enc, s, next);
5062 1.1 tron
5063 1.1 tron switch (ps_parsing) {
5064 1.3 spz case XML_SUSPENDED:
5065 1.1 tron *nextPtr = next;
5066 1.1 tron return XML_ERROR_NONE;
5067 1.1 tron case XML_FINISHED:
5068 1.1 tron return XML_ERROR_ABORTED;
5069 1.1 tron default:
5070 1.1 tron s = next;
5071 1.1 tron tok = XmlPrologTok(enc, s, end, &next);
5072 1.1 tron }
5073 1.1 tron }
5074 1.1 tron /* not reached */
5075 1.1 tron }
5076 1.1 tron
5077 1.1 tron static enum XML_Error PTRCALL
5078 1.1 tron epilogProcessor(XML_Parser parser,
5079 1.1 tron const char *s,
5080 1.1 tron const char *end,
5081 1.1 tron const char **nextPtr)
5082 1.1 tron {
5083 1.1 tron processor = epilogProcessor;
5084 1.1 tron eventPtr = s;
5085 1.1 tron for (;;) {
5086 1.1 tron const char *next = NULL;
5087 1.1 tron int tok = XmlPrologTok(encoding, s, end, &next);
5088 1.1 tron eventEndPtr = next;
5089 1.1 tron switch (tok) {
5090 1.1 tron /* report partial linebreak - it might be the last token */
5091 1.1 tron case -XML_TOK_PROLOG_S:
5092 1.1 tron if (defaultHandler) {
5093 1.1 tron reportDefault(parser, encoding, s, next);
5094 1.1 tron if (ps_parsing == XML_FINISHED)
5095 1.1 tron return XML_ERROR_ABORTED;
5096 1.1 tron }
5097 1.1 tron *nextPtr = next;
5098 1.1 tron return XML_ERROR_NONE;
5099 1.1 tron case XML_TOK_NONE:
5100 1.1 tron *nextPtr = s;
5101 1.1 tron return XML_ERROR_NONE;
5102 1.1 tron case XML_TOK_PROLOG_S:
5103 1.1 tron if (defaultHandler)
5104 1.1 tron reportDefault(parser, encoding, s, next);
5105 1.1 tron break;
5106 1.1 tron case XML_TOK_PI:
5107 1.1 tron if (!reportProcessingInstruction(parser, encoding, s, next))
5108 1.1 tron return XML_ERROR_NO_MEMORY;
5109 1.1 tron break;
5110 1.1 tron case XML_TOK_COMMENT:
5111 1.1 tron if (!reportComment(parser, encoding, s, next))
5112 1.1 tron return XML_ERROR_NO_MEMORY;
5113 1.1 tron break;
5114 1.1 tron case XML_TOK_INVALID:
5115 1.1 tron eventPtr = next;
5116 1.1 tron return XML_ERROR_INVALID_TOKEN;
5117 1.1 tron case XML_TOK_PARTIAL:
5118 1.1 tron if (!ps_finalBuffer) {
5119 1.1 tron *nextPtr = s;
5120 1.1 tron return XML_ERROR_NONE;
5121 1.1 tron }
5122 1.1 tron return XML_ERROR_UNCLOSED_TOKEN;
5123 1.1 tron case XML_TOK_PARTIAL_CHAR:
5124 1.1 tron if (!ps_finalBuffer) {
5125 1.1 tron *nextPtr = s;
5126 1.1 tron return XML_ERROR_NONE;
5127 1.1 tron }
5128 1.1 tron return XML_ERROR_PARTIAL_CHAR;
5129 1.1 tron default:
5130 1.1 tron return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
5131 1.1 tron }
5132 1.1 tron eventPtr = s = next;
5133 1.1 tron switch (ps_parsing) {
5134 1.3 spz case XML_SUSPENDED:
5135 1.1 tron *nextPtr = next;
5136 1.1 tron return XML_ERROR_NONE;
5137 1.1 tron case XML_FINISHED:
5138 1.1 tron return XML_ERROR_ABORTED;
5139 1.1 tron default: ;
5140 1.1 tron }
5141 1.1 tron }
5142 1.1 tron }
5143 1.1 tron
5144 1.1 tron static enum XML_Error
5145 1.1 tron processInternalEntity(XML_Parser parser, ENTITY *entity,
5146 1.1 tron XML_Bool betweenDecl)
5147 1.1 tron {
5148 1.1 tron const char *textStart, *textEnd;
5149 1.1 tron const char *next;
5150 1.1 tron enum XML_Error result;
5151 1.1 tron OPEN_INTERNAL_ENTITY *openEntity;
5152 1.1 tron
5153 1.1 tron if (freeInternalEntities) {
5154 1.1 tron openEntity = freeInternalEntities;
5155 1.1 tron freeInternalEntities = openEntity->next;
5156 1.1 tron }
5157 1.1 tron else {
5158 1.1 tron openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
5159 1.1 tron if (!openEntity)
5160 1.1 tron return XML_ERROR_NO_MEMORY;
5161 1.1 tron }
5162 1.1 tron entity->open = XML_TRUE;
5163 1.1 tron entity->processed = 0;
5164 1.1 tron openEntity->next = openInternalEntities;
5165 1.1 tron openInternalEntities = openEntity;
5166 1.1 tron openEntity->entity = entity;
5167 1.1 tron openEntity->startTagLevel = tagLevel;
5168 1.1 tron openEntity->betweenDecl = betweenDecl;
5169 1.1 tron openEntity->internalEventPtr = NULL;
5170 1.1 tron openEntity->internalEventEndPtr = NULL;
5171 1.1 tron textStart = (char *)entity->textPtr;
5172 1.1 tron textEnd = (char *)(entity->textPtr + entity->textLen);
5173 1.7 christos /* Set a safe default value in case 'next' does not get set */
5174 1.7 christos next = textStart;
5175 1.1 tron
5176 1.1 tron #ifdef XML_DTD
5177 1.1 tron if (entity->is_param) {
5178 1.1 tron int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
5179 1.3 spz result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
5180 1.1 tron next, &next, XML_FALSE);
5181 1.1 tron }
5182 1.3 spz else
5183 1.1 tron #endif /* XML_DTD */
5184 1.3 spz result = doContent(parser, tagLevel, internalEncoding, textStart,
5185 1.1 tron textEnd, &next, XML_FALSE);
5186 1.1 tron
5187 1.1 tron if (result == XML_ERROR_NONE) {
5188 1.1 tron if (textEnd != next && ps_parsing == XML_SUSPENDED) {
5189 1.1 tron entity->processed = (int)(next - textStart);
5190 1.1 tron processor = internalEntityProcessor;
5191 1.1 tron }
5192 1.1 tron else {
5193 1.1 tron entity->open = XML_FALSE;
5194 1.1 tron openInternalEntities = openEntity->next;
5195 1.1 tron /* put openEntity back in list of free instances */
5196 1.1 tron openEntity->next = freeInternalEntities;
5197 1.1 tron freeInternalEntities = openEntity;
5198 1.1 tron }
5199 1.1 tron }
5200 1.1 tron return result;
5201 1.1 tron }
5202 1.1 tron
5203 1.1 tron static enum XML_Error PTRCALL
5204 1.1 tron internalEntityProcessor(XML_Parser parser,
5205 1.1 tron const char *s,
5206 1.1 tron const char *end,
5207 1.1 tron const char **nextPtr)
5208 1.1 tron {
5209 1.1 tron ENTITY *entity;
5210 1.1 tron const char *textStart, *textEnd;
5211 1.1 tron const char *next;
5212 1.1 tron enum XML_Error result;
5213 1.1 tron OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
5214 1.1 tron if (!openEntity)
5215 1.1 tron return XML_ERROR_UNEXPECTED_STATE;
5216 1.1 tron
5217 1.1 tron entity = openEntity->entity;
5218 1.1 tron textStart = ((char *)entity->textPtr) + entity->processed;
5219 1.1 tron textEnd = (char *)(entity->textPtr + entity->textLen);
5220 1.7 christos /* Set a safe default value in case 'next' does not get set */
5221 1.7 christos next = textStart;
5222 1.1 tron
5223 1.1 tron #ifdef XML_DTD
5224 1.1 tron if (entity->is_param) {
5225 1.1 tron int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
5226 1.3 spz result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
5227 1.1 tron next, &next, XML_FALSE);
5228 1.1 tron }
5229 1.1 tron else
5230 1.1 tron #endif /* XML_DTD */
5231 1.3 spz result = doContent(parser, openEntity->startTagLevel, internalEncoding,
5232 1.3 spz textStart, textEnd, &next, XML_FALSE);
5233 1.1 tron
5234 1.1 tron if (result != XML_ERROR_NONE)
5235 1.1 tron return result;
5236 1.1 tron else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
5237 1.1 tron entity->processed = (int)(next - (char *)entity->textPtr);
5238 1.1 tron return result;
5239 1.1 tron }
5240 1.1 tron else {
5241 1.1 tron entity->open = XML_FALSE;
5242 1.1 tron openInternalEntities = openEntity->next;
5243 1.1 tron /* put openEntity back in list of free instances */
5244 1.1 tron openEntity->next = freeInternalEntities;
5245 1.1 tron freeInternalEntities = openEntity;
5246 1.1 tron }
5247 1.1 tron
5248 1.1 tron #ifdef XML_DTD
5249 1.1 tron if (entity->is_param) {
5250 1.1 tron int tok;
5251 1.1 tron processor = prologProcessor;
5252 1.1 tron tok = XmlPrologTok(encoding, s, end, &next);
5253 1.3 spz return doProlog(parser, encoding, s, end, tok, next, nextPtr,
5254 1.1 tron (XML_Bool)!ps_finalBuffer);
5255 1.1 tron }
5256 1.1 tron else
5257 1.1 tron #endif /* XML_DTD */
5258 1.1 tron {
5259 1.1 tron processor = contentProcessor;
5260 1.1 tron /* see externalEntityContentProcessor vs contentProcessor */
5261 1.1 tron return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
5262 1.3 spz nextPtr, (XML_Bool)!ps_finalBuffer);
5263 1.3 spz }
5264 1.1 tron }
5265 1.1 tron
5266 1.1 tron static enum XML_Error PTRCALL
5267 1.1 tron errorProcessor(XML_Parser parser,
5268 1.6 spz const char *UNUSED_P(s),
5269 1.6 spz const char *UNUSED_P(end),
5270 1.6 spz const char **UNUSED_P(nextPtr))
5271 1.1 tron {
5272 1.1 tron return errorCode;
5273 1.1 tron }
5274 1.1 tron
5275 1.1 tron static enum XML_Error
5276 1.1 tron storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5277 1.1 tron const char *ptr, const char *end,
5278 1.1 tron STRING_POOL *pool)
5279 1.1 tron {
5280 1.1 tron enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
5281 1.1 tron end, pool);
5282 1.1 tron if (result)
5283 1.1 tron return result;
5284 1.1 tron if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
5285 1.1 tron poolChop(pool);
5286 1.1 tron if (!poolAppendChar(pool, XML_T('\0')))
5287 1.1 tron return XML_ERROR_NO_MEMORY;
5288 1.1 tron return XML_ERROR_NONE;
5289 1.1 tron }
5290 1.1 tron
5291 1.1 tron static enum XML_Error
5292 1.1 tron appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
5293 1.1 tron const char *ptr, const char *end,
5294 1.1 tron STRING_POOL *pool)
5295 1.1 tron {
5296 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
5297 1.1 tron for (;;) {
5298 1.1 tron const char *next;
5299 1.1 tron int tok = XmlAttributeValueTok(enc, ptr, end, &next);
5300 1.1 tron switch (tok) {
5301 1.1 tron case XML_TOK_NONE:
5302 1.1 tron return XML_ERROR_NONE;
5303 1.1 tron case XML_TOK_INVALID:
5304 1.1 tron if (enc == encoding)
5305 1.1 tron eventPtr = next;
5306 1.1 tron return XML_ERROR_INVALID_TOKEN;
5307 1.1 tron case XML_TOK_PARTIAL:
5308 1.1 tron if (enc == encoding)
5309 1.1 tron eventPtr = ptr;
5310 1.1 tron return XML_ERROR_INVALID_TOKEN;
5311 1.1 tron case XML_TOK_CHAR_REF:
5312 1.1 tron {
5313 1.1 tron XML_Char buf[XML_ENCODE_MAX];
5314 1.1 tron int i;
5315 1.1 tron int n = XmlCharRefNumber(enc, ptr);
5316 1.1 tron if (n < 0) {
5317 1.1 tron if (enc == encoding)
5318 1.1 tron eventPtr = ptr;
5319 1.1 tron return XML_ERROR_BAD_CHAR_REF;
5320 1.1 tron }
5321 1.1 tron if (!isCdata
5322 1.1 tron && n == 0x20 /* space */
5323 1.1 tron && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5324 1.1 tron break;
5325 1.1 tron n = XmlEncode(n, (ICHAR *)buf);
5326 1.1 tron if (!n) {
5327 1.1 tron if (enc == encoding)
5328 1.1 tron eventPtr = ptr;
5329 1.1 tron return XML_ERROR_BAD_CHAR_REF;
5330 1.1 tron }
5331 1.1 tron for (i = 0; i < n; i++) {
5332 1.1 tron if (!poolAppendChar(pool, buf[i]))
5333 1.1 tron return XML_ERROR_NO_MEMORY;
5334 1.1 tron }
5335 1.1 tron }
5336 1.1 tron break;
5337 1.1 tron case XML_TOK_DATA_CHARS:
5338 1.1 tron if (!poolAppend(pool, enc, ptr, next))
5339 1.1 tron return XML_ERROR_NO_MEMORY;
5340 1.1 tron break;
5341 1.1 tron case XML_TOK_TRAILING_CR:
5342 1.1 tron next = ptr + enc->minBytesPerChar;
5343 1.1 tron /* fall through */
5344 1.1 tron case XML_TOK_ATTRIBUTE_VALUE_S:
5345 1.1 tron case XML_TOK_DATA_NEWLINE:
5346 1.1 tron if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5347 1.1 tron break;
5348 1.1 tron if (!poolAppendChar(pool, 0x20))
5349 1.1 tron return XML_ERROR_NO_MEMORY;
5350 1.1 tron break;
5351 1.1 tron case XML_TOK_ENTITY_REF:
5352 1.1 tron {
5353 1.1 tron const XML_Char *name;
5354 1.1 tron ENTITY *entity;
5355 1.1 tron char checkEntityDecl;
5356 1.1 tron XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
5357 1.1 tron ptr + enc->minBytesPerChar,
5358 1.1 tron next - enc->minBytesPerChar);
5359 1.1 tron if (ch) {
5360 1.1 tron if (!poolAppendChar(pool, ch))
5361 1.1 tron return XML_ERROR_NO_MEMORY;
5362 1.1 tron break;
5363 1.1 tron }
5364 1.1 tron name = poolStoreString(&temp2Pool, enc,
5365 1.1 tron ptr + enc->minBytesPerChar,
5366 1.1 tron next - enc->minBytesPerChar);
5367 1.1 tron if (!name)
5368 1.1 tron return XML_ERROR_NO_MEMORY;
5369 1.3 spz entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5370 1.1 tron poolDiscard(&temp2Pool);
5371 1.1 tron /* First, determine if a check for an existing declaration is needed;
5372 1.1 tron if yes, check that the entity exists, and that it is internal.
5373 1.1 tron */
5374 1.1 tron if (pool == &dtd->pool) /* are we called from prolog? */
5375 1.1 tron checkEntityDecl =
5376 1.1 tron #ifdef XML_DTD
5377 1.1 tron prologState.documentEntity &&
5378 1.1 tron #endif /* XML_DTD */
5379 1.1 tron (dtd->standalone
5380 1.1 tron ? !openInternalEntities
5381 1.1 tron : !dtd->hasParamEntityRefs);
5382 1.1 tron else /* if (pool == &tempPool): we are called from content */
5383 1.1 tron checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
5384 1.1 tron if (checkEntityDecl) {
5385 1.1 tron if (!entity)
5386 1.1 tron return XML_ERROR_UNDEFINED_ENTITY;
5387 1.1 tron else if (!entity->is_internal)
5388 1.1 tron return XML_ERROR_ENTITY_DECLARED_IN_PE;
5389 1.1 tron }
5390 1.1 tron else if (!entity) {
5391 1.1 tron /* Cannot report skipped entity here - see comments on
5392 1.1 tron skippedEntityHandler.
5393 1.1 tron if (skippedEntityHandler)
5394 1.1 tron skippedEntityHandler(handlerArg, name, 0);
5395 1.1 tron */
5396 1.1 tron /* Cannot call the default handler because this would be
5397 1.1 tron out of sync with the call to the startElementHandler.
5398 1.1 tron if ((pool == &tempPool) && defaultHandler)
5399 1.1 tron reportDefault(parser, enc, ptr, next);
5400 1.1 tron */
5401 1.1 tron break;
5402 1.1 tron }
5403 1.1 tron if (entity->open) {
5404 1.1 tron if (enc == encoding)
5405 1.1 tron eventPtr = ptr;
5406 1.1 tron return XML_ERROR_RECURSIVE_ENTITY_REF;
5407 1.1 tron }
5408 1.1 tron if (entity->notation) {
5409 1.1 tron if (enc == encoding)
5410 1.1 tron eventPtr = ptr;
5411 1.1 tron return XML_ERROR_BINARY_ENTITY_REF;
5412 1.1 tron }
5413 1.1 tron if (!entity->textPtr) {
5414 1.1 tron if (enc == encoding)
5415 1.1 tron eventPtr = ptr;
5416 1.3 spz return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5417 1.1 tron }
5418 1.1 tron else {
5419 1.1 tron enum XML_Error result;
5420 1.1 tron const XML_Char *textEnd = entity->textPtr + entity->textLen;
5421 1.1 tron entity->open = XML_TRUE;
5422 1.1 tron result = appendAttributeValue(parser, internalEncoding, isCdata,
5423 1.1 tron (char *)entity->textPtr,
5424 1.1 tron (char *)textEnd, pool);
5425 1.1 tron entity->open = XML_FALSE;
5426 1.1 tron if (result)
5427 1.1 tron return result;
5428 1.1 tron }
5429 1.1 tron }
5430 1.1 tron break;
5431 1.1 tron default:
5432 1.1 tron if (enc == encoding)
5433 1.1 tron eventPtr = ptr;
5434 1.1 tron return XML_ERROR_UNEXPECTED_STATE;
5435 1.1 tron }
5436 1.1 tron ptr = next;
5437 1.1 tron }
5438 1.1 tron /* not reached */
5439 1.1 tron }
5440 1.1 tron
5441 1.1 tron static enum XML_Error
5442 1.1 tron storeEntityValue(XML_Parser parser,
5443 1.1 tron const ENCODING *enc,
5444 1.1 tron const char *entityTextPtr,
5445 1.1 tron const char *entityTextEnd)
5446 1.1 tron {
5447 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
5448 1.1 tron STRING_POOL *pool = &(dtd->entityValuePool);
5449 1.1 tron enum XML_Error result = XML_ERROR_NONE;
5450 1.1 tron #ifdef XML_DTD
5451 1.1 tron int oldInEntityValue = prologState.inEntityValue;
5452 1.1 tron prologState.inEntityValue = 1;
5453 1.1 tron #endif /* XML_DTD */
5454 1.1 tron /* never return Null for the value argument in EntityDeclHandler,
5455 1.1 tron since this would indicate an external entity; therefore we
5456 1.1 tron have to make sure that entityValuePool.start is not null */
5457 1.1 tron if (!pool->blocks) {
5458 1.1 tron if (!poolGrow(pool))
5459 1.1 tron return XML_ERROR_NO_MEMORY;
5460 1.1 tron }
5461 1.1 tron
5462 1.1 tron for (;;) {
5463 1.1 tron const char *next;
5464 1.1 tron int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5465 1.1 tron switch (tok) {
5466 1.1 tron case XML_TOK_PARAM_ENTITY_REF:
5467 1.1 tron #ifdef XML_DTD
5468 1.1 tron if (isParamEntity || enc != encoding) {
5469 1.1 tron const XML_Char *name;
5470 1.1 tron ENTITY *entity;
5471 1.1 tron name = poolStoreString(&tempPool, enc,
5472 1.1 tron entityTextPtr + enc->minBytesPerChar,
5473 1.1 tron next - enc->minBytesPerChar);
5474 1.1 tron if (!name) {
5475 1.1 tron result = XML_ERROR_NO_MEMORY;
5476 1.1 tron goto endEntityValue;
5477 1.1 tron }
5478 1.3 spz entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
5479 1.1 tron poolDiscard(&tempPool);
5480 1.1 tron if (!entity) {
5481 1.1 tron /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5482 1.1 tron /* cannot report skipped entity here - see comments on
5483 1.1 tron skippedEntityHandler
5484 1.1 tron if (skippedEntityHandler)
5485 1.1 tron skippedEntityHandler(handlerArg, name, 0);
5486 1.1 tron */
5487 1.1 tron dtd->keepProcessing = dtd->standalone;
5488 1.1 tron goto endEntityValue;
5489 1.1 tron }
5490 1.1 tron if (entity->open) {
5491 1.1 tron if (enc == encoding)
5492 1.1 tron eventPtr = entityTextPtr;
5493 1.1 tron result = XML_ERROR_RECURSIVE_ENTITY_REF;
5494 1.1 tron goto endEntityValue;
5495 1.1 tron }
5496 1.1 tron if (entity->systemId) {
5497 1.1 tron if (externalEntityRefHandler) {
5498 1.1 tron dtd->paramEntityRead = XML_FALSE;
5499 1.1 tron entity->open = XML_TRUE;
5500 1.1 tron if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5501 1.1 tron 0,
5502 1.1 tron entity->base,
5503 1.1 tron entity->systemId,
5504 1.1 tron entity->publicId)) {
5505 1.1 tron entity->open = XML_FALSE;
5506 1.1 tron result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5507 1.1 tron goto endEntityValue;
5508 1.1 tron }
5509 1.1 tron entity->open = XML_FALSE;
5510 1.1 tron if (!dtd->paramEntityRead)
5511 1.1 tron dtd->keepProcessing = dtd->standalone;
5512 1.1 tron }
5513 1.1 tron else
5514 1.1 tron dtd->keepProcessing = dtd->standalone;
5515 1.1 tron }
5516 1.1 tron else {
5517 1.1 tron entity->open = XML_TRUE;
5518 1.1 tron result = storeEntityValue(parser,
5519 1.1 tron internalEncoding,
5520 1.1 tron (char *)entity->textPtr,
5521 1.1 tron (char *)(entity->textPtr
5522 1.1 tron + entity->textLen));
5523 1.1 tron entity->open = XML_FALSE;
5524 1.1 tron if (result)
5525 1.1 tron goto endEntityValue;
5526 1.1 tron }
5527 1.1 tron break;
5528 1.1 tron }
5529 1.1 tron #endif /* XML_DTD */
5530 1.1 tron /* In the internal subset, PE references are not legal
5531 1.1 tron within markup declarations, e.g entity values in this case. */
5532 1.1 tron eventPtr = entityTextPtr;
5533 1.1 tron result = XML_ERROR_PARAM_ENTITY_REF;
5534 1.1 tron goto endEntityValue;
5535 1.1 tron case XML_TOK_NONE:
5536 1.1 tron result = XML_ERROR_NONE;
5537 1.1 tron goto endEntityValue;
5538 1.1 tron case XML_TOK_ENTITY_REF:
5539 1.1 tron case XML_TOK_DATA_CHARS:
5540 1.1 tron if (!poolAppend(pool, enc, entityTextPtr, next)) {
5541 1.1 tron result = XML_ERROR_NO_MEMORY;
5542 1.1 tron goto endEntityValue;
5543 1.1 tron }
5544 1.1 tron break;
5545 1.1 tron case XML_TOK_TRAILING_CR:
5546 1.1 tron next = entityTextPtr + enc->minBytesPerChar;
5547 1.1 tron /* fall through */
5548 1.1 tron case XML_TOK_DATA_NEWLINE:
5549 1.1 tron if (pool->end == pool->ptr && !poolGrow(pool)) {
5550 1.1 tron result = XML_ERROR_NO_MEMORY;
5551 1.1 tron goto endEntityValue;
5552 1.1 tron }
5553 1.1 tron *(pool->ptr)++ = 0xA;
5554 1.1 tron break;
5555 1.1 tron case XML_TOK_CHAR_REF:
5556 1.1 tron {
5557 1.1 tron XML_Char buf[XML_ENCODE_MAX];
5558 1.1 tron int i;
5559 1.1 tron int n = XmlCharRefNumber(enc, entityTextPtr);
5560 1.1 tron if (n < 0) {
5561 1.1 tron if (enc == encoding)
5562 1.1 tron eventPtr = entityTextPtr;
5563 1.1 tron result = XML_ERROR_BAD_CHAR_REF;
5564 1.1 tron goto endEntityValue;
5565 1.1 tron }
5566 1.1 tron n = XmlEncode(n, (ICHAR *)buf);
5567 1.1 tron if (!n) {
5568 1.1 tron if (enc == encoding)
5569 1.1 tron eventPtr = entityTextPtr;
5570 1.1 tron result = XML_ERROR_BAD_CHAR_REF;
5571 1.1 tron goto endEntityValue;
5572 1.1 tron }
5573 1.1 tron for (i = 0; i < n; i++) {
5574 1.1 tron if (pool->end == pool->ptr && !poolGrow(pool)) {
5575 1.1 tron result = XML_ERROR_NO_MEMORY;
5576 1.1 tron goto endEntityValue;
5577 1.1 tron }
5578 1.1 tron *(pool->ptr)++ = buf[i];
5579 1.1 tron }
5580 1.1 tron }
5581 1.1 tron break;
5582 1.1 tron case XML_TOK_PARTIAL:
5583 1.1 tron if (enc == encoding)
5584 1.1 tron eventPtr = entityTextPtr;
5585 1.1 tron result = XML_ERROR_INVALID_TOKEN;
5586 1.1 tron goto endEntityValue;
5587 1.1 tron case XML_TOK_INVALID:
5588 1.1 tron if (enc == encoding)
5589 1.1 tron eventPtr = next;
5590 1.1 tron result = XML_ERROR_INVALID_TOKEN;
5591 1.1 tron goto endEntityValue;
5592 1.1 tron default:
5593 1.1 tron if (enc == encoding)
5594 1.1 tron eventPtr = entityTextPtr;
5595 1.1 tron result = XML_ERROR_UNEXPECTED_STATE;
5596 1.1 tron goto endEntityValue;
5597 1.1 tron }
5598 1.1 tron entityTextPtr = next;
5599 1.1 tron }
5600 1.1 tron endEntityValue:
5601 1.1 tron #ifdef XML_DTD
5602 1.1 tron prologState.inEntityValue = oldInEntityValue;
5603 1.1 tron #endif /* XML_DTD */
5604 1.1 tron return result;
5605 1.1 tron }
5606 1.1 tron
5607 1.1 tron static void FASTCALL
5608 1.1 tron normalizeLines(XML_Char *s)
5609 1.1 tron {
5610 1.1 tron XML_Char *p;
5611 1.1 tron for (;; s++) {
5612 1.1 tron if (*s == XML_T('\0'))
5613 1.1 tron return;
5614 1.1 tron if (*s == 0xD)
5615 1.1 tron break;
5616 1.1 tron }
5617 1.1 tron p = s;
5618 1.1 tron do {
5619 1.1 tron if (*s == 0xD) {
5620 1.1 tron *p++ = 0xA;
5621 1.1 tron if (*++s == 0xA)
5622 1.1 tron s++;
5623 1.1 tron }
5624 1.1 tron else
5625 1.1 tron *p++ = *s++;
5626 1.1 tron } while (*s);
5627 1.1 tron *p = XML_T('\0');
5628 1.1 tron }
5629 1.1 tron
5630 1.1 tron static int
5631 1.1 tron reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5632 1.1 tron const char *start, const char *end)
5633 1.1 tron {
5634 1.1 tron const XML_Char *target;
5635 1.1 tron XML_Char *data;
5636 1.1 tron const char *tem;
5637 1.1 tron if (!processingInstructionHandler) {
5638 1.1 tron if (defaultHandler)
5639 1.1 tron reportDefault(parser, enc, start, end);
5640 1.1 tron return 1;
5641 1.1 tron }
5642 1.1 tron start += enc->minBytesPerChar * 2;
5643 1.1 tron tem = start + XmlNameLength(enc, start);
5644 1.1 tron target = poolStoreString(&tempPool, enc, start, tem);
5645 1.1 tron if (!target)
5646 1.1 tron return 0;
5647 1.1 tron poolFinish(&tempPool);
5648 1.1 tron data = poolStoreString(&tempPool, enc,
5649 1.1 tron XmlSkipS(enc, tem),
5650 1.1 tron end - enc->minBytesPerChar*2);
5651 1.1 tron if (!data)
5652 1.1 tron return 0;
5653 1.1 tron normalizeLines(data);
5654 1.1 tron processingInstructionHandler(handlerArg, target, data);
5655 1.1 tron poolClear(&tempPool);
5656 1.1 tron return 1;
5657 1.1 tron }
5658 1.1 tron
5659 1.1 tron static int
5660 1.1 tron reportComment(XML_Parser parser, const ENCODING *enc,
5661 1.1 tron const char *start, const char *end)
5662 1.1 tron {
5663 1.1 tron XML_Char *data;
5664 1.1 tron if (!commentHandler) {
5665 1.1 tron if (defaultHandler)
5666 1.1 tron reportDefault(parser, enc, start, end);
5667 1.1 tron return 1;
5668 1.1 tron }
5669 1.1 tron data = poolStoreString(&tempPool,
5670 1.1 tron enc,
5671 1.1 tron start + enc->minBytesPerChar * 4,
5672 1.1 tron end - enc->minBytesPerChar * 3);
5673 1.1 tron if (!data)
5674 1.1 tron return 0;
5675 1.1 tron normalizeLines(data);
5676 1.1 tron commentHandler(handlerArg, data);
5677 1.1 tron poolClear(&tempPool);
5678 1.1 tron return 1;
5679 1.1 tron }
5680 1.1 tron
5681 1.1 tron static void
5682 1.1 tron reportDefault(XML_Parser parser, const ENCODING *enc,
5683 1.1 tron const char *s, const char *end)
5684 1.1 tron {
5685 1.1 tron if (MUST_CONVERT(enc, s)) {
5686 1.5 spz enum XML_Convert_Result convert_res;
5687 1.1 tron const char **eventPP;
5688 1.1 tron const char **eventEndPP;
5689 1.1 tron if (enc == encoding) {
5690 1.1 tron eventPP = &eventPtr;
5691 1.1 tron eventEndPP = &eventEndPtr;
5692 1.1 tron }
5693 1.1 tron else {
5694 1.1 tron eventPP = &(openInternalEntities->internalEventPtr);
5695 1.1 tron eventEndPP = &(openInternalEntities->internalEventEndPtr);
5696 1.1 tron }
5697 1.1 tron do {
5698 1.1 tron ICHAR *dataPtr = (ICHAR *)dataBuf;
5699 1.5 spz convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5700 1.1 tron *eventEndPP = s;
5701 1.1 tron defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
5702 1.1 tron *eventPP = s;
5703 1.5 spz } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
5704 1.1 tron }
5705 1.1 tron else
5706 1.1 tron defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5707 1.1 tron }
5708 1.1 tron
5709 1.1 tron
5710 1.1 tron static int
5711 1.1 tron defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5712 1.1 tron XML_Bool isId, const XML_Char *value, XML_Parser parser)
5713 1.1 tron {
5714 1.1 tron DEFAULT_ATTRIBUTE *att;
5715 1.1 tron if (value || isId) {
5716 1.1 tron /* The handling of default attributes gets messed up if we have
5717 1.1 tron a default which duplicates a non-default. */
5718 1.1 tron int i;
5719 1.1 tron for (i = 0; i < type->nDefaultAtts; i++)
5720 1.1 tron if (attId == type->defaultAtts[i].id)
5721 1.1 tron return 1;
5722 1.1 tron if (isId && !type->idAtt && !attId->xmlns)
5723 1.1 tron type->idAtt = attId;
5724 1.1 tron }
5725 1.1 tron if (type->nDefaultAtts == type->allocDefaultAtts) {
5726 1.1 tron if (type->allocDefaultAtts == 0) {
5727 1.1 tron type->allocDefaultAtts = 8;
5728 1.1 tron type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
5729 1.1 tron * sizeof(DEFAULT_ATTRIBUTE));
5730 1.1 tron if (!type->defaultAtts)
5731 1.1 tron return 0;
5732 1.1 tron }
5733 1.1 tron else {
5734 1.1 tron DEFAULT_ATTRIBUTE *temp;
5735 1.1 tron int count = type->allocDefaultAtts * 2;
5736 1.1 tron temp = (DEFAULT_ATTRIBUTE *)
5737 1.1 tron REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5738 1.1 tron if (temp == NULL)
5739 1.1 tron return 0;
5740 1.1 tron type->allocDefaultAtts = count;
5741 1.1 tron type->defaultAtts = temp;
5742 1.1 tron }
5743 1.1 tron }
5744 1.1 tron att = type->defaultAtts + type->nDefaultAtts;
5745 1.1 tron att->id = attId;
5746 1.1 tron att->value = value;
5747 1.1 tron att->isCdata = isCdata;
5748 1.1 tron if (!isCdata)
5749 1.1 tron attId->maybeTokenized = XML_TRUE;
5750 1.1 tron type->nDefaultAtts += 1;
5751 1.1 tron return 1;
5752 1.1 tron }
5753 1.1 tron
5754 1.1 tron static int
5755 1.1 tron setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
5756 1.1 tron {
5757 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
5758 1.1 tron const XML_Char *name;
5759 1.1 tron for (name = elementType->name; *name; name++) {
5760 1.1 tron if (*name == XML_T(ASCII_COLON)) {
5761 1.1 tron PREFIX *prefix;
5762 1.1 tron const XML_Char *s;
5763 1.1 tron for (s = elementType->name; s != name; s++) {
5764 1.1 tron if (!poolAppendChar(&dtd->pool, *s))
5765 1.1 tron return 0;
5766 1.1 tron }
5767 1.1 tron if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5768 1.1 tron return 0;
5769 1.3 spz prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5770 1.1 tron sizeof(PREFIX));
5771 1.1 tron if (!prefix)
5772 1.1 tron return 0;
5773 1.1 tron if (prefix->name == poolStart(&dtd->pool))
5774 1.1 tron poolFinish(&dtd->pool);
5775 1.1 tron else
5776 1.1 tron poolDiscard(&dtd->pool);
5777 1.1 tron elementType->prefix = prefix;
5778 1.1 tron
5779 1.1 tron }
5780 1.1 tron }
5781 1.1 tron return 1;
5782 1.1 tron }
5783 1.1 tron
5784 1.1 tron static ATTRIBUTE_ID *
5785 1.1 tron getAttributeId(XML_Parser parser, const ENCODING *enc,
5786 1.1 tron const char *start, const char *end)
5787 1.1 tron {
5788 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
5789 1.1 tron ATTRIBUTE_ID *id;
5790 1.1 tron const XML_Char *name;
5791 1.1 tron if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5792 1.1 tron return NULL;
5793 1.1 tron name = poolStoreString(&dtd->pool, enc, start, end);
5794 1.1 tron if (!name)
5795 1.1 tron return NULL;
5796 1.1 tron /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5797 1.1 tron ++name;
5798 1.3 spz id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
5799 1.1 tron if (!id)
5800 1.1 tron return NULL;
5801 1.1 tron if (id->name != name)
5802 1.1 tron poolDiscard(&dtd->pool);
5803 1.1 tron else {
5804 1.1 tron poolFinish(&dtd->pool);
5805 1.1 tron if (!ns)
5806 1.1 tron ;
5807 1.1 tron else if (name[0] == XML_T(ASCII_x)
5808 1.1 tron && name[1] == XML_T(ASCII_m)
5809 1.1 tron && name[2] == XML_T(ASCII_l)
5810 1.1 tron && name[3] == XML_T(ASCII_n)
5811 1.1 tron && name[4] == XML_T(ASCII_s)
5812 1.1 tron && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
5813 1.1 tron if (name[5] == XML_T('\0'))
5814 1.1 tron id->prefix = &dtd->defaultPrefix;
5815 1.1 tron else
5816 1.3 spz id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
5817 1.1 tron id->xmlns = XML_TRUE;
5818 1.1 tron }
5819 1.1 tron else {
5820 1.1 tron int i;
5821 1.1 tron for (i = 0; name[i]; i++) {
5822 1.1 tron /* attributes without prefix are *not* in the default namespace */
5823 1.1 tron if (name[i] == XML_T(ASCII_COLON)) {
5824 1.1 tron int j;
5825 1.1 tron for (j = 0; j < i; j++) {
5826 1.1 tron if (!poolAppendChar(&dtd->pool, name[j]))
5827 1.1 tron return NULL;
5828 1.1 tron }
5829 1.1 tron if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5830 1.1 tron return NULL;
5831 1.3 spz id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5832 1.1 tron sizeof(PREFIX));
5833 1.4 spz if (!id->prefix)
5834 1.4 spz return NULL;
5835 1.1 tron if (id->prefix->name == poolStart(&dtd->pool))
5836 1.1 tron poolFinish(&dtd->pool);
5837 1.1 tron else
5838 1.1 tron poolDiscard(&dtd->pool);
5839 1.1 tron break;
5840 1.1 tron }
5841 1.1 tron }
5842 1.1 tron }
5843 1.1 tron }
5844 1.1 tron return id;
5845 1.1 tron }
5846 1.1 tron
5847 1.1 tron #define CONTEXT_SEP XML_T(ASCII_FF)
5848 1.1 tron
5849 1.1 tron static const XML_Char *
5850 1.1 tron getContext(XML_Parser parser)
5851 1.1 tron {
5852 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
5853 1.1 tron HASH_TABLE_ITER iter;
5854 1.1 tron XML_Bool needSep = XML_FALSE;
5855 1.1 tron
5856 1.1 tron if (dtd->defaultPrefix.binding) {
5857 1.1 tron int i;
5858 1.1 tron int len;
5859 1.1 tron if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5860 1.1 tron return NULL;
5861 1.1 tron len = dtd->defaultPrefix.binding->uriLen;
5862 1.1 tron if (namespaceSeparator)
5863 1.1 tron len--;
5864 1.1 tron for (i = 0; i < len; i++)
5865 1.1 tron if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5866 1.1 tron return NULL;
5867 1.1 tron needSep = XML_TRUE;
5868 1.1 tron }
5869 1.1 tron
5870 1.1 tron hashTableIterInit(&iter, &(dtd->prefixes));
5871 1.1 tron for (;;) {
5872 1.1 tron int i;
5873 1.1 tron int len;
5874 1.1 tron const XML_Char *s;
5875 1.1 tron PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5876 1.1 tron if (!prefix)
5877 1.1 tron break;
5878 1.1 tron if (!prefix->binding)
5879 1.1 tron continue;
5880 1.1 tron if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5881 1.1 tron return NULL;
5882 1.1 tron for (s = prefix->name; *s; s++)
5883 1.1 tron if (!poolAppendChar(&tempPool, *s))
5884 1.1 tron return NULL;
5885 1.1 tron if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5886 1.1 tron return NULL;
5887 1.1 tron len = prefix->binding->uriLen;
5888 1.1 tron if (namespaceSeparator)
5889 1.1 tron len--;
5890 1.1 tron for (i = 0; i < len; i++)
5891 1.1 tron if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
5892 1.1 tron return NULL;
5893 1.1 tron needSep = XML_TRUE;
5894 1.1 tron }
5895 1.1 tron
5896 1.1 tron
5897 1.1 tron hashTableIterInit(&iter, &(dtd->generalEntities));
5898 1.1 tron for (;;) {
5899 1.1 tron const XML_Char *s;
5900 1.1 tron ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5901 1.1 tron if (!e)
5902 1.1 tron break;
5903 1.1 tron if (!e->open)
5904 1.1 tron continue;
5905 1.1 tron if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5906 1.1 tron return NULL;
5907 1.1 tron for (s = e->name; *s; s++)
5908 1.1 tron if (!poolAppendChar(&tempPool, *s))
5909 1.1 tron return 0;
5910 1.1 tron needSep = XML_TRUE;
5911 1.1 tron }
5912 1.1 tron
5913 1.1 tron if (!poolAppendChar(&tempPool, XML_T('\0')))
5914 1.1 tron return NULL;
5915 1.1 tron return tempPool.start;
5916 1.1 tron }
5917 1.1 tron
5918 1.1 tron static XML_Bool
5919 1.1 tron setContext(XML_Parser parser, const XML_Char *context)
5920 1.1 tron {
5921 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
5922 1.1 tron const XML_Char *s = context;
5923 1.1 tron
5924 1.1 tron while (*context != XML_T('\0')) {
5925 1.1 tron if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5926 1.1 tron ENTITY *e;
5927 1.1 tron if (!poolAppendChar(&tempPool, XML_T('\0')))
5928 1.1 tron return XML_FALSE;
5929 1.3 spz e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
5930 1.1 tron if (e)
5931 1.1 tron e->open = XML_TRUE;
5932 1.1 tron if (*s != XML_T('\0'))
5933 1.1 tron s++;
5934 1.1 tron context = s;
5935 1.1 tron poolDiscard(&tempPool);
5936 1.1 tron }
5937 1.1 tron else if (*s == XML_T(ASCII_EQUALS)) {
5938 1.1 tron PREFIX *prefix;
5939 1.1 tron if (poolLength(&tempPool) == 0)
5940 1.1 tron prefix = &dtd->defaultPrefix;
5941 1.1 tron else {
5942 1.1 tron if (!poolAppendChar(&tempPool, XML_T('\0')))
5943 1.1 tron return XML_FALSE;
5944 1.3 spz prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
5945 1.1 tron sizeof(PREFIX));
5946 1.1 tron if (!prefix)
5947 1.1 tron return XML_FALSE;
5948 1.1 tron if (prefix->name == poolStart(&tempPool)) {
5949 1.1 tron prefix->name = poolCopyString(&dtd->pool, prefix->name);
5950 1.1 tron if (!prefix->name)
5951 1.1 tron return XML_FALSE;
5952 1.1 tron }
5953 1.1 tron poolDiscard(&tempPool);
5954 1.1 tron }
5955 1.1 tron for (context = s + 1;
5956 1.1 tron *context != CONTEXT_SEP && *context != XML_T('\0');
5957 1.1 tron context++)
5958 1.1 tron if (!poolAppendChar(&tempPool, *context))
5959 1.1 tron return XML_FALSE;
5960 1.1 tron if (!poolAppendChar(&tempPool, XML_T('\0')))
5961 1.1 tron return XML_FALSE;
5962 1.1 tron if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
5963 1.1 tron &inheritedBindings) != XML_ERROR_NONE)
5964 1.1 tron return XML_FALSE;
5965 1.1 tron poolDiscard(&tempPool);
5966 1.1 tron if (*context != XML_T('\0'))
5967 1.1 tron ++context;
5968 1.1 tron s = context;
5969 1.1 tron }
5970 1.1 tron else {
5971 1.1 tron if (!poolAppendChar(&tempPool, *s))
5972 1.1 tron return XML_FALSE;
5973 1.1 tron s++;
5974 1.1 tron }
5975 1.1 tron }
5976 1.1 tron return XML_TRUE;
5977 1.1 tron }
5978 1.1 tron
5979 1.1 tron static void FASTCALL
5980 1.1 tron normalizePublicId(XML_Char *publicId)
5981 1.1 tron {
5982 1.1 tron XML_Char *p = publicId;
5983 1.1 tron XML_Char *s;
5984 1.1 tron for (s = publicId; *s; s++) {
5985 1.1 tron switch (*s) {
5986 1.1 tron case 0x20:
5987 1.1 tron case 0xD:
5988 1.1 tron case 0xA:
5989 1.1 tron if (p != publicId && p[-1] != 0x20)
5990 1.1 tron *p++ = 0x20;
5991 1.1 tron break;
5992 1.1 tron default:
5993 1.1 tron *p++ = *s;
5994 1.1 tron }
5995 1.1 tron }
5996 1.1 tron if (p != publicId && p[-1] == 0x20)
5997 1.1 tron --p;
5998 1.1 tron *p = XML_T('\0');
5999 1.1 tron }
6000 1.1 tron
6001 1.1 tron static DTD *
6002 1.1 tron dtdCreate(const XML_Memory_Handling_Suite *ms)
6003 1.1 tron {
6004 1.1 tron DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
6005 1.1 tron if (p == NULL)
6006 1.1 tron return p;
6007 1.1 tron poolInit(&(p->pool), ms);
6008 1.1 tron poolInit(&(p->entityValuePool), ms);
6009 1.1 tron hashTableInit(&(p->generalEntities), ms);
6010 1.1 tron hashTableInit(&(p->elementTypes), ms);
6011 1.1 tron hashTableInit(&(p->attributeIds), ms);
6012 1.1 tron hashTableInit(&(p->prefixes), ms);
6013 1.1 tron #ifdef XML_DTD
6014 1.1 tron p->paramEntityRead = XML_FALSE;
6015 1.1 tron hashTableInit(&(p->paramEntities), ms);
6016 1.1 tron #endif /* XML_DTD */
6017 1.1 tron p->defaultPrefix.name = NULL;
6018 1.1 tron p->defaultPrefix.binding = NULL;
6019 1.1 tron
6020 1.1 tron p->in_eldecl = XML_FALSE;
6021 1.1 tron p->scaffIndex = NULL;
6022 1.1 tron p->scaffold = NULL;
6023 1.1 tron p->scaffLevel = 0;
6024 1.1 tron p->scaffSize = 0;
6025 1.1 tron p->scaffCount = 0;
6026 1.1 tron p->contentStringLen = 0;
6027 1.1 tron
6028 1.1 tron p->keepProcessing = XML_TRUE;
6029 1.1 tron p->hasParamEntityRefs = XML_FALSE;
6030 1.1 tron p->standalone = XML_FALSE;
6031 1.1 tron return p;
6032 1.1 tron }
6033 1.1 tron
6034 1.1 tron static void
6035 1.1 tron dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
6036 1.1 tron {
6037 1.1 tron HASH_TABLE_ITER iter;
6038 1.1 tron hashTableIterInit(&iter, &(p->elementTypes));
6039 1.1 tron for (;;) {
6040 1.1 tron ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6041 1.1 tron if (!e)
6042 1.1 tron break;
6043 1.1 tron if (e->allocDefaultAtts != 0)
6044 1.1 tron ms->free_fcn(e->defaultAtts);
6045 1.1 tron }
6046 1.1 tron hashTableClear(&(p->generalEntities));
6047 1.1 tron #ifdef XML_DTD
6048 1.1 tron p->paramEntityRead = XML_FALSE;
6049 1.1 tron hashTableClear(&(p->paramEntities));
6050 1.1 tron #endif /* XML_DTD */
6051 1.1 tron hashTableClear(&(p->elementTypes));
6052 1.1 tron hashTableClear(&(p->attributeIds));
6053 1.1 tron hashTableClear(&(p->prefixes));
6054 1.1 tron poolClear(&(p->pool));
6055 1.1 tron poolClear(&(p->entityValuePool));
6056 1.1 tron p->defaultPrefix.name = NULL;
6057 1.1 tron p->defaultPrefix.binding = NULL;
6058 1.1 tron
6059 1.1 tron p->in_eldecl = XML_FALSE;
6060 1.1 tron
6061 1.1 tron ms->free_fcn(p->scaffIndex);
6062 1.1 tron p->scaffIndex = NULL;
6063 1.1 tron ms->free_fcn(p->scaffold);
6064 1.1 tron p->scaffold = NULL;
6065 1.1 tron
6066 1.1 tron p->scaffLevel = 0;
6067 1.1 tron p->scaffSize = 0;
6068 1.1 tron p->scaffCount = 0;
6069 1.1 tron p->contentStringLen = 0;
6070 1.1 tron
6071 1.1 tron p->keepProcessing = XML_TRUE;
6072 1.1 tron p->hasParamEntityRefs = XML_FALSE;
6073 1.1 tron p->standalone = XML_FALSE;
6074 1.1 tron }
6075 1.1 tron
6076 1.1 tron static void
6077 1.1 tron dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
6078 1.1 tron {
6079 1.1 tron HASH_TABLE_ITER iter;
6080 1.1 tron hashTableIterInit(&iter, &(p->elementTypes));
6081 1.1 tron for (;;) {
6082 1.1 tron ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6083 1.1 tron if (!e)
6084 1.1 tron break;
6085 1.1 tron if (e->allocDefaultAtts != 0)
6086 1.1 tron ms->free_fcn(e->defaultAtts);
6087 1.1 tron }
6088 1.1 tron hashTableDestroy(&(p->generalEntities));
6089 1.1 tron #ifdef XML_DTD
6090 1.1 tron hashTableDestroy(&(p->paramEntities));
6091 1.1 tron #endif /* XML_DTD */
6092 1.1 tron hashTableDestroy(&(p->elementTypes));
6093 1.1 tron hashTableDestroy(&(p->attributeIds));
6094 1.1 tron hashTableDestroy(&(p->prefixes));
6095 1.1 tron poolDestroy(&(p->pool));
6096 1.1 tron poolDestroy(&(p->entityValuePool));
6097 1.1 tron if (isDocEntity) {
6098 1.1 tron ms->free_fcn(p->scaffIndex);
6099 1.1 tron ms->free_fcn(p->scaffold);
6100 1.1 tron }
6101 1.1 tron ms->free_fcn(p);
6102 1.1 tron }
6103 1.1 tron
6104 1.1 tron /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
6105 1.1 tron The new DTD has already been initialized.
6106 1.1 tron */
6107 1.1 tron static int
6108 1.3 spz dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
6109 1.1 tron {
6110 1.1 tron HASH_TABLE_ITER iter;
6111 1.1 tron
6112 1.1 tron /* Copy the prefix table. */
6113 1.1 tron
6114 1.1 tron hashTableIterInit(&iter, &(oldDtd->prefixes));
6115 1.1 tron for (;;) {
6116 1.1 tron const XML_Char *name;
6117 1.1 tron const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
6118 1.1 tron if (!oldP)
6119 1.1 tron break;
6120 1.1 tron name = poolCopyString(&(newDtd->pool), oldP->name);
6121 1.1 tron if (!name)
6122 1.1 tron return 0;
6123 1.3 spz if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
6124 1.1 tron return 0;
6125 1.1 tron }
6126 1.1 tron
6127 1.1 tron hashTableIterInit(&iter, &(oldDtd->attributeIds));
6128 1.1 tron
6129 1.1 tron /* Copy the attribute id table. */
6130 1.1 tron
6131 1.1 tron for (;;) {
6132 1.1 tron ATTRIBUTE_ID *newA;
6133 1.1 tron const XML_Char *name;
6134 1.1 tron const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
6135 1.1 tron
6136 1.1 tron if (!oldA)
6137 1.1 tron break;
6138 1.1 tron /* Remember to allocate the scratch byte before the name. */
6139 1.1 tron if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
6140 1.1 tron return 0;
6141 1.1 tron name = poolCopyString(&(newDtd->pool), oldA->name);
6142 1.1 tron if (!name)
6143 1.1 tron return 0;
6144 1.1 tron ++name;
6145 1.3 spz newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
6146 1.1 tron sizeof(ATTRIBUTE_ID));
6147 1.1 tron if (!newA)
6148 1.1 tron return 0;
6149 1.1 tron newA->maybeTokenized = oldA->maybeTokenized;
6150 1.1 tron if (oldA->prefix) {
6151 1.1 tron newA->xmlns = oldA->xmlns;
6152 1.1 tron if (oldA->prefix == &oldDtd->defaultPrefix)
6153 1.1 tron newA->prefix = &newDtd->defaultPrefix;
6154 1.1 tron else
6155 1.3 spz newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
6156 1.1 tron oldA->prefix->name, 0);
6157 1.1 tron }
6158 1.1 tron }
6159 1.1 tron
6160 1.1 tron /* Copy the element type table. */
6161 1.1 tron
6162 1.1 tron hashTableIterInit(&iter, &(oldDtd->elementTypes));
6163 1.1 tron
6164 1.1 tron for (;;) {
6165 1.1 tron int i;
6166 1.1 tron ELEMENT_TYPE *newE;
6167 1.1 tron const XML_Char *name;
6168 1.1 tron const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
6169 1.1 tron if (!oldE)
6170 1.1 tron break;
6171 1.1 tron name = poolCopyString(&(newDtd->pool), oldE->name);
6172 1.1 tron if (!name)
6173 1.1 tron return 0;
6174 1.3 spz newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
6175 1.1 tron sizeof(ELEMENT_TYPE));
6176 1.1 tron if (!newE)
6177 1.1 tron return 0;
6178 1.1 tron if (oldE->nDefaultAtts) {
6179 1.1 tron newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
6180 1.1 tron ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
6181 1.1 tron if (!newE->defaultAtts) {
6182 1.1 tron return 0;
6183 1.1 tron }
6184 1.1 tron }
6185 1.1 tron if (oldE->idAtt)
6186 1.1 tron newE->idAtt = (ATTRIBUTE_ID *)
6187 1.3 spz lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
6188 1.1 tron newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
6189 1.1 tron if (oldE->prefix)
6190 1.3 spz newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
6191 1.1 tron oldE->prefix->name, 0);
6192 1.1 tron for (i = 0; i < newE->nDefaultAtts; i++) {
6193 1.1 tron newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
6194 1.3 spz lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
6195 1.1 tron newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
6196 1.1 tron if (oldE->defaultAtts[i].value) {
6197 1.1 tron newE->defaultAtts[i].value
6198 1.1 tron = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
6199 1.1 tron if (!newE->defaultAtts[i].value)
6200 1.1 tron return 0;
6201 1.1 tron }
6202 1.1 tron else
6203 1.1 tron newE->defaultAtts[i].value = NULL;
6204 1.1 tron }
6205 1.1 tron }
6206 1.1 tron
6207 1.1 tron /* Copy the entity tables. */
6208 1.3 spz if (!copyEntityTable(oldParser,
6209 1.3 spz &(newDtd->generalEntities),
6210 1.1 tron &(newDtd->pool),
6211 1.1 tron &(oldDtd->generalEntities)))
6212 1.1 tron return 0;
6213 1.1 tron
6214 1.1 tron #ifdef XML_DTD
6215 1.3 spz if (!copyEntityTable(oldParser,
6216 1.3 spz &(newDtd->paramEntities),
6217 1.1 tron &(newDtd->pool),
6218 1.1 tron &(oldDtd->paramEntities)))
6219 1.1 tron return 0;
6220 1.1 tron newDtd->paramEntityRead = oldDtd->paramEntityRead;
6221 1.1 tron #endif /* XML_DTD */
6222 1.1 tron
6223 1.1 tron newDtd->keepProcessing = oldDtd->keepProcessing;
6224 1.1 tron newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
6225 1.1 tron newDtd->standalone = oldDtd->standalone;
6226 1.1 tron
6227 1.1 tron /* Don't want deep copying for scaffolding */
6228 1.1 tron newDtd->in_eldecl = oldDtd->in_eldecl;
6229 1.1 tron newDtd->scaffold = oldDtd->scaffold;
6230 1.1 tron newDtd->contentStringLen = oldDtd->contentStringLen;
6231 1.1 tron newDtd->scaffSize = oldDtd->scaffSize;
6232 1.1 tron newDtd->scaffLevel = oldDtd->scaffLevel;
6233 1.1 tron newDtd->scaffIndex = oldDtd->scaffIndex;
6234 1.1 tron
6235 1.1 tron return 1;
6236 1.1 tron } /* End dtdCopy */
6237 1.1 tron
6238 1.1 tron static int
6239 1.3 spz copyEntityTable(XML_Parser oldParser,
6240 1.3 spz HASH_TABLE *newTable,
6241 1.1 tron STRING_POOL *newPool,
6242 1.1 tron const HASH_TABLE *oldTable)
6243 1.1 tron {
6244 1.1 tron HASH_TABLE_ITER iter;
6245 1.1 tron const XML_Char *cachedOldBase = NULL;
6246 1.1 tron const XML_Char *cachedNewBase = NULL;
6247 1.1 tron
6248 1.1 tron hashTableIterInit(&iter, oldTable);
6249 1.1 tron
6250 1.1 tron for (;;) {
6251 1.1 tron ENTITY *newE;
6252 1.1 tron const XML_Char *name;
6253 1.1 tron const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
6254 1.1 tron if (!oldE)
6255 1.1 tron break;
6256 1.1 tron name = poolCopyString(newPool, oldE->name);
6257 1.1 tron if (!name)
6258 1.1 tron return 0;
6259 1.3 spz newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
6260 1.1 tron if (!newE)
6261 1.1 tron return 0;
6262 1.1 tron if (oldE->systemId) {
6263 1.1 tron const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
6264 1.1 tron if (!tem)
6265 1.1 tron return 0;
6266 1.1 tron newE->systemId = tem;
6267 1.1 tron if (oldE->base) {
6268 1.1 tron if (oldE->base == cachedOldBase)
6269 1.1 tron newE->base = cachedNewBase;
6270 1.1 tron else {
6271 1.1 tron cachedOldBase = oldE->base;
6272 1.1 tron tem = poolCopyString(newPool, cachedOldBase);
6273 1.1 tron if (!tem)
6274 1.1 tron return 0;
6275 1.1 tron cachedNewBase = newE->base = tem;
6276 1.1 tron }
6277 1.1 tron }
6278 1.1 tron if (oldE->publicId) {
6279 1.1 tron tem = poolCopyString(newPool, oldE->publicId);
6280 1.1 tron if (!tem)
6281 1.1 tron return 0;
6282 1.1 tron newE->publicId = tem;
6283 1.1 tron }
6284 1.1 tron }
6285 1.1 tron else {
6286 1.1 tron const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
6287 1.1 tron oldE->textLen);
6288 1.1 tron if (!tem)
6289 1.1 tron return 0;
6290 1.1 tron newE->textPtr = tem;
6291 1.1 tron newE->textLen = oldE->textLen;
6292 1.1 tron }
6293 1.1 tron if (oldE->notation) {
6294 1.1 tron const XML_Char *tem = poolCopyString(newPool, oldE->notation);
6295 1.1 tron if (!tem)
6296 1.1 tron return 0;
6297 1.1 tron newE->notation = tem;
6298 1.1 tron }
6299 1.1 tron newE->is_param = oldE->is_param;
6300 1.1 tron newE->is_internal = oldE->is_internal;
6301 1.1 tron }
6302 1.1 tron return 1;
6303 1.1 tron }
6304 1.1 tron
6305 1.1 tron #define INIT_POWER 6
6306 1.1 tron
6307 1.1 tron static XML_Bool FASTCALL
6308 1.1 tron keyeq(KEY s1, KEY s2)
6309 1.1 tron {
6310 1.1 tron for (; *s1 == *s2; s1++, s2++)
6311 1.1 tron if (*s1 == 0)
6312 1.1 tron return XML_TRUE;
6313 1.1 tron return XML_FALSE;
6314 1.1 tron }
6315 1.1 tron
6316 1.7 christos static size_t
6317 1.7 christos keylen(KEY s)
6318 1.7 christos {
6319 1.7 christos size_t len = 0;
6320 1.7 christos for (; *s; s++, len++);
6321 1.7 christos return len;
6322 1.7 christos }
6323 1.7 christos
6324 1.7 christos static void
6325 1.7 christos copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)
6326 1.7 christos {
6327 1.7 christos key->k[0] = 0;
6328 1.7 christos key->k[1] = get_hash_secret_salt(parser);
6329 1.7 christos }
6330 1.7 christos
6331 1.1 tron static unsigned long FASTCALL
6332 1.3 spz hash(XML_Parser parser, KEY s)
6333 1.1 tron {
6334 1.7 christos struct siphash state;
6335 1.7 christos struct sipkey key;
6336 1.7 christos (void)sip_tobin;
6337 1.7 christos (void)sip24_valid;
6338 1.7 christos copy_salt_to_sipkey(parser, &key);
6339 1.7 christos sip24_init(&state, &key);
6340 1.7 christos sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
6341 1.7 christos return (unsigned long)sip24_final(&state);
6342 1.1 tron }
6343 1.1 tron
6344 1.1 tron static NAMED *
6345 1.3 spz lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
6346 1.1 tron {
6347 1.1 tron size_t i;
6348 1.1 tron if (table->size == 0) {
6349 1.1 tron size_t tsize;
6350 1.1 tron if (!createSize)
6351 1.1 tron return NULL;
6352 1.1 tron table->power = INIT_POWER;
6353 1.1 tron /* table->size is a power of 2 */
6354 1.1 tron table->size = (size_t)1 << INIT_POWER;
6355 1.1 tron tsize = table->size * sizeof(NAMED *);
6356 1.1 tron table->v = (NAMED **)table->mem->malloc_fcn(tsize);
6357 1.1 tron if (!table->v) {
6358 1.1 tron table->size = 0;
6359 1.1 tron return NULL;
6360 1.1 tron }
6361 1.1 tron memset(table->v, 0, tsize);
6362 1.3 spz i = hash(parser, name) & ((unsigned long)table->size - 1);
6363 1.1 tron }
6364 1.1 tron else {
6365 1.3 spz unsigned long h = hash(parser, name);
6366 1.1 tron unsigned long mask = (unsigned long)table->size - 1;
6367 1.1 tron unsigned char step = 0;
6368 1.1 tron i = h & mask;
6369 1.1 tron while (table->v[i]) {
6370 1.1 tron if (keyeq(name, table->v[i]->name))
6371 1.1 tron return table->v[i];
6372 1.1 tron if (!step)
6373 1.1 tron step = PROBE_STEP(h, mask, table->power);
6374 1.1 tron i < step ? (i += table->size - step) : (i -= step);
6375 1.1 tron }
6376 1.1 tron if (!createSize)
6377 1.1 tron return NULL;
6378 1.1 tron
6379 1.1 tron /* check for overflow (table is half full) */
6380 1.1 tron if (table->used >> (table->power - 1)) {
6381 1.1 tron unsigned char newPower = table->power + 1;
6382 1.1 tron size_t newSize = (size_t)1 << newPower;
6383 1.1 tron unsigned long newMask = (unsigned long)newSize - 1;
6384 1.1 tron size_t tsize = newSize * sizeof(NAMED *);
6385 1.1 tron NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
6386 1.1 tron if (!newV)
6387 1.1 tron return NULL;
6388 1.1 tron memset(newV, 0, tsize);
6389 1.1 tron for (i = 0; i < table->size; i++)
6390 1.1 tron if (table->v[i]) {
6391 1.3 spz unsigned long newHash = hash(parser, table->v[i]->name);
6392 1.1 tron size_t j = newHash & newMask;
6393 1.1 tron step = 0;
6394 1.1 tron while (newV[j]) {
6395 1.1 tron if (!step)
6396 1.1 tron step = PROBE_STEP(newHash, newMask, newPower);
6397 1.1 tron j < step ? (j += newSize - step) : (j -= step);
6398 1.1 tron }
6399 1.1 tron newV[j] = table->v[i];
6400 1.1 tron }
6401 1.1 tron table->mem->free_fcn(table->v);
6402 1.1 tron table->v = newV;
6403 1.1 tron table->power = newPower;
6404 1.1 tron table->size = newSize;
6405 1.1 tron i = h & newMask;
6406 1.1 tron step = 0;
6407 1.1 tron while (table->v[i]) {
6408 1.1 tron if (!step)
6409 1.1 tron step = PROBE_STEP(h, newMask, newPower);
6410 1.1 tron i < step ? (i += newSize - step) : (i -= step);
6411 1.1 tron }
6412 1.1 tron }
6413 1.1 tron }
6414 1.1 tron table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
6415 1.1 tron if (!table->v[i])
6416 1.1 tron return NULL;
6417 1.1 tron memset(table->v[i], 0, createSize);
6418 1.1 tron table->v[i]->name = name;
6419 1.1 tron (table->used)++;
6420 1.1 tron return table->v[i];
6421 1.1 tron }
6422 1.1 tron
6423 1.1 tron static void FASTCALL
6424 1.1 tron hashTableClear(HASH_TABLE *table)
6425 1.1 tron {
6426 1.1 tron size_t i;
6427 1.1 tron for (i = 0; i < table->size; i++) {
6428 1.1 tron table->mem->free_fcn(table->v[i]);
6429 1.1 tron table->v[i] = NULL;
6430 1.1 tron }
6431 1.1 tron table->used = 0;
6432 1.1 tron }
6433 1.1 tron
6434 1.1 tron static void FASTCALL
6435 1.1 tron hashTableDestroy(HASH_TABLE *table)
6436 1.1 tron {
6437 1.1 tron size_t i;
6438 1.1 tron for (i = 0; i < table->size; i++)
6439 1.1 tron table->mem->free_fcn(table->v[i]);
6440 1.1 tron table->mem->free_fcn(table->v);
6441 1.1 tron }
6442 1.1 tron
6443 1.1 tron static void FASTCALL
6444 1.1 tron hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
6445 1.1 tron {
6446 1.1 tron p->power = 0;
6447 1.1 tron p->size = 0;
6448 1.1 tron p->used = 0;
6449 1.1 tron p->v = NULL;
6450 1.1 tron p->mem = ms;
6451 1.1 tron }
6452 1.1 tron
6453 1.1 tron static void FASTCALL
6454 1.1 tron hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
6455 1.1 tron {
6456 1.1 tron iter->p = table->v;
6457 1.1 tron iter->end = iter->p + table->size;
6458 1.1 tron }
6459 1.1 tron
6460 1.1 tron static NAMED * FASTCALL
6461 1.1 tron hashTableIterNext(HASH_TABLE_ITER *iter)
6462 1.1 tron {
6463 1.1 tron while (iter->p != iter->end) {
6464 1.1 tron NAMED *tem = *(iter->p)++;
6465 1.1 tron if (tem)
6466 1.1 tron return tem;
6467 1.1 tron }
6468 1.1 tron return NULL;
6469 1.1 tron }
6470 1.1 tron
6471 1.1 tron static void FASTCALL
6472 1.1 tron poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
6473 1.1 tron {
6474 1.1 tron pool->blocks = NULL;
6475 1.1 tron pool->freeBlocks = NULL;
6476 1.1 tron pool->start = NULL;
6477 1.1 tron pool->ptr = NULL;
6478 1.1 tron pool->end = NULL;
6479 1.1 tron pool->mem = ms;
6480 1.1 tron }
6481 1.1 tron
6482 1.1 tron static void FASTCALL
6483 1.1 tron poolClear(STRING_POOL *pool)
6484 1.1 tron {
6485 1.1 tron if (!pool->freeBlocks)
6486 1.1 tron pool->freeBlocks = pool->blocks;
6487 1.1 tron else {
6488 1.1 tron BLOCK *p = pool->blocks;
6489 1.1 tron while (p) {
6490 1.1 tron BLOCK *tem = p->next;
6491 1.1 tron p->next = pool->freeBlocks;
6492 1.1 tron pool->freeBlocks = p;
6493 1.1 tron p = tem;
6494 1.1 tron }
6495 1.1 tron }
6496 1.1 tron pool->blocks = NULL;
6497 1.1 tron pool->start = NULL;
6498 1.1 tron pool->ptr = NULL;
6499 1.1 tron pool->end = NULL;
6500 1.1 tron }
6501 1.1 tron
6502 1.1 tron static void FASTCALL
6503 1.1 tron poolDestroy(STRING_POOL *pool)
6504 1.1 tron {
6505 1.1 tron BLOCK *p = pool->blocks;
6506 1.1 tron while (p) {
6507 1.1 tron BLOCK *tem = p->next;
6508 1.1 tron pool->mem->free_fcn(p);
6509 1.1 tron p = tem;
6510 1.1 tron }
6511 1.1 tron p = pool->freeBlocks;
6512 1.1 tron while (p) {
6513 1.1 tron BLOCK *tem = p->next;
6514 1.1 tron pool->mem->free_fcn(p);
6515 1.1 tron p = tem;
6516 1.1 tron }
6517 1.1 tron }
6518 1.1 tron
6519 1.1 tron static XML_Char *
6520 1.1 tron poolAppend(STRING_POOL *pool, const ENCODING *enc,
6521 1.1 tron const char *ptr, const char *end)
6522 1.1 tron {
6523 1.1 tron if (!pool->ptr && !poolGrow(pool))
6524 1.1 tron return NULL;
6525 1.1 tron for (;;) {
6526 1.5 spz const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6527 1.5 spz if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
6528 1.1 tron break;
6529 1.1 tron if (!poolGrow(pool))
6530 1.1 tron return NULL;
6531 1.1 tron }
6532 1.1 tron return pool->start;
6533 1.1 tron }
6534 1.1 tron
6535 1.1 tron static const XML_Char * FASTCALL
6536 1.1 tron poolCopyString(STRING_POOL *pool, const XML_Char *s)
6537 1.1 tron {
6538 1.1 tron do {
6539 1.1 tron if (!poolAppendChar(pool, *s))
6540 1.1 tron return NULL;
6541 1.1 tron } while (*s++);
6542 1.1 tron s = pool->start;
6543 1.1 tron poolFinish(pool);
6544 1.1 tron return s;
6545 1.1 tron }
6546 1.1 tron
6547 1.1 tron static const XML_Char *
6548 1.1 tron poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
6549 1.1 tron {
6550 1.1 tron if (!pool->ptr && !poolGrow(pool))
6551 1.1 tron return NULL;
6552 1.1 tron for (; n > 0; --n, s++) {
6553 1.1 tron if (!poolAppendChar(pool, *s))
6554 1.1 tron return NULL;
6555 1.1 tron }
6556 1.1 tron s = pool->start;
6557 1.1 tron poolFinish(pool);
6558 1.1 tron return s;
6559 1.1 tron }
6560 1.1 tron
6561 1.1 tron static const XML_Char * FASTCALL
6562 1.1 tron poolAppendString(STRING_POOL *pool, const XML_Char *s)
6563 1.1 tron {
6564 1.1 tron while (*s) {
6565 1.1 tron if (!poolAppendChar(pool, *s))
6566 1.1 tron return NULL;
6567 1.1 tron s++;
6568 1.1 tron }
6569 1.1 tron return pool->start;
6570 1.1 tron }
6571 1.1 tron
6572 1.1 tron static XML_Char *
6573 1.1 tron poolStoreString(STRING_POOL *pool, const ENCODING *enc,
6574 1.1 tron const char *ptr, const char *end)
6575 1.1 tron {
6576 1.1 tron if (!poolAppend(pool, enc, ptr, end))
6577 1.1 tron return NULL;
6578 1.1 tron if (pool->ptr == pool->end && !poolGrow(pool))
6579 1.1 tron return NULL;
6580 1.1 tron *(pool->ptr)++ = 0;
6581 1.1 tron return pool->start;
6582 1.1 tron }
6583 1.1 tron
6584 1.7 christos static size_t
6585 1.7 christos poolBytesToAllocateFor(int blockSize)
6586 1.7 christos {
6587 1.7 christos /* Unprotected math would be:
6588 1.7 christos ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
6589 1.7 christos **
6590 1.7 christos ** Detect overflow, avoiding _signed_ overflow undefined behavior
6591 1.7 christos ** For a + b * c we check b * c in isolation first, so that addition of a
6592 1.7 christos ** on top has no chance of making us accept a small non-negative number
6593 1.7 christos */
6594 1.7 christos const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
6595 1.7 christos
6596 1.7 christos if (blockSize <= 0)
6597 1.7 christos return 0;
6598 1.7 christos
6599 1.7 christos if (blockSize > (int)(INT_MAX / stretch))
6600 1.7 christos return 0;
6601 1.7 christos
6602 1.7 christos {
6603 1.7 christos const int stretchedBlockSize = blockSize * (int)stretch;
6604 1.7 christos const int bytesToAllocate = (int)(
6605 1.7 christos offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
6606 1.7 christos if (bytesToAllocate < 0)
6607 1.7 christos return 0;
6608 1.7 christos
6609 1.7 christos return (size_t)bytesToAllocate;
6610 1.7 christos }
6611 1.7 christos }
6612 1.7 christos
6613 1.1 tron static XML_Bool FASTCALL
6614 1.1 tron poolGrow(STRING_POOL *pool)
6615 1.1 tron {
6616 1.1 tron if (pool->freeBlocks) {
6617 1.1 tron if (pool->start == 0) {
6618 1.1 tron pool->blocks = pool->freeBlocks;
6619 1.1 tron pool->freeBlocks = pool->freeBlocks->next;
6620 1.1 tron pool->blocks->next = NULL;
6621 1.1 tron pool->start = pool->blocks->s;
6622 1.1 tron pool->end = pool->start + pool->blocks->size;
6623 1.1 tron pool->ptr = pool->start;
6624 1.1 tron return XML_TRUE;
6625 1.1 tron }
6626 1.1 tron if (pool->end - pool->start < pool->freeBlocks->size) {
6627 1.1 tron BLOCK *tem = pool->freeBlocks->next;
6628 1.1 tron pool->freeBlocks->next = pool->blocks;
6629 1.1 tron pool->blocks = pool->freeBlocks;
6630 1.1 tron pool->freeBlocks = tem;
6631 1.1 tron memcpy(pool->blocks->s, pool->start,
6632 1.1 tron (pool->end - pool->start) * sizeof(XML_Char));
6633 1.1 tron pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6634 1.1 tron pool->start = pool->blocks->s;
6635 1.1 tron pool->end = pool->start + pool->blocks->size;
6636 1.1 tron return XML_TRUE;
6637 1.1 tron }
6638 1.1 tron }
6639 1.1 tron if (pool->blocks && pool->start == pool->blocks->s) {
6640 1.5 spz BLOCK *temp;
6641 1.5 spz int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
6642 1.7 christos size_t bytesToAllocate;
6643 1.5 spz
6644 1.5 spz if (blockSize < 0)
6645 1.5 spz return XML_FALSE;
6646 1.5 spz
6647 1.7 christos bytesToAllocate = poolBytesToAllocateFor(blockSize);
6648 1.7 christos if (bytesToAllocate == 0)
6649 1.7 christos return XML_FALSE;
6650 1.7 christos
6651 1.5 spz temp = (BLOCK *)
6652 1.7 christos pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);
6653 1.3 spz if (temp == NULL)
6654 1.1 tron return XML_FALSE;
6655 1.3 spz pool->blocks = temp;
6656 1.1 tron pool->blocks->size = blockSize;
6657 1.1 tron pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6658 1.1 tron pool->start = pool->blocks->s;
6659 1.1 tron pool->end = pool->start + blockSize;
6660 1.1 tron }
6661 1.1 tron else {
6662 1.1 tron BLOCK *tem;
6663 1.1 tron int blockSize = (int)(pool->end - pool->start);
6664 1.7 christos size_t bytesToAllocate;
6665 1.5 spz
6666 1.5 spz if (blockSize < 0)
6667 1.5 spz return XML_FALSE;
6668 1.5 spz
6669 1.1 tron if (blockSize < INIT_BLOCK_SIZE)
6670 1.1 tron blockSize = INIT_BLOCK_SIZE;
6671 1.7 christos else {
6672 1.7 christos /* Detect overflow, avoiding _signed_ overflow undefined behavior */
6673 1.7 christos if ((int)((unsigned)blockSize * 2U) < 0) {
6674 1.7 christos return XML_FALSE;
6675 1.7 christos }
6676 1.1 tron blockSize *= 2;
6677 1.7 christos }
6678 1.7 christos
6679 1.7 christos bytesToAllocate = poolBytesToAllocateFor(blockSize);
6680 1.7 christos if (bytesToAllocate == 0)
6681 1.7 christos return XML_FALSE;
6682 1.7 christos
6683 1.7 christos tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
6684 1.1 tron if (!tem)
6685 1.1 tron return XML_FALSE;
6686 1.1 tron tem->size = blockSize;
6687 1.1 tron tem->next = pool->blocks;
6688 1.1 tron pool->blocks = tem;
6689 1.1 tron if (pool->ptr != pool->start)
6690 1.1 tron memcpy(tem->s, pool->start,
6691 1.1 tron (pool->ptr - pool->start) * sizeof(XML_Char));
6692 1.1 tron pool->ptr = tem->s + (pool->ptr - pool->start);
6693 1.1 tron pool->start = tem->s;
6694 1.1 tron pool->end = tem->s + blockSize;
6695 1.1 tron }
6696 1.1 tron return XML_TRUE;
6697 1.1 tron }
6698 1.1 tron
6699 1.1 tron static int FASTCALL
6700 1.1 tron nextScaffoldPart(XML_Parser parser)
6701 1.1 tron {
6702 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
6703 1.1 tron CONTENT_SCAFFOLD * me;
6704 1.1 tron int next;
6705 1.1 tron
6706 1.1 tron if (!dtd->scaffIndex) {
6707 1.1 tron dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6708 1.1 tron if (!dtd->scaffIndex)
6709 1.1 tron return -1;
6710 1.1 tron dtd->scaffIndex[0] = 0;
6711 1.1 tron }
6712 1.1 tron
6713 1.1 tron if (dtd->scaffCount >= dtd->scaffSize) {
6714 1.1 tron CONTENT_SCAFFOLD *temp;
6715 1.1 tron if (dtd->scaffold) {
6716 1.1 tron temp = (CONTENT_SCAFFOLD *)
6717 1.1 tron REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6718 1.1 tron if (temp == NULL)
6719 1.1 tron return -1;
6720 1.1 tron dtd->scaffSize *= 2;
6721 1.1 tron }
6722 1.1 tron else {
6723 1.1 tron temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6724 1.1 tron * sizeof(CONTENT_SCAFFOLD));
6725 1.1 tron if (temp == NULL)
6726 1.1 tron return -1;
6727 1.1 tron dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6728 1.1 tron }
6729 1.1 tron dtd->scaffold = temp;
6730 1.1 tron }
6731 1.1 tron next = dtd->scaffCount++;
6732 1.1 tron me = &dtd->scaffold[next];
6733 1.1 tron if (dtd->scaffLevel) {
6734 1.1 tron CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
6735 1.1 tron if (parent->lastchild) {
6736 1.1 tron dtd->scaffold[parent->lastchild].nextsib = next;
6737 1.1 tron }
6738 1.1 tron if (!parent->childcnt)
6739 1.1 tron parent->firstchild = next;
6740 1.1 tron parent->lastchild = next;
6741 1.1 tron parent->childcnt++;
6742 1.1 tron }
6743 1.1 tron me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6744 1.1 tron return next;
6745 1.1 tron }
6746 1.1 tron
6747 1.1 tron static void
6748 1.1 tron build_node(XML_Parser parser,
6749 1.1 tron int src_node,
6750 1.1 tron XML_Content *dest,
6751 1.1 tron XML_Content **contpos,
6752 1.1 tron XML_Char **strpos)
6753 1.1 tron {
6754 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
6755 1.1 tron dest->type = dtd->scaffold[src_node].type;
6756 1.1 tron dest->quant = dtd->scaffold[src_node].quant;
6757 1.1 tron if (dest->type == XML_CTYPE_NAME) {
6758 1.1 tron const XML_Char *src;
6759 1.1 tron dest->name = *strpos;
6760 1.1 tron src = dtd->scaffold[src_node].name;
6761 1.1 tron for (;;) {
6762 1.1 tron *(*strpos)++ = *src;
6763 1.1 tron if (!*src)
6764 1.1 tron break;
6765 1.1 tron src++;
6766 1.1 tron }
6767 1.1 tron dest->numchildren = 0;
6768 1.1 tron dest->children = NULL;
6769 1.1 tron }
6770 1.1 tron else {
6771 1.1 tron unsigned int i;
6772 1.1 tron int cn;
6773 1.1 tron dest->numchildren = dtd->scaffold[src_node].childcnt;
6774 1.1 tron dest->children = *contpos;
6775 1.1 tron *contpos += dest->numchildren;
6776 1.1 tron for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6777 1.1 tron i < dest->numchildren;
6778 1.1 tron i++, cn = dtd->scaffold[cn].nextsib) {
6779 1.1 tron build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6780 1.1 tron }
6781 1.1 tron dest->name = NULL;
6782 1.1 tron }
6783 1.1 tron }
6784 1.1 tron
6785 1.1 tron static XML_Content *
6786 1.1 tron build_model (XML_Parser parser)
6787 1.1 tron {
6788 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
6789 1.1 tron XML_Content *ret;
6790 1.1 tron XML_Content *cpos;
6791 1.1 tron XML_Char * str;
6792 1.1 tron int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6793 1.1 tron + (dtd->contentStringLen * sizeof(XML_Char)));
6794 1.1 tron
6795 1.1 tron ret = (XML_Content *)MALLOC(allocsize);
6796 1.1 tron if (!ret)
6797 1.1 tron return NULL;
6798 1.1 tron
6799 1.1 tron str = (XML_Char *) (&ret[dtd->scaffCount]);
6800 1.1 tron cpos = &ret[1];
6801 1.1 tron
6802 1.1 tron build_node(parser, 0, ret, &cpos, &str);
6803 1.1 tron return ret;
6804 1.1 tron }
6805 1.1 tron
6806 1.1 tron static ELEMENT_TYPE *
6807 1.1 tron getElementType(XML_Parser parser,
6808 1.1 tron const ENCODING *enc,
6809 1.1 tron const char *ptr,
6810 1.1 tron const char *end)
6811 1.1 tron {
6812 1.1 tron DTD * const dtd = _dtd; /* save one level of indirection */
6813 1.1 tron const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6814 1.1 tron ELEMENT_TYPE *ret;
6815 1.1 tron
6816 1.1 tron if (!name)
6817 1.1 tron return NULL;
6818 1.3 spz ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6819 1.1 tron if (!ret)
6820 1.1 tron return NULL;
6821 1.1 tron if (ret->name != name)
6822 1.1 tron poolDiscard(&dtd->pool);
6823 1.1 tron else {
6824 1.1 tron poolFinish(&dtd->pool);
6825 1.1 tron if (!setElementTypePrefix(parser, ret))
6826 1.1 tron return NULL;
6827 1.1 tron }
6828 1.1 tron return ret;
6829 1.1 tron }
6830