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