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