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