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