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