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