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