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