1104349Sphk/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
2104349Sphk   See the file COPYING for copying permission.
3104349Sphk*/
4104349Sphk
5104349Sphk#include <stddef.h>
6104349Sphk#include <string.h>                     /* memset(), memcpy() */
7178848Scokane#include <assert.h>
8247513Sdelphij#include <limits.h>                     /* UINT_MAX */
9247513Sdelphij#include <time.h>                       /* time() */
10104349Sphk
11178848Scokane#define XML_BUILDING_EXPAT 1
12178848Scokane
13104349Sphk#ifdef COMPILED_FROM_DSP
14104349Sphk#include "winconfig.h"
15104349Sphk#elif defined(MACOS_CLASSIC)
16104349Sphk#include "macconfig.h"
17247513Sdelphij#elif defined(__amigaos__)
18178848Scokane#include "amigaconfig.h"
19178848Scokane#elif defined(__WATCOMC__)
20178848Scokane#include "watcomconfig.h"
21178848Scokane#elif defined(HAVE_EXPAT_CONFIG_H)
22104349Sphk#include <expat_config.h>
23178848Scokane#endif /* ndef COMPILED_FROM_DSP */
24104349Sphk
25178848Scokane#include "ascii.h"
26104349Sphk#include "expat.h"
27104349Sphk
28104349Sphk#ifdef XML_UNICODE
29104349Sphk#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
30104349Sphk#define XmlConvert XmlUtf16Convert
31104349Sphk#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
32104349Sphk#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
33104349Sphk#define XmlEncode XmlUtf16Encode
34178848Scokane/* Using pointer subtraction to convert to integer type. */
35178848Scokane#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
36104349Sphktypedef unsigned short ICHAR;
37104349Sphk#else
38104349Sphk#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
39104349Sphk#define XmlConvert XmlUtf8Convert
40104349Sphk#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
41104349Sphk#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
42104349Sphk#define XmlEncode XmlUtf8Encode
43104349Sphk#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
44104349Sphktypedef char ICHAR;
45104349Sphk#endif
46104349Sphk
47104349Sphk
48104349Sphk#ifndef XML_NS
49104349Sphk
50104349Sphk#define XmlInitEncodingNS XmlInitEncoding
51104349Sphk#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
52104349Sphk#undef XmlGetInternalEncodingNS
53104349Sphk#define XmlGetInternalEncodingNS XmlGetInternalEncoding
54104349Sphk#define XmlParseXmlDeclNS XmlParseXmlDecl
55104349Sphk
56104349Sphk#endif
57104349Sphk
58104349Sphk#ifdef XML_UNICODE
59104349Sphk
60104349Sphk#ifdef XML_UNICODE_WCHAR_T
61104349Sphk#define XML_T(x) (const wchar_t)x
62104349Sphk#define XML_L(x) L ## x
63104349Sphk#else
64104349Sphk#define XML_T(x) (const unsigned short)x
65104349Sphk#define XML_L(x) x
66104349Sphk#endif
67104349Sphk
68104349Sphk#else
69104349Sphk
70104349Sphk#define XML_T(x) x
71104349Sphk#define XML_L(x) x
72104349Sphk
73104349Sphk#endif
74104349Sphk
75104349Sphk/* Round up n to be a multiple of sz, where sz is a power of 2. */
76104349Sphk#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
77104349Sphk
78104349Sphk/* Handle the case where memmove() doesn't exist. */
79104349Sphk#ifndef HAVE_MEMMOVE
80104349Sphk#ifdef HAVE_BCOPY
81104349Sphk#define memmove(d,s,l) bcopy((s),(d),(l))
82104349Sphk#else
83104349Sphk#error memmove does not exist on this platform, nor is a substitute available
84104349Sphk#endif /* HAVE_BCOPY */
85104349Sphk#endif /* HAVE_MEMMOVE */
86104349Sphk
87104349Sphk#include "internal.h"
88104349Sphk#include "xmltok.h"
89104349Sphk#include "xmlrole.h"
90104349Sphk
91104349Sphktypedef const XML_Char *KEY;
92104349Sphk
93104349Sphktypedef struct {
94104349Sphk  KEY name;
95104349Sphk} NAMED;
96104349Sphk
97104349Sphktypedef struct {
98104349Sphk  NAMED **v;
99178848Scokane  unsigned char power;
100104349Sphk  size_t size;
101104349Sphk  size_t used;
102178848Scokane  const XML_Memory_Handling_Suite *mem;
103104349Sphk} HASH_TABLE;
104104349Sphk
105178848Scokane/* Basic character hash algorithm, taken from Python's string hash:
106178848Scokane   h = h * 1000003 ^ character, the constant being a prime number.
107178848Scokane
108178848Scokane*/
109178848Scokane#ifdef XML_UNICODE
110178848Scokane#define CHAR_HASH(h, c) \
111178848Scokane  (((h) * 0xF4243) ^ (unsigned short)(c))
112178848Scokane#else
113178848Scokane#define CHAR_HASH(h, c) \
114178848Scokane  (((h) * 0xF4243) ^ (unsigned char)(c))
115178848Scokane#endif
116178848Scokane
117178848Scokane/* For probing (after a collision) we need a step size relative prime
118178848Scokane   to the hash table size, which is a power of 2. We use double-hashing,
119178848Scokane   since we can calculate a second hash value cheaply by taking those bits
120178848Scokane   of the first hash value that were discarded (masked out) when the table
121178848Scokane   index was calculated: index = hash & mask, where mask = table->size - 1.
122178848Scokane   We limit the maximum step size to table->size / 4 (mask >> 2) and make
123178848Scokane   it odd, since odd numbers are always relative prime to a power of 2.
124178848Scokane*/
125178848Scokane#define SECOND_HASH(hash, mask, power) \
126178848Scokane  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
127178848Scokane#define PROBE_STEP(hash, mask, power) \
128178848Scokane  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
129178848Scokane
130104349Sphktypedef struct {
131104349Sphk  NAMED **p;
132104349Sphk  NAMED **end;
133104349Sphk} HASH_TABLE_ITER;
134104349Sphk
135104349Sphk#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
136104349Sphk#define INIT_DATA_BUF_SIZE 1024
137104349Sphk#define INIT_ATTS_SIZE 16
138178848Scokane#define INIT_ATTS_VERSION 0xFFFFFFFF
139104349Sphk#define INIT_BLOCK_SIZE 1024
140104349Sphk#define INIT_BUFFER_SIZE 1024
141104349Sphk
142104349Sphk#define EXPAND_SPARE 24
143104349Sphk
144104349Sphktypedef struct binding {
145104349Sphk  struct prefix *prefix;
146104349Sphk  struct binding *nextTagBinding;
147104349Sphk  struct binding *prevPrefixBinding;
148104349Sphk  const struct attribute_id *attId;
149104349Sphk  XML_Char *uri;
150104349Sphk  int uriLen;
151104349Sphk  int uriAlloc;
152104349Sphk} BINDING;
153104349Sphk
154104349Sphktypedef struct prefix {
155104349Sphk  const XML_Char *name;
156104349Sphk  BINDING *binding;
157104349Sphk} PREFIX;
158104349Sphk
159104349Sphktypedef struct {
160104349Sphk  const XML_Char *str;
161104349Sphk  const XML_Char *localPart;
162104349Sphk  const XML_Char *prefix;
163104349Sphk  int strLen;
164104349Sphk  int uriLen;
165104349Sphk  int prefixLen;
166104349Sphk} TAG_NAME;
167104349Sphk
168104349Sphk/* TAG represents an open element.
169104349Sphk   The name of the element is stored in both the document and API
170104349Sphk   encodings.  The memory buffer 'buf' is a separately-allocated
171104349Sphk   memory area which stores the name.  During the XML_Parse()/
172104349Sphk   XMLParseBuffer() when the element is open, the memory for the 'raw'
173104349Sphk   version of the name (in the document encoding) is shared with the
174104349Sphk   document buffer.  If the element is open across calls to
175104349Sphk   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
176104349Sphk   contain the 'raw' name as well.
177104349Sphk
178104349Sphk   A parser re-uses these structures, maintaining a list of allocated
179104349Sphk   TAG objects in a free list.
180104349Sphk*/
181104349Sphktypedef struct tag {
182104349Sphk  struct tag *parent;           /* parent of this element */
183104349Sphk  const char *rawName;          /* tagName in the original encoding */
184104349Sphk  int rawNameLength;
185104349Sphk  TAG_NAME name;                /* tagName in the API encoding */
186104349Sphk  char *buf;                    /* buffer for name components */
187104349Sphk  char *bufEnd;                 /* end of the buffer */
188104349Sphk  BINDING *bindings;
189104349Sphk} TAG;
190104349Sphk
191104349Sphktypedef struct {
192104349Sphk  const XML_Char *name;
193104349Sphk  const XML_Char *textPtr;
194178848Scokane  int textLen;                  /* length in XML_Chars */
195178848Scokane  int processed;                /* # of processed bytes - when suspended */
196104349Sphk  const XML_Char *systemId;
197104349Sphk  const XML_Char *base;
198104349Sphk  const XML_Char *publicId;
199104349Sphk  const XML_Char *notation;
200104349Sphk  XML_Bool open;
201104349Sphk  XML_Bool is_param;
202104349Sphk  XML_Bool is_internal; /* true if declared in internal subset outside PE */
203104349Sphk} ENTITY;
204104349Sphk
205104349Sphktypedef struct {
206104349Sphk  enum XML_Content_Type         type;
207104349Sphk  enum XML_Content_Quant        quant;
208104349Sphk  const XML_Char *              name;
209104349Sphk  int                           firstchild;
210104349Sphk  int                           lastchild;
211104349Sphk  int                           childcnt;
212104349Sphk  int                           nextsib;
213104349Sphk} CONTENT_SCAFFOLD;
214104349Sphk
215104349Sphk#define INIT_SCAFFOLD_ELEMENTS 32
216104349Sphk
217104349Sphktypedef struct block {
218104349Sphk  struct block *next;
219104349Sphk  int size;
220104349Sphk  XML_Char s[1];
221104349Sphk} BLOCK;
222104349Sphk
223104349Sphktypedef struct {
224104349Sphk  BLOCK *blocks;
225104349Sphk  BLOCK *freeBlocks;
226104349Sphk  const XML_Char *end;
227104349Sphk  XML_Char *ptr;
228104349Sphk  XML_Char *start;
229178848Scokane  const XML_Memory_Handling_Suite *mem;
230104349Sphk} STRING_POOL;
231104349Sphk
232104349Sphk/* The XML_Char before the name is used to determine whether
233104349Sphk   an attribute has been specified. */
234104349Sphktypedef struct attribute_id {
235104349Sphk  XML_Char *name;
236104349Sphk  PREFIX *prefix;
237104349Sphk  XML_Bool maybeTokenized;
238104349Sphk  XML_Bool xmlns;
239104349Sphk} ATTRIBUTE_ID;
240104349Sphk
241104349Sphktypedef struct {
242104349Sphk  const ATTRIBUTE_ID *id;
243104349Sphk  XML_Bool isCdata;
244104349Sphk  const XML_Char *value;
245104349Sphk} DEFAULT_ATTRIBUTE;
246104349Sphk
247104349Sphktypedef struct {
248178848Scokane  unsigned long version;
249178848Scokane  unsigned long hash;
250178848Scokane  const XML_Char *uriName;
251178848Scokane} NS_ATT;
252178848Scokane
253178848Scokanetypedef struct {
254104349Sphk  const XML_Char *name;
255104349Sphk  PREFIX *prefix;
256104349Sphk  const ATTRIBUTE_ID *idAtt;
257104349Sphk  int nDefaultAtts;
258104349Sphk  int allocDefaultAtts;
259104349Sphk  DEFAULT_ATTRIBUTE *defaultAtts;
260104349Sphk} ELEMENT_TYPE;
261104349Sphk
262104349Sphktypedef struct {
263104349Sphk  HASH_TABLE generalEntities;
264104349Sphk  HASH_TABLE elementTypes;
265104349Sphk  HASH_TABLE attributeIds;
266104349Sphk  HASH_TABLE prefixes;
267104349Sphk  STRING_POOL pool;
268104349Sphk  STRING_POOL entityValuePool;
269104349Sphk  /* false once a parameter entity reference has been skipped */
270104349Sphk  XML_Bool keepProcessing;
271104349Sphk  /* true once an internal or external PE reference has been encountered;
272178848Scokane     this includes the reference to an external subset */
273104349Sphk  XML_Bool hasParamEntityRefs;
274104349Sphk  XML_Bool standalone;
275104349Sphk#ifdef XML_DTD
276104349Sphk  /* indicates if external PE has been read */
277104349Sphk  XML_Bool paramEntityRead;
278104349Sphk  HASH_TABLE paramEntities;
279104349Sphk#endif /* XML_DTD */
280104349Sphk  PREFIX defaultPrefix;
281104349Sphk  /* === scaffolding for building content model === */
282104349Sphk  XML_Bool in_eldecl;
283104349Sphk  CONTENT_SCAFFOLD *scaffold;
284104349Sphk  unsigned contentStringLen;
285104349Sphk  unsigned scaffSize;
286104349Sphk  unsigned scaffCount;
287104349Sphk  int scaffLevel;
288104349Sphk  int *scaffIndex;
289104349Sphk} DTD;
290104349Sphk
291104349Sphktypedef struct open_internal_entity {
292104349Sphk  const char *internalEventPtr;
293104349Sphk  const char *internalEventEndPtr;
294104349Sphk  struct open_internal_entity *next;
295104349Sphk  ENTITY *entity;
296178848Scokane  int startTagLevel;
297178848Scokane  XML_Bool betweenDecl; /* WFC: PE Between Declarations */
298104349Sphk} OPEN_INTERNAL_ENTITY;
299104349Sphk
300178848Scokanetypedef enum XML_Error PTRCALL Processor(XML_Parser parser,
301178848Scokane                                         const char *start,
302178848Scokane                                         const char *end,
303178848Scokane                                         const char **endPtr);
304104349Sphk
305104349Sphkstatic Processor prologProcessor;
306104349Sphkstatic Processor prologInitProcessor;
307104349Sphkstatic Processor contentProcessor;
308104349Sphkstatic Processor cdataSectionProcessor;
309104349Sphk#ifdef XML_DTD
310104349Sphkstatic Processor ignoreSectionProcessor;
311104349Sphkstatic Processor externalParEntProcessor;
312104349Sphkstatic Processor externalParEntInitProcessor;
313104349Sphkstatic Processor entityValueProcessor;
314104349Sphkstatic Processor entityValueInitProcessor;
315104349Sphk#endif /* XML_DTD */
316104349Sphkstatic Processor epilogProcessor;
317104349Sphkstatic Processor errorProcessor;
318104349Sphkstatic Processor externalEntityInitProcessor;
319104349Sphkstatic Processor externalEntityInitProcessor2;
320104349Sphkstatic Processor externalEntityInitProcessor3;
321104349Sphkstatic Processor externalEntityContentProcessor;
322178848Scokanestatic Processor internalEntityProcessor;
323104349Sphk
324178848Scokanestatic enum XML_Error
325104349SphkhandleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
326178848Scokanestatic enum XML_Error
327104349SphkprocessXmlDecl(XML_Parser parser, int isGeneralTextEntity,
328178848Scokane               const char *s, const char *next);
329178848Scokanestatic enum XML_Error
330104349SphkinitializeEncoding(XML_Parser parser);
331178848Scokanestatic enum XML_Error
332247513SdelphijdoProlog(XML_Parser parser, const ENCODING *enc, const char *s,
333247513Sdelphij         const char *end, int tok, const char *next, const char **nextPtr,
334178848Scokane         XML_Bool haveMore);
335178848Scokanestatic enum XML_Error
336247513SdelphijprocessInternalEntity(XML_Parser parser, ENTITY *entity,
337178848Scokane                      XML_Bool betweenDecl);
338178848Scokanestatic enum XML_Error
339104349SphkdoContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
340247513Sdelphij          const char *start, const char *end, const char **endPtr,
341178848Scokane          XML_Bool haveMore);
342178848Scokanestatic enum XML_Error
343104349SphkdoCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
344178848Scokane               const char *end, const char **nextPtr, XML_Bool haveMore);
345104349Sphk#ifdef XML_DTD
346178848Scokanestatic enum XML_Error
347104349SphkdoIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
348178848Scokane                const char *end, const char **nextPtr, XML_Bool haveMore);
349104349Sphk#endif /* XML_DTD */
350178848Scokane
351178848Scokanestatic enum XML_Error
352178848ScokanestoreAtts(XML_Parser parser, const ENCODING *, const char *s,
353178848Scokane          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
354178848Scokanestatic enum XML_Error
355104349SphkaddBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
356104349Sphk           const XML_Char *uri, BINDING **bindingsPtr);
357178848Scokanestatic int
358247513SdelphijdefineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
359178848Scokane                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
360178848Scokanestatic enum XML_Error
361104349SphkstoreAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
362104349Sphk                    const char *, const char *, STRING_POOL *);
363178848Scokanestatic enum XML_Error
364104349SphkappendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
365104349Sphk                     const char *, const char *, STRING_POOL *);
366178848Scokanestatic ATTRIBUTE_ID *
367104349SphkgetAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
368104349Sphk               const char *end);
369178848Scokanestatic int
370104349SphksetElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
371178848Scokanestatic enum XML_Error
372104349SphkstoreEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
373104349Sphk                 const char *end);
374178848Scokanestatic int
375104349SphkreportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
376104349Sphk                            const char *start, const char *end);
377178848Scokanestatic int
378104349SphkreportComment(XML_Parser parser, const ENCODING *enc, const char *start,
379104349Sphk              const char *end);
380178848Scokanestatic void
381104349SphkreportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
382104349Sphk              const char *end);
383104349Sphk
384178848Scokanestatic const XML_Char * getContext(XML_Parser parser);
385178848Scokanestatic XML_Bool
386104349SphksetContext(XML_Parser parser, const XML_Char *context);
387178848Scokane
388104349Sphkstatic void FASTCALL normalizePublicId(XML_Char *s);
389104349Sphk
390178848Scokanestatic DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
391104349Sphk/* do not call if parentParser != NULL */
392178848Scokanestatic void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
393178848Scokanestatic void
394178848ScokanedtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
395178848Scokanestatic int
396247513SdelphijdtdCopy(XML_Parser oldParser,
397247513Sdelphij        DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
398178848Scokanestatic int
399247513SdelphijcopyEntityTable(XML_Parser oldParser,
400247513Sdelphij                HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
401178848Scokanestatic NAMED *
402247513Sdelphijlookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
403104349Sphkstatic void FASTCALL
404178848ScokanehashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
405104349Sphkstatic void FASTCALL hashTableClear(HASH_TABLE *);
406104349Sphkstatic void FASTCALL hashTableDestroy(HASH_TABLE *);
407178848Scokanestatic void FASTCALL
408178848ScokanehashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
409104349Sphkstatic NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
410178848Scokane
411178848Scokanestatic void FASTCALL
412178848ScokanepoolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
413104349Sphkstatic void FASTCALL poolClear(STRING_POOL *);
414104349Sphkstatic void FASTCALL poolDestroy(STRING_POOL *);
415178848Scokanestatic XML_Char *
416104349SphkpoolAppend(STRING_POOL *pool, const ENCODING *enc,
417104349Sphk           const char *ptr, const char *end);
418178848Scokanestatic XML_Char *
419104349SphkpoolStoreString(STRING_POOL *pool, const ENCODING *enc,
420104349Sphk                const char *ptr, const char *end);
421104349Sphkstatic XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
422104349Sphkstatic const XML_Char * FASTCALL
423104349SphkpoolCopyString(STRING_POOL *pool, const XML_Char *s);
424178848Scokanestatic const XML_Char *
425104349SphkpoolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
426104349Sphkstatic const XML_Char * FASTCALL
427104349SphkpoolAppendString(STRING_POOL *pool, const XML_Char *s);
428178848Scokane
429178848Scokanestatic int FASTCALL nextScaffoldPart(XML_Parser parser);
430178848Scokanestatic XML_Content * build_model(XML_Parser parser);
431178848Scokanestatic ELEMENT_TYPE *
432178848ScokanegetElementType(XML_Parser parser, const ENCODING *enc,
433104349Sphk               const char *ptr, const char *end);
434104349Sphk
435247513Sdelphijstatic unsigned long generate_hash_secret_salt(void);
436247513Sdelphijstatic XML_Bool startParsing(XML_Parser parser);
437247513Sdelphij
438178848Scokanestatic XML_Parser
439178848ScokaneparserCreate(const XML_Char *encodingName,
440178848Scokane             const XML_Memory_Handling_Suite *memsuite,
441178848Scokane             const XML_Char *nameSep,
442178848Scokane             DTD *dtd);
443247513Sdelphij
444178848Scokanestatic void
445104349SphkparserInit(XML_Parser parser, const XML_Char *encodingName);
446104349Sphk
447104349Sphk#define poolStart(pool) ((pool)->start)
448104349Sphk#define poolEnd(pool) ((pool)->ptr)
449104349Sphk#define poolLength(pool) ((pool)->ptr - (pool)->start)
450104349Sphk#define poolChop(pool) ((void)--(pool->ptr))
451104349Sphk#define poolLastChar(pool) (((pool)->ptr)[-1])
452104349Sphk#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
453104349Sphk#define poolFinish(pool) ((pool)->start = (pool)->ptr)
454104349Sphk#define poolAppendChar(pool, c) \
455104349Sphk  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
456104349Sphk   ? 0 \
457104349Sphk   : ((*((pool)->ptr)++ = c), 1))
458104349Sphk
459104349Sphkstruct XML_ParserStruct {
460104349Sphk  /* The first member must be userData so that the XML_GetUserData
461104349Sphk     macro works. */
462104349Sphk  void *m_userData;
463104349Sphk  void *m_handlerArg;
464104349Sphk  char *m_buffer;
465178848Scokane  const XML_Memory_Handling_Suite m_mem;
466104349Sphk  /* first character to be parsed */
467104349Sphk  const char *m_bufferPtr;
468104349Sphk  /* past last character to be parsed */
469104349Sphk  char *m_bufferEnd;
470104349Sphk  /* allocated end of buffer */
471104349Sphk  const char *m_bufferLim;
472178848Scokane  XML_Index m_parseEndByteIndex;
473104349Sphk  const char *m_parseEndPtr;
474104349Sphk  XML_Char *m_dataBuf;
475104349Sphk  XML_Char *m_dataBufEnd;
476104349Sphk  XML_StartElementHandler m_startElementHandler;
477104349Sphk  XML_EndElementHandler m_endElementHandler;
478104349Sphk  XML_CharacterDataHandler m_characterDataHandler;
479104349Sphk  XML_ProcessingInstructionHandler m_processingInstructionHandler;
480104349Sphk  XML_CommentHandler m_commentHandler;
481104349Sphk  XML_StartCdataSectionHandler m_startCdataSectionHandler;
482104349Sphk  XML_EndCdataSectionHandler m_endCdataSectionHandler;
483104349Sphk  XML_DefaultHandler m_defaultHandler;
484104349Sphk  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
485104349Sphk  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
486104349Sphk  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
487104349Sphk  XML_NotationDeclHandler m_notationDeclHandler;
488104349Sphk  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
489104349Sphk  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
490104349Sphk  XML_NotStandaloneHandler m_notStandaloneHandler;
491104349Sphk  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
492178848Scokane  XML_Parser m_externalEntityRefHandlerArg;
493104349Sphk  XML_SkippedEntityHandler m_skippedEntityHandler;
494104349Sphk  XML_UnknownEncodingHandler m_unknownEncodingHandler;
495104349Sphk  XML_ElementDeclHandler m_elementDeclHandler;
496104349Sphk  XML_AttlistDeclHandler m_attlistDeclHandler;
497104349Sphk  XML_EntityDeclHandler m_entityDeclHandler;
498104349Sphk  XML_XmlDeclHandler m_xmlDeclHandler;
499104349Sphk  const ENCODING *m_encoding;
500104349Sphk  INIT_ENCODING m_initEncoding;
501104349Sphk  const ENCODING *m_internalEncoding;
502104349Sphk  const XML_Char *m_protocolEncodingName;
503104349Sphk  XML_Bool m_ns;
504104349Sphk  XML_Bool m_ns_triplets;
505104349Sphk  void *m_unknownEncodingMem;
506104349Sphk  void *m_unknownEncodingData;
507104349Sphk  void *m_unknownEncodingHandlerData;
508178848Scokane  void (XMLCALL *m_unknownEncodingRelease)(void *);
509104349Sphk  PROLOG_STATE m_prologState;
510104349Sphk  Processor *m_processor;
511104349Sphk  enum XML_Error m_errorCode;
512104349Sphk  const char *m_eventPtr;
513104349Sphk  const char *m_eventEndPtr;
514104349Sphk  const char *m_positionPtr;
515104349Sphk  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
516178848Scokane  OPEN_INTERNAL_ENTITY *m_freeInternalEntities;
517104349Sphk  XML_Bool m_defaultExpandInternalEntities;
518104349Sphk  int m_tagLevel;
519104349Sphk  ENTITY *m_declEntity;
520104349Sphk  const XML_Char *m_doctypeName;
521104349Sphk  const XML_Char *m_doctypeSysid;
522104349Sphk  const XML_Char *m_doctypePubid;
523104349Sphk  const XML_Char *m_declAttributeType;
524104349Sphk  const XML_Char *m_declNotationName;
525104349Sphk  const XML_Char *m_declNotationPublicId;
526104349Sphk  ELEMENT_TYPE *m_declElementType;
527104349Sphk  ATTRIBUTE_ID *m_declAttributeId;
528104349Sphk  XML_Bool m_declAttributeIsCdata;
529104349Sphk  XML_Bool m_declAttributeIsId;
530178848Scokane  DTD *m_dtd;
531104349Sphk  const XML_Char *m_curBase;
532104349Sphk  TAG *m_tagStack;
533104349Sphk  TAG *m_freeTagList;
534104349Sphk  BINDING *m_inheritedBindings;
535104349Sphk  BINDING *m_freeBindingList;
536104349Sphk  int m_attsSize;
537104349Sphk  int m_nSpecifiedAtts;
538104349Sphk  int m_idAttIndex;
539104349Sphk  ATTRIBUTE *m_atts;
540178848Scokane  NS_ATT *m_nsAtts;
541178848Scokane  unsigned long m_nsAttsVersion;
542178848Scokane  unsigned char m_nsAttsPower;
543247513Sdelphij#ifdef XML_ATTR_INFO
544247513Sdelphij  XML_AttrInfo *m_attInfo;
545247513Sdelphij#endif
546104349Sphk  POSITION m_position;
547104349Sphk  STRING_POOL m_tempPool;
548104349Sphk  STRING_POOL m_temp2Pool;
549104349Sphk  char *m_groupConnector;
550178848Scokane  unsigned int m_groupSize;
551104349Sphk  XML_Char m_namespaceSeparator;
552104349Sphk  XML_Parser m_parentParser;
553178848Scokane  XML_ParsingStatus m_parsingStatus;
554104349Sphk#ifdef XML_DTD
555104349Sphk  XML_Bool m_isParamEntity;
556104349Sphk  XML_Bool m_useForeignDTD;
557104349Sphk  enum XML_ParamEntityParsing m_paramEntityParsing;
558104349Sphk#endif
559247513Sdelphij  unsigned long m_hash_secret_salt;
560104349Sphk};
561104349Sphk
562178848Scokane#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
563178848Scokane#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
564178848Scokane#define FREE(p) (parser->m_mem.free_fcn((p)))
565104349Sphk
566104349Sphk#define userData (parser->m_userData)
567104349Sphk#define handlerArg (parser->m_handlerArg)
568104349Sphk#define startElementHandler (parser->m_startElementHandler)
569104349Sphk#define endElementHandler (parser->m_endElementHandler)
570104349Sphk#define characterDataHandler (parser->m_characterDataHandler)
571104349Sphk#define processingInstructionHandler \
572104349Sphk        (parser->m_processingInstructionHandler)
573104349Sphk#define commentHandler (parser->m_commentHandler)
574104349Sphk#define startCdataSectionHandler \
575104349Sphk        (parser->m_startCdataSectionHandler)
576104349Sphk#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
577104349Sphk#define defaultHandler (parser->m_defaultHandler)
578104349Sphk#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
579104349Sphk#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
580104349Sphk#define unparsedEntityDeclHandler \
581104349Sphk        (parser->m_unparsedEntityDeclHandler)
582104349Sphk#define notationDeclHandler (parser->m_notationDeclHandler)
583104349Sphk#define startNamespaceDeclHandler \
584104349Sphk        (parser->m_startNamespaceDeclHandler)
585104349Sphk#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
586104349Sphk#define notStandaloneHandler (parser->m_notStandaloneHandler)
587104349Sphk#define externalEntityRefHandler \
588104349Sphk        (parser->m_externalEntityRefHandler)
589104349Sphk#define externalEntityRefHandlerArg \
590104349Sphk        (parser->m_externalEntityRefHandlerArg)
591104349Sphk#define internalEntityRefHandler \
592104349Sphk        (parser->m_internalEntityRefHandler)
593104349Sphk#define skippedEntityHandler (parser->m_skippedEntityHandler)
594104349Sphk#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
595104349Sphk#define elementDeclHandler (parser->m_elementDeclHandler)
596104349Sphk#define attlistDeclHandler (parser->m_attlistDeclHandler)
597104349Sphk#define entityDeclHandler (parser->m_entityDeclHandler)
598104349Sphk#define xmlDeclHandler (parser->m_xmlDeclHandler)
599104349Sphk#define encoding (parser->m_encoding)
600104349Sphk#define initEncoding (parser->m_initEncoding)
601104349Sphk#define internalEncoding (parser->m_internalEncoding)
602104349Sphk#define unknownEncodingMem (parser->m_unknownEncodingMem)
603104349Sphk#define unknownEncodingData (parser->m_unknownEncodingData)
604104349Sphk#define unknownEncodingHandlerData \
605104349Sphk  (parser->m_unknownEncodingHandlerData)
606104349Sphk#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
607104349Sphk#define protocolEncodingName (parser->m_protocolEncodingName)
608104349Sphk#define ns (parser->m_ns)
609104349Sphk#define ns_triplets (parser->m_ns_triplets)
610104349Sphk#define prologState (parser->m_prologState)
611104349Sphk#define processor (parser->m_processor)
612104349Sphk#define errorCode (parser->m_errorCode)
613104349Sphk#define eventPtr (parser->m_eventPtr)
614104349Sphk#define eventEndPtr (parser->m_eventEndPtr)
615104349Sphk#define positionPtr (parser->m_positionPtr)
616104349Sphk#define position (parser->m_position)
617104349Sphk#define openInternalEntities (parser->m_openInternalEntities)
618178848Scokane#define freeInternalEntities (parser->m_freeInternalEntities)
619104349Sphk#define defaultExpandInternalEntities \
620104349Sphk        (parser->m_defaultExpandInternalEntities)
621104349Sphk#define tagLevel (parser->m_tagLevel)
622104349Sphk#define buffer (parser->m_buffer)
623104349Sphk#define bufferPtr (parser->m_bufferPtr)
624104349Sphk#define bufferEnd (parser->m_bufferEnd)
625104349Sphk#define parseEndByteIndex (parser->m_parseEndByteIndex)
626104349Sphk#define parseEndPtr (parser->m_parseEndPtr)
627104349Sphk#define bufferLim (parser->m_bufferLim)
628104349Sphk#define dataBuf (parser->m_dataBuf)
629104349Sphk#define dataBufEnd (parser->m_dataBufEnd)
630178848Scokane#define _dtd (parser->m_dtd)
631104349Sphk#define curBase (parser->m_curBase)
632104349Sphk#define declEntity (parser->m_declEntity)
633104349Sphk#define doctypeName (parser->m_doctypeName)
634104349Sphk#define doctypeSysid (parser->m_doctypeSysid)
635104349Sphk#define doctypePubid (parser->m_doctypePubid)
636104349Sphk#define declAttributeType (parser->m_declAttributeType)
637104349Sphk#define declNotationName (parser->m_declNotationName)
638104349Sphk#define declNotationPublicId (parser->m_declNotationPublicId)
639104349Sphk#define declElementType (parser->m_declElementType)
640104349Sphk#define declAttributeId (parser->m_declAttributeId)
641104349Sphk#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
642104349Sphk#define declAttributeIsId (parser->m_declAttributeIsId)
643104349Sphk#define freeTagList (parser->m_freeTagList)
644104349Sphk#define freeBindingList (parser->m_freeBindingList)
645104349Sphk#define inheritedBindings (parser->m_inheritedBindings)
646104349Sphk#define tagStack (parser->m_tagStack)
647104349Sphk#define atts (parser->m_atts)
648104349Sphk#define attsSize (parser->m_attsSize)
649104349Sphk#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
650104349Sphk#define idAttIndex (parser->m_idAttIndex)
651178848Scokane#define nsAtts (parser->m_nsAtts)
652178848Scokane#define nsAttsVersion (parser->m_nsAttsVersion)
653178848Scokane#define nsAttsPower (parser->m_nsAttsPower)
654247513Sdelphij#define attInfo (parser->m_attInfo)
655104349Sphk#define tempPool (parser->m_tempPool)
656104349Sphk#define temp2Pool (parser->m_temp2Pool)
657104349Sphk#define groupConnector (parser->m_groupConnector)
658104349Sphk#define groupSize (parser->m_groupSize)
659104349Sphk#define namespaceSeparator (parser->m_namespaceSeparator)
660104349Sphk#define parentParser (parser->m_parentParser)
661178848Scokane#define ps_parsing (parser->m_parsingStatus.parsing)
662178848Scokane#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
663104349Sphk#ifdef XML_DTD
664104349Sphk#define isParamEntity (parser->m_isParamEntity)
665104349Sphk#define useForeignDTD (parser->m_useForeignDTD)
666104349Sphk#define paramEntityParsing (parser->m_paramEntityParsing)
667104349Sphk#endif /* XML_DTD */
668247513Sdelphij#define hash_secret_salt (parser->m_hash_secret_salt)
669104349Sphk
670178848ScokaneXML_Parser XMLCALL
671104349SphkXML_ParserCreate(const XML_Char *encodingName)
672104349Sphk{
673104349Sphk  return XML_ParserCreate_MM(encodingName, NULL, NULL);
674104349Sphk}
675104349Sphk
676178848ScokaneXML_Parser XMLCALL
677104349SphkXML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
678104349Sphk{
679104349Sphk  XML_Char tmp[2];
680104349Sphk  *tmp = nsSep;
681104349Sphk  return XML_ParserCreate_MM(encodingName, NULL, tmp);
682104349Sphk}
683104349Sphk
684178848Scokanestatic const XML_Char implicitContext[] = {
685178848Scokane  ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
686247513Sdelphij  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
687178848Scokane  ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
688178848Scokane  ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
689178848Scokane  ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
690178848Scokane  ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
691178848Scokane};
692178848Scokane
693247513Sdelphijstatic unsigned long
694247513Sdelphijgenerate_hash_secret_salt(void)
695247513Sdelphij{
696247513Sdelphij  unsigned int seed = time(NULL) % UINT_MAX;
697247513Sdelphij  srand(seed);
698247513Sdelphij  return rand();
699247513Sdelphij}
700247513Sdelphij
701247513Sdelphijstatic XML_Bool  /* only valid for root parser */
702247513SdelphijstartParsing(XML_Parser parser)
703247513Sdelphij{
704247513Sdelphij    /* hash functions must be initialized before setContext() is called */
705247513Sdelphij    if (hash_secret_salt == 0)
706247513Sdelphij      hash_secret_salt = generate_hash_secret_salt();
707247513Sdelphij    if (ns) {
708247513Sdelphij      /* implicit context only set for root parser, since child
709247513Sdelphij         parsers (i.e. external entity parsers) will inherit it
710247513Sdelphij      */
711247513Sdelphij      return setContext(parser, implicitContext);
712247513Sdelphij    }
713247513Sdelphij    return XML_TRUE;
714247513Sdelphij}
715247513Sdelphij
716178848ScokaneXML_Parser XMLCALL
717104349SphkXML_ParserCreate_MM(const XML_Char *encodingName,
718104349Sphk                    const XML_Memory_Handling_Suite *memsuite,
719178848Scokane                    const XML_Char *nameSep)
720178848Scokane{
721247513Sdelphij  return parserCreate(encodingName, memsuite, nameSep, NULL);
722178848Scokane}
723178848Scokane
724178848Scokanestatic XML_Parser
725178848ScokaneparserCreate(const XML_Char *encodingName,
726178848Scokane             const XML_Memory_Handling_Suite *memsuite,
727178848Scokane             const XML_Char *nameSep,
728178848Scokane             DTD *dtd)
729178848Scokane{
730104349Sphk  XML_Parser parser;
731104349Sphk
732104349Sphk  if (memsuite) {
733104349Sphk    XML_Memory_Handling_Suite *mtemp;
734178848Scokane    parser = (XML_Parser)
735178848Scokane      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
736104349Sphk    if (parser != NULL) {
737178848Scokane      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
738104349Sphk      mtemp->malloc_fcn = memsuite->malloc_fcn;
739104349Sphk      mtemp->realloc_fcn = memsuite->realloc_fcn;
740104349Sphk      mtemp->free_fcn = memsuite->free_fcn;
741104349Sphk    }
742104349Sphk  }
743104349Sphk  else {
744104349Sphk    XML_Memory_Handling_Suite *mtemp;
745178848Scokane    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
746104349Sphk    if (parser != NULL) {
747178848Scokane      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
748104349Sphk      mtemp->malloc_fcn = malloc;
749104349Sphk      mtemp->realloc_fcn = realloc;
750104349Sphk      mtemp->free_fcn = free;
751104349Sphk    }
752104349Sphk  }
753104349Sphk
754104349Sphk  if (!parser)
755104349Sphk    return parser;
756104349Sphk
757104349Sphk  buffer = NULL;
758104349Sphk  bufferLim = NULL;
759104349Sphk
760104349Sphk  attsSize = INIT_ATTS_SIZE;
761178848Scokane  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
762104349Sphk  if (atts == NULL) {
763104349Sphk    FREE(parser);
764104349Sphk    return NULL;
765104349Sphk  }
766247513Sdelphij#ifdef XML_ATTR_INFO
767247513Sdelphij  attInfo = (XML_AttrInfo*)MALLOC(attsSize * sizeof(XML_AttrInfo));
768247513Sdelphij  if (attInfo == NULL) {
769247513Sdelphij    FREE(atts);
770247513Sdelphij    FREE(parser);
771247513Sdelphij    return NULL;
772247513Sdelphij  }
773247513Sdelphij#endif
774178848Scokane  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
775104349Sphk  if (dataBuf == NULL) {
776104349Sphk    FREE(atts);
777247513Sdelphij#ifdef XML_ATTR_INFO
778247513Sdelphij    FREE(attInfo);
779247513Sdelphij#endif
780104349Sphk    FREE(parser);
781104349Sphk    return NULL;
782104349Sphk  }
783104349Sphk  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
784104349Sphk
785178848Scokane  if (dtd)
786178848Scokane    _dtd = dtd;
787178848Scokane  else {
788178848Scokane    _dtd = dtdCreate(&parser->m_mem);
789178848Scokane    if (_dtd == NULL) {
790178848Scokane      FREE(dataBuf);
791178848Scokane      FREE(atts);
792247513Sdelphij#ifdef XML_ATTR_INFO
793247513Sdelphij      FREE(attInfo);
794247513Sdelphij#endif
795178848Scokane      FREE(parser);
796178848Scokane      return NULL;
797178848Scokane    }
798178848Scokane  }
799178848Scokane
800104349Sphk  freeBindingList = NULL;
801104349Sphk  freeTagList = NULL;
802178848Scokane  freeInternalEntities = NULL;
803104349Sphk
804104349Sphk  groupSize = 0;
805104349Sphk  groupConnector = NULL;
806104349Sphk
807104349Sphk  unknownEncodingHandler = NULL;
808104349Sphk  unknownEncodingHandlerData = NULL;
809104349Sphk
810178848Scokane  namespaceSeparator = ASCII_EXCL;
811104349Sphk  ns = XML_FALSE;
812104349Sphk  ns_triplets = XML_FALSE;
813104349Sphk
814178848Scokane  nsAtts = NULL;
815178848Scokane  nsAttsVersion = 0;
816178848Scokane  nsAttsPower = 0;
817178848Scokane
818104349Sphk  poolInit(&tempPool, &(parser->m_mem));
819104349Sphk  poolInit(&temp2Pool, &(parser->m_mem));
820104349Sphk  parserInit(parser, encodingName);
821104349Sphk
822178848Scokane  if (encodingName && !protocolEncodingName) {
823104349Sphk    XML_ParserFree(parser);
824104349Sphk    return NULL;
825104349Sphk  }
826104349Sphk
827104349Sphk  if (nameSep) {
828104349Sphk    ns = XML_TRUE;
829104349Sphk    internalEncoding = XmlGetInternalEncodingNS();
830104349Sphk    namespaceSeparator = *nameSep;
831104349Sphk  }
832104349Sphk  else {
833104349Sphk    internalEncoding = XmlGetInternalEncoding();
834104349Sphk  }
835104349Sphk
836104349Sphk  return parser;
837104349Sphk}
838104349Sphk
839178848Scokanestatic void
840104349SphkparserInit(XML_Parser parser, const XML_Char *encodingName)
841104349Sphk{
842104349Sphk  processor = prologInitProcessor;
843104349Sphk  XmlPrologStateInit(&prologState);
844104349Sphk  protocolEncodingName = (encodingName != NULL
845104349Sphk                          ? poolCopyString(&tempPool, encodingName)
846104349Sphk                          : NULL);
847104349Sphk  curBase = NULL;
848104349Sphk  XmlInitEncoding(&initEncoding, &encoding, 0);
849104349Sphk  userData = NULL;
850104349Sphk  handlerArg = NULL;
851104349Sphk  startElementHandler = NULL;
852104349Sphk  endElementHandler = NULL;
853104349Sphk  characterDataHandler = NULL;
854104349Sphk  processingInstructionHandler = NULL;
855104349Sphk  commentHandler = NULL;
856104349Sphk  startCdataSectionHandler = NULL;
857104349Sphk  endCdataSectionHandler = NULL;
858104349Sphk  defaultHandler = NULL;
859104349Sphk  startDoctypeDeclHandler = NULL;
860104349Sphk  endDoctypeDeclHandler = NULL;
861104349Sphk  unparsedEntityDeclHandler = NULL;
862104349Sphk  notationDeclHandler = NULL;
863104349Sphk  startNamespaceDeclHandler = NULL;
864104349Sphk  endNamespaceDeclHandler = NULL;
865104349Sphk  notStandaloneHandler = NULL;
866104349Sphk  externalEntityRefHandler = NULL;
867104349Sphk  externalEntityRefHandlerArg = parser;
868104349Sphk  skippedEntityHandler = NULL;
869104349Sphk  elementDeclHandler = NULL;
870104349Sphk  attlistDeclHandler = NULL;
871104349Sphk  entityDeclHandler = NULL;
872104349Sphk  xmlDeclHandler = NULL;
873104349Sphk  bufferPtr = buffer;
874104349Sphk  bufferEnd = buffer;
875104349Sphk  parseEndByteIndex = 0;
876104349Sphk  parseEndPtr = NULL;
877104349Sphk  declElementType = NULL;
878104349Sphk  declAttributeId = NULL;
879104349Sphk  declEntity = NULL;
880104349Sphk  doctypeName = NULL;
881104349Sphk  doctypeSysid = NULL;
882104349Sphk  doctypePubid = NULL;
883104349Sphk  declAttributeType = NULL;
884104349Sphk  declNotationName = NULL;
885104349Sphk  declNotationPublicId = NULL;
886104349Sphk  declAttributeIsCdata = XML_FALSE;
887104349Sphk  declAttributeIsId = XML_FALSE;
888104349Sphk  memset(&position, 0, sizeof(POSITION));
889104349Sphk  errorCode = XML_ERROR_NONE;
890104349Sphk  eventPtr = NULL;
891104349Sphk  eventEndPtr = NULL;
892104349Sphk  positionPtr = NULL;
893178848Scokane  openInternalEntities = NULL;
894104349Sphk  defaultExpandInternalEntities = XML_TRUE;
895104349Sphk  tagLevel = 0;
896104349Sphk  tagStack = NULL;
897104349Sphk  inheritedBindings = NULL;
898104349Sphk  nSpecifiedAtts = 0;
899104349Sphk  unknownEncodingMem = NULL;
900104349Sphk  unknownEncodingRelease = NULL;
901104349Sphk  unknownEncodingData = NULL;
902104349Sphk  parentParser = NULL;
903178848Scokane  ps_parsing = XML_INITIALIZED;
904104349Sphk#ifdef XML_DTD
905104349Sphk  isParamEntity = XML_FALSE;
906104349Sphk  useForeignDTD = XML_FALSE;
907104349Sphk  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
908104349Sphk#endif
909247513Sdelphij  hash_secret_salt = 0;
910104349Sphk}
911104349Sphk
912104349Sphk/* moves list of bindings to freeBindingList */
913104349Sphkstatic void FASTCALL
914104349SphkmoveToFreeBindingList(XML_Parser parser, BINDING *bindings)
915104349Sphk{
916104349Sphk  while (bindings) {
917104349Sphk    BINDING *b = bindings;
918104349Sphk    bindings = bindings->nextTagBinding;
919104349Sphk    b->nextTagBinding = freeBindingList;
920104349Sphk    freeBindingList = b;
921104349Sphk  }
922104349Sphk}
923104349Sphk
924178848ScokaneXML_Bool XMLCALL
925104349SphkXML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
926104349Sphk{
927104349Sphk  TAG *tStk;
928178848Scokane  OPEN_INTERNAL_ENTITY *openEntityList;
929178848Scokane  if (parentParser)
930104349Sphk    return XML_FALSE;
931104349Sphk  /* move tagStack to freeTagList */
932104349Sphk  tStk = tagStack;
933104349Sphk  while (tStk) {
934104349Sphk    TAG *tag = tStk;
935104349Sphk    tStk = tStk->parent;
936104349Sphk    tag->parent = freeTagList;
937104349Sphk    moveToFreeBindingList(parser, tag->bindings);
938104349Sphk    tag->bindings = NULL;
939104349Sphk    freeTagList = tag;
940104349Sphk  }
941178848Scokane  /* move openInternalEntities to freeInternalEntities */
942178848Scokane  openEntityList = openInternalEntities;
943178848Scokane  while (openEntityList) {
944178848Scokane    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
945178848Scokane    openEntityList = openEntity->next;
946178848Scokane    openEntity->next = freeInternalEntities;
947178848Scokane    freeInternalEntities = openEntity;
948178848Scokane  }
949104349Sphk  moveToFreeBindingList(parser, inheritedBindings);
950178848Scokane  FREE(unknownEncodingMem);
951104349Sphk  if (unknownEncodingRelease)
952104349Sphk    unknownEncodingRelease(unknownEncodingData);
953104349Sphk  poolClear(&tempPool);
954104349Sphk  poolClear(&temp2Pool);
955104349Sphk  parserInit(parser, encodingName);
956178848Scokane  dtdReset(_dtd, &parser->m_mem);
957247513Sdelphij  return XML_TRUE;
958104349Sphk}
959104349Sphk
960178848Scokaneenum XML_Status XMLCALL
961104349SphkXML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
962104349Sphk{
963178848Scokane  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
964178848Scokane     XXX There's no way for the caller to determine which of the
965178848Scokane     XXX possible error cases caused the XML_STATUS_ERROR return.
966178848Scokane  */
967178848Scokane  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
968178848Scokane    return XML_STATUS_ERROR;
969104349Sphk  if (encodingName == NULL)
970104349Sphk    protocolEncodingName = NULL;
971104349Sphk  else {
972104349Sphk    protocolEncodingName = poolCopyString(&tempPool, encodingName);
973104349Sphk    if (!protocolEncodingName)
974178848Scokane      return XML_STATUS_ERROR;
975104349Sphk  }
976178848Scokane  return XML_STATUS_OK;
977104349Sphk}
978104349Sphk
979178848ScokaneXML_Parser XMLCALL
980104349SphkXML_ExternalEntityParserCreate(XML_Parser oldParser,
981104349Sphk                               const XML_Char *context,
982104349Sphk                               const XML_Char *encodingName)
983104349Sphk{
984104349Sphk  XML_Parser parser = oldParser;
985178848Scokane  DTD *newDtd = NULL;
986178848Scokane  DTD *oldDtd = _dtd;
987104349Sphk  XML_StartElementHandler oldStartElementHandler = startElementHandler;
988104349Sphk  XML_EndElementHandler oldEndElementHandler = endElementHandler;
989104349Sphk  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
990104349Sphk  XML_ProcessingInstructionHandler oldProcessingInstructionHandler
991104349Sphk      = processingInstructionHandler;
992104349Sphk  XML_CommentHandler oldCommentHandler = commentHandler;
993104349Sphk  XML_StartCdataSectionHandler oldStartCdataSectionHandler
994104349Sphk      = startCdataSectionHandler;
995104349Sphk  XML_EndCdataSectionHandler oldEndCdataSectionHandler
996104349Sphk      = endCdataSectionHandler;
997104349Sphk  XML_DefaultHandler oldDefaultHandler = defaultHandler;
998104349Sphk  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
999104349Sphk      = unparsedEntityDeclHandler;
1000104349Sphk  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
1001104349Sphk  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
1002104349Sphk      = startNamespaceDeclHandler;
1003104349Sphk  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
1004104349Sphk      = endNamespaceDeclHandler;
1005104349Sphk  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
1006104349Sphk  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
1007104349Sphk      = externalEntityRefHandler;
1008104349Sphk  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
1009104349Sphk  XML_UnknownEncodingHandler oldUnknownEncodingHandler
1010104349Sphk      = unknownEncodingHandler;
1011104349Sphk  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
1012104349Sphk  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
1013104349Sphk  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
1014104349Sphk  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
1015104349Sphk  ELEMENT_TYPE * oldDeclElementType = declElementType;
1016104349Sphk
1017104349Sphk  void *oldUserData = userData;
1018104349Sphk  void *oldHandlerArg = handlerArg;
1019104349Sphk  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
1020178848Scokane  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
1021104349Sphk#ifdef XML_DTD
1022178848Scokane  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
1023104349Sphk  int oldInEntityValue = prologState.inEntityValue;
1024104349Sphk#endif
1025104349Sphk  XML_Bool oldns_triplets = ns_triplets;
1026247513Sdelphij  /* Note that the new parser shares the same hash secret as the old
1027247513Sdelphij     parser, so that dtdCopy and copyEntityTable can lookup values
1028247513Sdelphij     from hash tables associated with either parser without us having
1029247513Sdelphij     to worry which hash secrets each table has.
1030247513Sdelphij  */
1031247513Sdelphij  unsigned long oldhash_secret_salt = hash_secret_salt;
1032104349Sphk
1033178848Scokane#ifdef XML_DTD
1034178848Scokane  if (!context)
1035178848Scokane    newDtd = oldDtd;
1036178848Scokane#endif /* XML_DTD */
1037178848Scokane
1038104349Sphk  /* Note that the magical uses of the pre-processor to make field
1039104349Sphk     access look more like C++ require that `parser' be overwritten
1040104349Sphk     here.  This makes this function more painful to follow than it
1041104349Sphk     would be otherwise.
1042104349Sphk  */
1043104349Sphk  if (ns) {
1044104349Sphk    XML_Char tmp[2];
1045104349Sphk    *tmp = namespaceSeparator;
1046178848Scokane    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
1047104349Sphk  }
1048104349Sphk  else {
1049178848Scokane    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
1050104349Sphk  }
1051104349Sphk
1052104349Sphk  if (!parser)
1053104349Sphk    return NULL;
1054104349Sphk
1055104349Sphk  startElementHandler = oldStartElementHandler;
1056104349Sphk  endElementHandler = oldEndElementHandler;
1057104349Sphk  characterDataHandler = oldCharacterDataHandler;
1058104349Sphk  processingInstructionHandler = oldProcessingInstructionHandler;
1059104349Sphk  commentHandler = oldCommentHandler;
1060104349Sphk  startCdataSectionHandler = oldStartCdataSectionHandler;
1061104349Sphk  endCdataSectionHandler = oldEndCdataSectionHandler;
1062104349Sphk  defaultHandler = oldDefaultHandler;
1063104349Sphk  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1064104349Sphk  notationDeclHandler = oldNotationDeclHandler;
1065104349Sphk  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1066104349Sphk  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1067104349Sphk  notStandaloneHandler = oldNotStandaloneHandler;
1068104349Sphk  externalEntityRefHandler = oldExternalEntityRefHandler;
1069104349Sphk  skippedEntityHandler = oldSkippedEntityHandler;
1070104349Sphk  unknownEncodingHandler = oldUnknownEncodingHandler;
1071104349Sphk  elementDeclHandler = oldElementDeclHandler;
1072104349Sphk  attlistDeclHandler = oldAttlistDeclHandler;
1073104349Sphk  entityDeclHandler = oldEntityDeclHandler;
1074104349Sphk  xmlDeclHandler = oldXmlDeclHandler;
1075104349Sphk  declElementType = oldDeclElementType;
1076104349Sphk  userData = oldUserData;
1077104349Sphk  if (oldUserData == oldHandlerArg)
1078104349Sphk    handlerArg = userData;
1079104349Sphk  else
1080104349Sphk    handlerArg = parser;
1081104349Sphk  if (oldExternalEntityRefHandlerArg != oldParser)
1082104349Sphk    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1083104349Sphk  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1084104349Sphk  ns_triplets = oldns_triplets;
1085247513Sdelphij  hash_secret_salt = oldhash_secret_salt;
1086104349Sphk  parentParser = oldParser;
1087104349Sphk#ifdef XML_DTD
1088104349Sphk  paramEntityParsing = oldParamEntityParsing;
1089104349Sphk  prologState.inEntityValue = oldInEntityValue;
1090104349Sphk  if (context) {
1091104349Sphk#endif /* XML_DTD */
1092247513Sdelphij    if (!dtdCopy(oldParser, _dtd, oldDtd, &parser->m_mem)
1093178848Scokane      || !setContext(parser, context)) {
1094104349Sphk      XML_ParserFree(parser);
1095104349Sphk      return NULL;
1096104349Sphk    }
1097104349Sphk    processor = externalEntityInitProcessor;
1098104349Sphk#ifdef XML_DTD
1099104349Sphk  }
1100104349Sphk  else {
1101178848Scokane    /* The DTD instance referenced by _dtd is shared between the document's
1102178848Scokane       root parser and external PE parsers, therefore one does not need to
1103178848Scokane       call setContext. In addition, one also *must* not call setContext,
1104178848Scokane       because this would overwrite existing prefix->binding pointers in
1105178848Scokane       _dtd with ones that get destroyed with the external PE parser.
1106178848Scokane       This would leave those prefixes with dangling pointers.
1107178848Scokane    */
1108104349Sphk    isParamEntity = XML_TRUE;
1109104349Sphk    XmlPrologStateInitExternalEntity(&prologState);
1110104349Sphk    processor = externalParEntInitProcessor;
1111104349Sphk  }
1112104349Sphk#endif /* XML_DTD */
1113104349Sphk  return parser;
1114104349Sphk}
1115104349Sphk
1116104349Sphkstatic void FASTCALL
1117104349SphkdestroyBindings(BINDING *bindings, XML_Parser parser)
1118104349Sphk{
1119104349Sphk  for (;;) {
1120104349Sphk    BINDING *b = bindings;
1121104349Sphk    if (!b)
1122104349Sphk      break;
1123104349Sphk    bindings = b->nextTagBinding;
1124104349Sphk    FREE(b->uri);
1125104349Sphk    FREE(b);
1126104349Sphk  }
1127104349Sphk}
1128104349Sphk
1129178848Scokanevoid XMLCALL
1130104349SphkXML_ParserFree(XML_Parser parser)
1131104349Sphk{
1132178848Scokane  TAG *tagList;
1133178848Scokane  OPEN_INTERNAL_ENTITY *entityList;
1134178848Scokane  if (parser == NULL)
1135178848Scokane    return;
1136178848Scokane  /* free tagStack and freeTagList */
1137178848Scokane  tagList = tagStack;
1138104349Sphk  for (;;) {
1139104349Sphk    TAG *p;
1140178848Scokane    if (tagList == NULL) {
1141104349Sphk      if (freeTagList == NULL)
1142104349Sphk        break;
1143178848Scokane      tagList = freeTagList;
1144104349Sphk      freeTagList = NULL;
1145104349Sphk    }
1146178848Scokane    p = tagList;
1147178848Scokane    tagList = tagList->parent;
1148104349Sphk    FREE(p->buf);
1149104349Sphk    destroyBindings(p->bindings, parser);
1150104349Sphk    FREE(p);
1151104349Sphk  }
1152178848Scokane  /* free openInternalEntities and freeInternalEntities */
1153178848Scokane  entityList = openInternalEntities;
1154178848Scokane  for (;;) {
1155178848Scokane    OPEN_INTERNAL_ENTITY *openEntity;
1156178848Scokane    if (entityList == NULL) {
1157178848Scokane      if (freeInternalEntities == NULL)
1158178848Scokane        break;
1159178848Scokane      entityList = freeInternalEntities;
1160178848Scokane      freeInternalEntities = NULL;
1161178848Scokane    }
1162178848Scokane    openEntity = entityList;
1163178848Scokane    entityList = entityList->next;
1164178848Scokane    FREE(openEntity);
1165178848Scokane  }
1166178848Scokane
1167104349Sphk  destroyBindings(freeBindingList, parser);
1168104349Sphk  destroyBindings(inheritedBindings, parser);
1169104349Sphk  poolDestroy(&tempPool);
1170104349Sphk  poolDestroy(&temp2Pool);
1171104349Sphk#ifdef XML_DTD
1172178848Scokane  /* external parameter entity parsers share the DTD structure
1173178848Scokane     parser->m_dtd with the root parser, so we must not destroy it
1174178848Scokane  */
1175178848Scokane  if (!isParamEntity && _dtd)
1176178848Scokane#else
1177178848Scokane  if (_dtd)
1178104349Sphk#endif /* XML_DTD */
1179178848Scokane    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
1180104349Sphk  FREE((void *)atts);
1181247513Sdelphij#ifdef XML_ATTR_INFO
1182247513Sdelphij  FREE((void *)attInfo);
1183247513Sdelphij#endif
1184178848Scokane  FREE(groupConnector);
1185178848Scokane  FREE(buffer);
1186104349Sphk  FREE(dataBuf);
1187178848Scokane  FREE(nsAtts);
1188178848Scokane  FREE(unknownEncodingMem);
1189104349Sphk  if (unknownEncodingRelease)
1190104349Sphk    unknownEncodingRelease(unknownEncodingData);
1191104349Sphk  FREE(parser);
1192104349Sphk}
1193104349Sphk
1194178848Scokanevoid XMLCALL
1195104349SphkXML_UseParserAsHandlerArg(XML_Parser parser)
1196104349Sphk{
1197104349Sphk  handlerArg = parser;
1198104349Sphk}
1199104349Sphk
1200178848Scokaneenum XML_Error XMLCALL
1201104349SphkXML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
1202104349Sphk{
1203104349Sphk#ifdef XML_DTD
1204104349Sphk  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1205178848Scokane  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1206104349Sphk    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
1207104349Sphk  useForeignDTD = useDTD;
1208104349Sphk  return XML_ERROR_NONE;
1209104349Sphk#else
1210104349Sphk  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
1211104349Sphk#endif
1212104349Sphk}
1213104349Sphk
1214178848Scokanevoid XMLCALL
1215104349SphkXML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
1216104349Sphk{
1217104349Sphk  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1218178848Scokane  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1219104349Sphk    return;
1220104349Sphk  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
1221104349Sphk}
1222104349Sphk
1223178848Scokanevoid XMLCALL
1224104349SphkXML_SetUserData(XML_Parser parser, void *p)
1225104349Sphk{
1226104349Sphk  if (handlerArg == userData)
1227104349Sphk    handlerArg = userData = p;
1228104349Sphk  else
1229104349Sphk    userData = p;
1230104349Sphk}
1231104349Sphk
1232178848Scokaneenum XML_Status XMLCALL
1233104349SphkXML_SetBase(XML_Parser parser, const XML_Char *p)
1234104349Sphk{
1235104349Sphk  if (p) {
1236178848Scokane    p = poolCopyString(&_dtd->pool, p);
1237104349Sphk    if (!p)
1238178848Scokane      return XML_STATUS_ERROR;
1239104349Sphk    curBase = p;
1240104349Sphk  }
1241104349Sphk  else
1242104349Sphk    curBase = NULL;
1243178848Scokane  return XML_STATUS_OK;
1244104349Sphk}
1245104349Sphk
1246178848Scokaneconst XML_Char * XMLCALL
1247104349SphkXML_GetBase(XML_Parser parser)
1248104349Sphk{
1249104349Sphk  return curBase;
1250104349Sphk}
1251104349Sphk
1252178848Scokaneint XMLCALL
1253104349SphkXML_GetSpecifiedAttributeCount(XML_Parser parser)
1254104349Sphk{
1255104349Sphk  return nSpecifiedAtts;
1256104349Sphk}
1257104349Sphk
1258178848Scokaneint XMLCALL
1259104349SphkXML_GetIdAttributeIndex(XML_Parser parser)
1260104349Sphk{
1261104349Sphk  return idAttIndex;
1262104349Sphk}
1263104349Sphk
1264247513Sdelphij#ifdef XML_ATTR_INFO
1265247513Sdelphijconst XML_AttrInfo * XMLCALL
1266247513SdelphijXML_GetAttributeInfo(XML_Parser parser)
1267247513Sdelphij{
1268247513Sdelphij  return attInfo;
1269247513Sdelphij}
1270247513Sdelphij#endif
1271247513Sdelphij
1272178848Scokanevoid XMLCALL
1273104349SphkXML_SetElementHandler(XML_Parser parser,
1274104349Sphk                      XML_StartElementHandler start,
1275104349Sphk                      XML_EndElementHandler end)
1276104349Sphk{
1277104349Sphk  startElementHandler = start;
1278104349Sphk  endElementHandler = end;
1279104349Sphk}
1280104349Sphk
1281178848Scokanevoid XMLCALL
1282104349SphkXML_SetStartElementHandler(XML_Parser parser,
1283104349Sphk                           XML_StartElementHandler start) {
1284104349Sphk  startElementHandler = start;
1285104349Sphk}
1286104349Sphk
1287178848Scokanevoid XMLCALL
1288104349SphkXML_SetEndElementHandler(XML_Parser parser,
1289104349Sphk                         XML_EndElementHandler end) {
1290104349Sphk  endElementHandler = end;
1291104349Sphk}
1292104349Sphk
1293178848Scokanevoid XMLCALL
1294104349SphkXML_SetCharacterDataHandler(XML_Parser parser,
1295104349Sphk                            XML_CharacterDataHandler handler)
1296104349Sphk{
1297104349Sphk  characterDataHandler = handler;
1298104349Sphk}
1299104349Sphk
1300178848Scokanevoid XMLCALL
1301104349SphkXML_SetProcessingInstructionHandler(XML_Parser parser,
1302104349Sphk                                    XML_ProcessingInstructionHandler handler)
1303104349Sphk{
1304104349Sphk  processingInstructionHandler = handler;
1305104349Sphk}
1306104349Sphk
1307178848Scokanevoid XMLCALL
1308104349SphkXML_SetCommentHandler(XML_Parser parser,
1309104349Sphk                      XML_CommentHandler handler)
1310104349Sphk{
1311104349Sphk  commentHandler = handler;
1312104349Sphk}
1313104349Sphk
1314178848Scokanevoid XMLCALL
1315104349SphkXML_SetCdataSectionHandler(XML_Parser parser,
1316104349Sphk                           XML_StartCdataSectionHandler start,
1317104349Sphk                           XML_EndCdataSectionHandler end)
1318104349Sphk{
1319104349Sphk  startCdataSectionHandler = start;
1320104349Sphk  endCdataSectionHandler = end;
1321104349Sphk}
1322104349Sphk
1323178848Scokanevoid XMLCALL
1324104349SphkXML_SetStartCdataSectionHandler(XML_Parser parser,
1325104349Sphk                                XML_StartCdataSectionHandler start) {
1326104349Sphk  startCdataSectionHandler = start;
1327104349Sphk}
1328104349Sphk
1329178848Scokanevoid XMLCALL
1330104349SphkXML_SetEndCdataSectionHandler(XML_Parser parser,
1331104349Sphk                              XML_EndCdataSectionHandler end) {
1332104349Sphk  endCdataSectionHandler = end;
1333104349Sphk}
1334104349Sphk
1335178848Scokanevoid XMLCALL
1336104349SphkXML_SetDefaultHandler(XML_Parser parser,
1337104349Sphk                      XML_DefaultHandler handler)
1338104349Sphk{
1339104349Sphk  defaultHandler = handler;
1340104349Sphk  defaultExpandInternalEntities = XML_FALSE;
1341104349Sphk}
1342104349Sphk
1343178848Scokanevoid XMLCALL
1344104349SphkXML_SetDefaultHandlerExpand(XML_Parser parser,
1345104349Sphk                            XML_DefaultHandler handler)
1346104349Sphk{
1347104349Sphk  defaultHandler = handler;
1348104349Sphk  defaultExpandInternalEntities = XML_TRUE;
1349104349Sphk}
1350104349Sphk
1351178848Scokanevoid XMLCALL
1352104349SphkXML_SetDoctypeDeclHandler(XML_Parser parser,
1353104349Sphk                          XML_StartDoctypeDeclHandler start,
1354104349Sphk                          XML_EndDoctypeDeclHandler end)
1355104349Sphk{
1356104349Sphk  startDoctypeDeclHandler = start;
1357104349Sphk  endDoctypeDeclHandler = end;
1358104349Sphk}
1359104349Sphk
1360178848Scokanevoid XMLCALL
1361104349SphkXML_SetStartDoctypeDeclHandler(XML_Parser parser,
1362104349Sphk                               XML_StartDoctypeDeclHandler start) {
1363104349Sphk  startDoctypeDeclHandler = start;
1364104349Sphk}
1365104349Sphk
1366178848Scokanevoid XMLCALL
1367104349SphkXML_SetEndDoctypeDeclHandler(XML_Parser parser,
1368104349Sphk                             XML_EndDoctypeDeclHandler end) {
1369104349Sphk  endDoctypeDeclHandler = end;
1370104349Sphk}
1371104349Sphk
1372178848Scokanevoid XMLCALL
1373104349SphkXML_SetUnparsedEntityDeclHandler(XML_Parser parser,
1374104349Sphk                                 XML_UnparsedEntityDeclHandler handler)
1375104349Sphk{
1376104349Sphk  unparsedEntityDeclHandler = handler;
1377104349Sphk}
1378104349Sphk
1379178848Scokanevoid XMLCALL
1380104349SphkXML_SetNotationDeclHandler(XML_Parser parser,
1381104349Sphk                           XML_NotationDeclHandler handler)
1382104349Sphk{
1383104349Sphk  notationDeclHandler = handler;
1384104349Sphk}
1385104349Sphk
1386178848Scokanevoid XMLCALL
1387104349SphkXML_SetNamespaceDeclHandler(XML_Parser parser,
1388104349Sphk                            XML_StartNamespaceDeclHandler start,
1389104349Sphk                            XML_EndNamespaceDeclHandler end)
1390104349Sphk{
1391104349Sphk  startNamespaceDeclHandler = start;
1392104349Sphk  endNamespaceDeclHandler = end;
1393104349Sphk}
1394104349Sphk
1395178848Scokanevoid XMLCALL
1396104349SphkXML_SetStartNamespaceDeclHandler(XML_Parser parser,
1397104349Sphk                                 XML_StartNamespaceDeclHandler start) {
1398104349Sphk  startNamespaceDeclHandler = start;
1399104349Sphk}
1400104349Sphk
1401178848Scokanevoid XMLCALL
1402104349SphkXML_SetEndNamespaceDeclHandler(XML_Parser parser,
1403104349Sphk                               XML_EndNamespaceDeclHandler end) {
1404104349Sphk  endNamespaceDeclHandler = end;
1405104349Sphk}
1406104349Sphk
1407178848Scokanevoid XMLCALL
1408104349SphkXML_SetNotStandaloneHandler(XML_Parser parser,
1409104349Sphk                            XML_NotStandaloneHandler handler)
1410104349Sphk{
1411104349Sphk  notStandaloneHandler = handler;
1412104349Sphk}
1413104349Sphk
1414178848Scokanevoid XMLCALL
1415104349SphkXML_SetExternalEntityRefHandler(XML_Parser parser,
1416104349Sphk                                XML_ExternalEntityRefHandler handler)
1417104349Sphk{
1418104349Sphk  externalEntityRefHandler = handler;
1419104349Sphk}
1420104349Sphk
1421178848Scokanevoid XMLCALL
1422104349SphkXML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
1423104349Sphk{
1424104349Sphk  if (arg)
1425178848Scokane    externalEntityRefHandlerArg = (XML_Parser)arg;
1426104349Sphk  else
1427104349Sphk    externalEntityRefHandlerArg = parser;
1428104349Sphk}
1429104349Sphk
1430178848Scokanevoid XMLCALL
1431104349SphkXML_SetSkippedEntityHandler(XML_Parser parser,
1432104349Sphk                            XML_SkippedEntityHandler handler)
1433104349Sphk{
1434104349Sphk  skippedEntityHandler = handler;
1435104349Sphk}
1436104349Sphk
1437178848Scokanevoid XMLCALL
1438104349SphkXML_SetUnknownEncodingHandler(XML_Parser parser,
1439104349Sphk                              XML_UnknownEncodingHandler handler,
1440104349Sphk                              void *data)
1441104349Sphk{
1442104349Sphk  unknownEncodingHandler = handler;
1443104349Sphk  unknownEncodingHandlerData = data;
1444104349Sphk}
1445104349Sphk
1446178848Scokanevoid XMLCALL
1447104349SphkXML_SetElementDeclHandler(XML_Parser parser,
1448104349Sphk                          XML_ElementDeclHandler eldecl)
1449104349Sphk{
1450104349Sphk  elementDeclHandler = eldecl;
1451104349Sphk}
1452104349Sphk
1453178848Scokanevoid XMLCALL
1454104349SphkXML_SetAttlistDeclHandler(XML_Parser parser,
1455104349Sphk                          XML_AttlistDeclHandler attdecl)
1456104349Sphk{
1457104349Sphk  attlistDeclHandler = attdecl;
1458104349Sphk}
1459104349Sphk
1460178848Scokanevoid XMLCALL
1461104349SphkXML_SetEntityDeclHandler(XML_Parser parser,
1462104349Sphk                         XML_EntityDeclHandler handler)
1463104349Sphk{
1464104349Sphk  entityDeclHandler = handler;
1465104349Sphk}
1466104349Sphk
1467178848Scokanevoid XMLCALL
1468104349SphkXML_SetXmlDeclHandler(XML_Parser parser,
1469104349Sphk                      XML_XmlDeclHandler handler) {
1470104349Sphk  xmlDeclHandler = handler;
1471104349Sphk}
1472104349Sphk
1473178848Scokaneint XMLCALL
1474104349SphkXML_SetParamEntityParsing(XML_Parser parser,
1475104349Sphk                          enum XML_ParamEntityParsing peParsing)
1476104349Sphk{
1477104349Sphk  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1478178848Scokane  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1479104349Sphk    return 0;
1480104349Sphk#ifdef XML_DTD
1481104349Sphk  paramEntityParsing = peParsing;
1482104349Sphk  return 1;
1483104349Sphk#else
1484104349Sphk  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
1485104349Sphk#endif
1486104349Sphk}
1487104349Sphk
1488247513Sdelphijint XMLCALL
1489247513SdelphijXML_SetHashSalt(XML_Parser parser,
1490247513Sdelphij                unsigned long hash_salt)
1491247513Sdelphij{
1492247513Sdelphij  /* block after XML_Parse()/XML_ParseBuffer() has been called */
1493247513Sdelphij  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
1494247513Sdelphij    return 0;
1495247513Sdelphij  hash_secret_salt = hash_salt;
1496247513Sdelphij  return 1;
1497247513Sdelphij}
1498247513Sdelphij
1499178848Scokaneenum XML_Status XMLCALL
1500104349SphkXML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
1501104349Sphk{
1502178848Scokane  switch (ps_parsing) {
1503178848Scokane  case XML_SUSPENDED:
1504178848Scokane    errorCode = XML_ERROR_SUSPENDED;
1505178848Scokane    return XML_STATUS_ERROR;
1506178848Scokane  case XML_FINISHED:
1507178848Scokane    errorCode = XML_ERROR_FINISHED;
1508178848Scokane    return XML_STATUS_ERROR;
1509247513Sdelphij  case XML_INITIALIZED:
1510247513Sdelphij    if (parentParser == NULL && !startParsing(parser)) {
1511247513Sdelphij      errorCode = XML_ERROR_NO_MEMORY;
1512247513Sdelphij      return XML_STATUS_ERROR;
1513247513Sdelphij    }
1514178848Scokane  default:
1515178848Scokane    ps_parsing = XML_PARSING;
1516178848Scokane  }
1517178848Scokane
1518104349Sphk  if (len == 0) {
1519178848Scokane    ps_finalBuffer = (XML_Bool)isFinal;
1520104349Sphk    if (!isFinal)
1521104349Sphk      return XML_STATUS_OK;
1522104349Sphk    positionPtr = bufferPtr;
1523178848Scokane    parseEndPtr = bufferEnd;
1524178848Scokane
1525178848Scokane    /* If data are left over from last buffer, and we now know that these
1526178848Scokane       data are the final chunk of input, then we have to check them again
1527178848Scokane       to detect errors based on that fact.
1528178848Scokane    */
1529178848Scokane    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1530178848Scokane
1531178848Scokane    if (errorCode == XML_ERROR_NONE) {
1532178848Scokane      switch (ps_parsing) {
1533178848Scokane      case XML_SUSPENDED:
1534178848Scokane        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1535178848Scokane        positionPtr = bufferPtr;
1536178848Scokane        return XML_STATUS_SUSPENDED;
1537247513Sdelphij      case XML_INITIALIZED:
1538178848Scokane      case XML_PARSING:
1539178848Scokane        ps_parsing = XML_FINISHED;
1540178848Scokane        /* fall through */
1541178848Scokane      default:
1542178848Scokane        return XML_STATUS_OK;
1543178848Scokane      }
1544178848Scokane    }
1545104349Sphk    eventEndPtr = eventPtr;
1546104349Sphk    processor = errorProcessor;
1547104349Sphk    return XML_STATUS_ERROR;
1548104349Sphk  }
1549104349Sphk#ifndef XML_CONTEXT_BYTES
1550104349Sphk  else if (bufferPtr == bufferEnd) {
1551104349Sphk    const char *end;
1552104349Sphk    int nLeftOver;
1553178848Scokane    enum XML_Error result;
1554104349Sphk    parseEndByteIndex += len;
1555104349Sphk    positionPtr = s;
1556178848Scokane    ps_finalBuffer = (XML_Bool)isFinal;
1557178848Scokane
1558104349Sphk    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
1559178848Scokane
1560104349Sphk    if (errorCode != XML_ERROR_NONE) {
1561104349Sphk      eventEndPtr = eventPtr;
1562104349Sphk      processor = errorProcessor;
1563104349Sphk      return XML_STATUS_ERROR;
1564104349Sphk    }
1565178848Scokane    else {
1566178848Scokane      switch (ps_parsing) {
1567178848Scokane      case XML_SUSPENDED:
1568178848Scokane        result = XML_STATUS_SUSPENDED;
1569178848Scokane        break;
1570178848Scokane      case XML_INITIALIZED:
1571178848Scokane      case XML_PARSING:
1572178848Scokane        if (isFinal) {
1573178848Scokane          ps_parsing = XML_FINISHED;
1574247513Sdelphij          return XML_STATUS_OK;
1575178848Scokane        }
1576247513Sdelphij      /* fall through */
1577247513Sdelphij      default:
1578247513Sdelphij        result = XML_STATUS_OK;
1579178848Scokane      }
1580178848Scokane    }
1581178848Scokane
1582104349Sphk    XmlUpdatePosition(encoding, positionPtr, end, &position);
1583104349Sphk    nLeftOver = s + len - end;
1584104349Sphk    if (nLeftOver) {
1585104349Sphk      if (buffer == NULL || nLeftOver > bufferLim - buffer) {
1586104349Sphk        /* FIXME avoid integer overflow */
1587104349Sphk        char *temp;
1588178848Scokane        temp = (buffer == NULL
1589178848Scokane                ? (char *)MALLOC(len * 2)
1590178848Scokane                : (char *)REALLOC(buffer, len * 2));
1591104349Sphk        if (temp == NULL) {
1592104349Sphk          errorCode = XML_ERROR_NO_MEMORY;
1593104349Sphk          eventPtr = eventEndPtr = NULL;
1594104349Sphk          processor = errorProcessor;
1595104349Sphk          return XML_STATUS_ERROR;
1596104349Sphk        }
1597247513Sdelphij        buffer = temp;
1598104349Sphk        bufferLim = buffer + len * 2;
1599104349Sphk      }
1600104349Sphk      memcpy(buffer, end, nLeftOver);
1601104349Sphk    }
1602178848Scokane    bufferPtr = buffer;
1603178848Scokane    bufferEnd = buffer + nLeftOver;
1604178848Scokane    positionPtr = bufferPtr;
1605178848Scokane    parseEndPtr = bufferEnd;
1606178848Scokane    eventPtr = bufferPtr;
1607178848Scokane    eventEndPtr = bufferPtr;
1608178848Scokane    return result;
1609104349Sphk  }
1610104349Sphk#endif  /* not defined XML_CONTEXT_BYTES */
1611104349Sphk  else {
1612104349Sphk    void *buff = XML_GetBuffer(parser, len);
1613104349Sphk    if (buff == NULL)
1614104349Sphk      return XML_STATUS_ERROR;
1615104349Sphk    else {
1616104349Sphk      memcpy(buff, s, len);
1617104349Sphk      return XML_ParseBuffer(parser, len, isFinal);
1618104349Sphk    }
1619104349Sphk  }
1620104349Sphk}
1621104349Sphk
1622178848Scokaneenum XML_Status XMLCALL
1623104349SphkXML_ParseBuffer(XML_Parser parser, int len, int isFinal)
1624104349Sphk{
1625178848Scokane  const char *start;
1626178848Scokane  enum XML_Status result = XML_STATUS_OK;
1627178848Scokane
1628178848Scokane  switch (ps_parsing) {
1629178848Scokane  case XML_SUSPENDED:
1630178848Scokane    errorCode = XML_ERROR_SUSPENDED;
1631178848Scokane    return XML_STATUS_ERROR;
1632178848Scokane  case XML_FINISHED:
1633178848Scokane    errorCode = XML_ERROR_FINISHED;
1634178848Scokane    return XML_STATUS_ERROR;
1635247513Sdelphij  case XML_INITIALIZED:
1636247513Sdelphij    if (parentParser == NULL && !startParsing(parser)) {
1637247513Sdelphij      errorCode = XML_ERROR_NO_MEMORY;
1638247513Sdelphij      return XML_STATUS_ERROR;
1639247513Sdelphij    }
1640178848Scokane  default:
1641178848Scokane    ps_parsing = XML_PARSING;
1642178848Scokane  }
1643178848Scokane
1644178848Scokane  start = bufferPtr;
1645104349Sphk  positionPtr = start;
1646104349Sphk  bufferEnd += len;
1647178848Scokane  parseEndPtr = bufferEnd;
1648104349Sphk  parseEndByteIndex += len;
1649178848Scokane  ps_finalBuffer = (XML_Bool)isFinal;
1650178848Scokane
1651178848Scokane  errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
1652178848Scokane
1653178848Scokane  if (errorCode != XML_ERROR_NONE) {
1654104349Sphk    eventEndPtr = eventPtr;
1655104349Sphk    processor = errorProcessor;
1656104349Sphk    return XML_STATUS_ERROR;
1657104349Sphk  }
1658178848Scokane  else {
1659178848Scokane    switch (ps_parsing) {
1660178848Scokane    case XML_SUSPENDED:
1661178848Scokane      result = XML_STATUS_SUSPENDED;
1662178848Scokane      break;
1663247513Sdelphij    case XML_INITIALIZED:
1664178848Scokane    case XML_PARSING:
1665178848Scokane      if (isFinal) {
1666178848Scokane        ps_parsing = XML_FINISHED;
1667178848Scokane        return result;
1668178848Scokane      }
1669178848Scokane    default: ;  /* should not happen */
1670178848Scokane    }
1671178848Scokane  }
1672178848Scokane
1673178848Scokane  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1674178848Scokane  positionPtr = bufferPtr;
1675178848Scokane  return result;
1676104349Sphk}
1677104349Sphk
1678178848Scokanevoid * XMLCALL
1679104349SphkXML_GetBuffer(XML_Parser parser, int len)
1680104349Sphk{
1681286902Sdelphij/* BEGIN MOZILLA CHANGE (sanity check len) */
1682286902Sdelphij  if (len < 0) {
1683286902Sdelphij    errorCode = XML_ERROR_NO_MEMORY;
1684286902Sdelphij    return NULL;
1685286902Sdelphij  }
1686286902Sdelphij/* END MOZILLA CHANGE */
1687178848Scokane  switch (ps_parsing) {
1688178848Scokane  case XML_SUSPENDED:
1689178848Scokane    errorCode = XML_ERROR_SUSPENDED;
1690178848Scokane    return NULL;
1691178848Scokane  case XML_FINISHED:
1692178848Scokane    errorCode = XML_ERROR_FINISHED;
1693178848Scokane    return NULL;
1694178848Scokane  default: ;
1695178848Scokane  }
1696178848Scokane
1697104349Sphk  if (len > bufferLim - bufferEnd) {
1698178848Scokane    int neededSize = len + (int)(bufferEnd - bufferPtr);
1699286902Sdelphij/* BEGIN MOZILLA CHANGE (sanity check neededSize) */
1700286902Sdelphij    if (neededSize < 0) {
1701286902Sdelphij      errorCode = XML_ERROR_NO_MEMORY;
1702286902Sdelphij      return NULL;
1703286902Sdelphij    }
1704286902Sdelphij/* END MOZILLA CHANGE */
1705104349Sphk#ifdef XML_CONTEXT_BYTES
1706178848Scokane    int keep = (int)(bufferPtr - buffer);
1707104349Sphk
1708104349Sphk    if (keep > XML_CONTEXT_BYTES)
1709104349Sphk      keep = XML_CONTEXT_BYTES;
1710104349Sphk    neededSize += keep;
1711104349Sphk#endif  /* defined XML_CONTEXT_BYTES */
1712104349Sphk    if (neededSize  <= bufferLim - buffer) {
1713104349Sphk#ifdef XML_CONTEXT_BYTES
1714104349Sphk      if (keep < bufferPtr - buffer) {
1715178848Scokane        int offset = (int)(bufferPtr - buffer) - keep;
1716104349Sphk        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
1717104349Sphk        bufferEnd -= offset;
1718104349Sphk        bufferPtr -= offset;
1719104349Sphk      }
1720104349Sphk#else
1721104349Sphk      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
1722104349Sphk      bufferEnd = buffer + (bufferEnd - bufferPtr);
1723104349Sphk      bufferPtr = buffer;
1724104349Sphk#endif  /* not defined XML_CONTEXT_BYTES */
1725104349Sphk    }
1726104349Sphk    else {
1727104349Sphk      char *newBuf;
1728178848Scokane      int bufferSize = (int)(bufferLim - bufferPtr);
1729104349Sphk      if (bufferSize == 0)
1730104349Sphk        bufferSize = INIT_BUFFER_SIZE;
1731104349Sphk      do {
1732104349Sphk        bufferSize *= 2;
1733286902Sdelphij/* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */
1734286902Sdelphij      } while (bufferSize < neededSize && bufferSize > 0);
1735286902Sdelphij/* END MOZILLA CHANGE */
1736286902Sdelphij/* BEGIN MOZILLA CHANGE (sanity check bufferSize) */
1737286902Sdelphij      if (bufferSize <= 0) {
1738286902Sdelphij        errorCode = XML_ERROR_NO_MEMORY;
1739286902Sdelphij        return NULL;
1740286902Sdelphij      }
1741286902Sdelphij/* END MOZILLA CHANGE */
1742178848Scokane      newBuf = (char *)MALLOC(bufferSize);
1743104349Sphk      if (newBuf == 0) {
1744104349Sphk        errorCode = XML_ERROR_NO_MEMORY;
1745104349Sphk        return NULL;
1746104349Sphk      }
1747104349Sphk      bufferLim = newBuf + bufferSize;
1748104349Sphk#ifdef XML_CONTEXT_BYTES
1749104349Sphk      if (bufferPtr) {
1750178848Scokane        int keep = (int)(bufferPtr - buffer);
1751104349Sphk        if (keep > XML_CONTEXT_BYTES)
1752104349Sphk          keep = XML_CONTEXT_BYTES;
1753104349Sphk        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
1754104349Sphk        FREE(buffer);
1755104349Sphk        buffer = newBuf;
1756104349Sphk        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
1757104349Sphk        bufferPtr = buffer + keep;
1758104349Sphk      }
1759104349Sphk      else {
1760104349Sphk        bufferEnd = newBuf + (bufferEnd - bufferPtr);
1761104349Sphk        bufferPtr = buffer = newBuf;
1762104349Sphk      }
1763104349Sphk#else
1764104349Sphk      if (bufferPtr) {
1765104349Sphk        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
1766104349Sphk        FREE(buffer);
1767104349Sphk      }
1768104349Sphk      bufferEnd = newBuf + (bufferEnd - bufferPtr);
1769104349Sphk      bufferPtr = buffer = newBuf;
1770104349Sphk#endif  /* not defined XML_CONTEXT_BYTES */
1771104349Sphk    }
1772247513Sdelphij    eventPtr = eventEndPtr = NULL;
1773247513Sdelphij    positionPtr = NULL;
1774104349Sphk  }
1775104349Sphk  return bufferEnd;
1776104349Sphk}
1777104349Sphk
1778178848Scokaneenum XML_Status XMLCALL
1779178848ScokaneXML_StopParser(XML_Parser parser, XML_Bool resumable)
1780178848Scokane{
1781178848Scokane  switch (ps_parsing) {
1782178848Scokane  case XML_SUSPENDED:
1783178848Scokane    if (resumable) {
1784178848Scokane      errorCode = XML_ERROR_SUSPENDED;
1785178848Scokane      return XML_STATUS_ERROR;
1786178848Scokane    }
1787178848Scokane    ps_parsing = XML_FINISHED;
1788178848Scokane    break;
1789178848Scokane  case XML_FINISHED:
1790178848Scokane    errorCode = XML_ERROR_FINISHED;
1791178848Scokane    return XML_STATUS_ERROR;
1792178848Scokane  default:
1793178848Scokane    if (resumable) {
1794178848Scokane#ifdef XML_DTD
1795178848Scokane      if (isParamEntity) {
1796178848Scokane        errorCode = XML_ERROR_SUSPEND_PE;
1797178848Scokane        return XML_STATUS_ERROR;
1798178848Scokane      }
1799178848Scokane#endif
1800178848Scokane      ps_parsing = XML_SUSPENDED;
1801178848Scokane    }
1802178848Scokane    else
1803178848Scokane      ps_parsing = XML_FINISHED;
1804178848Scokane  }
1805178848Scokane  return XML_STATUS_OK;
1806178848Scokane}
1807178848Scokane
1808178848Scokaneenum XML_Status XMLCALL
1809178848ScokaneXML_ResumeParser(XML_Parser parser)
1810178848Scokane{
1811178848Scokane  enum XML_Status result = XML_STATUS_OK;
1812178848Scokane
1813178848Scokane  if (ps_parsing != XML_SUSPENDED) {
1814178848Scokane    errorCode = XML_ERROR_NOT_SUSPENDED;
1815178848Scokane    return XML_STATUS_ERROR;
1816178848Scokane  }
1817178848Scokane  ps_parsing = XML_PARSING;
1818178848Scokane
1819178848Scokane  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
1820178848Scokane
1821178848Scokane  if (errorCode != XML_ERROR_NONE) {
1822178848Scokane    eventEndPtr = eventPtr;
1823178848Scokane    processor = errorProcessor;
1824178848Scokane    return XML_STATUS_ERROR;
1825178848Scokane  }
1826178848Scokane  else {
1827178848Scokane    switch (ps_parsing) {
1828178848Scokane    case XML_SUSPENDED:
1829178848Scokane      result = XML_STATUS_SUSPENDED;
1830178848Scokane      break;
1831247513Sdelphij    case XML_INITIALIZED:
1832178848Scokane    case XML_PARSING:
1833178848Scokane      if (ps_finalBuffer) {
1834178848Scokane        ps_parsing = XML_FINISHED;
1835178848Scokane        return result;
1836178848Scokane      }
1837178848Scokane    default: ;
1838178848Scokane    }
1839178848Scokane  }
1840178848Scokane
1841178848Scokane  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
1842178848Scokane  positionPtr = bufferPtr;
1843178848Scokane  return result;
1844178848Scokane}
1845178848Scokane
1846178848Scokanevoid XMLCALL
1847178848ScokaneXML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
1848178848Scokane{
1849178848Scokane  assert(status != NULL);
1850178848Scokane  *status = parser->m_parsingStatus;
1851178848Scokane}
1852178848Scokane
1853178848Scokaneenum XML_Error XMLCALL
1854104349SphkXML_GetErrorCode(XML_Parser parser)
1855104349Sphk{
1856104349Sphk  return errorCode;
1857104349Sphk}
1858104349Sphk
1859178848ScokaneXML_Index XMLCALL
1860104349SphkXML_GetCurrentByteIndex(XML_Parser parser)
1861104349Sphk{
1862104349Sphk  if (eventPtr)
1863104349Sphk    return parseEndByteIndex - (parseEndPtr - eventPtr);
1864104349Sphk  return -1;
1865104349Sphk}
1866104349Sphk
1867178848Scokaneint XMLCALL
1868104349SphkXML_GetCurrentByteCount(XML_Parser parser)
1869104349Sphk{
1870104349Sphk  if (eventEndPtr && eventPtr)
1871178848Scokane    return (int)(eventEndPtr - eventPtr);
1872104349Sphk  return 0;
1873104349Sphk}
1874104349Sphk
1875178848Scokaneconst char * XMLCALL
1876104349SphkXML_GetInputContext(XML_Parser parser, int *offset, int *size)
1877104349Sphk{
1878104349Sphk#ifdef XML_CONTEXT_BYTES
1879104349Sphk  if (eventPtr && buffer) {
1880178848Scokane    *offset = (int)(eventPtr - buffer);
1881178848Scokane    *size   = (int)(bufferEnd - buffer);
1882104349Sphk    return buffer;
1883104349Sphk  }
1884104349Sphk#endif /* defined XML_CONTEXT_BYTES */
1885104349Sphk  return (char *) 0;
1886104349Sphk}
1887104349Sphk
1888178848ScokaneXML_Size XMLCALL
1889104349SphkXML_GetCurrentLineNumber(XML_Parser parser)
1890104349Sphk{
1891178848Scokane  if (eventPtr && eventPtr >= positionPtr) {
1892104349Sphk    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1893104349Sphk    positionPtr = eventPtr;
1894104349Sphk  }
1895104349Sphk  return position.lineNumber + 1;
1896104349Sphk}
1897104349Sphk
1898178848ScokaneXML_Size XMLCALL
1899104349SphkXML_GetCurrentColumnNumber(XML_Parser parser)
1900104349Sphk{
1901178848Scokane  if (eventPtr && eventPtr >= positionPtr) {
1902104349Sphk    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
1903104349Sphk    positionPtr = eventPtr;
1904104349Sphk  }
1905104349Sphk  return position.columnNumber;
1906104349Sphk}
1907104349Sphk
1908178848Scokanevoid XMLCALL
1909178848ScokaneXML_FreeContentModel(XML_Parser parser, XML_Content *model)
1910178848Scokane{
1911178848Scokane  FREE(model);
1912178848Scokane}
1913178848Scokane
1914178848Scokanevoid * XMLCALL
1915178848ScokaneXML_MemMalloc(XML_Parser parser, size_t size)
1916178848Scokane{
1917178848Scokane  return MALLOC(size);
1918178848Scokane}
1919178848Scokane
1920178848Scokanevoid * XMLCALL
1921178848ScokaneXML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
1922178848Scokane{
1923178848Scokane  return REALLOC(ptr, size);
1924178848Scokane}
1925178848Scokane
1926178848Scokanevoid XMLCALL
1927178848ScokaneXML_MemFree(XML_Parser parser, void *ptr)
1928178848Scokane{
1929178848Scokane  FREE(ptr);
1930178848Scokane}
1931178848Scokane
1932178848Scokanevoid XMLCALL
1933104349SphkXML_DefaultCurrent(XML_Parser parser)
1934104349Sphk{
1935104349Sphk  if (defaultHandler) {
1936104349Sphk    if (openInternalEntities)
1937104349Sphk      reportDefault(parser,
1938104349Sphk                    internalEncoding,
1939104349Sphk                    openInternalEntities->internalEventPtr,
1940104349Sphk                    openInternalEntities->internalEventEndPtr);
1941104349Sphk    else
1942104349Sphk      reportDefault(parser, encoding, eventPtr, eventEndPtr);
1943104349Sphk  }
1944104349Sphk}
1945104349Sphk
1946178848Scokaneconst XML_LChar * XMLCALL
1947104349SphkXML_ErrorString(enum XML_Error code)
1948104349Sphk{
1949178848Scokane  static const XML_LChar* const message[] = {
1950104349Sphk    0,
1951104349Sphk    XML_L("out of memory"),
1952104349Sphk    XML_L("syntax error"),
1953104349Sphk    XML_L("no element found"),
1954104349Sphk    XML_L("not well-formed (invalid token)"),
1955104349Sphk    XML_L("unclosed token"),
1956104349Sphk    XML_L("partial character"),
1957104349Sphk    XML_L("mismatched tag"),
1958104349Sphk    XML_L("duplicate attribute"),
1959104349Sphk    XML_L("junk after document element"),
1960104349Sphk    XML_L("illegal parameter entity reference"),
1961104349Sphk    XML_L("undefined entity"),
1962104349Sphk    XML_L("recursive entity reference"),
1963104349Sphk    XML_L("asynchronous entity"),
1964104349Sphk    XML_L("reference to invalid character number"),
1965104349Sphk    XML_L("reference to binary entity"),
1966104349Sphk    XML_L("reference to external entity in attribute"),
1967178848Scokane    XML_L("XML or text declaration not at start of entity"),
1968104349Sphk    XML_L("unknown encoding"),
1969104349Sphk    XML_L("encoding specified in XML declaration is incorrect"),
1970104349Sphk    XML_L("unclosed CDATA section"),
1971104349Sphk    XML_L("error in processing external entity reference"),
1972104349Sphk    XML_L("document is not standalone"),
1973104349Sphk    XML_L("unexpected parser state - please send a bug report"),
1974104349Sphk    XML_L("entity declared in parameter entity"),
1975104349Sphk    XML_L("requested feature requires XML_DTD support in Expat"),
1976178848Scokane    XML_L("cannot change setting once parsing has begun"),
1977178848Scokane    XML_L("unbound prefix"),
1978178848Scokane    XML_L("must not undeclare prefix"),
1979178848Scokane    XML_L("incomplete markup in parameter entity"),
1980178848Scokane    XML_L("XML declaration not well-formed"),
1981178848Scokane    XML_L("text declaration not well-formed"),
1982178848Scokane    XML_L("illegal character(s) in public id"),
1983178848Scokane    XML_L("parser suspended"),
1984178848Scokane    XML_L("parser not suspended"),
1985178848Scokane    XML_L("parsing aborted"),
1986178848Scokane    XML_L("parsing finished"),
1987178848Scokane    XML_L("cannot suspend in external parameter entity"),
1988178848Scokane    XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
1989178848Scokane    XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
1990178848Scokane    XML_L("prefix must not be bound to one of the reserved namespace names")
1991104349Sphk  };
1992104349Sphk  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
1993104349Sphk    return message[code];
1994104349Sphk  return NULL;
1995104349Sphk}
1996104349Sphk
1997178848Scokaneconst XML_LChar * XMLCALL
1998104349SphkXML_ExpatVersion(void) {
1999104349Sphk
2000104349Sphk  /* V1 is used to string-ize the version number. However, it would
2001104349Sphk     string-ize the actual version macro *names* unless we get them
2002104349Sphk     substituted before being passed to V1. CPP is defined to expand
2003104349Sphk     a macro, then rescan for more expansions. Thus, we use V2 to expand
2004104349Sphk     the version macros, then CPP will expand the resulting V1() macro
2005104349Sphk     with the correct numerals. */
2006104349Sphk  /* ### I'm assuming cpp is portable in this respect... */
2007104349Sphk
2008104349Sphk#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
2009104349Sphk#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
2010104349Sphk
2011104349Sphk  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
2012104349Sphk
2013104349Sphk#undef V1
2014104349Sphk#undef V2
2015104349Sphk}
2016104349Sphk
2017178848ScokaneXML_Expat_Version XMLCALL
2018104349SphkXML_ExpatVersionInfo(void)
2019104349Sphk{
2020104349Sphk  XML_Expat_Version version;
2021104349Sphk
2022104349Sphk  version.major = XML_MAJOR_VERSION;
2023104349Sphk  version.minor = XML_MINOR_VERSION;
2024104349Sphk  version.micro = XML_MICRO_VERSION;
2025104349Sphk
2026104349Sphk  return version;
2027104349Sphk}
2028104349Sphk
2029178848Scokaneconst XML_Feature * XMLCALL
2030104349SphkXML_GetFeatureList(void)
2031104349Sphk{
2032178848Scokane  static const XML_Feature features[] = {
2033178848Scokane    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"),
2034178848Scokane     sizeof(XML_Char)},
2035178848Scokane    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
2036178848Scokane     sizeof(XML_LChar)},
2037104349Sphk#ifdef XML_UNICODE
2038178848Scokane    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0},
2039104349Sphk#endif
2040104349Sphk#ifdef XML_UNICODE_WCHAR_T
2041178848Scokane    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0},
2042104349Sphk#endif
2043104349Sphk#ifdef XML_DTD
2044178848Scokane    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0},
2045104349Sphk#endif
2046104349Sphk#ifdef XML_CONTEXT_BYTES
2047104349Sphk    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"),
2048104349Sphk     XML_CONTEXT_BYTES},
2049104349Sphk#endif
2050104349Sphk#ifdef XML_MIN_SIZE
2051178848Scokane    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
2052104349Sphk#endif
2053178848Scokane#ifdef XML_NS
2054178848Scokane    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
2055178848Scokane#endif
2056178848Scokane#ifdef XML_LARGE_SIZE
2057178848Scokane    {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
2058247513Sdelphij#endif
2059247513Sdelphij#ifdef XML_ATTR_INFO
2060247513Sdelphij    {XML_FEATURE_ATTR_INFO,        XML_L("XML_ATTR_INFO"), 0},
2061247513Sdelphij#endif
2062178848Scokane    {XML_FEATURE_END,              NULL, 0}
2063104349Sphk  };
2064104349Sphk
2065104349Sphk  return features;
2066104349Sphk}
2067104349Sphk
2068104349Sphk/* Initially tag->rawName always points into the parse buffer;
2069104349Sphk   for those TAG instances opened while the current parse buffer was
2070104349Sphk   processed, and not yet closed, we need to store tag->rawName in a more
2071104349Sphk   permanent location, since the parse buffer is about to be discarded.
2072104349Sphk*/
2073178848Scokanestatic XML_Bool
2074104349SphkstoreRawNames(XML_Parser parser)
2075104349Sphk{
2076104349Sphk  TAG *tag = tagStack;
2077104349Sphk  while (tag) {
2078104349Sphk    int bufSize;
2079104349Sphk    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
2080104349Sphk    char *rawNameBuf = tag->buf + nameLen;
2081104349Sphk    /* Stop if already stored.  Since tagStack is a stack, we can stop
2082104349Sphk       at the first entry that has already been copied; everything
2083104349Sphk       below it in the stack is already been accounted for in a
2084104349Sphk       previous call to this function.
2085104349Sphk    */
2086178848Scokane    if (tag->rawName == rawNameBuf)
2087104349Sphk      break;
2088104349Sphk    /* For re-use purposes we need to ensure that the
2089104349Sphk       size of tag->buf is a multiple of sizeof(XML_Char).
2090104349Sphk    */
2091104349Sphk    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
2092104349Sphk    if (bufSize > tag->bufEnd - tag->buf) {
2093178848Scokane      char *temp = (char *)REALLOC(tag->buf, bufSize);
2094104349Sphk      if (temp == NULL)
2095104349Sphk        return XML_FALSE;
2096178848Scokane      /* if tag->name.str points to tag->buf (only when namespace
2097178848Scokane         processing is off) then we have to update it
2098178848Scokane      */
2099178848Scokane      if (tag->name.str == (XML_Char *)tag->buf)
2100178848Scokane        tag->name.str = (XML_Char *)temp;
2101178848Scokane      /* if tag->name.localPart is set (when namespace processing is on)
2102178848Scokane         then update it as well, since it will always point into tag->buf
2103178848Scokane      */
2104178848Scokane      if (tag->name.localPart)
2105178848Scokane        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
2106178848Scokane                                                  (XML_Char *)tag->buf);
2107104349Sphk      tag->buf = temp;
2108104349Sphk      tag->bufEnd = temp + bufSize;
2109104349Sphk      rawNameBuf = temp + nameLen;
2110104349Sphk    }
2111104349Sphk    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
2112104349Sphk    tag->rawName = rawNameBuf;
2113104349Sphk    tag = tag->parent;
2114104349Sphk  }
2115104349Sphk  return XML_TRUE;
2116104349Sphk}
2117104349Sphk
2118178848Scokanestatic enum XML_Error PTRCALL
2119104349SphkcontentProcessor(XML_Parser parser,
2120104349Sphk                 const char *start,
2121104349Sphk                 const char *end,
2122104349Sphk                 const char **endPtr)
2123104349Sphk{
2124247513Sdelphij  enum XML_Error result = doContent(parser, 0, encoding, start, end,
2125178848Scokane                                    endPtr, (XML_Bool)!ps_finalBuffer);
2126178848Scokane  if (result == XML_ERROR_NONE) {
2127178848Scokane    if (!storeRawNames(parser))
2128178848Scokane      return XML_ERROR_NO_MEMORY;
2129178848Scokane  }
2130104349Sphk  return result;
2131104349Sphk}
2132104349Sphk
2133178848Scokanestatic enum XML_Error PTRCALL
2134104349SphkexternalEntityInitProcessor(XML_Parser parser,
2135104349Sphk                            const char *start,
2136104349Sphk                            const char *end,
2137104349Sphk                            const char **endPtr)
2138104349Sphk{
2139104349Sphk  enum XML_Error result = initializeEncoding(parser);
2140104349Sphk  if (result != XML_ERROR_NONE)
2141104349Sphk    return result;
2142104349Sphk  processor = externalEntityInitProcessor2;
2143104349Sphk  return externalEntityInitProcessor2(parser, start, end, endPtr);
2144104349Sphk}
2145104349Sphk
2146178848Scokanestatic enum XML_Error PTRCALL
2147104349SphkexternalEntityInitProcessor2(XML_Parser parser,
2148104349Sphk                             const char *start,
2149104349Sphk                             const char *end,
2150104349Sphk                             const char **endPtr)
2151104349Sphk{
2152104349Sphk  const char *next = start; /* XmlContentTok doesn't always set the last arg */
2153104349Sphk  int tok = XmlContentTok(encoding, start, end, &next);
2154104349Sphk  switch (tok) {
2155104349Sphk  case XML_TOK_BOM:
2156104349Sphk    /* If we are at the end of the buffer, this would cause the next stage,
2157104349Sphk       i.e. externalEntityInitProcessor3, to pass control directly to
2158104349Sphk       doContent (by detecting XML_TOK_NONE) without processing any xml text
2159104349Sphk       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
2160104349Sphk    */
2161178848Scokane    if (next == end && !ps_finalBuffer) {
2162104349Sphk      *endPtr = next;
2163104349Sphk      return XML_ERROR_NONE;
2164104349Sphk    }
2165104349Sphk    start = next;
2166104349Sphk    break;
2167104349Sphk  case XML_TOK_PARTIAL:
2168178848Scokane    if (!ps_finalBuffer) {
2169104349Sphk      *endPtr = start;
2170104349Sphk      return XML_ERROR_NONE;
2171104349Sphk    }
2172104349Sphk    eventPtr = start;
2173104349Sphk    return XML_ERROR_UNCLOSED_TOKEN;
2174104349Sphk  case XML_TOK_PARTIAL_CHAR:
2175178848Scokane    if (!ps_finalBuffer) {
2176104349Sphk      *endPtr = start;
2177104349Sphk      return XML_ERROR_NONE;
2178104349Sphk    }
2179104349Sphk    eventPtr = start;
2180104349Sphk    return XML_ERROR_PARTIAL_CHAR;
2181104349Sphk  }
2182104349Sphk  processor = externalEntityInitProcessor3;
2183104349Sphk  return externalEntityInitProcessor3(parser, start, end, endPtr);
2184104349Sphk}
2185104349Sphk
2186178848Scokanestatic enum XML_Error PTRCALL
2187104349SphkexternalEntityInitProcessor3(XML_Parser parser,
2188104349Sphk                             const char *start,
2189104349Sphk                             const char *end,
2190104349Sphk                             const char **endPtr)
2191104349Sphk{
2192178848Scokane  int tok;
2193104349Sphk  const char *next = start; /* XmlContentTok doesn't always set the last arg */
2194178848Scokane  eventPtr = start;
2195178848Scokane  tok = XmlContentTok(encoding, start, end, &next);
2196178848Scokane  eventEndPtr = next;
2197178848Scokane
2198104349Sphk  switch (tok) {
2199104349Sphk  case XML_TOK_XML_DECL:
2200104349Sphk    {
2201178848Scokane      enum XML_Error result;
2202178848Scokane      result = processXmlDecl(parser, 1, start, next);
2203104349Sphk      if (result != XML_ERROR_NONE)
2204104349Sphk        return result;
2205178848Scokane      switch (ps_parsing) {
2206247513Sdelphij      case XML_SUSPENDED:
2207178848Scokane        *endPtr = next;
2208178848Scokane        return XML_ERROR_NONE;
2209178848Scokane      case XML_FINISHED:
2210178848Scokane        return XML_ERROR_ABORTED;
2211178848Scokane      default:
2212178848Scokane        start = next;
2213178848Scokane      }
2214104349Sphk    }
2215104349Sphk    break;
2216104349Sphk  case XML_TOK_PARTIAL:
2217178848Scokane    if (!ps_finalBuffer) {
2218104349Sphk      *endPtr = start;
2219104349Sphk      return XML_ERROR_NONE;
2220104349Sphk    }
2221104349Sphk    return XML_ERROR_UNCLOSED_TOKEN;
2222104349Sphk  case XML_TOK_PARTIAL_CHAR:
2223178848Scokane    if (!ps_finalBuffer) {
2224104349Sphk      *endPtr = start;
2225104349Sphk      return XML_ERROR_NONE;
2226104349Sphk    }
2227104349Sphk    return XML_ERROR_PARTIAL_CHAR;
2228104349Sphk  }
2229104349Sphk  processor = externalEntityContentProcessor;
2230104349Sphk  tagLevel = 1;
2231104349Sphk  return externalEntityContentProcessor(parser, start, end, endPtr);
2232104349Sphk}
2233104349Sphk
2234178848Scokanestatic enum XML_Error PTRCALL
2235104349SphkexternalEntityContentProcessor(XML_Parser parser,
2236104349Sphk                               const char *start,
2237104349Sphk                               const char *end,
2238104349Sphk                               const char **endPtr)
2239104349Sphk{
2240247513Sdelphij  enum XML_Error result = doContent(parser, 1, encoding, start, end,
2241178848Scokane                                    endPtr, (XML_Bool)!ps_finalBuffer);
2242178848Scokane  if (result == XML_ERROR_NONE) {
2243178848Scokane    if (!storeRawNames(parser))
2244178848Scokane      return XML_ERROR_NO_MEMORY;
2245178848Scokane  }
2246104349Sphk  return result;
2247104349Sphk}
2248104349Sphk
2249178848Scokanestatic enum XML_Error
2250104349SphkdoContent(XML_Parser parser,
2251104349Sphk          int startTagLevel,
2252104349Sphk          const ENCODING *enc,
2253104349Sphk          const char *s,
2254104349Sphk          const char *end,
2255178848Scokane          const char **nextPtr,
2256178848Scokane          XML_Bool haveMore)
2257104349Sphk{
2258178848Scokane  /* save one level of indirection */
2259247513Sdelphij  DTD * const dtd = _dtd;
2260178848Scokane
2261104349Sphk  const char **eventPP;
2262104349Sphk  const char **eventEndPP;
2263104349Sphk  if (enc == encoding) {
2264104349Sphk    eventPP = &eventPtr;
2265104349Sphk    eventEndPP = &eventEndPtr;
2266104349Sphk  }
2267104349Sphk  else {
2268104349Sphk    eventPP = &(openInternalEntities->internalEventPtr);
2269104349Sphk    eventEndPP = &(openInternalEntities->internalEventEndPtr);
2270104349Sphk  }
2271104349Sphk  *eventPP = s;
2272178848Scokane
2273104349Sphk  for (;;) {
2274104349Sphk    const char *next = s; /* XmlContentTok doesn't always set the last arg */
2275104349Sphk    int tok = XmlContentTok(enc, s, end, &next);
2276104349Sphk    *eventEndPP = next;
2277104349Sphk    switch (tok) {
2278104349Sphk    case XML_TOK_TRAILING_CR:
2279178848Scokane      if (haveMore) {
2280104349Sphk        *nextPtr = s;
2281104349Sphk        return XML_ERROR_NONE;
2282104349Sphk      }
2283104349Sphk      *eventEndPP = end;
2284104349Sphk      if (characterDataHandler) {
2285104349Sphk        XML_Char c = 0xA;
2286104349Sphk        characterDataHandler(handlerArg, &c, 1);
2287104349Sphk      }
2288104349Sphk      else if (defaultHandler)
2289104349Sphk        reportDefault(parser, enc, s, end);
2290247513Sdelphij      /* We are at the end of the final buffer, should we check for
2291247513Sdelphij         XML_SUSPENDED, XML_FINISHED?
2292178848Scokane      */
2293104349Sphk      if (startTagLevel == 0)
2294104349Sphk        return XML_ERROR_NO_ELEMENTS;
2295104349Sphk      if (tagLevel != startTagLevel)
2296104349Sphk        return XML_ERROR_ASYNC_ENTITY;
2297178848Scokane      *nextPtr = end;
2298104349Sphk      return XML_ERROR_NONE;
2299104349Sphk    case XML_TOK_NONE:
2300178848Scokane      if (haveMore) {
2301104349Sphk        *nextPtr = s;
2302104349Sphk        return XML_ERROR_NONE;
2303104349Sphk      }
2304104349Sphk      if (startTagLevel > 0) {
2305104349Sphk        if (tagLevel != startTagLevel)
2306104349Sphk          return XML_ERROR_ASYNC_ENTITY;
2307178848Scokane        *nextPtr = s;
2308104349Sphk        return XML_ERROR_NONE;
2309104349Sphk      }
2310104349Sphk      return XML_ERROR_NO_ELEMENTS;
2311104349Sphk    case XML_TOK_INVALID:
2312104349Sphk      *eventPP = next;
2313104349Sphk      return XML_ERROR_INVALID_TOKEN;
2314104349Sphk    case XML_TOK_PARTIAL:
2315178848Scokane      if (haveMore) {
2316104349Sphk        *nextPtr = s;
2317104349Sphk        return XML_ERROR_NONE;
2318104349Sphk      }
2319104349Sphk      return XML_ERROR_UNCLOSED_TOKEN;
2320104349Sphk    case XML_TOK_PARTIAL_CHAR:
2321178848Scokane      if (haveMore) {
2322104349Sphk        *nextPtr = s;
2323104349Sphk        return XML_ERROR_NONE;
2324104349Sphk      }
2325104349Sphk      return XML_ERROR_PARTIAL_CHAR;
2326104349Sphk    case XML_TOK_ENTITY_REF:
2327104349Sphk      {
2328104349Sphk        const XML_Char *name;
2329104349Sphk        ENTITY *entity;
2330104349Sphk        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
2331104349Sphk                                              s + enc->minBytesPerChar,
2332104349Sphk                                              next - enc->minBytesPerChar);
2333104349Sphk        if (ch) {
2334104349Sphk          if (characterDataHandler)
2335104349Sphk            characterDataHandler(handlerArg, &ch, 1);
2336104349Sphk          else if (defaultHandler)
2337104349Sphk            reportDefault(parser, enc, s, next);
2338104349Sphk          break;
2339104349Sphk        }
2340178848Scokane        name = poolStoreString(&dtd->pool, enc,
2341104349Sphk                                s + enc->minBytesPerChar,
2342104349Sphk                                next - enc->minBytesPerChar);
2343104349Sphk        if (!name)
2344104349Sphk          return XML_ERROR_NO_MEMORY;
2345247513Sdelphij        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
2346178848Scokane        poolDiscard(&dtd->pool);
2347104349Sphk        /* First, determine if a check for an existing declaration is needed;
2348104349Sphk           if yes, check that the entity exists, and that it is internal,
2349104349Sphk           otherwise call the skipped entity or default handler.
2350104349Sphk        */
2351178848Scokane        if (!dtd->hasParamEntityRefs || dtd->standalone) {
2352104349Sphk          if (!entity)
2353104349Sphk            return XML_ERROR_UNDEFINED_ENTITY;
2354104349Sphk          else if (!entity->is_internal)
2355104349Sphk            return XML_ERROR_ENTITY_DECLARED_IN_PE;
2356104349Sphk        }
2357104349Sphk        else if (!entity) {
2358104349Sphk          if (skippedEntityHandler)
2359104349Sphk            skippedEntityHandler(handlerArg, name, 0);
2360104349Sphk          else if (defaultHandler)
2361104349Sphk            reportDefault(parser, enc, s, next);
2362104349Sphk          break;
2363104349Sphk        }
2364104349Sphk        if (entity->open)
2365104349Sphk          return XML_ERROR_RECURSIVE_ENTITY_REF;
2366104349Sphk        if (entity->notation)
2367104349Sphk          return XML_ERROR_BINARY_ENTITY_REF;
2368104349Sphk        if (entity->textPtr) {
2369104349Sphk          enum XML_Error result;
2370104349Sphk          if (!defaultExpandInternalEntities) {
2371104349Sphk            if (skippedEntityHandler)
2372104349Sphk              skippedEntityHandler(handlerArg, entity->name, 0);
2373104349Sphk            else if (defaultHandler)
2374104349Sphk              reportDefault(parser, enc, s, next);
2375104349Sphk            break;
2376104349Sphk          }
2377178848Scokane          result = processInternalEntity(parser, entity, XML_FALSE);
2378178848Scokane          if (result != XML_ERROR_NONE)
2379104349Sphk            return result;
2380104349Sphk        }
2381104349Sphk        else if (externalEntityRefHandler) {
2382104349Sphk          const XML_Char *context;
2383104349Sphk          entity->open = XML_TRUE;
2384104349Sphk          context = getContext(parser);
2385104349Sphk          entity->open = XML_FALSE;
2386104349Sphk          if (!context)
2387104349Sphk            return XML_ERROR_NO_MEMORY;
2388104349Sphk          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
2389104349Sphk                                        context,
2390104349Sphk                                        entity->base,
2391104349Sphk                                        entity->systemId,
2392104349Sphk                                        entity->publicId))
2393104349Sphk            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
2394104349Sphk          poolDiscard(&tempPool);
2395104349Sphk        }
2396104349Sphk        else if (defaultHandler)
2397104349Sphk          reportDefault(parser, enc, s, next);
2398104349Sphk        break;
2399104349Sphk      }
2400178848Scokane    case XML_TOK_START_TAG_NO_ATTS:
2401178848Scokane      /* fall through */
2402104349Sphk    case XML_TOK_START_TAG_WITH_ATTS:
2403104349Sphk      {
2404104349Sphk        TAG *tag;
2405104349Sphk        enum XML_Error result;
2406104349Sphk        XML_Char *toPtr;
2407104349Sphk        if (freeTagList) {
2408104349Sphk          tag = freeTagList;
2409104349Sphk          freeTagList = freeTagList->parent;
2410104349Sphk        }
2411104349Sphk        else {
2412178848Scokane          tag = (TAG *)MALLOC(sizeof(TAG));
2413104349Sphk          if (!tag)
2414104349Sphk            return XML_ERROR_NO_MEMORY;
2415178848Scokane          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
2416104349Sphk          if (!tag->buf) {
2417104349Sphk            FREE(tag);
2418104349Sphk            return XML_ERROR_NO_MEMORY;
2419104349Sphk          }
2420104349Sphk          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
2421104349Sphk        }
2422104349Sphk        tag->bindings = NULL;
2423104349Sphk        tag->parent = tagStack;
2424104349Sphk        tagStack = tag;
2425104349Sphk        tag->name.localPart = NULL;
2426104349Sphk        tag->name.prefix = NULL;
2427104349Sphk        tag->rawName = s + enc->minBytesPerChar;
2428104349Sphk        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
2429104349Sphk        ++tagLevel;
2430104349Sphk        {
2431104349Sphk          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
2432104349Sphk          const char *fromPtr = tag->rawName;
2433104349Sphk          toPtr = (XML_Char *)tag->buf;
2434104349Sphk          for (;;) {
2435104349Sphk            int bufSize;
2436104349Sphk            int convLen;
2437104349Sphk            XmlConvert(enc,
2438104349Sphk                       &fromPtr, rawNameEnd,
2439104349Sphk                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
2440178848Scokane            convLen = (int)(toPtr - (XML_Char *)tag->buf);
2441104349Sphk            if (fromPtr == rawNameEnd) {
2442104349Sphk              tag->name.strLen = convLen;
2443104349Sphk              break;
2444104349Sphk            }
2445178848Scokane            bufSize = (int)(tag->bufEnd - tag->buf) << 1;
2446104349Sphk            {
2447178848Scokane              char *temp = (char *)REALLOC(tag->buf, bufSize);
2448104349Sphk              if (temp == NULL)
2449104349Sphk                return XML_ERROR_NO_MEMORY;
2450104349Sphk              tag->buf = temp;
2451104349Sphk              tag->bufEnd = temp + bufSize;
2452104349Sphk              toPtr = (XML_Char *)temp + convLen;
2453104349Sphk            }
2454104349Sphk          }
2455104349Sphk        }
2456104349Sphk        tag->name.str = (XML_Char *)tag->buf;
2457104349Sphk        *toPtr = XML_T('\0');
2458178848Scokane        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
2459178848Scokane        if (result)
2460178848Scokane          return result;
2461178848Scokane        if (startElementHandler)
2462104349Sphk          startElementHandler(handlerArg, tag->name.str,
2463104349Sphk                              (const XML_Char **)atts);
2464104349Sphk        else if (defaultHandler)
2465104349Sphk          reportDefault(parser, enc, s, next);
2466104349Sphk        poolClear(&tempPool);
2467104349Sphk        break;
2468104349Sphk      }
2469178848Scokane    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
2470178848Scokane      /* fall through */
2471104349Sphk    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
2472178848Scokane      {
2473104349Sphk        const char *rawName = s + enc->minBytesPerChar;
2474104349Sphk        enum XML_Error result;
2475104349Sphk        BINDING *bindings = NULL;
2476178848Scokane        XML_Bool noElmHandlers = XML_TRUE;
2477104349Sphk        TAG_NAME name;
2478104349Sphk        name.str = poolStoreString(&tempPool, enc, rawName,
2479104349Sphk                                   rawName + XmlNameLength(enc, rawName));
2480104349Sphk        if (!name.str)
2481104349Sphk          return XML_ERROR_NO_MEMORY;
2482104349Sphk        poolFinish(&tempPool);
2483104349Sphk        result = storeAtts(parser, enc, s, &name, &bindings);
2484104349Sphk        if (result)
2485104349Sphk          return result;
2486104349Sphk        poolFinish(&tempPool);
2487178848Scokane        if (startElementHandler) {
2488104349Sphk          startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
2489178848Scokane          noElmHandlers = XML_FALSE;
2490178848Scokane        }
2491104349Sphk        if (endElementHandler) {
2492104349Sphk          if (startElementHandler)
2493104349Sphk            *eventPP = *eventEndPP;
2494104349Sphk          endElementHandler(handlerArg, name.str);
2495178848Scokane          noElmHandlers = XML_FALSE;
2496104349Sphk        }
2497178848Scokane        if (noElmHandlers && defaultHandler)
2498178848Scokane          reportDefault(parser, enc, s, next);
2499104349Sphk        poolClear(&tempPool);
2500104349Sphk        while (bindings) {
2501104349Sphk          BINDING *b = bindings;
2502104349Sphk          if (endNamespaceDeclHandler)
2503104349Sphk            endNamespaceDeclHandler(handlerArg, b->prefix->name);
2504104349Sphk          bindings = bindings->nextTagBinding;
2505104349Sphk          b->nextTagBinding = freeBindingList;
2506104349Sphk          freeBindingList = b;
2507104349Sphk          b->prefix->binding = b->prevPrefixBinding;
2508104349Sphk        }
2509104349Sphk      }
2510104349Sphk      if (tagLevel == 0)
2511104349Sphk        return epilogProcessor(parser, next, end, nextPtr);
2512104349Sphk      break;
2513104349Sphk    case XML_TOK_END_TAG:
2514104349Sphk      if (tagLevel == startTagLevel)
2515104349Sphk        return XML_ERROR_ASYNC_ENTITY;
2516104349Sphk      else {
2517104349Sphk        int len;
2518104349Sphk        const char *rawName;
2519104349Sphk        TAG *tag = tagStack;
2520104349Sphk        tagStack = tag->parent;
2521104349Sphk        tag->parent = freeTagList;
2522104349Sphk        freeTagList = tag;
2523104349Sphk        rawName = s + enc->minBytesPerChar*2;
2524104349Sphk        len = XmlNameLength(enc, rawName);
2525104349Sphk        if (len != tag->rawNameLength
2526104349Sphk            || memcmp(tag->rawName, rawName, len) != 0) {
2527104349Sphk          *eventPP = rawName;
2528104349Sphk          return XML_ERROR_TAG_MISMATCH;
2529104349Sphk        }
2530104349Sphk        --tagLevel;
2531104349Sphk        if (endElementHandler) {
2532104349Sphk          const XML_Char *localPart;
2533104349Sphk          const XML_Char *prefix;
2534104349Sphk          XML_Char *uri;
2535104349Sphk          localPart = tag->name.localPart;
2536104349Sphk          if (ns && localPart) {
2537104349Sphk            /* localPart and prefix may have been overwritten in
2538104349Sphk               tag->name.str, since this points to the binding->uri
2539104349Sphk               buffer which gets re-used; so we have to add them again
2540104349Sphk            */
2541104349Sphk            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
2542104349Sphk            /* don't need to check for space - already done in storeAtts() */
2543104349Sphk            while (*localPart) *uri++ = *localPart++;
2544104349Sphk            prefix = (XML_Char *)tag->name.prefix;
2545104349Sphk            if (ns_triplets && prefix) {
2546104349Sphk              *uri++ = namespaceSeparator;
2547104349Sphk              while (*prefix) *uri++ = *prefix++;
2548104349Sphk             }
2549104349Sphk            *uri = XML_T('\0');
2550104349Sphk          }
2551104349Sphk          endElementHandler(handlerArg, tag->name.str);
2552104349Sphk        }
2553104349Sphk        else if (defaultHandler)
2554104349Sphk          reportDefault(parser, enc, s, next);
2555104349Sphk        while (tag->bindings) {
2556104349Sphk          BINDING *b = tag->bindings;
2557104349Sphk          if (endNamespaceDeclHandler)
2558104349Sphk            endNamespaceDeclHandler(handlerArg, b->prefix->name);
2559104349Sphk          tag->bindings = tag->bindings->nextTagBinding;
2560104349Sphk          b->nextTagBinding = freeBindingList;
2561104349Sphk          freeBindingList = b;
2562104349Sphk          b->prefix->binding = b->prevPrefixBinding;
2563104349Sphk        }
2564104349Sphk        if (tagLevel == 0)
2565104349Sphk          return epilogProcessor(parser, next, end, nextPtr);
2566104349Sphk      }
2567104349Sphk      break;
2568104349Sphk    case XML_TOK_CHAR_REF:
2569104349Sphk      {
2570104349Sphk        int n = XmlCharRefNumber(enc, s);
2571104349Sphk        if (n < 0)
2572104349Sphk          return XML_ERROR_BAD_CHAR_REF;
2573104349Sphk        if (characterDataHandler) {
2574104349Sphk          XML_Char buf[XML_ENCODE_MAX];
2575104349Sphk          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
2576104349Sphk        }
2577104349Sphk        else if (defaultHandler)
2578104349Sphk          reportDefault(parser, enc, s, next);
2579104349Sphk      }
2580104349Sphk      break;
2581104349Sphk    case XML_TOK_XML_DECL:
2582104349Sphk      return XML_ERROR_MISPLACED_XML_PI;
2583104349Sphk    case XML_TOK_DATA_NEWLINE:
2584104349Sphk      if (characterDataHandler) {
2585104349Sphk        XML_Char c = 0xA;
2586104349Sphk        characterDataHandler(handlerArg, &c, 1);
2587104349Sphk      }
2588104349Sphk      else if (defaultHandler)
2589104349Sphk        reportDefault(parser, enc, s, next);
2590104349Sphk      break;
2591104349Sphk    case XML_TOK_CDATA_SECT_OPEN:
2592104349Sphk      {
2593104349Sphk        enum XML_Error result;
2594104349Sphk        if (startCdataSectionHandler)
2595104349Sphk          startCdataSectionHandler(handlerArg);
2596104349Sphk#if 0
2597104349Sphk        /* Suppose you doing a transformation on a document that involves
2598104349Sphk           changing only the character data.  You set up a defaultHandler
2599104349Sphk           and a characterDataHandler.  The defaultHandler simply copies
2600104349Sphk           characters through.  The characterDataHandler does the
2601104349Sphk           transformation and writes the characters out escaping them as
2602104349Sphk           necessary.  This case will fail to work if we leave out the
2603104349Sphk           following two lines (because & and < inside CDATA sections will
2604104349Sphk           be incorrectly escaped).
2605104349Sphk
2606104349Sphk           However, now we have a start/endCdataSectionHandler, so it seems
2607104349Sphk           easier to let the user deal with this.
2608104349Sphk        */
2609104349Sphk        else if (characterDataHandler)
2610104349Sphk          characterDataHandler(handlerArg, dataBuf, 0);
2611104349Sphk#endif
2612104349Sphk        else if (defaultHandler)
2613104349Sphk          reportDefault(parser, enc, s, next);
2614178848Scokane        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
2615178848Scokane        if (result != XML_ERROR_NONE)
2616178848Scokane          return result;
2617178848Scokane        else if (!next) {
2618104349Sphk          processor = cdataSectionProcessor;
2619104349Sphk          return result;
2620104349Sphk        }
2621104349Sphk      }
2622104349Sphk      break;
2623104349Sphk    case XML_TOK_TRAILING_RSQB:
2624178848Scokane      if (haveMore) {
2625104349Sphk        *nextPtr = s;
2626104349Sphk        return XML_ERROR_NONE;
2627104349Sphk      }
2628104349Sphk      if (characterDataHandler) {
2629104349Sphk        if (MUST_CONVERT(enc, s)) {
2630104349Sphk          ICHAR *dataPtr = (ICHAR *)dataBuf;
2631104349Sphk          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
2632104349Sphk          characterDataHandler(handlerArg, dataBuf,
2633178848Scokane                               (int)(dataPtr - (ICHAR *)dataBuf));
2634104349Sphk        }
2635104349Sphk        else
2636104349Sphk          characterDataHandler(handlerArg,
2637104349Sphk                               (XML_Char *)s,
2638178848Scokane                               (int)((XML_Char *)end - (XML_Char *)s));
2639104349Sphk      }
2640104349Sphk      else if (defaultHandler)
2641104349Sphk        reportDefault(parser, enc, s, end);
2642247513Sdelphij      /* We are at the end of the final buffer, should we check for
2643247513Sdelphij         XML_SUSPENDED, XML_FINISHED?
2644178848Scokane      */
2645104349Sphk      if (startTagLevel == 0) {
2646104349Sphk        *eventPP = end;
2647104349Sphk        return XML_ERROR_NO_ELEMENTS;
2648104349Sphk      }
2649104349Sphk      if (tagLevel != startTagLevel) {
2650104349Sphk        *eventPP = end;
2651104349Sphk        return XML_ERROR_ASYNC_ENTITY;
2652104349Sphk      }
2653178848Scokane      *nextPtr = end;
2654104349Sphk      return XML_ERROR_NONE;
2655247513Sdelphij    case XML_TOK_DATA_CHARS:
2656178848Scokane      {
2657178848Scokane        XML_CharacterDataHandler charDataHandler = characterDataHandler;
2658178848Scokane        if (charDataHandler) {
2659178848Scokane          if (MUST_CONVERT(enc, s)) {
2660178848Scokane            for (;;) {
2661178848Scokane              ICHAR *dataPtr = (ICHAR *)dataBuf;
2662178848Scokane              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
2663178848Scokane              *eventEndPP = s;
2664178848Scokane              charDataHandler(handlerArg, dataBuf,
2665178848Scokane                              (int)(dataPtr - (ICHAR *)dataBuf));
2666178848Scokane              if (s == next)
2667178848Scokane                break;
2668178848Scokane              *eventPP = s;
2669178848Scokane            }
2670104349Sphk          }
2671178848Scokane          else
2672178848Scokane            charDataHandler(handlerArg,
2673178848Scokane                            (XML_Char *)s,
2674178848Scokane                            (int)((XML_Char *)next - (XML_Char *)s));
2675104349Sphk        }
2676178848Scokane        else if (defaultHandler)
2677178848Scokane          reportDefault(parser, enc, s, next);
2678104349Sphk      }
2679104349Sphk      break;
2680104349Sphk    case XML_TOK_PI:
2681104349Sphk      if (!reportProcessingInstruction(parser, enc, s, next))
2682104349Sphk        return XML_ERROR_NO_MEMORY;
2683104349Sphk      break;
2684104349Sphk    case XML_TOK_COMMENT:
2685104349Sphk      if (!reportComment(parser, enc, s, next))
2686104349Sphk        return XML_ERROR_NO_MEMORY;
2687104349Sphk      break;
2688104349Sphk    default:
2689104349Sphk      if (defaultHandler)
2690104349Sphk        reportDefault(parser, enc, s, next);
2691104349Sphk      break;
2692104349Sphk    }
2693104349Sphk    *eventPP = s = next;
2694178848Scokane    switch (ps_parsing) {
2695247513Sdelphij    case XML_SUSPENDED:
2696178848Scokane      *nextPtr = next;
2697178848Scokane      return XML_ERROR_NONE;
2698178848Scokane    case XML_FINISHED:
2699178848Scokane      return XML_ERROR_ABORTED;
2700178848Scokane    default: ;
2701178848Scokane    }
2702104349Sphk  }
2703104349Sphk  /* not reached */
2704104349Sphk}
2705104349Sphk
2706178848Scokane/* Precondition: all arguments must be non-NULL;
2707178848Scokane   Purpose:
2708178848Scokane   - normalize attributes
2709178848Scokane   - check attributes for well-formedness
2710178848Scokane   - generate namespace aware attribute names (URI, prefix)
2711178848Scokane   - build list of attributes for startElementHandler
2712178848Scokane   - default attributes
2713178848Scokane   - process namespace declarations (check and report them)
2714178848Scokane   - generate namespace aware element name (URI, prefix)
2715104349Sphk*/
2716178848Scokanestatic enum XML_Error
2717104349SphkstoreAtts(XML_Parser parser, const ENCODING *enc,
2718104349Sphk          const char *attStr, TAG_NAME *tagNamePtr,
2719104349Sphk          BINDING **bindingsPtr)
2720104349Sphk{
2721178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
2722178848Scokane  ELEMENT_TYPE *elementType;
2723178848Scokane  int nDefaultAtts;
2724104349Sphk  const XML_Char **appAtts;   /* the attribute list for the application */
2725104349Sphk  int attIndex = 0;
2726104349Sphk  int prefixLen;
2727104349Sphk  int i;
2728104349Sphk  int n;
2729104349Sphk  XML_Char *uri;
2730104349Sphk  int nPrefixes = 0;
2731104349Sphk  BINDING *binding;
2732104349Sphk  const XML_Char *localPart;
2733104349Sphk
2734104349Sphk  /* lookup the element type name */
2735247513Sdelphij  elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
2736178848Scokane  if (!elementType) {
2737178848Scokane    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
2738178848Scokane    if (!name)
2739178848Scokane      return XML_ERROR_NO_MEMORY;
2740247513Sdelphij    elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
2741178848Scokane                                         sizeof(ELEMENT_TYPE));
2742178848Scokane    if (!elementType)
2743178848Scokane      return XML_ERROR_NO_MEMORY;
2744178848Scokane    if (ns && !setElementTypePrefix(parser, elementType))
2745178848Scokane      return XML_ERROR_NO_MEMORY;
2746104349Sphk  }
2747178848Scokane  nDefaultAtts = elementType->nDefaultAtts;
2748178848Scokane
2749104349Sphk  /* get the attributes from the tokenizer */
2750104349Sphk  n = XmlGetAttributes(enc, attStr, attsSize, atts);
2751104349Sphk  if (n + nDefaultAtts > attsSize) {
2752104349Sphk    int oldAttsSize = attsSize;
2753104349Sphk    ATTRIBUTE *temp;
2754247513Sdelphij#ifdef XML_ATTR_INFO
2755247513Sdelphij    XML_AttrInfo *temp2;
2756247513Sdelphij#endif
2757104349Sphk    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
2758178848Scokane    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
2759104349Sphk    if (temp == NULL)
2760104349Sphk      return XML_ERROR_NO_MEMORY;
2761104349Sphk    atts = temp;
2762247513Sdelphij#ifdef XML_ATTR_INFO
2763247513Sdelphij    temp2 = (XML_AttrInfo *)REALLOC((void *)attInfo, attsSize * sizeof(XML_AttrInfo));
2764247513Sdelphij    if (temp2 == NULL)
2765247513Sdelphij      return XML_ERROR_NO_MEMORY;
2766247513Sdelphij    attInfo = temp2;
2767247513Sdelphij#endif
2768104349Sphk    if (n > oldAttsSize)
2769104349Sphk      XmlGetAttributes(enc, attStr, n, atts);
2770104349Sphk  }
2771178848Scokane
2772104349Sphk  appAtts = (const XML_Char **)atts;
2773104349Sphk  for (i = 0; i < n; i++) {
2774247513Sdelphij    ATTRIBUTE *currAtt = &atts[i];
2775247513Sdelphij#ifdef XML_ATTR_INFO
2776247513Sdelphij    XML_AttrInfo *currAttInfo = &attInfo[i];
2777247513Sdelphij#endif
2778104349Sphk    /* add the name and value to the attribute list */
2779247513Sdelphij    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,
2780247513Sdelphij                                         currAtt->name
2781247513Sdelphij                                         + XmlNameLength(enc, currAtt->name));
2782104349Sphk    if (!attId)
2783104349Sphk      return XML_ERROR_NO_MEMORY;
2784247513Sdelphij#ifdef XML_ATTR_INFO
2785247513Sdelphij    currAttInfo->nameStart = parseEndByteIndex - (parseEndPtr - currAtt->name);
2786247513Sdelphij    currAttInfo->nameEnd = currAttInfo->nameStart +
2787247513Sdelphij                           XmlNameLength(enc, currAtt->name);
2788247513Sdelphij    currAttInfo->valueStart = parseEndByteIndex -
2789247513Sdelphij                            (parseEndPtr - currAtt->valuePtr);
2790247513Sdelphij    currAttInfo->valueEnd = parseEndByteIndex - (parseEndPtr - currAtt->valueEnd);
2791247513Sdelphij#endif
2792178848Scokane    /* Detect duplicate attributes by their QNames. This does not work when
2793178848Scokane       namespace processing is turned on and different prefixes for the same
2794178848Scokane       namespace are used. For this case we have a check further down.
2795178848Scokane    */
2796104349Sphk    if ((attId->name)[-1]) {
2797104349Sphk      if (enc == encoding)
2798104349Sphk        eventPtr = atts[i].name;
2799104349Sphk      return XML_ERROR_DUPLICATE_ATTRIBUTE;
2800104349Sphk    }
2801104349Sphk    (attId->name)[-1] = 1;
2802104349Sphk    appAtts[attIndex++] = attId->name;
2803104349Sphk    if (!atts[i].normalized) {
2804104349Sphk      enum XML_Error result;
2805104349Sphk      XML_Bool isCdata = XML_TRUE;
2806104349Sphk
2807104349Sphk      /* figure out whether declared as other than CDATA */
2808104349Sphk      if (attId->maybeTokenized) {
2809104349Sphk        int j;
2810104349Sphk        for (j = 0; j < nDefaultAtts; j++) {
2811104349Sphk          if (attId == elementType->defaultAtts[j].id) {
2812104349Sphk            isCdata = elementType->defaultAtts[j].isCdata;
2813104349Sphk            break;
2814104349Sphk          }
2815104349Sphk        }
2816104349Sphk      }
2817104349Sphk
2818104349Sphk      /* normalize the attribute value */
2819104349Sphk      result = storeAttributeValue(parser, enc, isCdata,
2820104349Sphk                                   atts[i].valuePtr, atts[i].valueEnd,
2821104349Sphk                                   &tempPool);
2822104349Sphk      if (result)
2823104349Sphk        return result;
2824178848Scokane      appAtts[attIndex] = poolStart(&tempPool);
2825178848Scokane      poolFinish(&tempPool);
2826104349Sphk    }
2827178848Scokane    else {
2828104349Sphk      /* the value did not need normalizing */
2829104349Sphk      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
2830104349Sphk                                          atts[i].valueEnd);
2831104349Sphk      if (appAtts[attIndex] == 0)
2832104349Sphk        return XML_ERROR_NO_MEMORY;
2833104349Sphk      poolFinish(&tempPool);
2834104349Sphk    }
2835104349Sphk    /* handle prefixed attribute names */
2836178848Scokane    if (attId->prefix) {
2837104349Sphk      if (attId->xmlns) {
2838104349Sphk        /* deal with namespace declarations here */
2839178848Scokane        enum XML_Error result = addBinding(parser, attId->prefix, attId,
2840178848Scokane                                           appAtts[attIndex], bindingsPtr);
2841178848Scokane        if (result)
2842178848Scokane          return result;
2843104349Sphk        --attIndex;
2844104349Sphk      }
2845104349Sphk      else {
2846104349Sphk        /* deal with other prefixed names later */
2847104349Sphk        attIndex++;
2848104349Sphk        nPrefixes++;
2849104349Sphk        (attId->name)[-1] = 2;
2850104349Sphk      }
2851104349Sphk    }
2852104349Sphk    else
2853104349Sphk      attIndex++;
2854104349Sphk  }
2855178848Scokane
2856178848Scokane  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
2857178848Scokane  nSpecifiedAtts = attIndex;
2858178848Scokane  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
2859178848Scokane    for (i = 0; i < attIndex; i += 2)
2860178848Scokane      if (appAtts[i] == elementType->idAtt->name) {
2861178848Scokane        idAttIndex = i;
2862178848Scokane        break;
2863178848Scokane      }
2864178848Scokane  }
2865178848Scokane  else
2866178848Scokane    idAttIndex = -1;
2867178848Scokane
2868178848Scokane  /* do attribute defaulting */
2869178848Scokane  for (i = 0; i < nDefaultAtts; i++) {
2870178848Scokane    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
2871178848Scokane    if (!(da->id->name)[-1] && da->value) {
2872178848Scokane      if (da->id->prefix) {
2873178848Scokane        if (da->id->xmlns) {
2874178848Scokane          enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
2875178848Scokane                                             da->value, bindingsPtr);
2876178848Scokane          if (result)
2877178848Scokane            return result;
2878104349Sphk        }
2879104349Sphk        else {
2880178848Scokane          (da->id->name)[-1] = 2;
2881178848Scokane          nPrefixes++;
2882104349Sphk          appAtts[attIndex++] = da->id->name;
2883104349Sphk          appAtts[attIndex++] = da->value;
2884104349Sphk        }
2885104349Sphk      }
2886178848Scokane      else {
2887178848Scokane        (da->id->name)[-1] = 1;
2888178848Scokane        appAtts[attIndex++] = da->id->name;
2889178848Scokane        appAtts[attIndex++] = da->value;
2890178848Scokane      }
2891104349Sphk    }
2892104349Sphk  }
2893178848Scokane  appAtts[attIndex] = 0;
2894178848Scokane
2895178848Scokane  /* expand prefixed attribute names, check for duplicates,
2896178848Scokane     and clear flags that say whether attributes were specified */
2897104349Sphk  i = 0;
2898104349Sphk  if (nPrefixes) {
2899178848Scokane    int j;  /* hash table index */
2900178848Scokane    unsigned long version = nsAttsVersion;
2901178848Scokane    int nsAttsSize = (int)1 << nsAttsPower;
2902178848Scokane    /* size of hash table must be at least 2 * (# of prefixed attributes) */
2903178848Scokane    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */
2904178848Scokane      NS_ATT *temp;
2905178848Scokane      /* hash table size must also be a power of 2 and >= 8 */
2906178848Scokane      while (nPrefixes >> nsAttsPower++);
2907178848Scokane      if (nsAttsPower < 3)
2908178848Scokane        nsAttsPower = 3;
2909178848Scokane      nsAttsSize = (int)1 << nsAttsPower;
2910178848Scokane      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
2911178848Scokane      if (!temp)
2912178848Scokane        return XML_ERROR_NO_MEMORY;
2913178848Scokane      nsAtts = temp;
2914178848Scokane      version = 0;  /* force re-initialization of nsAtts hash table */
2915178848Scokane    }
2916178848Scokane    /* using a version flag saves us from initializing nsAtts every time */
2917178848Scokane    if (!version) {  /* initialize version flags when version wraps around */
2918178848Scokane      version = INIT_ATTS_VERSION;
2919178848Scokane      for (j = nsAttsSize; j != 0; )
2920178848Scokane        nsAtts[--j].version = version;
2921178848Scokane    }
2922178848Scokane    nsAttsVersion = --version;
2923178848Scokane
2924178848Scokane    /* expand prefixed names and check for duplicates */
2925104349Sphk    for (; i < attIndex; i += 2) {
2926178848Scokane      const XML_Char *s = appAtts[i];
2927178848Scokane      if (s[-1] == 2) {  /* prefixed */
2928104349Sphk        ATTRIBUTE_ID *id;
2929178848Scokane        const BINDING *b;
2930247513Sdelphij        unsigned long uriHash = hash_secret_salt;
2931178848Scokane        ((XML_Char *)s)[-1] = 0;  /* clear flag */
2932247513Sdelphij        id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
2933178848Scokane        b = id->prefix->binding;
2934178848Scokane        if (!b)
2935178848Scokane          return XML_ERROR_UNBOUND_PREFIX;
2936178848Scokane
2937178848Scokane        /* as we expand the name we also calculate its hash value */
2938178848Scokane        for (j = 0; j < b->uriLen; j++) {
2939178848Scokane          const XML_Char c = b->uri[j];
2940178848Scokane          if (!poolAppendChar(&tempPool, c))
2941178848Scokane            return XML_ERROR_NO_MEMORY;
2942178848Scokane          uriHash = CHAR_HASH(uriHash, c);
2943178848Scokane        }
2944178848Scokane        while (*s++ != XML_T(ASCII_COLON))
2945178848Scokane          ;
2946178848Scokane        do {  /* copies null terminator */
2947178848Scokane          const XML_Char c = *s;
2948178848Scokane          if (!poolAppendChar(&tempPool, *s))
2949178848Scokane            return XML_ERROR_NO_MEMORY;
2950178848Scokane          uriHash = CHAR_HASH(uriHash, c);
2951178848Scokane        } while (*s++);
2952178848Scokane
2953178848Scokane        { /* Check hash table for duplicate of expanded name (uriName).
2954247513Sdelphij             Derived from code in lookup(parser, HASH_TABLE *table, ...).
2955178848Scokane          */
2956178848Scokane          unsigned char step = 0;
2957178848Scokane          unsigned long mask = nsAttsSize - 1;
2958178848Scokane          j = uriHash & mask;  /* index into hash table */
2959178848Scokane          while (nsAtts[j].version == version) {
2960178848Scokane            /* for speed we compare stored hash values first */
2961178848Scokane            if (uriHash == nsAtts[j].hash) {
2962178848Scokane              const XML_Char *s1 = poolStart(&tempPool);
2963178848Scokane              const XML_Char *s2 = nsAtts[j].uriName;
2964178848Scokane              /* s1 is null terminated, but not s2 */
2965178848Scokane              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
2966178848Scokane              if (*s1 == 0)
2967178848Scokane                return XML_ERROR_DUPLICATE_ATTRIBUTE;
2968178848Scokane            }
2969178848Scokane            if (!step)
2970178848Scokane              step = PROBE_STEP(uriHash, mask, nsAttsPower);
2971178848Scokane            j < step ? (j += nsAttsSize - step) : (j -= step);
2972104349Sphk          }
2973178848Scokane        }
2974178848Scokane
2975178848Scokane        if (ns_triplets) {  /* append namespace separator and prefix */
2976178848Scokane          tempPool.ptr[-1] = namespaceSeparator;
2977178848Scokane          s = b->prefix->name;
2978104349Sphk          do {
2979104349Sphk            if (!poolAppendChar(&tempPool, *s))
2980104349Sphk              return XML_ERROR_NO_MEMORY;
2981104349Sphk          } while (*s++);
2982178848Scokane        }
2983104349Sphk
2984178848Scokane        /* store expanded name in attribute list */
2985178848Scokane        s = poolStart(&tempPool);
2986178848Scokane        poolFinish(&tempPool);
2987178848Scokane        appAtts[i] = s;
2988178848Scokane
2989178848Scokane        /* fill empty slot with new version, uriName and hash value */
2990178848Scokane        nsAtts[j].version = version;
2991178848Scokane        nsAtts[j].hash = uriHash;
2992178848Scokane        nsAtts[j].uriName = s;
2993178848Scokane
2994178848Scokane        if (!--nPrefixes) {
2995178848Scokane          i += 2;
2996178848Scokane          break;
2997104349Sphk        }
2998104349Sphk      }
2999178848Scokane      else  /* not prefixed */
3000178848Scokane        ((XML_Char *)s)[-1] = 0;  /* clear flag */
3001104349Sphk    }
3002104349Sphk  }
3003178848Scokane  /* clear flags for the remaining attributes */
3004104349Sphk  for (; i < attIndex; i += 2)
3005104349Sphk    ((XML_Char *)(appAtts[i]))[-1] = 0;
3006104349Sphk  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
3007104349Sphk    binding->attId->name[-1] = 0;
3008178848Scokane
3009178848Scokane  if (!ns)
3010178848Scokane    return XML_ERROR_NONE;
3011178848Scokane
3012104349Sphk  /* expand the element type name */
3013104349Sphk  if (elementType->prefix) {
3014104349Sphk    binding = elementType->prefix->binding;
3015104349Sphk    if (!binding)
3016178848Scokane      return XML_ERROR_UNBOUND_PREFIX;
3017104349Sphk    localPart = tagNamePtr->str;
3018178848Scokane    while (*localPart++ != XML_T(ASCII_COLON))
3019104349Sphk      ;
3020104349Sphk  }
3021178848Scokane  else if (dtd->defaultPrefix.binding) {
3022178848Scokane    binding = dtd->defaultPrefix.binding;
3023104349Sphk    localPart = tagNamePtr->str;
3024104349Sphk  }
3025104349Sphk  else
3026104349Sphk    return XML_ERROR_NONE;
3027104349Sphk  prefixLen = 0;
3028178848Scokane  if (ns_triplets && binding->prefix->name) {
3029104349Sphk    for (; binding->prefix->name[prefixLen++];)
3030178848Scokane      ;  /* prefixLen includes null terminator */
3031104349Sphk  }
3032104349Sphk  tagNamePtr->localPart = localPart;
3033104349Sphk  tagNamePtr->uriLen = binding->uriLen;
3034104349Sphk  tagNamePtr->prefix = binding->prefix->name;
3035104349Sphk  tagNamePtr->prefixLen = prefixLen;
3036104349Sphk  for (i = 0; localPart[i++];)
3037178848Scokane    ;  /* i includes null terminator */
3038104349Sphk  n = i + binding->uriLen + prefixLen;
3039104349Sphk  if (n > binding->uriAlloc) {
3040104349Sphk    TAG *p;
3041178848Scokane    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
3042104349Sphk    if (!uri)
3043104349Sphk      return XML_ERROR_NO_MEMORY;
3044104349Sphk    binding->uriAlloc = n + EXPAND_SPARE;
3045104349Sphk    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
3046104349Sphk    for (p = tagStack; p; p = p->parent)
3047104349Sphk      if (p->name.str == binding->uri)
3048104349Sphk        p->name.str = uri;
3049104349Sphk    FREE(binding->uri);
3050104349Sphk    binding->uri = uri;
3051104349Sphk  }
3052178848Scokane  /* if namespaceSeparator != '\0' then uri includes it already */
3053104349Sphk  uri = binding->uri + binding->uriLen;
3054104349Sphk  memcpy(uri, localPart, i * sizeof(XML_Char));
3055178848Scokane  /* we always have a namespace separator between localPart and prefix */
3056104349Sphk  if (prefixLen) {
3057178848Scokane    uri += i - 1;
3058178848Scokane    *uri = namespaceSeparator;  /* replace null terminator */
3059104349Sphk    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
3060104349Sphk  }
3061104349Sphk  tagNamePtr->str = binding->uri;
3062104349Sphk  return XML_ERROR_NONE;
3063104349Sphk}
3064104349Sphk
3065178848Scokane/* addBinding() overwrites the value of prefix->binding without checking.
3066178848Scokane   Therefore one must keep track of the old value outside of addBinding().
3067178848Scokane*/
3068178848Scokanestatic enum XML_Error
3069104349SphkaddBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
3070104349Sphk           const XML_Char *uri, BINDING **bindingsPtr)
3071104349Sphk{
3072178848Scokane  static const XML_Char xmlNamespace[] = {
3073178848Scokane    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3074178848Scokane    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3075247513Sdelphij    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
3076178848Scokane    ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
3077178848Scokane    ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
3078178848Scokane    ASCII_e, '\0'
3079178848Scokane  };
3080247513Sdelphij  static const int xmlLen =
3081178848Scokane    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
3082178848Scokane  static const XML_Char xmlnsNamespace[] = {
3083178848Scokane    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
3084178848Scokane    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
3085247513Sdelphij    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
3086247513Sdelphij    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
3087178848Scokane    ASCII_SLASH, '\0'
3088178848Scokane  };
3089247513Sdelphij  static const int xmlnsLen =
3090178848Scokane    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
3091178848Scokane
3092178848Scokane  XML_Bool mustBeXML = XML_FALSE;
3093178848Scokane  XML_Bool isXML = XML_TRUE;
3094178848Scokane  XML_Bool isXMLNS = XML_TRUE;
3095247513Sdelphij
3096104349Sphk  BINDING *b;
3097104349Sphk  int len;
3098178848Scokane
3099178848Scokane  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
3100178848Scokane  if (*uri == XML_T('\0') && prefix->name)
3101178848Scokane    return XML_ERROR_UNDECLARING_PREFIX;
3102178848Scokane
3103178848Scokane  if (prefix->name
3104178848Scokane      && prefix->name[0] == XML_T(ASCII_x)
3105178848Scokane      && prefix->name[1] == XML_T(ASCII_m)
3106178848Scokane      && prefix->name[2] == XML_T(ASCII_l)) {
3107178848Scokane
3108178848Scokane    /* Not allowed to bind xmlns */
3109178848Scokane    if (prefix->name[3] == XML_T(ASCII_n)
3110178848Scokane        && prefix->name[4] == XML_T(ASCII_s)
3111178848Scokane        && prefix->name[5] == XML_T('\0'))
3112178848Scokane      return XML_ERROR_RESERVED_PREFIX_XMLNS;
3113178848Scokane
3114178848Scokane    if (prefix->name[3] == XML_T('\0'))
3115178848Scokane      mustBeXML = XML_TRUE;
3116178848Scokane  }
3117178848Scokane
3118178848Scokane  for (len = 0; uri[len]; len++) {
3119178848Scokane    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
3120178848Scokane      isXML = XML_FALSE;
3121178848Scokane
3122247513Sdelphij    if (!mustBeXML && isXMLNS
3123178848Scokane        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
3124178848Scokane      isXMLNS = XML_FALSE;
3125178848Scokane  }
3126178848Scokane  isXML = isXML && len == xmlLen;
3127178848Scokane  isXMLNS = isXMLNS && len == xmlnsLen;
3128178848Scokane
3129178848Scokane  if (mustBeXML != isXML)
3130178848Scokane    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
3131178848Scokane                     : XML_ERROR_RESERVED_NAMESPACE_URI;
3132178848Scokane
3133178848Scokane  if (isXMLNS)
3134178848Scokane    return XML_ERROR_RESERVED_NAMESPACE_URI;
3135178848Scokane
3136104349Sphk  if (namespaceSeparator)
3137104349Sphk    len++;
3138104349Sphk  if (freeBindingList) {
3139104349Sphk    b = freeBindingList;
3140104349Sphk    if (len > b->uriAlloc) {
3141178848Scokane      XML_Char *temp = (XML_Char *)REALLOC(b->uri,
3142178848Scokane                          sizeof(XML_Char) * (len + EXPAND_SPARE));
3143104349Sphk      if (temp == NULL)
3144178848Scokane        return XML_ERROR_NO_MEMORY;
3145104349Sphk      b->uri = temp;
3146104349Sphk      b->uriAlloc = len + EXPAND_SPARE;
3147104349Sphk    }
3148104349Sphk    freeBindingList = b->nextTagBinding;
3149104349Sphk  }
3150104349Sphk  else {
3151178848Scokane    b = (BINDING *)MALLOC(sizeof(BINDING));
3152104349Sphk    if (!b)
3153178848Scokane      return XML_ERROR_NO_MEMORY;
3154178848Scokane    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
3155104349Sphk    if (!b->uri) {
3156104349Sphk      FREE(b);
3157178848Scokane      return XML_ERROR_NO_MEMORY;
3158104349Sphk    }
3159104349Sphk    b->uriAlloc = len + EXPAND_SPARE;
3160104349Sphk  }
3161104349Sphk  b->uriLen = len;
3162104349Sphk  memcpy(b->uri, uri, len * sizeof(XML_Char));
3163104349Sphk  if (namespaceSeparator)
3164104349Sphk    b->uri[len - 1] = namespaceSeparator;
3165104349Sphk  b->prefix = prefix;
3166104349Sphk  b->attId = attId;
3167104349Sphk  b->prevPrefixBinding = prefix->binding;
3168178848Scokane  /* NULL binding when default namespace undeclared */
3169178848Scokane  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
3170104349Sphk    prefix->binding = NULL;
3171104349Sphk  else
3172104349Sphk    prefix->binding = b;
3173104349Sphk  b->nextTagBinding = *bindingsPtr;
3174104349Sphk  *bindingsPtr = b;
3175178848Scokane  /* if attId == NULL then we are not starting a namespace scope */
3176178848Scokane  if (attId && startNamespaceDeclHandler)
3177104349Sphk    startNamespaceDeclHandler(handlerArg, prefix->name,
3178104349Sphk                              prefix->binding ? uri : 0);
3179178848Scokane  return XML_ERROR_NONE;
3180104349Sphk}
3181104349Sphk
3182104349Sphk/* The idea here is to avoid using stack for each CDATA section when
3183104349Sphk   the whole file is parsed with one call.
3184104349Sphk*/
3185178848Scokanestatic enum XML_Error PTRCALL
3186104349SphkcdataSectionProcessor(XML_Parser parser,
3187104349Sphk                      const char *start,
3188104349Sphk                      const char *end,
3189104349Sphk                      const char **endPtr)
3190104349Sphk{
3191178848Scokane  enum XML_Error result = doCdataSection(parser, encoding, &start, end,
3192178848Scokane                                         endPtr, (XML_Bool)!ps_finalBuffer);
3193178848Scokane  if (result != XML_ERROR_NONE)
3194178848Scokane    return result;
3195104349Sphk  if (start) {
3196104349Sphk    if (parentParser) {  /* we are parsing an external entity */
3197104349Sphk      processor = externalEntityContentProcessor;
3198104349Sphk      return externalEntityContentProcessor(parser, start, end, endPtr);
3199104349Sphk    }
3200104349Sphk    else {
3201104349Sphk      processor = contentProcessor;
3202104349Sphk      return contentProcessor(parser, start, end, endPtr);
3203104349Sphk    }
3204104349Sphk  }
3205104349Sphk  return result;
3206104349Sphk}
3207104349Sphk
3208178848Scokane/* startPtr gets set to non-null if the section is closed, and to null if
3209104349Sphk   the section is not yet closed.
3210104349Sphk*/
3211178848Scokanestatic enum XML_Error
3212104349SphkdoCdataSection(XML_Parser parser,
3213104349Sphk               const ENCODING *enc,
3214104349Sphk               const char **startPtr,
3215104349Sphk               const char *end,
3216178848Scokane               const char **nextPtr,
3217178848Scokane               XML_Bool haveMore)
3218104349Sphk{
3219104349Sphk  const char *s = *startPtr;
3220104349Sphk  const char **eventPP;
3221104349Sphk  const char **eventEndPP;
3222104349Sphk  if (enc == encoding) {
3223104349Sphk    eventPP = &eventPtr;
3224104349Sphk    *eventPP = s;
3225104349Sphk    eventEndPP = &eventEndPtr;
3226104349Sphk  }
3227104349Sphk  else {
3228104349Sphk    eventPP = &(openInternalEntities->internalEventPtr);
3229104349Sphk    eventEndPP = &(openInternalEntities->internalEventEndPtr);
3230104349Sphk  }
3231104349Sphk  *eventPP = s;
3232104349Sphk  *startPtr = NULL;
3233178848Scokane
3234104349Sphk  for (;;) {
3235104349Sphk    const char *next;
3236104349Sphk    int tok = XmlCdataSectionTok(enc, s, end, &next);
3237104349Sphk    *eventEndPP = next;
3238104349Sphk    switch (tok) {
3239104349Sphk    case XML_TOK_CDATA_SECT_CLOSE:
3240104349Sphk      if (endCdataSectionHandler)
3241104349Sphk        endCdataSectionHandler(handlerArg);
3242104349Sphk#if 0
3243104349Sphk      /* see comment under XML_TOK_CDATA_SECT_OPEN */
3244104349Sphk      else if (characterDataHandler)
3245104349Sphk        characterDataHandler(handlerArg, dataBuf, 0);
3246104349Sphk#endif
3247104349Sphk      else if (defaultHandler)
3248104349Sphk        reportDefault(parser, enc, s, next);
3249104349Sphk      *startPtr = next;
3250178848Scokane      *nextPtr = next;
3251178848Scokane      if (ps_parsing == XML_FINISHED)
3252178848Scokane        return XML_ERROR_ABORTED;
3253178848Scokane      else
3254178848Scokane        return XML_ERROR_NONE;
3255104349Sphk    case XML_TOK_DATA_NEWLINE:
3256104349Sphk      if (characterDataHandler) {
3257104349Sphk        XML_Char c = 0xA;
3258104349Sphk        characterDataHandler(handlerArg, &c, 1);
3259104349Sphk      }
3260104349Sphk      else if (defaultHandler)
3261104349Sphk        reportDefault(parser, enc, s, next);
3262104349Sphk      break;
3263104349Sphk    case XML_TOK_DATA_CHARS:
3264178848Scokane      {
3265178848Scokane        XML_CharacterDataHandler charDataHandler = characterDataHandler;
3266178848Scokane        if (charDataHandler) {
3267178848Scokane          if (MUST_CONVERT(enc, s)) {
3268178848Scokane            for (;;) {
3269178848Scokane              ICHAR *dataPtr = (ICHAR *)dataBuf;
3270178848Scokane              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
3271178848Scokane              *eventEndPP = next;
3272178848Scokane              charDataHandler(handlerArg, dataBuf,
3273178848Scokane                              (int)(dataPtr - (ICHAR *)dataBuf));
3274178848Scokane              if (s == next)
3275178848Scokane                break;
3276178848Scokane              *eventPP = s;
3277178848Scokane            }
3278104349Sphk          }
3279178848Scokane          else
3280178848Scokane            charDataHandler(handlerArg,
3281178848Scokane                            (XML_Char *)s,
3282178848Scokane                            (int)((XML_Char *)next - (XML_Char *)s));
3283104349Sphk        }
3284178848Scokane        else if (defaultHandler)
3285178848Scokane          reportDefault(parser, enc, s, next);
3286104349Sphk      }
3287104349Sphk      break;
3288104349Sphk    case XML_TOK_INVALID:
3289104349Sphk      *eventPP = next;
3290104349Sphk      return XML_ERROR_INVALID_TOKEN;
3291104349Sphk    case XML_TOK_PARTIAL_CHAR:
3292178848Scokane      if (haveMore) {
3293104349Sphk        *nextPtr = s;
3294104349Sphk        return XML_ERROR_NONE;
3295104349Sphk      }
3296104349Sphk      return XML_ERROR_PARTIAL_CHAR;
3297104349Sphk    case XML_TOK_PARTIAL:
3298104349Sphk    case XML_TOK_NONE:
3299178848Scokane      if (haveMore) {
3300104349Sphk        *nextPtr = s;
3301104349Sphk        return XML_ERROR_NONE;
3302104349Sphk      }
3303104349Sphk      return XML_ERROR_UNCLOSED_CDATA_SECTION;
3304104349Sphk    default:
3305104349Sphk      *eventPP = next;
3306104349Sphk      return XML_ERROR_UNEXPECTED_STATE;
3307104349Sphk    }
3308178848Scokane
3309104349Sphk    *eventPP = s = next;
3310178848Scokane    switch (ps_parsing) {
3311178848Scokane    case XML_SUSPENDED:
3312178848Scokane      *nextPtr = next;
3313178848Scokane      return XML_ERROR_NONE;
3314178848Scokane    case XML_FINISHED:
3315178848Scokane      return XML_ERROR_ABORTED;
3316178848Scokane    default: ;
3317178848Scokane    }
3318104349Sphk  }
3319104349Sphk  /* not reached */
3320104349Sphk}
3321104349Sphk
3322104349Sphk#ifdef XML_DTD
3323104349Sphk
3324104349Sphk/* The idea here is to avoid using stack for each IGNORE section when
3325104349Sphk   the whole file is parsed with one call.
3326104349Sphk*/
3327178848Scokanestatic enum XML_Error PTRCALL
3328104349SphkignoreSectionProcessor(XML_Parser parser,
3329104349Sphk                       const char *start,
3330104349Sphk                       const char *end,
3331104349Sphk                       const char **endPtr)
3332104349Sphk{
3333247513Sdelphij  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,
3334178848Scokane                                          endPtr, (XML_Bool)!ps_finalBuffer);
3335178848Scokane  if (result != XML_ERROR_NONE)
3336178848Scokane    return result;
3337104349Sphk  if (start) {
3338104349Sphk    processor = prologProcessor;
3339104349Sphk    return prologProcessor(parser, start, end, endPtr);
3340104349Sphk  }
3341104349Sphk  return result;
3342104349Sphk}
3343104349Sphk
3344104349Sphk/* startPtr gets set to non-null is the section is closed, and to null
3345104349Sphk   if the section is not yet closed.
3346104349Sphk*/
3347178848Scokanestatic enum XML_Error
3348104349SphkdoIgnoreSection(XML_Parser parser,
3349104349Sphk                const ENCODING *enc,
3350104349Sphk                const char **startPtr,
3351104349Sphk                const char *end,
3352178848Scokane                const char **nextPtr,
3353178848Scokane                XML_Bool haveMore)
3354104349Sphk{
3355104349Sphk  const char *next;
3356104349Sphk  int tok;
3357104349Sphk  const char *s = *startPtr;
3358104349Sphk  const char **eventPP;
3359104349Sphk  const char **eventEndPP;
3360104349Sphk  if (enc == encoding) {
3361104349Sphk    eventPP = &eventPtr;
3362104349Sphk    *eventPP = s;
3363104349Sphk    eventEndPP = &eventEndPtr;
3364104349Sphk  }
3365104349Sphk  else {
3366104349Sphk    eventPP = &(openInternalEntities->internalEventPtr);
3367104349Sphk    eventEndPP = &(openInternalEntities->internalEventEndPtr);
3368104349Sphk  }
3369104349Sphk  *eventPP = s;
3370104349Sphk  *startPtr = NULL;
3371104349Sphk  tok = XmlIgnoreSectionTok(enc, s, end, &next);
3372104349Sphk  *eventEndPP = next;
3373104349Sphk  switch (tok) {
3374104349Sphk  case XML_TOK_IGNORE_SECT:
3375104349Sphk    if (defaultHandler)
3376104349Sphk      reportDefault(parser, enc, s, next);
3377104349Sphk    *startPtr = next;
3378178848Scokane    *nextPtr = next;
3379178848Scokane    if (ps_parsing == XML_FINISHED)
3380178848Scokane      return XML_ERROR_ABORTED;
3381178848Scokane    else
3382178848Scokane      return XML_ERROR_NONE;
3383104349Sphk  case XML_TOK_INVALID:
3384104349Sphk    *eventPP = next;
3385104349Sphk    return XML_ERROR_INVALID_TOKEN;
3386104349Sphk  case XML_TOK_PARTIAL_CHAR:
3387178848Scokane    if (haveMore) {
3388104349Sphk      *nextPtr = s;
3389104349Sphk      return XML_ERROR_NONE;
3390104349Sphk    }
3391104349Sphk    return XML_ERROR_PARTIAL_CHAR;
3392104349Sphk  case XML_TOK_PARTIAL:
3393104349Sphk  case XML_TOK_NONE:
3394178848Scokane    if (haveMore) {
3395104349Sphk      *nextPtr = s;
3396104349Sphk      return XML_ERROR_NONE;
3397104349Sphk    }
3398104349Sphk    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
3399104349Sphk  default:
3400104349Sphk    *eventPP = next;
3401104349Sphk    return XML_ERROR_UNEXPECTED_STATE;
3402104349Sphk  }
3403104349Sphk  /* not reached */
3404104349Sphk}
3405104349Sphk
3406104349Sphk#endif /* XML_DTD */
3407104349Sphk
3408178848Scokanestatic enum XML_Error
3409104349SphkinitializeEncoding(XML_Parser parser)
3410104349Sphk{
3411104349Sphk  const char *s;
3412104349Sphk#ifdef XML_UNICODE
3413104349Sphk  char encodingBuf[128];
3414104349Sphk  if (!protocolEncodingName)
3415104349Sphk    s = NULL;
3416104349Sphk  else {
3417104349Sphk    int i;
3418104349Sphk    for (i = 0; protocolEncodingName[i]; i++) {
3419104349Sphk      if (i == sizeof(encodingBuf) - 1
3420104349Sphk          || (protocolEncodingName[i] & ~0x7f) != 0) {
3421104349Sphk        encodingBuf[0] = '\0';
3422104349Sphk        break;
3423104349Sphk      }
3424104349Sphk      encodingBuf[i] = (char)protocolEncodingName[i];
3425104349Sphk    }
3426104349Sphk    encodingBuf[i] = '\0';
3427104349Sphk    s = encodingBuf;
3428104349Sphk  }
3429104349Sphk#else
3430104349Sphk  s = protocolEncodingName;
3431104349Sphk#endif
3432104349Sphk  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
3433104349Sphk    return XML_ERROR_NONE;
3434104349Sphk  return handleUnknownEncoding(parser, protocolEncodingName);
3435104349Sphk}
3436104349Sphk
3437178848Scokanestatic enum XML_Error
3438104349SphkprocessXmlDecl(XML_Parser parser, int isGeneralTextEntity,
3439104349Sphk               const char *s, const char *next)
3440104349Sphk{
3441104349Sphk  const char *encodingName = NULL;
3442104349Sphk  const XML_Char *storedEncName = NULL;
3443104349Sphk  const ENCODING *newEncoding = NULL;
3444104349Sphk  const char *version = NULL;
3445104349Sphk  const char *versionend;
3446104349Sphk  const XML_Char *storedversion = NULL;
3447104349Sphk  int standalone = -1;
3448104349Sphk  if (!(ns
3449104349Sphk        ? XmlParseXmlDeclNS
3450104349Sphk        : XmlParseXmlDecl)(isGeneralTextEntity,
3451104349Sphk                           encoding,
3452104349Sphk                           s,
3453104349Sphk                           next,
3454104349Sphk                           &eventPtr,
3455104349Sphk                           &version,
3456104349Sphk                           &versionend,
3457104349Sphk                           &encodingName,
3458104349Sphk                           &newEncoding,
3459178848Scokane                           &standalone)) {
3460178848Scokane    if (isGeneralTextEntity)
3461178848Scokane      return XML_ERROR_TEXT_DECL;
3462178848Scokane    else
3463178848Scokane      return XML_ERROR_XML_DECL;
3464178848Scokane  }
3465104349Sphk  if (!isGeneralTextEntity && standalone == 1) {
3466178848Scokane    _dtd->standalone = XML_TRUE;
3467104349Sphk#ifdef XML_DTD
3468104349Sphk    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
3469104349Sphk      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
3470104349Sphk#endif /* XML_DTD */
3471104349Sphk  }
3472104349Sphk  if (xmlDeclHandler) {
3473104349Sphk    if (encodingName != NULL) {
3474104349Sphk      storedEncName = poolStoreString(&temp2Pool,
3475104349Sphk                                      encoding,
3476104349Sphk                                      encodingName,
3477104349Sphk                                      encodingName
3478104349Sphk                                      + XmlNameLength(encoding, encodingName));
3479104349Sphk      if (!storedEncName)
3480104349Sphk              return XML_ERROR_NO_MEMORY;
3481104349Sphk      poolFinish(&temp2Pool);
3482104349Sphk    }
3483104349Sphk    if (version) {
3484104349Sphk      storedversion = poolStoreString(&temp2Pool,
3485104349Sphk                                      encoding,
3486104349Sphk                                      version,
3487104349Sphk                                      versionend - encoding->minBytesPerChar);
3488104349Sphk      if (!storedversion)
3489104349Sphk        return XML_ERROR_NO_MEMORY;
3490104349Sphk    }
3491104349Sphk    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
3492104349Sphk  }
3493104349Sphk  else if (defaultHandler)
3494104349Sphk    reportDefault(parser, encoding, s, next);
3495104349Sphk  if (protocolEncodingName == NULL) {
3496104349Sphk    if (newEncoding) {
3497104349Sphk      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
3498104349Sphk        eventPtr = encodingName;
3499104349Sphk        return XML_ERROR_INCORRECT_ENCODING;
3500104349Sphk      }
3501104349Sphk      encoding = newEncoding;
3502104349Sphk    }
3503104349Sphk    else if (encodingName) {
3504104349Sphk      enum XML_Error result;
3505104349Sphk      if (!storedEncName) {
3506104349Sphk        storedEncName = poolStoreString(
3507104349Sphk          &temp2Pool, encoding, encodingName,
3508104349Sphk          encodingName + XmlNameLength(encoding, encodingName));
3509104349Sphk        if (!storedEncName)
3510104349Sphk          return XML_ERROR_NO_MEMORY;
3511104349Sphk      }
3512104349Sphk      result = handleUnknownEncoding(parser, storedEncName);
3513104349Sphk      poolClear(&temp2Pool);
3514104349Sphk      if (result == XML_ERROR_UNKNOWN_ENCODING)
3515104349Sphk        eventPtr = encodingName;
3516104349Sphk      return result;
3517104349Sphk    }
3518104349Sphk  }
3519104349Sphk
3520104349Sphk  if (storedEncName || storedversion)
3521104349Sphk    poolClear(&temp2Pool);
3522104349Sphk
3523104349Sphk  return XML_ERROR_NONE;
3524104349Sphk}
3525104349Sphk
3526178848Scokanestatic enum XML_Error
3527104349SphkhandleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
3528104349Sphk{
3529104349Sphk  if (unknownEncodingHandler) {
3530104349Sphk    XML_Encoding info;
3531104349Sphk    int i;
3532104349Sphk    for (i = 0; i < 256; i++)
3533104349Sphk      info.map[i] = -1;
3534104349Sphk    info.convert = NULL;
3535104349Sphk    info.data = NULL;
3536104349Sphk    info.release = NULL;
3537104349Sphk    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
3538104349Sphk                               &info)) {
3539104349Sphk      ENCODING *enc;
3540104349Sphk      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
3541104349Sphk      if (!unknownEncodingMem) {
3542104349Sphk        if (info.release)
3543104349Sphk          info.release(info.data);
3544104349Sphk        return XML_ERROR_NO_MEMORY;
3545104349Sphk      }
3546104349Sphk      enc = (ns
3547104349Sphk             ? XmlInitUnknownEncodingNS
3548104349Sphk             : XmlInitUnknownEncoding)(unknownEncodingMem,
3549104349Sphk                                       info.map,
3550104349Sphk                                       info.convert,
3551104349Sphk                                       info.data);
3552104349Sphk      if (enc) {
3553104349Sphk        unknownEncodingData = info.data;
3554104349Sphk        unknownEncodingRelease = info.release;
3555104349Sphk        encoding = enc;
3556104349Sphk        return XML_ERROR_NONE;
3557104349Sphk      }
3558104349Sphk    }
3559104349Sphk    if (info.release != NULL)
3560104349Sphk      info.release(info.data);
3561104349Sphk  }
3562104349Sphk  return XML_ERROR_UNKNOWN_ENCODING;
3563104349Sphk}
3564104349Sphk
3565178848Scokanestatic enum XML_Error PTRCALL
3566104349SphkprologInitProcessor(XML_Parser parser,
3567104349Sphk                    const char *s,
3568104349Sphk                    const char *end,
3569104349Sphk                    const char **nextPtr)
3570104349Sphk{
3571104349Sphk  enum XML_Error result = initializeEncoding(parser);
3572104349Sphk  if (result != XML_ERROR_NONE)
3573104349Sphk    return result;
3574104349Sphk  processor = prologProcessor;
3575104349Sphk  return prologProcessor(parser, s, end, nextPtr);
3576104349Sphk}
3577104349Sphk
3578104349Sphk#ifdef XML_DTD
3579104349Sphk
3580178848Scokanestatic enum XML_Error PTRCALL
3581104349SphkexternalParEntInitProcessor(XML_Parser parser,
3582104349Sphk                            const char *s,
3583104349Sphk                            const char *end,
3584104349Sphk                            const char **nextPtr)
3585104349Sphk{
3586104349Sphk  enum XML_Error result = initializeEncoding(parser);
3587104349Sphk  if (result != XML_ERROR_NONE)
3588104349Sphk    return result;
3589104349Sphk
3590104349Sphk  /* we know now that XML_Parse(Buffer) has been called,
3591104349Sphk     so we consider the external parameter entity read */
3592178848Scokane  _dtd->paramEntityRead = XML_TRUE;
3593104349Sphk
3594104349Sphk  if (prologState.inEntityValue) {
3595104349Sphk    processor = entityValueInitProcessor;
3596104349Sphk    return entityValueInitProcessor(parser, s, end, nextPtr);
3597104349Sphk  }
3598104349Sphk  else {
3599104349Sphk    processor = externalParEntProcessor;
3600104349Sphk    return externalParEntProcessor(parser, s, end, nextPtr);
3601104349Sphk  }
3602104349Sphk}
3603104349Sphk
3604178848Scokanestatic enum XML_Error PTRCALL
3605104349SphkentityValueInitProcessor(XML_Parser parser,
3606104349Sphk                         const char *s,
3607104349Sphk                         const char *end,
3608104349Sphk                         const char **nextPtr)
3609104349Sphk{
3610178848Scokane  int tok;
3611104349Sphk  const char *start = s;
3612178848Scokane  const char *next = start;
3613178848Scokane  eventPtr = start;
3614104349Sphk
3615247513Sdelphij  for (;;) {
3616104349Sphk    tok = XmlPrologTok(encoding, start, end, &next);
3617178848Scokane    eventEndPtr = next;
3618104349Sphk    if (tok <= 0) {
3619178848Scokane      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3620178848Scokane        *nextPtr = s;
3621178848Scokane        return XML_ERROR_NONE;
3622104349Sphk      }
3623104349Sphk      switch (tok) {
3624104349Sphk      case XML_TOK_INVALID:
3625178848Scokane        return XML_ERROR_INVALID_TOKEN;
3626104349Sphk      case XML_TOK_PARTIAL:
3627178848Scokane        return XML_ERROR_UNCLOSED_TOKEN;
3628104349Sphk      case XML_TOK_PARTIAL_CHAR:
3629178848Scokane        return XML_ERROR_PARTIAL_CHAR;
3630104349Sphk      case XML_TOK_NONE:   /* start == end */
3631104349Sphk      default:
3632104349Sphk        break;
3633104349Sphk      }
3634178848Scokane      /* found end of entity value - can store it now */
3635104349Sphk      return storeEntityValue(parser, encoding, s, end);
3636104349Sphk    }
3637104349Sphk    else if (tok == XML_TOK_XML_DECL) {
3638178848Scokane      enum XML_Error result;
3639178848Scokane      result = processXmlDecl(parser, 0, start, next);
3640178848Scokane      if (result != XML_ERROR_NONE)
3641178848Scokane        return result;
3642178848Scokane      switch (ps_parsing) {
3643247513Sdelphij      case XML_SUSPENDED:
3644178848Scokane        *nextPtr = next;
3645178848Scokane        return XML_ERROR_NONE;
3646178848Scokane      case XML_FINISHED:
3647178848Scokane        return XML_ERROR_ABORTED;
3648178848Scokane      default:
3649178848Scokane        *nextPtr = next;
3650178848Scokane      }
3651104349Sphk      /* stop scanning for text declaration - we found one */
3652104349Sphk      processor = entityValueProcessor;
3653104349Sphk      return entityValueProcessor(parser, next, end, nextPtr);
3654104349Sphk    }
3655104349Sphk    /* If we are at the end of the buffer, this would cause XmlPrologTok to
3656104349Sphk       return XML_TOK_NONE on the next call, which would then cause the
3657104349Sphk       function to exit with *nextPtr set to s - that is what we want for other
3658104349Sphk       tokens, but not for the BOM - we would rather like to skip it;
3659104349Sphk       then, when this routine is entered the next time, XmlPrologTok will
3660104349Sphk       return XML_TOK_INVALID, since the BOM is still in the buffer
3661104349Sphk    */
3662178848Scokane    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
3663104349Sphk      *nextPtr = next;
3664104349Sphk      return XML_ERROR_NONE;
3665104349Sphk    }
3666104349Sphk    start = next;
3667178848Scokane    eventPtr = start;
3668104349Sphk  }
3669104349Sphk}
3670104349Sphk
3671178848Scokanestatic enum XML_Error PTRCALL
3672104349SphkexternalParEntProcessor(XML_Parser parser,
3673104349Sphk                        const char *s,
3674104349Sphk                        const char *end,
3675104349Sphk                        const char **nextPtr)
3676104349Sphk{
3677104349Sphk  const char *next = s;
3678104349Sphk  int tok;
3679104349Sphk
3680178848Scokane  tok = XmlPrologTok(encoding, s, end, &next);
3681104349Sphk  if (tok <= 0) {
3682178848Scokane    if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3683104349Sphk      *nextPtr = s;
3684104349Sphk      return XML_ERROR_NONE;
3685104349Sphk    }
3686104349Sphk    switch (tok) {
3687104349Sphk    case XML_TOK_INVALID:
3688104349Sphk      return XML_ERROR_INVALID_TOKEN;
3689104349Sphk    case XML_TOK_PARTIAL:
3690104349Sphk      return XML_ERROR_UNCLOSED_TOKEN;
3691104349Sphk    case XML_TOK_PARTIAL_CHAR:
3692104349Sphk      return XML_ERROR_PARTIAL_CHAR;
3693104349Sphk    case XML_TOK_NONE:   /* start == end */
3694104349Sphk    default:
3695104349Sphk      break;
3696104349Sphk    }
3697104349Sphk  }
3698104349Sphk  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
3699104349Sphk     However, when parsing an external subset, doProlog will not accept a BOM
3700104349Sphk     as valid, and report a syntax error, so we have to skip the BOM
3701104349Sphk  */
3702104349Sphk  else if (tok == XML_TOK_BOM) {
3703104349Sphk    s = next;
3704104349Sphk    tok = XmlPrologTok(encoding, s, end, &next);
3705104349Sphk  }
3706104349Sphk
3707104349Sphk  processor = prologProcessor;
3708247513Sdelphij  return doProlog(parser, encoding, s, end, tok, next,
3709178848Scokane                  nextPtr, (XML_Bool)!ps_finalBuffer);
3710104349Sphk}
3711104349Sphk
3712178848Scokanestatic enum XML_Error PTRCALL
3713104349SphkentityValueProcessor(XML_Parser parser,
3714104349Sphk                     const char *s,
3715104349Sphk                     const char *end,
3716104349Sphk                     const char **nextPtr)
3717104349Sphk{
3718104349Sphk  const char *start = s;
3719104349Sphk  const char *next = s;
3720104349Sphk  const ENCODING *enc = encoding;
3721104349Sphk  int tok;
3722104349Sphk
3723104349Sphk  for (;;) {
3724104349Sphk    tok = XmlPrologTok(enc, start, end, &next);
3725104349Sphk    if (tok <= 0) {
3726178848Scokane      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
3727104349Sphk        *nextPtr = s;
3728104349Sphk        return XML_ERROR_NONE;
3729104349Sphk      }
3730104349Sphk      switch (tok) {
3731104349Sphk      case XML_TOK_INVALID:
3732178848Scokane        return XML_ERROR_INVALID_TOKEN;
3733104349Sphk      case XML_TOK_PARTIAL:
3734178848Scokane        return XML_ERROR_UNCLOSED_TOKEN;
3735104349Sphk      case XML_TOK_PARTIAL_CHAR:
3736178848Scokane        return XML_ERROR_PARTIAL_CHAR;
3737104349Sphk      case XML_TOK_NONE:   /* start == end */
3738104349Sphk      default:
3739104349Sphk        break;
3740104349Sphk      }
3741178848Scokane      /* found end of entity value - can store it now */
3742104349Sphk      return storeEntityValue(parser, enc, s, end);
3743104349Sphk    }
3744104349Sphk    start = next;
3745104349Sphk  }
3746104349Sphk}
3747104349Sphk
3748104349Sphk#endif /* XML_DTD */
3749104349Sphk
3750178848Scokanestatic enum XML_Error PTRCALL
3751104349SphkprologProcessor(XML_Parser parser,
3752104349Sphk                const char *s,
3753104349Sphk                const char *end,
3754104349Sphk                const char **nextPtr)
3755104349Sphk{
3756104349Sphk  const char *next = s;
3757104349Sphk  int tok = XmlPrologTok(encoding, s, end, &next);
3758247513Sdelphij  return doProlog(parser, encoding, s, end, tok, next,
3759178848Scokane                  nextPtr, (XML_Bool)!ps_finalBuffer);
3760104349Sphk}
3761104349Sphk
3762178848Scokanestatic enum XML_Error
3763104349SphkdoProlog(XML_Parser parser,
3764104349Sphk         const ENCODING *enc,
3765104349Sphk         const char *s,
3766104349Sphk         const char *end,
3767104349Sphk         int tok,
3768104349Sphk         const char *next,
3769178848Scokane         const char **nextPtr,
3770178848Scokane         XML_Bool haveMore)
3771104349Sphk{
3772104349Sphk#ifdef XML_DTD
3773178848Scokane  static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
3774104349Sphk#endif /* XML_DTD */
3775247513Sdelphij  static const XML_Char atypeCDATA[] =
3776178848Scokane      { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
3777178848Scokane  static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
3778178848Scokane  static const XML_Char atypeIDREF[] =
3779178848Scokane      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
3780178848Scokane  static const XML_Char atypeIDREFS[] =
3781178848Scokane      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
3782178848Scokane  static const XML_Char atypeENTITY[] =
3783178848Scokane      { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
3784178848Scokane  static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N,
3785178848Scokane      ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
3786104349Sphk  static const XML_Char atypeNMTOKEN[] = {
3787178848Scokane      ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
3788178848Scokane  static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T,
3789178848Scokane      ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
3790178848Scokane  static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
3791178848Scokane      ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
3792178848Scokane  static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
3793178848Scokane  static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };
3794104349Sphk
3795178848Scokane  /* save one level of indirection */
3796247513Sdelphij  DTD * const dtd = _dtd;
3797178848Scokane
3798104349Sphk  const char **eventPP;
3799104349Sphk  const char **eventEndPP;
3800104349Sphk  enum XML_Content_Quant quant;
3801104349Sphk
3802104349Sphk  if (enc == encoding) {
3803104349Sphk    eventPP = &eventPtr;
3804104349Sphk    eventEndPP = &eventEndPtr;
3805104349Sphk  }
3806104349Sphk  else {
3807104349Sphk    eventPP = &(openInternalEntities->internalEventPtr);
3808104349Sphk    eventEndPP = &(openInternalEntities->internalEventEndPtr);
3809104349Sphk  }
3810178848Scokane
3811104349Sphk  for (;;) {
3812104349Sphk    int role;
3813104349Sphk    XML_Bool handleDefault = XML_TRUE;
3814104349Sphk    *eventPP = s;
3815104349Sphk    *eventEndPP = next;
3816104349Sphk    if (tok <= 0) {
3817178848Scokane      if (haveMore && tok != XML_TOK_INVALID) {
3818104349Sphk        *nextPtr = s;
3819104349Sphk        return XML_ERROR_NONE;
3820104349Sphk      }
3821104349Sphk      switch (tok) {
3822104349Sphk      case XML_TOK_INVALID:
3823104349Sphk        *eventPP = next;
3824104349Sphk        return XML_ERROR_INVALID_TOKEN;
3825104349Sphk      case XML_TOK_PARTIAL:
3826104349Sphk        return XML_ERROR_UNCLOSED_TOKEN;
3827104349Sphk      case XML_TOK_PARTIAL_CHAR:
3828104349Sphk        return XML_ERROR_PARTIAL_CHAR;
3829247513Sdelphij      case -XML_TOK_PROLOG_S:
3830247513Sdelphij        tok = -tok;
3831247513Sdelphij        break;
3832104349Sphk      case XML_TOK_NONE:
3833104349Sphk#ifdef XML_DTD
3834178848Scokane        /* for internal PE NOT referenced between declarations */
3835178848Scokane        if (enc != encoding && !openInternalEntities->betweenDecl) {
3836178848Scokane          *nextPtr = s;
3837104349Sphk          return XML_ERROR_NONE;
3838178848Scokane        }
3839178848Scokane        /* WFC: PE Between Declarations - must check that PE contains
3840178848Scokane           complete markup, not only for external PEs, but also for
3841178848Scokane           internal PEs if the reference occurs between declarations.
3842178848Scokane        */
3843178848Scokane        if (isParamEntity || enc != encoding) {
3844104349Sphk          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
3845104349Sphk              == XML_ROLE_ERROR)
3846178848Scokane            return XML_ERROR_INCOMPLETE_PE;
3847178848Scokane          *nextPtr = s;
3848104349Sphk          return XML_ERROR_NONE;
3849104349Sphk        }
3850104349Sphk#endif /* XML_DTD */
3851104349Sphk        return XML_ERROR_NO_ELEMENTS;
3852104349Sphk      default:
3853104349Sphk        tok = -tok;
3854247513Sdelphij        next = end;
3855104349Sphk        break;
3856104349Sphk      }
3857104349Sphk    }
3858104349Sphk    role = XmlTokenRole(&prologState, tok, s, next, enc);
3859104349Sphk    switch (role) {
3860104349Sphk    case XML_ROLE_XML_DECL:
3861104349Sphk      {
3862104349Sphk        enum XML_Error result = processXmlDecl(parser, 0, s, next);
3863104349Sphk        if (result != XML_ERROR_NONE)
3864104349Sphk          return result;
3865104349Sphk        enc = encoding;
3866104349Sphk        handleDefault = XML_FALSE;
3867104349Sphk      }
3868104349Sphk      break;
3869104349Sphk    case XML_ROLE_DOCTYPE_NAME:
3870104349Sphk      if (startDoctypeDeclHandler) {
3871104349Sphk        doctypeName = poolStoreString(&tempPool, enc, s, next);
3872104349Sphk        if (!doctypeName)
3873104349Sphk          return XML_ERROR_NO_MEMORY;
3874104349Sphk        poolFinish(&tempPool);
3875104349Sphk        doctypePubid = NULL;
3876104349Sphk        handleDefault = XML_FALSE;
3877104349Sphk      }
3878104349Sphk      doctypeSysid = NULL; /* always initialize to NULL */
3879104349Sphk      break;
3880104349Sphk    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
3881104349Sphk      if (startDoctypeDeclHandler) {
3882104349Sphk        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
3883104349Sphk                                doctypePubid, 1);
3884104349Sphk        doctypeName = NULL;
3885104349Sphk        poolClear(&tempPool);
3886104349Sphk        handleDefault = XML_FALSE;
3887104349Sphk      }
3888104349Sphk      break;
3889104349Sphk#ifdef XML_DTD
3890104349Sphk    case XML_ROLE_TEXT_DECL:
3891104349Sphk      {
3892104349Sphk        enum XML_Error result = processXmlDecl(parser, 1, s, next);
3893104349Sphk        if (result != XML_ERROR_NONE)
3894104349Sphk          return result;
3895104349Sphk        enc = encoding;
3896104349Sphk        handleDefault = XML_FALSE;
3897104349Sphk      }
3898104349Sphk      break;
3899104349Sphk#endif /* XML_DTD */
3900104349Sphk    case XML_ROLE_DOCTYPE_PUBLIC_ID:
3901104349Sphk#ifdef XML_DTD
3902104349Sphk      useForeignDTD = XML_FALSE;
3903247513Sdelphij      declEntity = (ENTITY *)lookup(parser,
3904247513Sdelphij                                    &dtd->paramEntities,
3905178848Scokane                                    externalSubsetName,
3906178848Scokane                                    sizeof(ENTITY));
3907178848Scokane      if (!declEntity)
3908178848Scokane        return XML_ERROR_NO_MEMORY;
3909104349Sphk#endif /* XML_DTD */
3910178848Scokane      dtd->hasParamEntityRefs = XML_TRUE;
3911104349Sphk      if (startDoctypeDeclHandler) {
3912247513Sdelphij        XML_Char *pubId;
3913178848Scokane        if (!XmlIsPublicId(enc, s, next, eventPP))
3914178848Scokane          return XML_ERROR_PUBLICID;
3915247513Sdelphij        pubId = poolStoreString(&tempPool, enc,
3916247513Sdelphij                                s + enc->minBytesPerChar,
3917247513Sdelphij                                next - enc->minBytesPerChar);
3918247513Sdelphij        if (!pubId)
3919104349Sphk          return XML_ERROR_NO_MEMORY;
3920247513Sdelphij        normalizePublicId(pubId);
3921104349Sphk        poolFinish(&tempPool);
3922247513Sdelphij        doctypePubid = pubId;
3923104349Sphk        handleDefault = XML_FALSE;
3924178848Scokane        goto alreadyChecked;
3925104349Sphk      }
3926104349Sphk      /* fall through */
3927104349Sphk    case XML_ROLE_ENTITY_PUBLIC_ID:
3928104349Sphk      if (!XmlIsPublicId(enc, s, next, eventPP))
3929178848Scokane        return XML_ERROR_PUBLICID;
3930178848Scokane    alreadyChecked:
3931178848Scokane      if (dtd->keepProcessing && declEntity) {
3932178848Scokane        XML_Char *tem = poolStoreString(&dtd->pool,
3933104349Sphk                                        enc,
3934104349Sphk                                        s + enc->minBytesPerChar,
3935104349Sphk                                        next - enc->minBytesPerChar);
3936104349Sphk        if (!tem)
3937104349Sphk          return XML_ERROR_NO_MEMORY;
3938104349Sphk        normalizePublicId(tem);
3939104349Sphk        declEntity->publicId = tem;
3940178848Scokane        poolFinish(&dtd->pool);
3941104349Sphk        if (entityDeclHandler)
3942104349Sphk          handleDefault = XML_FALSE;
3943104349Sphk      }
3944104349Sphk      break;
3945104349Sphk    case XML_ROLE_DOCTYPE_CLOSE:
3946104349Sphk      if (doctypeName) {
3947104349Sphk        startDoctypeDeclHandler(handlerArg, doctypeName,
3948104349Sphk                                doctypeSysid, doctypePubid, 0);
3949104349Sphk        poolClear(&tempPool);
3950104349Sphk        handleDefault = XML_FALSE;
3951104349Sphk      }
3952104349Sphk      /* doctypeSysid will be non-NULL in the case of a previous
3953104349Sphk         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
3954104349Sphk         was not set, indicating an external subset
3955104349Sphk      */
3956178848Scokane#ifdef XML_DTD
3957104349Sphk      if (doctypeSysid || useForeignDTD) {
3958178848Scokane        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
3959178848Scokane        dtd->hasParamEntityRefs = XML_TRUE;
3960104349Sphk        if (paramEntityParsing && externalEntityRefHandler) {
3961247513Sdelphij          ENTITY *entity = (ENTITY *)lookup(parser,
3962247513Sdelphij                                            &dtd->paramEntities,
3963104349Sphk                                            externalSubsetName,
3964104349Sphk                                            sizeof(ENTITY));
3965104349Sphk          if (!entity)
3966104349Sphk            return XML_ERROR_NO_MEMORY;
3967178848Scokane          if (useForeignDTD)
3968104349Sphk            entity->base = curBase;
3969178848Scokane          dtd->paramEntityRead = XML_FALSE;
3970104349Sphk          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
3971104349Sphk                                        0,
3972104349Sphk                                        entity->base,
3973104349Sphk                                        entity->systemId,
3974104349Sphk                                        entity->publicId))
3975104349Sphk            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3976178848Scokane          if (dtd->paramEntityRead) {
3977247513Sdelphij            if (!dtd->standalone &&
3978247513Sdelphij                notStandaloneHandler &&
3979178848Scokane                !notStandaloneHandler(handlerArg))
3980178848Scokane              return XML_ERROR_NOT_STANDALONE;
3981178848Scokane          }
3982178848Scokane          /* if we didn't read the foreign DTD then this means that there
3983178848Scokane             is no external subset and we must reset dtd->hasParamEntityRefs
3984178848Scokane          */
3985178848Scokane          else if (!doctypeSysid)
3986178848Scokane            dtd->hasParamEntityRefs = hadParamEntityRefs;
3987178848Scokane          /* end of DTD - no need to update dtd->keepProcessing */
3988104349Sphk        }
3989104349Sphk        useForeignDTD = XML_FALSE;
3990104349Sphk      }
3991104349Sphk#endif /* XML_DTD */
3992104349Sphk      if (endDoctypeDeclHandler) {
3993104349Sphk        endDoctypeDeclHandler(handlerArg);
3994104349Sphk        handleDefault = XML_FALSE;
3995104349Sphk      }
3996104349Sphk      break;
3997104349Sphk    case XML_ROLE_INSTANCE_START:
3998104349Sphk#ifdef XML_DTD
3999178848Scokane      /* if there is no DOCTYPE declaration then now is the
4000104349Sphk         last chance to read the foreign DTD
4001104349Sphk      */
4002178848Scokane      if (useForeignDTD) {
4003178848Scokane        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
4004178848Scokane        dtd->hasParamEntityRefs = XML_TRUE;
4005104349Sphk        if (paramEntityParsing && externalEntityRefHandler) {
4006247513Sdelphij          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4007104349Sphk                                            externalSubsetName,
4008104349Sphk                                            sizeof(ENTITY));
4009104349Sphk          if (!entity)
4010104349Sphk            return XML_ERROR_NO_MEMORY;
4011104349Sphk          entity->base = curBase;
4012178848Scokane          dtd->paramEntityRead = XML_FALSE;
4013104349Sphk          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4014104349Sphk                                        0,
4015104349Sphk                                        entity->base,
4016104349Sphk                                        entity->systemId,
4017104349Sphk                                        entity->publicId))
4018104349Sphk            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4019178848Scokane          if (dtd->paramEntityRead) {
4020178848Scokane            if (!dtd->standalone &&
4021178848Scokane                notStandaloneHandler &&
4022178848Scokane                !notStandaloneHandler(handlerArg))
4023178848Scokane              return XML_ERROR_NOT_STANDALONE;
4024178848Scokane          }
4025178848Scokane          /* if we didn't read the foreign DTD then this means that there
4026178848Scokane             is no external subset and we must reset dtd->hasParamEntityRefs
4027178848Scokane          */
4028178848Scokane          else
4029178848Scokane            dtd->hasParamEntityRefs = hadParamEntityRefs;
4030178848Scokane          /* end of DTD - no need to update dtd->keepProcessing */
4031104349Sphk        }
4032178848Scokane      }
4033104349Sphk#endif /* XML_DTD */
4034104349Sphk      processor = contentProcessor;
4035104349Sphk      return contentProcessor(parser, s, end, nextPtr);
4036104349Sphk    case XML_ROLE_ATTLIST_ELEMENT_NAME:
4037104349Sphk      declElementType = getElementType(parser, enc, s, next);
4038104349Sphk      if (!declElementType)
4039104349Sphk        return XML_ERROR_NO_MEMORY;
4040104349Sphk      goto checkAttListDeclHandler;
4041104349Sphk    case XML_ROLE_ATTRIBUTE_NAME:
4042104349Sphk      declAttributeId = getAttributeId(parser, enc, s, next);
4043104349Sphk      if (!declAttributeId)
4044104349Sphk        return XML_ERROR_NO_MEMORY;
4045104349Sphk      declAttributeIsCdata = XML_FALSE;
4046104349Sphk      declAttributeType = NULL;
4047104349Sphk      declAttributeIsId = XML_FALSE;
4048104349Sphk      goto checkAttListDeclHandler;
4049104349Sphk    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
4050104349Sphk      declAttributeIsCdata = XML_TRUE;
4051104349Sphk      declAttributeType = atypeCDATA;
4052104349Sphk      goto checkAttListDeclHandler;
4053104349Sphk    case XML_ROLE_ATTRIBUTE_TYPE_ID:
4054104349Sphk      declAttributeIsId = XML_TRUE;
4055104349Sphk      declAttributeType = atypeID;
4056104349Sphk      goto checkAttListDeclHandler;
4057104349Sphk    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
4058104349Sphk      declAttributeType = atypeIDREF;
4059104349Sphk      goto checkAttListDeclHandler;
4060104349Sphk    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
4061104349Sphk      declAttributeType = atypeIDREFS;
4062104349Sphk      goto checkAttListDeclHandler;
4063104349Sphk    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
4064104349Sphk      declAttributeType = atypeENTITY;
4065104349Sphk      goto checkAttListDeclHandler;
4066104349Sphk    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
4067104349Sphk      declAttributeType = atypeENTITIES;
4068104349Sphk      goto checkAttListDeclHandler;
4069104349Sphk    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
4070104349Sphk      declAttributeType = atypeNMTOKEN;
4071104349Sphk      goto checkAttListDeclHandler;
4072104349Sphk    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
4073104349Sphk      declAttributeType = atypeNMTOKENS;
4074104349Sphk    checkAttListDeclHandler:
4075178848Scokane      if (dtd->keepProcessing && attlistDeclHandler)
4076104349Sphk        handleDefault = XML_FALSE;
4077104349Sphk      break;
4078104349Sphk    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
4079104349Sphk    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
4080178848Scokane      if (dtd->keepProcessing && attlistDeclHandler) {
4081104349Sphk        const XML_Char *prefix;
4082104349Sphk        if (declAttributeType) {
4083104349Sphk          prefix = enumValueSep;
4084104349Sphk        }
4085104349Sphk        else {
4086104349Sphk          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
4087104349Sphk                    ? notationPrefix
4088104349Sphk                    : enumValueStart);
4089104349Sphk        }
4090104349Sphk        if (!poolAppendString(&tempPool, prefix))
4091104349Sphk          return XML_ERROR_NO_MEMORY;
4092104349Sphk        if (!poolAppend(&tempPool, enc, s, next))
4093104349Sphk          return XML_ERROR_NO_MEMORY;
4094104349Sphk        declAttributeType = tempPool.start;
4095104349Sphk        handleDefault = XML_FALSE;
4096104349Sphk      }
4097104349Sphk      break;
4098104349Sphk    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
4099104349Sphk    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
4100178848Scokane      if (dtd->keepProcessing) {
4101104349Sphk        if (!defineAttribute(declElementType, declAttributeId,
4102178848Scokane                             declAttributeIsCdata, declAttributeIsId,
4103178848Scokane                             0, parser))
4104104349Sphk          return XML_ERROR_NO_MEMORY;
4105104349Sphk        if (attlistDeclHandler && declAttributeType) {
4106178848Scokane          if (*declAttributeType == XML_T(ASCII_LPAREN)
4107178848Scokane              || (*declAttributeType == XML_T(ASCII_N)
4108178848Scokane                  && declAttributeType[1] == XML_T(ASCII_O))) {
4109104349Sphk            /* Enumerated or Notation type */
4110178848Scokane            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4111104349Sphk                || !poolAppendChar(&tempPool, XML_T('\0')))
4112104349Sphk              return XML_ERROR_NO_MEMORY;
4113104349Sphk            declAttributeType = tempPool.start;
4114104349Sphk            poolFinish(&tempPool);
4115104349Sphk          }
4116104349Sphk          *eventEndPP = s;
4117104349Sphk          attlistDeclHandler(handlerArg, declElementType->name,
4118104349Sphk                             declAttributeId->name, declAttributeType,
4119104349Sphk                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
4120104349Sphk          poolClear(&tempPool);
4121104349Sphk          handleDefault = XML_FALSE;
4122104349Sphk        }
4123104349Sphk      }
4124104349Sphk      break;
4125104349Sphk    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
4126104349Sphk    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
4127178848Scokane      if (dtd->keepProcessing) {
4128104349Sphk        const XML_Char *attVal;
4129178848Scokane        enum XML_Error result =
4130178848Scokane          storeAttributeValue(parser, enc, declAttributeIsCdata,
4131178848Scokane                              s + enc->minBytesPerChar,
4132178848Scokane                              next - enc->minBytesPerChar,
4133178848Scokane                              &dtd->pool);
4134104349Sphk        if (result)
4135104349Sphk          return result;
4136178848Scokane        attVal = poolStart(&dtd->pool);
4137178848Scokane        poolFinish(&dtd->pool);
4138104349Sphk        /* ID attributes aren't allowed to have a default */
4139104349Sphk        if (!defineAttribute(declElementType, declAttributeId,
4140104349Sphk                             declAttributeIsCdata, XML_FALSE, attVal, parser))
4141104349Sphk          return XML_ERROR_NO_MEMORY;
4142104349Sphk        if (attlistDeclHandler && declAttributeType) {
4143178848Scokane          if (*declAttributeType == XML_T(ASCII_LPAREN)
4144178848Scokane              || (*declAttributeType == XML_T(ASCII_N)
4145178848Scokane                  && declAttributeType[1] == XML_T(ASCII_O))) {
4146104349Sphk            /* Enumerated or Notation type */
4147178848Scokane            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
4148104349Sphk                || !poolAppendChar(&tempPool, XML_T('\0')))
4149104349Sphk              return XML_ERROR_NO_MEMORY;
4150104349Sphk            declAttributeType = tempPool.start;
4151104349Sphk            poolFinish(&tempPool);
4152104349Sphk          }
4153104349Sphk          *eventEndPP = s;
4154104349Sphk          attlistDeclHandler(handlerArg, declElementType->name,
4155104349Sphk                             declAttributeId->name, declAttributeType,
4156104349Sphk                             attVal,
4157104349Sphk                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
4158104349Sphk          poolClear(&tempPool);
4159104349Sphk          handleDefault = XML_FALSE;
4160104349Sphk        }
4161104349Sphk      }
4162104349Sphk      break;
4163104349Sphk    case XML_ROLE_ENTITY_VALUE:
4164178848Scokane      if (dtd->keepProcessing) {
4165104349Sphk        enum XML_Error result = storeEntityValue(parser, enc,
4166104349Sphk                                            s + enc->minBytesPerChar,
4167104349Sphk                                            next - enc->minBytesPerChar);
4168104349Sphk        if (declEntity) {
4169178848Scokane          declEntity->textPtr = poolStart(&dtd->entityValuePool);
4170178848Scokane          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
4171178848Scokane          poolFinish(&dtd->entityValuePool);
4172104349Sphk          if (entityDeclHandler) {
4173104349Sphk            *eventEndPP = s;
4174104349Sphk            entityDeclHandler(handlerArg,
4175104349Sphk                              declEntity->name,
4176104349Sphk                              declEntity->is_param,
4177104349Sphk                              declEntity->textPtr,
4178104349Sphk                              declEntity->textLen,
4179104349Sphk                              curBase, 0, 0, 0);
4180104349Sphk            handleDefault = XML_FALSE;
4181104349Sphk          }
4182104349Sphk        }
4183104349Sphk        else
4184178848Scokane          poolDiscard(&dtd->entityValuePool);
4185104349Sphk        if (result != XML_ERROR_NONE)
4186104349Sphk          return result;
4187104349Sphk      }
4188104349Sphk      break;
4189104349Sphk    case XML_ROLE_DOCTYPE_SYSTEM_ID:
4190104349Sphk#ifdef XML_DTD
4191104349Sphk      useForeignDTD = XML_FALSE;
4192104349Sphk#endif /* XML_DTD */
4193178848Scokane      dtd->hasParamEntityRefs = XML_TRUE;
4194104349Sphk      if (startDoctypeDeclHandler) {
4195104349Sphk        doctypeSysid = poolStoreString(&tempPool, enc,
4196104349Sphk                                       s + enc->minBytesPerChar,
4197104349Sphk                                       next - enc->minBytesPerChar);
4198104349Sphk        if (doctypeSysid == NULL)
4199104349Sphk          return XML_ERROR_NO_MEMORY;
4200104349Sphk        poolFinish(&tempPool);
4201104349Sphk        handleDefault = XML_FALSE;
4202104349Sphk      }
4203104349Sphk#ifdef XML_DTD
4204104349Sphk      else
4205104349Sphk        /* use externalSubsetName to make doctypeSysid non-NULL
4206104349Sphk           for the case where no startDoctypeDeclHandler is set */
4207104349Sphk        doctypeSysid = externalSubsetName;
4208104349Sphk#endif /* XML_DTD */
4209178848Scokane      if (!dtd->standalone
4210104349Sphk#ifdef XML_DTD
4211104349Sphk          && !paramEntityParsing
4212104349Sphk#endif /* XML_DTD */
4213104349Sphk          && notStandaloneHandler
4214104349Sphk          && !notStandaloneHandler(handlerArg))
4215104349Sphk        return XML_ERROR_NOT_STANDALONE;
4216104349Sphk#ifndef XML_DTD
4217104349Sphk      break;
4218104349Sphk#else /* XML_DTD */
4219104349Sphk      if (!declEntity) {
4220247513Sdelphij        declEntity = (ENTITY *)lookup(parser,
4221247513Sdelphij                                      &dtd->paramEntities,
4222104349Sphk                                      externalSubsetName,
4223104349Sphk                                      sizeof(ENTITY));
4224104349Sphk        if (!declEntity)
4225104349Sphk          return XML_ERROR_NO_MEMORY;
4226104349Sphk        declEntity->publicId = NULL;
4227104349Sphk      }
4228104349Sphk      /* fall through */
4229104349Sphk#endif /* XML_DTD */
4230104349Sphk    case XML_ROLE_ENTITY_SYSTEM_ID:
4231178848Scokane      if (dtd->keepProcessing && declEntity) {
4232178848Scokane        declEntity->systemId = poolStoreString(&dtd->pool, enc,
4233104349Sphk                                               s + enc->minBytesPerChar,
4234104349Sphk                                               next - enc->minBytesPerChar);
4235104349Sphk        if (!declEntity->systemId)
4236104349Sphk          return XML_ERROR_NO_MEMORY;
4237104349Sphk        declEntity->base = curBase;
4238178848Scokane        poolFinish(&dtd->pool);
4239104349Sphk        if (entityDeclHandler)
4240104349Sphk          handleDefault = XML_FALSE;
4241104349Sphk      }
4242104349Sphk      break;
4243104349Sphk    case XML_ROLE_ENTITY_COMPLETE:
4244178848Scokane      if (dtd->keepProcessing && declEntity && entityDeclHandler) {
4245104349Sphk        *eventEndPP = s;
4246104349Sphk        entityDeclHandler(handlerArg,
4247104349Sphk                          declEntity->name,
4248104349Sphk                          declEntity->is_param,
4249104349Sphk                          0,0,
4250104349Sphk                          declEntity->base,
4251104349Sphk                          declEntity->systemId,
4252104349Sphk                          declEntity->publicId,
4253104349Sphk                          0);
4254104349Sphk        handleDefault = XML_FALSE;
4255104349Sphk      }
4256104349Sphk      break;
4257104349Sphk    case XML_ROLE_ENTITY_NOTATION_NAME:
4258178848Scokane      if (dtd->keepProcessing && declEntity) {
4259178848Scokane        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
4260104349Sphk        if (!declEntity->notation)
4261104349Sphk          return XML_ERROR_NO_MEMORY;
4262178848Scokane        poolFinish(&dtd->pool);
4263104349Sphk        if (unparsedEntityDeclHandler) {
4264104349Sphk          *eventEndPP = s;
4265104349Sphk          unparsedEntityDeclHandler(handlerArg,
4266104349Sphk                                    declEntity->name,
4267104349Sphk                                    declEntity->base,
4268104349Sphk                                    declEntity->systemId,
4269104349Sphk                                    declEntity->publicId,
4270104349Sphk                                    declEntity->notation);
4271104349Sphk          handleDefault = XML_FALSE;
4272104349Sphk        }
4273104349Sphk        else if (entityDeclHandler) {
4274104349Sphk          *eventEndPP = s;
4275104349Sphk          entityDeclHandler(handlerArg,
4276104349Sphk                            declEntity->name,
4277104349Sphk                            0,0,0,
4278104349Sphk                            declEntity->base,
4279104349Sphk                            declEntity->systemId,
4280104349Sphk                            declEntity->publicId,
4281104349Sphk                            declEntity->notation);
4282104349Sphk          handleDefault = XML_FALSE;
4283104349Sphk        }
4284104349Sphk      }
4285104349Sphk      break;
4286104349Sphk    case XML_ROLE_GENERAL_ENTITY_NAME:
4287104349Sphk      {
4288104349Sphk        if (XmlPredefinedEntityName(enc, s, next)) {
4289104349Sphk          declEntity = NULL;
4290104349Sphk          break;
4291104349Sphk        }
4292178848Scokane        if (dtd->keepProcessing) {
4293178848Scokane          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4294104349Sphk          if (!name)
4295104349Sphk            return XML_ERROR_NO_MEMORY;
4296247513Sdelphij          declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
4297104349Sphk                                        sizeof(ENTITY));
4298104349Sphk          if (!declEntity)
4299104349Sphk            return XML_ERROR_NO_MEMORY;
4300104349Sphk          if (declEntity->name != name) {
4301178848Scokane            poolDiscard(&dtd->pool);
4302104349Sphk            declEntity = NULL;
4303104349Sphk          }
4304104349Sphk          else {
4305178848Scokane            poolFinish(&dtd->pool);
4306104349Sphk            declEntity->publicId = NULL;
4307104349Sphk            declEntity->is_param = XML_FALSE;
4308104349Sphk            /* if we have a parent parser or are reading an internal parameter
4309104349Sphk               entity, then the entity declaration is not considered "internal"
4310104349Sphk            */
4311104349Sphk            declEntity->is_internal = !(parentParser || openInternalEntities);
4312104349Sphk            if (entityDeclHandler)
4313104349Sphk              handleDefault = XML_FALSE;
4314104349Sphk          }
4315104349Sphk        }
4316104349Sphk        else {
4317178848Scokane          poolDiscard(&dtd->pool);
4318104349Sphk          declEntity = NULL;
4319104349Sphk        }
4320104349Sphk      }
4321104349Sphk      break;
4322104349Sphk    case XML_ROLE_PARAM_ENTITY_NAME:
4323104349Sphk#ifdef XML_DTD
4324178848Scokane      if (dtd->keepProcessing) {
4325178848Scokane        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
4326104349Sphk        if (!name)
4327104349Sphk          return XML_ERROR_NO_MEMORY;
4328247513Sdelphij        declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
4329104349Sphk                                           name, sizeof(ENTITY));
4330104349Sphk        if (!declEntity)
4331104349Sphk          return XML_ERROR_NO_MEMORY;
4332104349Sphk        if (declEntity->name != name) {
4333178848Scokane          poolDiscard(&dtd->pool);
4334104349Sphk          declEntity = NULL;
4335104349Sphk        }
4336104349Sphk        else {
4337178848Scokane          poolFinish(&dtd->pool);
4338104349Sphk          declEntity->publicId = NULL;
4339104349Sphk          declEntity->is_param = XML_TRUE;
4340104349Sphk          /* if we have a parent parser or are reading an internal parameter
4341104349Sphk             entity, then the entity declaration is not considered "internal"
4342104349Sphk          */
4343104349Sphk          declEntity->is_internal = !(parentParser || openInternalEntities);
4344104349Sphk          if (entityDeclHandler)
4345104349Sphk            handleDefault = XML_FALSE;
4346104349Sphk        }
4347104349Sphk      }
4348104349Sphk      else {
4349178848Scokane        poolDiscard(&dtd->pool);
4350104349Sphk        declEntity = NULL;
4351104349Sphk      }
4352104349Sphk#else /* not XML_DTD */
4353104349Sphk      declEntity = NULL;
4354104349Sphk#endif /* XML_DTD */
4355104349Sphk      break;
4356104349Sphk    case XML_ROLE_NOTATION_NAME:
4357104349Sphk      declNotationPublicId = NULL;
4358104349Sphk      declNotationName = NULL;
4359104349Sphk      if (notationDeclHandler) {
4360104349Sphk        declNotationName = poolStoreString(&tempPool, enc, s, next);
4361104349Sphk        if (!declNotationName)
4362104349Sphk          return XML_ERROR_NO_MEMORY;
4363104349Sphk        poolFinish(&tempPool);
4364104349Sphk        handleDefault = XML_FALSE;
4365104349Sphk      }
4366104349Sphk      break;
4367104349Sphk    case XML_ROLE_NOTATION_PUBLIC_ID:
4368104349Sphk      if (!XmlIsPublicId(enc, s, next, eventPP))
4369178848Scokane        return XML_ERROR_PUBLICID;
4370104349Sphk      if (declNotationName) {  /* means notationDeclHandler != NULL */
4371104349Sphk        XML_Char *tem = poolStoreString(&tempPool,
4372104349Sphk                                        enc,
4373104349Sphk                                        s + enc->minBytesPerChar,
4374104349Sphk                                        next - enc->minBytesPerChar);
4375104349Sphk        if (!tem)
4376104349Sphk          return XML_ERROR_NO_MEMORY;
4377104349Sphk        normalizePublicId(tem);
4378104349Sphk        declNotationPublicId = tem;
4379104349Sphk        poolFinish(&tempPool);
4380104349Sphk        handleDefault = XML_FALSE;
4381104349Sphk      }
4382104349Sphk      break;
4383104349Sphk    case XML_ROLE_NOTATION_SYSTEM_ID:
4384104349Sphk      if (declNotationName && notationDeclHandler) {
4385104349Sphk        const XML_Char *systemId
4386104349Sphk          = poolStoreString(&tempPool, enc,
4387104349Sphk                            s + enc->minBytesPerChar,
4388104349Sphk                            next - enc->minBytesPerChar);
4389104349Sphk        if (!systemId)
4390104349Sphk          return XML_ERROR_NO_MEMORY;
4391104349Sphk        *eventEndPP = s;
4392104349Sphk        notationDeclHandler(handlerArg,
4393104349Sphk                            declNotationName,
4394104349Sphk                            curBase,
4395104349Sphk                            systemId,
4396104349Sphk                            declNotationPublicId);
4397104349Sphk        handleDefault = XML_FALSE;
4398104349Sphk      }
4399104349Sphk      poolClear(&tempPool);
4400104349Sphk      break;
4401104349Sphk    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
4402104349Sphk      if (declNotationPublicId && notationDeclHandler) {
4403104349Sphk        *eventEndPP = s;
4404104349Sphk        notationDeclHandler(handlerArg,
4405104349Sphk                            declNotationName,
4406104349Sphk                            curBase,
4407104349Sphk                            0,
4408104349Sphk                            declNotationPublicId);
4409104349Sphk        handleDefault = XML_FALSE;
4410104349Sphk      }
4411104349Sphk      poolClear(&tempPool);
4412104349Sphk      break;
4413104349Sphk    case XML_ROLE_ERROR:
4414104349Sphk      switch (tok) {
4415104349Sphk      case XML_TOK_PARAM_ENTITY_REF:
4416178848Scokane        /* PE references in internal subset are
4417247513Sdelphij           not allowed within declarations. */
4418104349Sphk        return XML_ERROR_PARAM_ENTITY_REF;
4419104349Sphk      case XML_TOK_XML_DECL:
4420104349Sphk        return XML_ERROR_MISPLACED_XML_PI;
4421104349Sphk      default:
4422104349Sphk        return XML_ERROR_SYNTAX;
4423104349Sphk      }
4424104349Sphk#ifdef XML_DTD
4425104349Sphk    case XML_ROLE_IGNORE_SECT:
4426104349Sphk      {
4427104349Sphk        enum XML_Error result;
4428104349Sphk        if (defaultHandler)
4429104349Sphk          reportDefault(parser, enc, s, next);
4430104349Sphk        handleDefault = XML_FALSE;
4431178848Scokane        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
4432178848Scokane        if (result != XML_ERROR_NONE)
4433178848Scokane          return result;
4434178848Scokane        else if (!next) {
4435104349Sphk          processor = ignoreSectionProcessor;
4436104349Sphk          return result;
4437104349Sphk        }
4438104349Sphk      }
4439104349Sphk      break;
4440104349Sphk#endif /* XML_DTD */
4441104349Sphk    case XML_ROLE_GROUP_OPEN:
4442104349Sphk      if (prologState.level >= groupSize) {
4443104349Sphk        if (groupSize) {
4444178848Scokane          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
4445104349Sphk          if (temp == NULL)
4446104349Sphk            return XML_ERROR_NO_MEMORY;
4447104349Sphk          groupConnector = temp;
4448178848Scokane          if (dtd->scaffIndex) {
4449178848Scokane            int *temp = (int *)REALLOC(dtd->scaffIndex,
4450178848Scokane                          groupSize * sizeof(int));
4451104349Sphk            if (temp == NULL)
4452104349Sphk              return XML_ERROR_NO_MEMORY;
4453178848Scokane            dtd->scaffIndex = temp;
4454104349Sphk          }
4455104349Sphk        }
4456104349Sphk        else {
4457178848Scokane          groupConnector = (char *)MALLOC(groupSize = 32);
4458104349Sphk          if (!groupConnector)
4459104349Sphk            return XML_ERROR_NO_MEMORY;
4460104349Sphk        }
4461104349Sphk      }
4462104349Sphk      groupConnector[prologState.level] = 0;
4463178848Scokane      if (dtd->in_eldecl) {
4464104349Sphk        int myindex = nextScaffoldPart(parser);
4465104349Sphk        if (myindex < 0)
4466104349Sphk          return XML_ERROR_NO_MEMORY;
4467178848Scokane        dtd->scaffIndex[dtd->scaffLevel] = myindex;
4468178848Scokane        dtd->scaffLevel++;
4469178848Scokane        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
4470104349Sphk        if (elementDeclHandler)
4471104349Sphk          handleDefault = XML_FALSE;
4472104349Sphk      }
4473104349Sphk      break;
4474104349Sphk    case XML_ROLE_GROUP_SEQUENCE:
4475178848Scokane      if (groupConnector[prologState.level] == ASCII_PIPE)
4476104349Sphk        return XML_ERROR_SYNTAX;
4477178848Scokane      groupConnector[prologState.level] = ASCII_COMMA;
4478178848Scokane      if (dtd->in_eldecl && elementDeclHandler)
4479104349Sphk        handleDefault = XML_FALSE;
4480104349Sphk      break;
4481104349Sphk    case XML_ROLE_GROUP_CHOICE:
4482178848Scokane      if (groupConnector[prologState.level] == ASCII_COMMA)
4483104349Sphk        return XML_ERROR_SYNTAX;
4484178848Scokane      if (dtd->in_eldecl
4485104349Sphk          && !groupConnector[prologState.level]
4486178848Scokane          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4487104349Sphk              != XML_CTYPE_MIXED)
4488104349Sphk          ) {
4489178848Scokane        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4490104349Sphk            = XML_CTYPE_CHOICE;
4491104349Sphk        if (elementDeclHandler)
4492104349Sphk          handleDefault = XML_FALSE;
4493104349Sphk      }
4494178848Scokane      groupConnector[prologState.level] = ASCII_PIPE;
4495104349Sphk      break;
4496104349Sphk    case XML_ROLE_PARAM_ENTITY_REF:
4497104349Sphk#ifdef XML_DTD
4498104349Sphk    case XML_ROLE_INNER_PARAM_ENTITY_REF:
4499178848Scokane      dtd->hasParamEntityRefs = XML_TRUE;
4500104349Sphk      if (!paramEntityParsing)
4501178848Scokane        dtd->keepProcessing = dtd->standalone;
4502104349Sphk      else {
4503104349Sphk        const XML_Char *name;
4504104349Sphk        ENTITY *entity;
4505178848Scokane        name = poolStoreString(&dtd->pool, enc,
4506104349Sphk                                s + enc->minBytesPerChar,
4507104349Sphk                                next - enc->minBytesPerChar);
4508104349Sphk        if (!name)
4509104349Sphk          return XML_ERROR_NO_MEMORY;
4510247513Sdelphij        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
4511178848Scokane        poolDiscard(&dtd->pool);
4512104349Sphk        /* first, determine if a check for an existing declaration is needed;
4513104349Sphk           if yes, check that the entity exists, and that it is internal,
4514104349Sphk           otherwise call the skipped entity handler
4515104349Sphk        */
4516104349Sphk        if (prologState.documentEntity &&
4517178848Scokane            (dtd->standalone
4518104349Sphk             ? !openInternalEntities
4519178848Scokane             : !dtd->hasParamEntityRefs)) {
4520104349Sphk          if (!entity)
4521104349Sphk            return XML_ERROR_UNDEFINED_ENTITY;
4522104349Sphk          else if (!entity->is_internal)
4523104349Sphk            return XML_ERROR_ENTITY_DECLARED_IN_PE;
4524104349Sphk        }
4525104349Sphk        else if (!entity) {
4526178848Scokane          dtd->keepProcessing = dtd->standalone;
4527104349Sphk          /* cannot report skipped entities in declarations */
4528104349Sphk          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
4529104349Sphk            skippedEntityHandler(handlerArg, name, 1);
4530104349Sphk            handleDefault = XML_FALSE;
4531104349Sphk          }
4532104349Sphk          break;
4533104349Sphk        }
4534104349Sphk        if (entity->open)
4535104349Sphk          return XML_ERROR_RECURSIVE_ENTITY_REF;
4536104349Sphk        if (entity->textPtr) {
4537104349Sphk          enum XML_Error result;
4538247513Sdelphij          XML_Bool betweenDecl =
4539178848Scokane            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
4540178848Scokane          result = processInternalEntity(parser, entity, betweenDecl);
4541104349Sphk          if (result != XML_ERROR_NONE)
4542104349Sphk            return result;
4543104349Sphk          handleDefault = XML_FALSE;
4544104349Sphk          break;
4545104349Sphk        }
4546104349Sphk        if (externalEntityRefHandler) {
4547178848Scokane          dtd->paramEntityRead = XML_FALSE;
4548104349Sphk          entity->open = XML_TRUE;
4549104349Sphk          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
4550104349Sphk                                        0,
4551104349Sphk                                        entity->base,
4552104349Sphk                                        entity->systemId,
4553104349Sphk                                        entity->publicId)) {
4554104349Sphk            entity->open = XML_FALSE;
4555104349Sphk            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
4556104349Sphk          }
4557104349Sphk          entity->open = XML_FALSE;
4558104349Sphk          handleDefault = XML_FALSE;
4559178848Scokane          if (!dtd->paramEntityRead) {
4560178848Scokane            dtd->keepProcessing = dtd->standalone;
4561104349Sphk            break;
4562104349Sphk          }
4563104349Sphk        }
4564104349Sphk        else {
4565178848Scokane          dtd->keepProcessing = dtd->standalone;
4566104349Sphk          break;
4567104349Sphk        }
4568104349Sphk      }
4569104349Sphk#endif /* XML_DTD */
4570178848Scokane      if (!dtd->standalone &&
4571104349Sphk          notStandaloneHandler &&
4572104349Sphk          !notStandaloneHandler(handlerArg))
4573104349Sphk        return XML_ERROR_NOT_STANDALONE;
4574104349Sphk      break;
4575104349Sphk
4576104349Sphk    /* Element declaration stuff */
4577104349Sphk
4578104349Sphk    case XML_ROLE_ELEMENT_NAME:
4579104349Sphk      if (elementDeclHandler) {
4580104349Sphk        declElementType = getElementType(parser, enc, s, next);
4581104349Sphk        if (!declElementType)
4582104349Sphk          return XML_ERROR_NO_MEMORY;
4583178848Scokane        dtd->scaffLevel = 0;
4584178848Scokane        dtd->scaffCount = 0;
4585178848Scokane        dtd->in_eldecl = XML_TRUE;
4586104349Sphk        handleDefault = XML_FALSE;
4587104349Sphk      }
4588104349Sphk      break;
4589104349Sphk
4590104349Sphk    case XML_ROLE_CONTENT_ANY:
4591104349Sphk    case XML_ROLE_CONTENT_EMPTY:
4592178848Scokane      if (dtd->in_eldecl) {
4593104349Sphk        if (elementDeclHandler) {
4594104349Sphk          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
4595104349Sphk          if (!content)
4596104349Sphk            return XML_ERROR_NO_MEMORY;
4597104349Sphk          content->quant = XML_CQUANT_NONE;
4598104349Sphk          content->name = NULL;
4599104349Sphk          content->numchildren = 0;
4600104349Sphk          content->children = NULL;
4601104349Sphk          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
4602104349Sphk                           XML_CTYPE_ANY :
4603104349Sphk                           XML_CTYPE_EMPTY);
4604104349Sphk          *eventEndPP = s;
4605104349Sphk          elementDeclHandler(handlerArg, declElementType->name, content);
4606104349Sphk          handleDefault = XML_FALSE;
4607104349Sphk        }
4608178848Scokane        dtd->in_eldecl = XML_FALSE;
4609104349Sphk      }
4610104349Sphk      break;
4611104349Sphk
4612104349Sphk    case XML_ROLE_CONTENT_PCDATA:
4613178848Scokane      if (dtd->in_eldecl) {
4614178848Scokane        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
4615104349Sphk            = XML_CTYPE_MIXED;
4616104349Sphk        if (elementDeclHandler)
4617104349Sphk          handleDefault = XML_FALSE;
4618104349Sphk      }
4619104349Sphk      break;
4620104349Sphk
4621104349Sphk    case XML_ROLE_CONTENT_ELEMENT:
4622104349Sphk      quant = XML_CQUANT_NONE;
4623104349Sphk      goto elementContent;
4624104349Sphk    case XML_ROLE_CONTENT_ELEMENT_OPT:
4625104349Sphk      quant = XML_CQUANT_OPT;
4626104349Sphk      goto elementContent;
4627104349Sphk    case XML_ROLE_CONTENT_ELEMENT_REP:
4628104349Sphk      quant = XML_CQUANT_REP;
4629104349Sphk      goto elementContent;
4630104349Sphk    case XML_ROLE_CONTENT_ELEMENT_PLUS:
4631104349Sphk      quant = XML_CQUANT_PLUS;
4632104349Sphk    elementContent:
4633178848Scokane      if (dtd->in_eldecl) {
4634104349Sphk        ELEMENT_TYPE *el;
4635104349Sphk        const XML_Char *name;
4636104349Sphk        int nameLen;
4637104349Sphk        const char *nxt = (quant == XML_CQUANT_NONE
4638104349Sphk                           ? next
4639104349Sphk                           : next - enc->minBytesPerChar);
4640104349Sphk        int myindex = nextScaffoldPart(parser);
4641104349Sphk        if (myindex < 0)
4642104349Sphk          return XML_ERROR_NO_MEMORY;
4643178848Scokane        dtd->scaffold[myindex].type = XML_CTYPE_NAME;
4644178848Scokane        dtd->scaffold[myindex].quant = quant;
4645104349Sphk        el = getElementType(parser, enc, s, nxt);
4646104349Sphk        if (!el)
4647104349Sphk          return XML_ERROR_NO_MEMORY;
4648104349Sphk        name = el->name;
4649178848Scokane        dtd->scaffold[myindex].name = name;
4650104349Sphk        nameLen = 0;
4651104349Sphk        for (; name[nameLen++]; );
4652178848Scokane        dtd->contentStringLen +=  nameLen;
4653104349Sphk        if (elementDeclHandler)
4654104349Sphk          handleDefault = XML_FALSE;
4655104349Sphk      }
4656104349Sphk      break;
4657104349Sphk
4658104349Sphk    case XML_ROLE_GROUP_CLOSE:
4659104349Sphk      quant = XML_CQUANT_NONE;
4660104349Sphk      goto closeGroup;
4661104349Sphk    case XML_ROLE_GROUP_CLOSE_OPT:
4662104349Sphk      quant = XML_CQUANT_OPT;
4663104349Sphk      goto closeGroup;
4664104349Sphk    case XML_ROLE_GROUP_CLOSE_REP:
4665104349Sphk      quant = XML_CQUANT_REP;
4666104349Sphk      goto closeGroup;
4667104349Sphk    case XML_ROLE_GROUP_CLOSE_PLUS:
4668104349Sphk      quant = XML_CQUANT_PLUS;
4669104349Sphk    closeGroup:
4670178848Scokane      if (dtd->in_eldecl) {
4671104349Sphk        if (elementDeclHandler)
4672104349Sphk          handleDefault = XML_FALSE;
4673178848Scokane        dtd->scaffLevel--;
4674178848Scokane        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
4675178848Scokane        if (dtd->scaffLevel == 0) {
4676104349Sphk          if (!handleDefault) {
4677104349Sphk            XML_Content *model = build_model(parser);
4678104349Sphk            if (!model)
4679104349Sphk              return XML_ERROR_NO_MEMORY;
4680104349Sphk            *eventEndPP = s;
4681104349Sphk            elementDeclHandler(handlerArg, declElementType->name, model);
4682104349Sphk          }
4683178848Scokane          dtd->in_eldecl = XML_FALSE;
4684178848Scokane          dtd->contentStringLen = 0;
4685104349Sphk        }
4686104349Sphk      }
4687104349Sphk      break;
4688104349Sphk      /* End element declaration stuff */
4689104349Sphk
4690104349Sphk    case XML_ROLE_PI:
4691104349Sphk      if (!reportProcessingInstruction(parser, enc, s, next))
4692104349Sphk        return XML_ERROR_NO_MEMORY;
4693104349Sphk      handleDefault = XML_FALSE;
4694104349Sphk      break;
4695104349Sphk    case XML_ROLE_COMMENT:
4696104349Sphk      if (!reportComment(parser, enc, s, next))
4697104349Sphk        return XML_ERROR_NO_MEMORY;
4698104349Sphk      handleDefault = XML_FALSE;
4699104349Sphk      break;
4700104349Sphk    case XML_ROLE_NONE:
4701104349Sphk      switch (tok) {
4702104349Sphk      case XML_TOK_BOM:
4703104349Sphk        handleDefault = XML_FALSE;
4704104349Sphk        break;
4705104349Sphk      }
4706104349Sphk      break;
4707104349Sphk    case XML_ROLE_DOCTYPE_NONE:
4708104349Sphk      if (startDoctypeDeclHandler)
4709104349Sphk        handleDefault = XML_FALSE;
4710104349Sphk      break;
4711104349Sphk    case XML_ROLE_ENTITY_NONE:
4712178848Scokane      if (dtd->keepProcessing && entityDeclHandler)
4713104349Sphk        handleDefault = XML_FALSE;
4714104349Sphk      break;
4715104349Sphk    case XML_ROLE_NOTATION_NONE:
4716104349Sphk      if (notationDeclHandler)
4717104349Sphk        handleDefault = XML_FALSE;
4718104349Sphk      break;
4719104349Sphk    case XML_ROLE_ATTLIST_NONE:
4720178848Scokane      if (dtd->keepProcessing && attlistDeclHandler)
4721104349Sphk        handleDefault = XML_FALSE;
4722104349Sphk      break;
4723104349Sphk    case XML_ROLE_ELEMENT_NONE:
4724104349Sphk      if (elementDeclHandler)
4725104349Sphk        handleDefault = XML_FALSE;
4726104349Sphk      break;
4727104349Sphk    } /* end of big switch */
4728104349Sphk
4729178848Scokane    if (handleDefault && defaultHandler)
4730104349Sphk      reportDefault(parser, enc, s, next);
4731104349Sphk
4732178848Scokane    switch (ps_parsing) {
4733247513Sdelphij    case XML_SUSPENDED:
4734178848Scokane      *nextPtr = next;
4735178848Scokane      return XML_ERROR_NONE;
4736178848Scokane    case XML_FINISHED:
4737178848Scokane      return XML_ERROR_ABORTED;
4738178848Scokane    default:
4739178848Scokane      s = next;
4740178848Scokane      tok = XmlPrologTok(enc, s, end, &next);
4741178848Scokane    }
4742104349Sphk  }
4743104349Sphk  /* not reached */
4744104349Sphk}
4745104349Sphk
4746178848Scokanestatic enum XML_Error PTRCALL
4747104349SphkepilogProcessor(XML_Parser parser,
4748104349Sphk                const char *s,
4749104349Sphk                const char *end,
4750104349Sphk                const char **nextPtr)
4751104349Sphk{
4752104349Sphk  processor = epilogProcessor;
4753104349Sphk  eventPtr = s;
4754104349Sphk  for (;;) {
4755104349Sphk    const char *next = NULL;
4756104349Sphk    int tok = XmlPrologTok(encoding, s, end, &next);
4757104349Sphk    eventEndPtr = next;
4758104349Sphk    switch (tok) {
4759104349Sphk    /* report partial linebreak - it might be the last token */
4760178848Scokane    case -XML_TOK_PROLOG_S:
4761104349Sphk      if (defaultHandler) {
4762104349Sphk        reportDefault(parser, encoding, s, next);
4763178848Scokane        if (ps_parsing == XML_FINISHED)
4764178848Scokane          return XML_ERROR_ABORTED;
4765104349Sphk      }
4766178848Scokane      *nextPtr = next;
4767104349Sphk      return XML_ERROR_NONE;
4768104349Sphk    case XML_TOK_NONE:
4769178848Scokane      *nextPtr = s;
4770104349Sphk      return XML_ERROR_NONE;
4771104349Sphk    case XML_TOK_PROLOG_S:
4772104349Sphk      if (defaultHandler)
4773104349Sphk        reportDefault(parser, encoding, s, next);
4774104349Sphk      break;
4775104349Sphk    case XML_TOK_PI:
4776104349Sphk      if (!reportProcessingInstruction(parser, encoding, s, next))
4777104349Sphk        return XML_ERROR_NO_MEMORY;
4778104349Sphk      break;
4779104349Sphk    case XML_TOK_COMMENT:
4780104349Sphk      if (!reportComment(parser, encoding, s, next))
4781104349Sphk        return XML_ERROR_NO_MEMORY;
4782104349Sphk      break;
4783104349Sphk    case XML_TOK_INVALID:
4784104349Sphk      eventPtr = next;
4785104349Sphk      return XML_ERROR_INVALID_TOKEN;
4786104349Sphk    case XML_TOK_PARTIAL:
4787178848Scokane      if (!ps_finalBuffer) {
4788104349Sphk        *nextPtr = s;
4789104349Sphk        return XML_ERROR_NONE;
4790104349Sphk      }
4791104349Sphk      return XML_ERROR_UNCLOSED_TOKEN;
4792104349Sphk    case XML_TOK_PARTIAL_CHAR:
4793178848Scokane      if (!ps_finalBuffer) {
4794104349Sphk        *nextPtr = s;
4795104349Sphk        return XML_ERROR_NONE;
4796104349Sphk      }
4797104349Sphk      return XML_ERROR_PARTIAL_CHAR;
4798104349Sphk    default:
4799104349Sphk      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
4800104349Sphk    }
4801104349Sphk    eventPtr = s = next;
4802178848Scokane    switch (ps_parsing) {
4803247513Sdelphij    case XML_SUSPENDED:
4804178848Scokane      *nextPtr = next;
4805178848Scokane      return XML_ERROR_NONE;
4806178848Scokane    case XML_FINISHED:
4807178848Scokane      return XML_ERROR_ABORTED;
4808178848Scokane    default: ;
4809178848Scokane    }
4810104349Sphk  }
4811104349Sphk}
4812104349Sphk
4813178848Scokanestatic enum XML_Error
4814178848ScokaneprocessInternalEntity(XML_Parser parser, ENTITY *entity,
4815178848Scokane                      XML_Bool betweenDecl)
4816104349Sphk{
4817178848Scokane  const char *textStart, *textEnd;
4818178848Scokane  const char *next;
4819104349Sphk  enum XML_Error result;
4820178848Scokane  OPEN_INTERNAL_ENTITY *openEntity;
4821178848Scokane
4822178848Scokane  if (freeInternalEntities) {
4823178848Scokane    openEntity = freeInternalEntities;
4824178848Scokane    freeInternalEntities = openEntity->next;
4825178848Scokane  }
4826178848Scokane  else {
4827178848Scokane    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
4828178848Scokane    if (!openEntity)
4829178848Scokane      return XML_ERROR_NO_MEMORY;
4830178848Scokane  }
4831104349Sphk  entity->open = XML_TRUE;
4832178848Scokane  entity->processed = 0;
4833178848Scokane  openEntity->next = openInternalEntities;
4834178848Scokane  openInternalEntities = openEntity;
4835178848Scokane  openEntity->entity = entity;
4836178848Scokane  openEntity->startTagLevel = tagLevel;
4837178848Scokane  openEntity->betweenDecl = betweenDecl;
4838178848Scokane  openEntity->internalEventPtr = NULL;
4839178848Scokane  openEntity->internalEventEndPtr = NULL;
4840178848Scokane  textStart = (char *)entity->textPtr;
4841178848Scokane  textEnd = (char *)(entity->textPtr + entity->textLen);
4842178848Scokane
4843178848Scokane#ifdef XML_DTD
4844178848Scokane  if (entity->is_param) {
4845178848Scokane    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4846247513Sdelphij    result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4847178848Scokane                      next, &next, XML_FALSE);
4848178848Scokane  }
4849247513Sdelphij  else
4850178848Scokane#endif /* XML_DTD */
4851247513Sdelphij    result = doContent(parser, tagLevel, internalEncoding, textStart,
4852178848Scokane                       textEnd, &next, XML_FALSE);
4853178848Scokane
4854178848Scokane  if (result == XML_ERROR_NONE) {
4855178848Scokane    if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4856178848Scokane      entity->processed = (int)(next - textStart);
4857178848Scokane      processor = internalEntityProcessor;
4858178848Scokane    }
4859178848Scokane    else {
4860178848Scokane      entity->open = XML_FALSE;
4861178848Scokane      openInternalEntities = openEntity->next;
4862178848Scokane      /* put openEntity back in list of free instances */
4863178848Scokane      openEntity->next = freeInternalEntities;
4864178848Scokane      freeInternalEntities = openEntity;
4865178848Scokane    }
4866178848Scokane  }
4867104349Sphk  return result;
4868104349Sphk}
4869104349Sphk
4870178848Scokanestatic enum XML_Error PTRCALL
4871178848ScokaneinternalEntityProcessor(XML_Parser parser,
4872178848Scokane                        const char *s,
4873178848Scokane                        const char *end,
4874178848Scokane                        const char **nextPtr)
4875178848Scokane{
4876178848Scokane  ENTITY *entity;
4877178848Scokane  const char *textStart, *textEnd;
4878178848Scokane  const char *next;
4879178848Scokane  enum XML_Error result;
4880178848Scokane  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
4881178848Scokane  if (!openEntity)
4882178848Scokane    return XML_ERROR_UNEXPECTED_STATE;
4883178848Scokane
4884178848Scokane  entity = openEntity->entity;
4885178848Scokane  textStart = ((char *)entity->textPtr) + entity->processed;
4886178848Scokane  textEnd = (char *)(entity->textPtr + entity->textLen);
4887178848Scokane
4888178848Scokane#ifdef XML_DTD
4889178848Scokane  if (entity->is_param) {
4890178848Scokane    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
4891247513Sdelphij    result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
4892178848Scokane                      next, &next, XML_FALSE);
4893178848Scokane  }
4894178848Scokane  else
4895104349Sphk#endif /* XML_DTD */
4896247513Sdelphij    result = doContent(parser, openEntity->startTagLevel, internalEncoding,
4897247513Sdelphij                       textStart, textEnd, &next, XML_FALSE);
4898104349Sphk
4899178848Scokane  if (result != XML_ERROR_NONE)
4900178848Scokane    return result;
4901178848Scokane  else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
4902178848Scokane    entity->processed = (int)(next - (char *)entity->textPtr);
4903178848Scokane    return result;
4904178848Scokane  }
4905178848Scokane  else {
4906178848Scokane    entity->open = XML_FALSE;
4907178848Scokane    openInternalEntities = openEntity->next;
4908178848Scokane    /* put openEntity back in list of free instances */
4909178848Scokane    openEntity->next = freeInternalEntities;
4910178848Scokane    freeInternalEntities = openEntity;
4911178848Scokane  }
4912178848Scokane
4913178848Scokane#ifdef XML_DTD
4914178848Scokane  if (entity->is_param) {
4915178848Scokane    int tok;
4916178848Scokane    processor = prologProcessor;
4917178848Scokane    tok = XmlPrologTok(encoding, s, end, &next);
4918247513Sdelphij    return doProlog(parser, encoding, s, end, tok, next, nextPtr,
4919178848Scokane                    (XML_Bool)!ps_finalBuffer);
4920178848Scokane  }
4921178848Scokane  else
4922178848Scokane#endif /* XML_DTD */
4923178848Scokane  {
4924178848Scokane    processor = contentProcessor;
4925178848Scokane    /* see externalEntityContentProcessor vs contentProcessor */
4926178848Scokane    return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
4927247513Sdelphij                     nextPtr, (XML_Bool)!ps_finalBuffer);
4928247513Sdelphij  }
4929178848Scokane}
4930178848Scokane
4931178848Scokanestatic enum XML_Error PTRCALL
4932104349SphkerrorProcessor(XML_Parser parser,
4933104349Sphk               const char *s,
4934104349Sphk               const char *end,
4935104349Sphk               const char **nextPtr)
4936104349Sphk{
4937104349Sphk  return errorCode;
4938104349Sphk}
4939104349Sphk
4940178848Scokanestatic enum XML_Error
4941104349SphkstoreAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4942104349Sphk                    const char *ptr, const char *end,
4943104349Sphk                    STRING_POOL *pool)
4944104349Sphk{
4945104349Sphk  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
4946104349Sphk                                               end, pool);
4947104349Sphk  if (result)
4948104349Sphk    return result;
4949104349Sphk  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
4950104349Sphk    poolChop(pool);
4951104349Sphk  if (!poolAppendChar(pool, XML_T('\0')))
4952104349Sphk    return XML_ERROR_NO_MEMORY;
4953104349Sphk  return XML_ERROR_NONE;
4954104349Sphk}
4955104349Sphk
4956178848Scokanestatic enum XML_Error
4957104349SphkappendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
4958104349Sphk                     const char *ptr, const char *end,
4959104349Sphk                     STRING_POOL *pool)
4960104349Sphk{
4961178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
4962104349Sphk  for (;;) {
4963104349Sphk    const char *next;
4964104349Sphk    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
4965104349Sphk    switch (tok) {
4966104349Sphk    case XML_TOK_NONE:
4967104349Sphk      return XML_ERROR_NONE;
4968104349Sphk    case XML_TOK_INVALID:
4969104349Sphk      if (enc == encoding)
4970104349Sphk        eventPtr = next;
4971104349Sphk      return XML_ERROR_INVALID_TOKEN;
4972104349Sphk    case XML_TOK_PARTIAL:
4973104349Sphk      if (enc == encoding)
4974104349Sphk        eventPtr = ptr;
4975104349Sphk      return XML_ERROR_INVALID_TOKEN;
4976104349Sphk    case XML_TOK_CHAR_REF:
4977104349Sphk      {
4978104349Sphk        XML_Char buf[XML_ENCODE_MAX];
4979104349Sphk        int i;
4980104349Sphk        int n = XmlCharRefNumber(enc, ptr);
4981104349Sphk        if (n < 0) {
4982104349Sphk          if (enc == encoding)
4983104349Sphk            eventPtr = ptr;
4984104349Sphk          return XML_ERROR_BAD_CHAR_REF;
4985104349Sphk        }
4986104349Sphk        if (!isCdata
4987104349Sphk            && n == 0x20 /* space */
4988104349Sphk            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
4989104349Sphk          break;
4990104349Sphk        n = XmlEncode(n, (ICHAR *)buf);
4991104349Sphk        if (!n) {
4992104349Sphk          if (enc == encoding)
4993104349Sphk            eventPtr = ptr;
4994104349Sphk          return XML_ERROR_BAD_CHAR_REF;
4995104349Sphk        }
4996104349Sphk        for (i = 0; i < n; i++) {
4997104349Sphk          if (!poolAppendChar(pool, buf[i]))
4998104349Sphk            return XML_ERROR_NO_MEMORY;
4999104349Sphk        }
5000104349Sphk      }
5001104349Sphk      break;
5002104349Sphk    case XML_TOK_DATA_CHARS:
5003104349Sphk      if (!poolAppend(pool, enc, ptr, next))
5004104349Sphk        return XML_ERROR_NO_MEMORY;
5005104349Sphk      break;
5006104349Sphk    case XML_TOK_TRAILING_CR:
5007104349Sphk      next = ptr + enc->minBytesPerChar;
5008104349Sphk      /* fall through */
5009104349Sphk    case XML_TOK_ATTRIBUTE_VALUE_S:
5010104349Sphk    case XML_TOK_DATA_NEWLINE:
5011104349Sphk      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
5012104349Sphk        break;
5013104349Sphk      if (!poolAppendChar(pool, 0x20))
5014104349Sphk        return XML_ERROR_NO_MEMORY;
5015104349Sphk      break;
5016104349Sphk    case XML_TOK_ENTITY_REF:
5017104349Sphk      {
5018104349Sphk        const XML_Char *name;
5019104349Sphk        ENTITY *entity;
5020104349Sphk        char checkEntityDecl;
5021104349Sphk        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
5022104349Sphk                                              ptr + enc->minBytesPerChar,
5023104349Sphk                                              next - enc->minBytesPerChar);
5024104349Sphk        if (ch) {
5025104349Sphk          if (!poolAppendChar(pool, ch))
5026104349Sphk                return XML_ERROR_NO_MEMORY;
5027104349Sphk          break;
5028104349Sphk        }
5029104349Sphk        name = poolStoreString(&temp2Pool, enc,
5030104349Sphk                               ptr + enc->minBytesPerChar,
5031104349Sphk                               next - enc->minBytesPerChar);
5032104349Sphk        if (!name)
5033104349Sphk          return XML_ERROR_NO_MEMORY;
5034247513Sdelphij        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
5035104349Sphk        poolDiscard(&temp2Pool);
5036178848Scokane        /* First, determine if a check for an existing declaration is needed;
5037178848Scokane           if yes, check that the entity exists, and that it is internal.
5038104349Sphk        */
5039178848Scokane        if (pool == &dtd->pool)  /* are we called from prolog? */
5040104349Sphk          checkEntityDecl =
5041104349Sphk#ifdef XML_DTD
5042104349Sphk              prologState.documentEntity &&
5043104349Sphk#endif /* XML_DTD */
5044178848Scokane              (dtd->standalone
5045104349Sphk               ? !openInternalEntities
5046178848Scokane               : !dtd->hasParamEntityRefs);
5047104349Sphk        else /* if (pool == &tempPool): we are called from content */
5048178848Scokane          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
5049104349Sphk        if (checkEntityDecl) {
5050104349Sphk          if (!entity)
5051104349Sphk            return XML_ERROR_UNDEFINED_ENTITY;
5052104349Sphk          else if (!entity->is_internal)
5053104349Sphk            return XML_ERROR_ENTITY_DECLARED_IN_PE;
5054104349Sphk        }
5055104349Sphk        else if (!entity) {
5056178848Scokane          /* Cannot report skipped entity here - see comments on
5057178848Scokane             skippedEntityHandler.
5058104349Sphk          if (skippedEntityHandler)
5059104349Sphk            skippedEntityHandler(handlerArg, name, 0);
5060104349Sphk          */
5061178848Scokane          /* Cannot call the default handler because this would be
5062178848Scokane             out of sync with the call to the startElementHandler.
5063104349Sphk          if ((pool == &tempPool) && defaultHandler)
5064104349Sphk            reportDefault(parser, enc, ptr, next);
5065178848Scokane          */
5066104349Sphk          break;
5067104349Sphk        }
5068104349Sphk        if (entity->open) {
5069104349Sphk          if (enc == encoding)
5070104349Sphk            eventPtr = ptr;
5071104349Sphk          return XML_ERROR_RECURSIVE_ENTITY_REF;
5072104349Sphk        }
5073104349Sphk        if (entity->notation) {
5074104349Sphk          if (enc == encoding)
5075104349Sphk            eventPtr = ptr;
5076104349Sphk          return XML_ERROR_BINARY_ENTITY_REF;
5077104349Sphk        }
5078104349Sphk        if (!entity->textPtr) {
5079104349Sphk          if (enc == encoding)
5080104349Sphk            eventPtr = ptr;
5081247513Sdelphij          return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
5082104349Sphk        }
5083104349Sphk        else {
5084104349Sphk          enum XML_Error result;
5085104349Sphk          const XML_Char *textEnd = entity->textPtr + entity->textLen;
5086104349Sphk          entity->open = XML_TRUE;
5087104349Sphk          result = appendAttributeValue(parser, internalEncoding, isCdata,
5088104349Sphk                                        (char *)entity->textPtr,
5089104349Sphk                                        (char *)textEnd, pool);
5090104349Sphk          entity->open = XML_FALSE;
5091104349Sphk          if (result)
5092104349Sphk            return result;
5093104349Sphk        }
5094104349Sphk      }
5095104349Sphk      break;
5096104349Sphk    default:
5097104349Sphk      if (enc == encoding)
5098104349Sphk        eventPtr = ptr;
5099104349Sphk      return XML_ERROR_UNEXPECTED_STATE;
5100104349Sphk    }
5101104349Sphk    ptr = next;
5102104349Sphk  }
5103104349Sphk  /* not reached */
5104104349Sphk}
5105104349Sphk
5106178848Scokanestatic enum XML_Error
5107104349SphkstoreEntityValue(XML_Parser parser,
5108104349Sphk                 const ENCODING *enc,
5109104349Sphk                 const char *entityTextPtr,
5110104349Sphk                 const char *entityTextEnd)
5111104349Sphk{
5112178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
5113178848Scokane  STRING_POOL *pool = &(dtd->entityValuePool);
5114104349Sphk  enum XML_Error result = XML_ERROR_NONE;
5115104349Sphk#ifdef XML_DTD
5116104349Sphk  int oldInEntityValue = prologState.inEntityValue;
5117104349Sphk  prologState.inEntityValue = 1;
5118104349Sphk#endif /* XML_DTD */
5119104349Sphk  /* never return Null for the value argument in EntityDeclHandler,
5120104349Sphk     since this would indicate an external entity; therefore we
5121104349Sphk     have to make sure that entityValuePool.start is not null */
5122104349Sphk  if (!pool->blocks) {
5123104349Sphk    if (!poolGrow(pool))
5124104349Sphk      return XML_ERROR_NO_MEMORY;
5125104349Sphk  }
5126104349Sphk
5127104349Sphk  for (;;) {
5128104349Sphk    const char *next;
5129104349Sphk    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
5130104349Sphk    switch (tok) {
5131104349Sphk    case XML_TOK_PARAM_ENTITY_REF:
5132104349Sphk#ifdef XML_DTD
5133104349Sphk      if (isParamEntity || enc != encoding) {
5134104349Sphk        const XML_Char *name;
5135104349Sphk        ENTITY *entity;
5136104349Sphk        name = poolStoreString(&tempPool, enc,
5137104349Sphk                               entityTextPtr + enc->minBytesPerChar,
5138104349Sphk                               next - enc->minBytesPerChar);
5139104349Sphk        if (!name) {
5140104349Sphk          result = XML_ERROR_NO_MEMORY;
5141104349Sphk          goto endEntityValue;
5142104349Sphk        }
5143247513Sdelphij        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
5144104349Sphk        poolDiscard(&tempPool);
5145104349Sphk        if (!entity) {
5146104349Sphk          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
5147104349Sphk          /* cannot report skipped entity here - see comments on
5148104349Sphk             skippedEntityHandler
5149104349Sphk          if (skippedEntityHandler)
5150104349Sphk            skippedEntityHandler(handlerArg, name, 0);
5151104349Sphk          */
5152178848Scokane          dtd->keepProcessing = dtd->standalone;
5153104349Sphk          goto endEntityValue;
5154104349Sphk        }
5155104349Sphk        if (entity->open) {
5156104349Sphk          if (enc == encoding)
5157104349Sphk            eventPtr = entityTextPtr;
5158104349Sphk          result = XML_ERROR_RECURSIVE_ENTITY_REF;
5159104349Sphk          goto endEntityValue;
5160104349Sphk        }
5161104349Sphk        if (entity->systemId) {
5162104349Sphk          if (externalEntityRefHandler) {
5163178848Scokane            dtd->paramEntityRead = XML_FALSE;
5164104349Sphk            entity->open = XML_TRUE;
5165104349Sphk            if (!externalEntityRefHandler(externalEntityRefHandlerArg,
5166104349Sphk                                          0,
5167104349Sphk                                          entity->base,
5168104349Sphk                                          entity->systemId,
5169104349Sphk                                          entity->publicId)) {
5170104349Sphk              entity->open = XML_FALSE;
5171104349Sphk              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5172104349Sphk              goto endEntityValue;
5173104349Sphk            }
5174104349Sphk            entity->open = XML_FALSE;
5175178848Scokane            if (!dtd->paramEntityRead)
5176178848Scokane              dtd->keepProcessing = dtd->standalone;
5177104349Sphk          }
5178104349Sphk          else
5179178848Scokane            dtd->keepProcessing = dtd->standalone;
5180104349Sphk        }
5181104349Sphk        else {
5182104349Sphk          entity->open = XML_TRUE;
5183104349Sphk          result = storeEntityValue(parser,
5184104349Sphk                                    internalEncoding,
5185104349Sphk                                    (char *)entity->textPtr,
5186104349Sphk                                    (char *)(entity->textPtr
5187104349Sphk                                             + entity->textLen));
5188104349Sphk          entity->open = XML_FALSE;
5189104349Sphk          if (result)
5190104349Sphk            goto endEntityValue;
5191104349Sphk        }
5192104349Sphk        break;
5193104349Sphk      }
5194104349Sphk#endif /* XML_DTD */
5195178848Scokane      /* In the internal subset, PE references are not legal
5196178848Scokane         within markup declarations, e.g entity values in this case. */
5197104349Sphk      eventPtr = entityTextPtr;
5198104349Sphk      result = XML_ERROR_PARAM_ENTITY_REF;
5199104349Sphk      goto endEntityValue;
5200104349Sphk    case XML_TOK_NONE:
5201104349Sphk      result = XML_ERROR_NONE;
5202104349Sphk      goto endEntityValue;
5203104349Sphk    case XML_TOK_ENTITY_REF:
5204104349Sphk    case XML_TOK_DATA_CHARS:
5205104349Sphk      if (!poolAppend(pool, enc, entityTextPtr, next)) {
5206104349Sphk        result = XML_ERROR_NO_MEMORY;
5207104349Sphk        goto endEntityValue;
5208104349Sphk      }
5209104349Sphk      break;
5210104349Sphk    case XML_TOK_TRAILING_CR:
5211104349Sphk      next = entityTextPtr + enc->minBytesPerChar;
5212104349Sphk      /* fall through */
5213104349Sphk    case XML_TOK_DATA_NEWLINE:
5214104349Sphk      if (pool->end == pool->ptr && !poolGrow(pool)) {
5215104349Sphk              result = XML_ERROR_NO_MEMORY;
5216104349Sphk        goto endEntityValue;
5217104349Sphk      }
5218104349Sphk      *(pool->ptr)++ = 0xA;
5219104349Sphk      break;
5220104349Sphk    case XML_TOK_CHAR_REF:
5221104349Sphk      {
5222104349Sphk        XML_Char buf[XML_ENCODE_MAX];
5223104349Sphk        int i;
5224104349Sphk        int n = XmlCharRefNumber(enc, entityTextPtr);
5225104349Sphk        if (n < 0) {
5226104349Sphk          if (enc == encoding)
5227104349Sphk            eventPtr = entityTextPtr;
5228104349Sphk          result = XML_ERROR_BAD_CHAR_REF;
5229104349Sphk          goto endEntityValue;
5230104349Sphk        }
5231104349Sphk        n = XmlEncode(n, (ICHAR *)buf);
5232104349Sphk        if (!n) {
5233104349Sphk          if (enc == encoding)
5234104349Sphk            eventPtr = entityTextPtr;
5235104349Sphk          result = XML_ERROR_BAD_CHAR_REF;
5236104349Sphk          goto endEntityValue;
5237104349Sphk        }
5238104349Sphk        for (i = 0; i < n; i++) {
5239104349Sphk          if (pool->end == pool->ptr && !poolGrow(pool)) {
5240104349Sphk            result = XML_ERROR_NO_MEMORY;
5241104349Sphk            goto endEntityValue;
5242104349Sphk          }
5243104349Sphk          *(pool->ptr)++ = buf[i];
5244104349Sphk        }
5245104349Sphk      }
5246104349Sphk      break;
5247104349Sphk    case XML_TOK_PARTIAL:
5248104349Sphk      if (enc == encoding)
5249104349Sphk        eventPtr = entityTextPtr;
5250104349Sphk      result = XML_ERROR_INVALID_TOKEN;
5251104349Sphk      goto endEntityValue;
5252104349Sphk    case XML_TOK_INVALID:
5253104349Sphk      if (enc == encoding)
5254104349Sphk        eventPtr = next;
5255104349Sphk      result = XML_ERROR_INVALID_TOKEN;
5256104349Sphk      goto endEntityValue;
5257104349Sphk    default:
5258104349Sphk      if (enc == encoding)
5259104349Sphk        eventPtr = entityTextPtr;
5260104349Sphk      result = XML_ERROR_UNEXPECTED_STATE;
5261104349Sphk      goto endEntityValue;
5262104349Sphk    }
5263104349Sphk    entityTextPtr = next;
5264104349Sphk  }
5265104349SphkendEntityValue:
5266104349Sphk#ifdef XML_DTD
5267104349Sphk  prologState.inEntityValue = oldInEntityValue;
5268104349Sphk#endif /* XML_DTD */
5269104349Sphk  return result;
5270104349Sphk}
5271104349Sphk
5272104349Sphkstatic void FASTCALL
5273104349SphknormalizeLines(XML_Char *s)
5274104349Sphk{
5275104349Sphk  XML_Char *p;
5276104349Sphk  for (;; s++) {
5277104349Sphk    if (*s == XML_T('\0'))
5278104349Sphk      return;
5279104349Sphk    if (*s == 0xD)
5280104349Sphk      break;
5281104349Sphk  }
5282104349Sphk  p = s;
5283104349Sphk  do {
5284104349Sphk    if (*s == 0xD) {
5285104349Sphk      *p++ = 0xA;
5286104349Sphk      if (*++s == 0xA)
5287104349Sphk        s++;
5288104349Sphk    }
5289104349Sphk    else
5290104349Sphk      *p++ = *s++;
5291104349Sphk  } while (*s);
5292104349Sphk  *p = XML_T('\0');
5293104349Sphk}
5294104349Sphk
5295178848Scokanestatic int
5296104349SphkreportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
5297104349Sphk                            const char *start, const char *end)
5298104349Sphk{
5299104349Sphk  const XML_Char *target;
5300104349Sphk  XML_Char *data;
5301104349Sphk  const char *tem;
5302104349Sphk  if (!processingInstructionHandler) {
5303104349Sphk    if (defaultHandler)
5304104349Sphk      reportDefault(parser, enc, start, end);
5305104349Sphk    return 1;
5306104349Sphk  }
5307104349Sphk  start += enc->minBytesPerChar * 2;
5308104349Sphk  tem = start + XmlNameLength(enc, start);
5309104349Sphk  target = poolStoreString(&tempPool, enc, start, tem);
5310104349Sphk  if (!target)
5311104349Sphk    return 0;
5312104349Sphk  poolFinish(&tempPool);
5313104349Sphk  data = poolStoreString(&tempPool, enc,
5314104349Sphk                        XmlSkipS(enc, tem),
5315104349Sphk                        end - enc->minBytesPerChar*2);
5316104349Sphk  if (!data)
5317104349Sphk    return 0;
5318104349Sphk  normalizeLines(data);
5319104349Sphk  processingInstructionHandler(handlerArg, target, data);
5320104349Sphk  poolClear(&tempPool);
5321104349Sphk  return 1;
5322104349Sphk}
5323104349Sphk
5324178848Scokanestatic int
5325104349SphkreportComment(XML_Parser parser, const ENCODING *enc,
5326104349Sphk              const char *start, const char *end)
5327104349Sphk{
5328104349Sphk  XML_Char *data;
5329104349Sphk  if (!commentHandler) {
5330104349Sphk    if (defaultHandler)
5331104349Sphk      reportDefault(parser, enc, start, end);
5332104349Sphk    return 1;
5333104349Sphk  }
5334104349Sphk  data = poolStoreString(&tempPool,
5335104349Sphk                         enc,
5336104349Sphk                         start + enc->minBytesPerChar * 4,
5337104349Sphk                         end - enc->minBytesPerChar * 3);
5338104349Sphk  if (!data)
5339104349Sphk    return 0;
5340104349Sphk  normalizeLines(data);
5341104349Sphk  commentHandler(handlerArg, data);
5342104349Sphk  poolClear(&tempPool);
5343104349Sphk  return 1;
5344104349Sphk}
5345104349Sphk
5346178848Scokanestatic void
5347104349SphkreportDefault(XML_Parser parser, const ENCODING *enc,
5348104349Sphk              const char *s, const char *end)
5349104349Sphk{
5350104349Sphk  if (MUST_CONVERT(enc, s)) {
5351104349Sphk    const char **eventPP;
5352104349Sphk    const char **eventEndPP;
5353104349Sphk    if (enc == encoding) {
5354104349Sphk      eventPP = &eventPtr;
5355104349Sphk      eventEndPP = &eventEndPtr;
5356104349Sphk    }
5357104349Sphk    else {
5358104349Sphk      eventPP = &(openInternalEntities->internalEventPtr);
5359104349Sphk      eventEndPP = &(openInternalEntities->internalEventEndPtr);
5360104349Sphk    }
5361104349Sphk    do {
5362104349Sphk      ICHAR *dataPtr = (ICHAR *)dataBuf;
5363104349Sphk      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
5364104349Sphk      *eventEndPP = s;
5365178848Scokane      defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
5366104349Sphk      *eventPP = s;
5367104349Sphk    } while (s != end);
5368104349Sphk  }
5369104349Sphk  else
5370178848Scokane    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
5371104349Sphk}
5372104349Sphk
5373104349Sphk
5374178848Scokanestatic int
5375104349SphkdefineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
5376104349Sphk                XML_Bool isId, const XML_Char *value, XML_Parser parser)
5377104349Sphk{
5378104349Sphk  DEFAULT_ATTRIBUTE *att;
5379104349Sphk  if (value || isId) {
5380104349Sphk    /* The handling of default attributes gets messed up if we have
5381104349Sphk       a default which duplicates a non-default. */
5382104349Sphk    int i;
5383104349Sphk    for (i = 0; i < type->nDefaultAtts; i++)
5384104349Sphk      if (attId == type->defaultAtts[i].id)
5385104349Sphk        return 1;
5386104349Sphk    if (isId && !type->idAtt && !attId->xmlns)
5387104349Sphk      type->idAtt = attId;
5388104349Sphk  }
5389104349Sphk  if (type->nDefaultAtts == type->allocDefaultAtts) {
5390104349Sphk    if (type->allocDefaultAtts == 0) {
5391104349Sphk      type->allocDefaultAtts = 8;
5392178848Scokane      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
5393178848Scokane                            * sizeof(DEFAULT_ATTRIBUTE));
5394104349Sphk      if (!type->defaultAtts)
5395104349Sphk        return 0;
5396104349Sphk    }
5397104349Sphk    else {
5398104349Sphk      DEFAULT_ATTRIBUTE *temp;
5399104349Sphk      int count = type->allocDefaultAtts * 2;
5400178848Scokane      temp = (DEFAULT_ATTRIBUTE *)
5401178848Scokane        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
5402104349Sphk      if (temp == NULL)
5403104349Sphk        return 0;
5404104349Sphk      type->allocDefaultAtts = count;
5405104349Sphk      type->defaultAtts = temp;
5406104349Sphk    }
5407104349Sphk  }
5408104349Sphk  att = type->defaultAtts + type->nDefaultAtts;
5409104349Sphk  att->id = attId;
5410104349Sphk  att->value = value;
5411104349Sphk  att->isCdata = isCdata;
5412104349Sphk  if (!isCdata)
5413104349Sphk    attId->maybeTokenized = XML_TRUE;
5414104349Sphk  type->nDefaultAtts += 1;
5415104349Sphk  return 1;
5416104349Sphk}
5417104349Sphk
5418178848Scokanestatic int
5419104349SphksetElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
5420104349Sphk{
5421178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
5422104349Sphk  const XML_Char *name;
5423104349Sphk  for (name = elementType->name; *name; name++) {
5424178848Scokane    if (*name == XML_T(ASCII_COLON)) {
5425104349Sphk      PREFIX *prefix;
5426104349Sphk      const XML_Char *s;
5427104349Sphk      for (s = elementType->name; s != name; s++) {
5428178848Scokane        if (!poolAppendChar(&dtd->pool, *s))
5429104349Sphk          return 0;
5430104349Sphk      }
5431178848Scokane      if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5432104349Sphk        return 0;
5433247513Sdelphij      prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5434104349Sphk                                sizeof(PREFIX));
5435104349Sphk      if (!prefix)
5436104349Sphk        return 0;
5437178848Scokane      if (prefix->name == poolStart(&dtd->pool))
5438178848Scokane        poolFinish(&dtd->pool);
5439104349Sphk      else
5440178848Scokane        poolDiscard(&dtd->pool);
5441104349Sphk      elementType->prefix = prefix;
5442104349Sphk
5443104349Sphk    }
5444104349Sphk  }
5445104349Sphk  return 1;
5446104349Sphk}
5447104349Sphk
5448178848Scokanestatic ATTRIBUTE_ID *
5449104349SphkgetAttributeId(XML_Parser parser, const ENCODING *enc,
5450104349Sphk               const char *start, const char *end)
5451104349Sphk{
5452178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
5453104349Sphk  ATTRIBUTE_ID *id;
5454104349Sphk  const XML_Char *name;
5455178848Scokane  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5456104349Sphk    return NULL;
5457178848Scokane  name = poolStoreString(&dtd->pool, enc, start, end);
5458104349Sphk  if (!name)
5459104349Sphk    return NULL;
5460178848Scokane  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
5461104349Sphk  ++name;
5462247513Sdelphij  id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
5463104349Sphk  if (!id)
5464104349Sphk    return NULL;
5465104349Sphk  if (id->name != name)
5466178848Scokane    poolDiscard(&dtd->pool);
5467104349Sphk  else {
5468178848Scokane    poolFinish(&dtd->pool);
5469104349Sphk    if (!ns)
5470104349Sphk      ;
5471178848Scokane    else if (name[0] == XML_T(ASCII_x)
5472178848Scokane        && name[1] == XML_T(ASCII_m)
5473178848Scokane        && name[2] == XML_T(ASCII_l)
5474178848Scokane        && name[3] == XML_T(ASCII_n)
5475178848Scokane        && name[4] == XML_T(ASCII_s)
5476178848Scokane        && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
5477178848Scokane      if (name[5] == XML_T('\0'))
5478178848Scokane        id->prefix = &dtd->defaultPrefix;
5479104349Sphk      else
5480247513Sdelphij        id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
5481104349Sphk      id->xmlns = XML_TRUE;
5482104349Sphk    }
5483104349Sphk    else {
5484104349Sphk      int i;
5485104349Sphk      for (i = 0; name[i]; i++) {
5486178848Scokane        /* attributes without prefix are *not* in the default namespace */
5487178848Scokane        if (name[i] == XML_T(ASCII_COLON)) {
5488104349Sphk          int j;
5489104349Sphk          for (j = 0; j < i; j++) {
5490178848Scokane            if (!poolAppendChar(&dtd->pool, name[j]))
5491104349Sphk              return NULL;
5492104349Sphk          }
5493178848Scokane          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
5494104349Sphk            return NULL;
5495247513Sdelphij          id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
5496104349Sphk                                        sizeof(PREFIX));
5497178848Scokane          if (id->prefix->name == poolStart(&dtd->pool))
5498178848Scokane            poolFinish(&dtd->pool);
5499104349Sphk          else
5500178848Scokane            poolDiscard(&dtd->pool);
5501104349Sphk          break;
5502104349Sphk        }
5503104349Sphk      }
5504104349Sphk    }
5505104349Sphk  }
5506104349Sphk  return id;
5507104349Sphk}
5508104349Sphk
5509178848Scokane#define CONTEXT_SEP XML_T(ASCII_FF)
5510104349Sphk
5511178848Scokanestatic const XML_Char *
5512104349SphkgetContext(XML_Parser parser)
5513104349Sphk{
5514178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
5515104349Sphk  HASH_TABLE_ITER iter;
5516104349Sphk  XML_Bool needSep = XML_FALSE;
5517104349Sphk
5518178848Scokane  if (dtd->defaultPrefix.binding) {
5519104349Sphk    int i;
5520104349Sphk    int len;
5521178848Scokane    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5522104349Sphk      return NULL;
5523178848Scokane    len = dtd->defaultPrefix.binding->uriLen;
5524178848Scokane    if (namespaceSeparator)
5525104349Sphk      len--;
5526104349Sphk    for (i = 0; i < len; i++)
5527178848Scokane      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
5528104349Sphk        return NULL;
5529104349Sphk    needSep = XML_TRUE;
5530104349Sphk  }
5531104349Sphk
5532178848Scokane  hashTableIterInit(&iter, &(dtd->prefixes));
5533104349Sphk  for (;;) {
5534104349Sphk    int i;
5535104349Sphk    int len;
5536104349Sphk    const XML_Char *s;
5537104349Sphk    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
5538104349Sphk    if (!prefix)
5539104349Sphk      break;
5540104349Sphk    if (!prefix->binding)
5541104349Sphk      continue;
5542104349Sphk    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5543104349Sphk      return NULL;
5544104349Sphk    for (s = prefix->name; *s; s++)
5545104349Sphk      if (!poolAppendChar(&tempPool, *s))
5546104349Sphk        return NULL;
5547178848Scokane    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
5548104349Sphk      return NULL;
5549104349Sphk    len = prefix->binding->uriLen;
5550178848Scokane    if (namespaceSeparator)
5551104349Sphk      len--;
5552104349Sphk    for (i = 0; i < len; i++)
5553104349Sphk      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
5554104349Sphk        return NULL;
5555104349Sphk    needSep = XML_TRUE;
5556104349Sphk  }
5557104349Sphk
5558104349Sphk
5559178848Scokane  hashTableIterInit(&iter, &(dtd->generalEntities));
5560104349Sphk  for (;;) {
5561104349Sphk    const XML_Char *s;
5562104349Sphk    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
5563104349Sphk    if (!e)
5564104349Sphk      break;
5565104349Sphk    if (!e->open)
5566104349Sphk      continue;
5567104349Sphk    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
5568104349Sphk      return NULL;
5569104349Sphk    for (s = e->name; *s; s++)
5570104349Sphk      if (!poolAppendChar(&tempPool, *s))
5571104349Sphk        return 0;
5572104349Sphk    needSep = XML_TRUE;
5573104349Sphk  }
5574104349Sphk
5575104349Sphk  if (!poolAppendChar(&tempPool, XML_T('\0')))
5576104349Sphk    return NULL;
5577104349Sphk  return tempPool.start;
5578104349Sphk}
5579104349Sphk
5580178848Scokanestatic XML_Bool
5581104349SphksetContext(XML_Parser parser, const XML_Char *context)
5582104349Sphk{
5583178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
5584104349Sphk  const XML_Char *s = context;
5585104349Sphk
5586104349Sphk  while (*context != XML_T('\0')) {
5587104349Sphk    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
5588104349Sphk      ENTITY *e;
5589104349Sphk      if (!poolAppendChar(&tempPool, XML_T('\0')))
5590104349Sphk        return XML_FALSE;
5591247513Sdelphij      e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&tempPool), 0);
5592104349Sphk      if (e)
5593104349Sphk        e->open = XML_TRUE;
5594104349Sphk      if (*s != XML_T('\0'))
5595104349Sphk        s++;
5596104349Sphk      context = s;
5597104349Sphk      poolDiscard(&tempPool);
5598104349Sphk    }
5599178848Scokane    else if (*s == XML_T(ASCII_EQUALS)) {
5600104349Sphk      PREFIX *prefix;
5601104349Sphk      if (poolLength(&tempPool) == 0)
5602178848Scokane        prefix = &dtd->defaultPrefix;
5603104349Sphk      else {
5604104349Sphk        if (!poolAppendChar(&tempPool, XML_T('\0')))
5605104349Sphk          return XML_FALSE;
5606247513Sdelphij        prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&tempPool),
5607104349Sphk                                  sizeof(PREFIX));
5608104349Sphk        if (!prefix)
5609104349Sphk          return XML_FALSE;
5610104349Sphk        if (prefix->name == poolStart(&tempPool)) {
5611178848Scokane          prefix->name = poolCopyString(&dtd->pool, prefix->name);
5612104349Sphk          if (!prefix->name)
5613104349Sphk            return XML_FALSE;
5614104349Sphk        }
5615104349Sphk        poolDiscard(&tempPool);
5616104349Sphk      }
5617104349Sphk      for (context = s + 1;
5618104349Sphk           *context != CONTEXT_SEP && *context != XML_T('\0');
5619104349Sphk           context++)
5620104349Sphk        if (!poolAppendChar(&tempPool, *context))
5621104349Sphk          return XML_FALSE;
5622104349Sphk      if (!poolAppendChar(&tempPool, XML_T('\0')))
5623104349Sphk        return XML_FALSE;
5624178848Scokane      if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
5625178848Scokane                     &inheritedBindings) != XML_ERROR_NONE)
5626104349Sphk        return XML_FALSE;
5627104349Sphk      poolDiscard(&tempPool);
5628104349Sphk      if (*context != XML_T('\0'))
5629104349Sphk        ++context;
5630104349Sphk      s = context;
5631104349Sphk    }
5632104349Sphk    else {
5633104349Sphk      if (!poolAppendChar(&tempPool, *s))
5634104349Sphk        return XML_FALSE;
5635104349Sphk      s++;
5636104349Sphk    }
5637104349Sphk  }
5638104349Sphk  return XML_TRUE;
5639104349Sphk}
5640104349Sphk
5641104349Sphkstatic void FASTCALL
5642104349SphknormalizePublicId(XML_Char *publicId)
5643104349Sphk{
5644104349Sphk  XML_Char *p = publicId;
5645104349Sphk  XML_Char *s;
5646104349Sphk  for (s = publicId; *s; s++) {
5647104349Sphk    switch (*s) {
5648104349Sphk    case 0x20:
5649104349Sphk    case 0xD:
5650104349Sphk    case 0xA:
5651104349Sphk      if (p != publicId && p[-1] != 0x20)
5652104349Sphk        *p++ = 0x20;
5653104349Sphk      break;
5654104349Sphk    default:
5655104349Sphk      *p++ = *s;
5656104349Sphk    }
5657104349Sphk  }
5658104349Sphk  if (p != publicId && p[-1] == 0x20)
5659104349Sphk    --p;
5660104349Sphk  *p = XML_T('\0');
5661104349Sphk}
5662104349Sphk
5663178848Scokanestatic DTD *
5664178848ScokanedtdCreate(const XML_Memory_Handling_Suite *ms)
5665104349Sphk{
5666178848Scokane  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD));
5667178848Scokane  if (p == NULL)
5668178848Scokane    return p;
5669104349Sphk  poolInit(&(p->pool), ms);
5670104349Sphk  poolInit(&(p->entityValuePool), ms);
5671104349Sphk  hashTableInit(&(p->generalEntities), ms);
5672104349Sphk  hashTableInit(&(p->elementTypes), ms);
5673104349Sphk  hashTableInit(&(p->attributeIds), ms);
5674104349Sphk  hashTableInit(&(p->prefixes), ms);
5675104349Sphk#ifdef XML_DTD
5676104349Sphk  p->paramEntityRead = XML_FALSE;
5677104349Sphk  hashTableInit(&(p->paramEntities), ms);
5678104349Sphk#endif /* XML_DTD */
5679104349Sphk  p->defaultPrefix.name = NULL;
5680104349Sphk  p->defaultPrefix.binding = NULL;
5681104349Sphk
5682104349Sphk  p->in_eldecl = XML_FALSE;
5683104349Sphk  p->scaffIndex = NULL;
5684104349Sphk  p->scaffold = NULL;
5685104349Sphk  p->scaffLevel = 0;
5686104349Sphk  p->scaffSize = 0;
5687104349Sphk  p->scaffCount = 0;
5688104349Sphk  p->contentStringLen = 0;
5689104349Sphk
5690104349Sphk  p->keepProcessing = XML_TRUE;
5691104349Sphk  p->hasParamEntityRefs = XML_FALSE;
5692104349Sphk  p->standalone = XML_FALSE;
5693178848Scokane  return p;
5694104349Sphk}
5695104349Sphk
5696178848Scokanestatic void
5697178848ScokanedtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
5698104349Sphk{
5699104349Sphk  HASH_TABLE_ITER iter;
5700104349Sphk  hashTableIterInit(&iter, &(p->elementTypes));
5701104349Sphk  for (;;) {
5702104349Sphk    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5703104349Sphk    if (!e)
5704104349Sphk      break;
5705104349Sphk    if (e->allocDefaultAtts != 0)
5706178848Scokane      ms->free_fcn(e->defaultAtts);
5707104349Sphk  }
5708104349Sphk  hashTableClear(&(p->generalEntities));
5709104349Sphk#ifdef XML_DTD
5710104349Sphk  p->paramEntityRead = XML_FALSE;
5711104349Sphk  hashTableClear(&(p->paramEntities));
5712104349Sphk#endif /* XML_DTD */
5713104349Sphk  hashTableClear(&(p->elementTypes));
5714104349Sphk  hashTableClear(&(p->attributeIds));
5715104349Sphk  hashTableClear(&(p->prefixes));
5716104349Sphk  poolClear(&(p->pool));
5717104349Sphk  poolClear(&(p->entityValuePool));
5718104349Sphk  p->defaultPrefix.name = NULL;
5719104349Sphk  p->defaultPrefix.binding = NULL;
5720104349Sphk
5721104349Sphk  p->in_eldecl = XML_FALSE;
5722178848Scokane
5723178848Scokane  ms->free_fcn(p->scaffIndex);
5724178848Scokane  p->scaffIndex = NULL;
5725178848Scokane  ms->free_fcn(p->scaffold);
5726178848Scokane  p->scaffold = NULL;
5727178848Scokane
5728104349Sphk  p->scaffLevel = 0;
5729104349Sphk  p->scaffSize = 0;
5730104349Sphk  p->scaffCount = 0;
5731104349Sphk  p->contentStringLen = 0;
5732104349Sphk
5733104349Sphk  p->keepProcessing = XML_TRUE;
5734104349Sphk  p->hasParamEntityRefs = XML_FALSE;
5735104349Sphk  p->standalone = XML_FALSE;
5736104349Sphk}
5737104349Sphk
5738178848Scokanestatic void
5739178848ScokanedtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
5740104349Sphk{
5741104349Sphk  HASH_TABLE_ITER iter;
5742104349Sphk  hashTableIterInit(&iter, &(p->elementTypes));
5743104349Sphk  for (;;) {
5744104349Sphk    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5745104349Sphk    if (!e)
5746104349Sphk      break;
5747104349Sphk    if (e->allocDefaultAtts != 0)
5748178848Scokane      ms->free_fcn(e->defaultAtts);
5749104349Sphk  }
5750104349Sphk  hashTableDestroy(&(p->generalEntities));
5751104349Sphk#ifdef XML_DTD
5752104349Sphk  hashTableDestroy(&(p->paramEntities));
5753104349Sphk#endif /* XML_DTD */
5754104349Sphk  hashTableDestroy(&(p->elementTypes));
5755104349Sphk  hashTableDestroy(&(p->attributeIds));
5756104349Sphk  hashTableDestroy(&(p->prefixes));
5757104349Sphk  poolDestroy(&(p->pool));
5758104349Sphk  poolDestroy(&(p->entityValuePool));
5759178848Scokane  if (isDocEntity) {
5760178848Scokane    ms->free_fcn(p->scaffIndex);
5761178848Scokane    ms->free_fcn(p->scaffold);
5762104349Sphk  }
5763178848Scokane  ms->free_fcn(p);
5764104349Sphk}
5765104349Sphk
5766178848Scokane/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
5767104349Sphk   The new DTD has already been initialized.
5768104349Sphk*/
5769178848Scokanestatic int
5770247513SdelphijdtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
5771104349Sphk{
5772104349Sphk  HASH_TABLE_ITER iter;
5773104349Sphk
5774104349Sphk  /* Copy the prefix table. */
5775104349Sphk
5776104349Sphk  hashTableIterInit(&iter, &(oldDtd->prefixes));
5777104349Sphk  for (;;) {
5778104349Sphk    const XML_Char *name;
5779104349Sphk    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
5780104349Sphk    if (!oldP)
5781104349Sphk      break;
5782104349Sphk    name = poolCopyString(&(newDtd->pool), oldP->name);
5783104349Sphk    if (!name)
5784104349Sphk      return 0;
5785247513Sdelphij    if (!lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
5786104349Sphk      return 0;
5787104349Sphk  }
5788104349Sphk
5789104349Sphk  hashTableIterInit(&iter, &(oldDtd->attributeIds));
5790104349Sphk
5791104349Sphk  /* Copy the attribute id table. */
5792104349Sphk
5793104349Sphk  for (;;) {
5794104349Sphk    ATTRIBUTE_ID *newA;
5795104349Sphk    const XML_Char *name;
5796104349Sphk    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
5797104349Sphk
5798104349Sphk    if (!oldA)
5799104349Sphk      break;
5800104349Sphk    /* Remember to allocate the scratch byte before the name. */
5801104349Sphk    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
5802104349Sphk      return 0;
5803104349Sphk    name = poolCopyString(&(newDtd->pool), oldA->name);
5804104349Sphk    if (!name)
5805104349Sphk      return 0;
5806104349Sphk    ++name;
5807247513Sdelphij    newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
5808104349Sphk                                  sizeof(ATTRIBUTE_ID));
5809104349Sphk    if (!newA)
5810104349Sphk      return 0;
5811104349Sphk    newA->maybeTokenized = oldA->maybeTokenized;
5812104349Sphk    if (oldA->prefix) {
5813104349Sphk      newA->xmlns = oldA->xmlns;
5814104349Sphk      if (oldA->prefix == &oldDtd->defaultPrefix)
5815104349Sphk        newA->prefix = &newDtd->defaultPrefix;
5816104349Sphk      else
5817247513Sdelphij        newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
5818104349Sphk                                        oldA->prefix->name, 0);
5819104349Sphk    }
5820104349Sphk  }
5821104349Sphk
5822104349Sphk  /* Copy the element type table. */
5823104349Sphk
5824104349Sphk  hashTableIterInit(&iter, &(oldDtd->elementTypes));
5825104349Sphk
5826104349Sphk  for (;;) {
5827104349Sphk    int i;
5828104349Sphk    ELEMENT_TYPE *newE;
5829104349Sphk    const XML_Char *name;
5830104349Sphk    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
5831104349Sphk    if (!oldE)
5832104349Sphk      break;
5833104349Sphk    name = poolCopyString(&(newDtd->pool), oldE->name);
5834104349Sphk    if (!name)
5835104349Sphk      return 0;
5836247513Sdelphij    newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
5837104349Sphk                                  sizeof(ELEMENT_TYPE));
5838104349Sphk    if (!newE)
5839104349Sphk      return 0;
5840104349Sphk    if (oldE->nDefaultAtts) {
5841104349Sphk      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
5842178848Scokane          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
5843104349Sphk      if (!newE->defaultAtts) {
5844178848Scokane        ms->free_fcn(newE);
5845104349Sphk        return 0;
5846104349Sphk      }
5847104349Sphk    }
5848104349Sphk    if (oldE->idAtt)
5849104349Sphk      newE->idAtt = (ATTRIBUTE_ID *)
5850247513Sdelphij          lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
5851104349Sphk    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
5852104349Sphk    if (oldE->prefix)
5853247513Sdelphij      newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
5854104349Sphk                                      oldE->prefix->name, 0);
5855104349Sphk    for (i = 0; i < newE->nDefaultAtts; i++) {
5856104349Sphk      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
5857247513Sdelphij          lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
5858104349Sphk      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
5859104349Sphk      if (oldE->defaultAtts[i].value) {
5860104349Sphk        newE->defaultAtts[i].value
5861104349Sphk            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
5862104349Sphk        if (!newE->defaultAtts[i].value)
5863104349Sphk          return 0;
5864104349Sphk      }
5865104349Sphk      else
5866104349Sphk        newE->defaultAtts[i].value = NULL;
5867104349Sphk    }
5868104349Sphk  }
5869104349Sphk
5870104349Sphk  /* Copy the entity tables. */
5871247513Sdelphij  if (!copyEntityTable(oldParser,
5872247513Sdelphij                       &(newDtd->generalEntities),
5873104349Sphk                       &(newDtd->pool),
5874178848Scokane                       &(oldDtd->generalEntities)))
5875104349Sphk      return 0;
5876104349Sphk
5877104349Sphk#ifdef XML_DTD
5878247513Sdelphij  if (!copyEntityTable(oldParser,
5879247513Sdelphij                       &(newDtd->paramEntities),
5880104349Sphk                       &(newDtd->pool),
5881178848Scokane                       &(oldDtd->paramEntities)))
5882104349Sphk      return 0;
5883104349Sphk  newDtd->paramEntityRead = oldDtd->paramEntityRead;
5884104349Sphk#endif /* XML_DTD */
5885104349Sphk
5886104349Sphk  newDtd->keepProcessing = oldDtd->keepProcessing;
5887104349Sphk  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
5888104349Sphk  newDtd->standalone = oldDtd->standalone;
5889104349Sphk
5890104349Sphk  /* Don't want deep copying for scaffolding */
5891104349Sphk  newDtd->in_eldecl = oldDtd->in_eldecl;
5892104349Sphk  newDtd->scaffold = oldDtd->scaffold;
5893104349Sphk  newDtd->contentStringLen = oldDtd->contentStringLen;
5894104349Sphk  newDtd->scaffSize = oldDtd->scaffSize;
5895104349Sphk  newDtd->scaffLevel = oldDtd->scaffLevel;
5896104349Sphk  newDtd->scaffIndex = oldDtd->scaffIndex;
5897104349Sphk
5898104349Sphk  return 1;
5899104349Sphk}  /* End dtdCopy */
5900104349Sphk
5901178848Scokanestatic int
5902247513SdelphijcopyEntityTable(XML_Parser oldParser,
5903247513Sdelphij                HASH_TABLE *newTable,
5904104349Sphk                STRING_POOL *newPool,
5905178848Scokane                const HASH_TABLE *oldTable)
5906104349Sphk{
5907104349Sphk  HASH_TABLE_ITER iter;
5908104349Sphk  const XML_Char *cachedOldBase = NULL;
5909104349Sphk  const XML_Char *cachedNewBase = NULL;
5910104349Sphk
5911104349Sphk  hashTableIterInit(&iter, oldTable);
5912104349Sphk
5913104349Sphk  for (;;) {
5914104349Sphk    ENTITY *newE;
5915104349Sphk    const XML_Char *name;
5916104349Sphk    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
5917104349Sphk    if (!oldE)
5918104349Sphk      break;
5919104349Sphk    name = poolCopyString(newPool, oldE->name);
5920104349Sphk    if (!name)
5921104349Sphk      return 0;
5922247513Sdelphij    newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
5923104349Sphk    if (!newE)
5924104349Sphk      return 0;
5925104349Sphk    if (oldE->systemId) {
5926104349Sphk      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
5927104349Sphk      if (!tem)
5928104349Sphk        return 0;
5929104349Sphk      newE->systemId = tem;
5930104349Sphk      if (oldE->base) {
5931104349Sphk        if (oldE->base == cachedOldBase)
5932104349Sphk          newE->base = cachedNewBase;
5933104349Sphk        else {
5934104349Sphk          cachedOldBase = oldE->base;
5935104349Sphk          tem = poolCopyString(newPool, cachedOldBase);
5936104349Sphk          if (!tem)
5937104349Sphk            return 0;
5938104349Sphk          cachedNewBase = newE->base = tem;
5939104349Sphk        }
5940104349Sphk      }
5941104349Sphk      if (oldE->publicId) {
5942104349Sphk        tem = poolCopyString(newPool, oldE->publicId);
5943104349Sphk        if (!tem)
5944104349Sphk          return 0;
5945104349Sphk        newE->publicId = tem;
5946104349Sphk      }
5947104349Sphk    }
5948104349Sphk    else {
5949104349Sphk      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
5950104349Sphk                                            oldE->textLen);
5951104349Sphk      if (!tem)
5952104349Sphk        return 0;
5953104349Sphk      newE->textPtr = tem;
5954104349Sphk      newE->textLen = oldE->textLen;
5955104349Sphk    }
5956104349Sphk    if (oldE->notation) {
5957104349Sphk      const XML_Char *tem = poolCopyString(newPool, oldE->notation);
5958104349Sphk      if (!tem)
5959104349Sphk        return 0;
5960104349Sphk      newE->notation = tem;
5961104349Sphk    }
5962104349Sphk    newE->is_param = oldE->is_param;
5963104349Sphk    newE->is_internal = oldE->is_internal;
5964104349Sphk  }
5965104349Sphk  return 1;
5966104349Sphk}
5967104349Sphk
5968178848Scokane#define INIT_POWER 6
5969104349Sphk
5970178848Scokanestatic XML_Bool FASTCALL
5971104349Sphkkeyeq(KEY s1, KEY s2)
5972104349Sphk{
5973104349Sphk  for (; *s1 == *s2; s1++, s2++)
5974104349Sphk    if (*s1 == 0)
5975178848Scokane      return XML_TRUE;
5976178848Scokane  return XML_FALSE;
5977104349Sphk}
5978104349Sphk
5979104349Sphkstatic unsigned long FASTCALL
5980247513Sdelphijhash(XML_Parser parser, KEY s)
5981104349Sphk{
5982247513Sdelphij  unsigned long h = hash_secret_salt;
5983104349Sphk  while (*s)
5984178848Scokane    h = CHAR_HASH(h, *s++);
5985104349Sphk  return h;
5986104349Sphk}
5987104349Sphk
5988178848Scokanestatic NAMED *
5989247513Sdelphijlookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
5990104349Sphk{
5991104349Sphk  size_t i;
5992104349Sphk  if (table->size == 0) {
5993104349Sphk    size_t tsize;
5994104349Sphk    if (!createSize)
5995104349Sphk      return NULL;
5996178848Scokane    table->power = INIT_POWER;
5997178848Scokane    /* table->size is a power of 2 */
5998178848Scokane    table->size = (size_t)1 << INIT_POWER;
5999178848Scokane    tsize = table->size * sizeof(NAMED *);
6000178848Scokane    table->v = (NAMED **)table->mem->malloc_fcn(tsize);
6001178848Scokane    if (!table->v) {
6002178848Scokane      table->size = 0;
6003104349Sphk      return NULL;
6004178848Scokane    }
6005104349Sphk    memset(table->v, 0, tsize);
6006247513Sdelphij    i = hash(parser, name) & ((unsigned long)table->size - 1);
6007104349Sphk  }
6008104349Sphk  else {
6009247513Sdelphij    unsigned long h = hash(parser, name);
6010178848Scokane    unsigned long mask = (unsigned long)table->size - 1;
6011178848Scokane    unsigned char step = 0;
6012178848Scokane    i = h & mask;
6013178848Scokane    while (table->v[i]) {
6014104349Sphk      if (keyeq(name, table->v[i]->name))
6015104349Sphk        return table->v[i];
6016178848Scokane      if (!step)
6017178848Scokane        step = PROBE_STEP(h, mask, table->power);
6018178848Scokane      i < step ? (i += table->size - step) : (i -= step);
6019104349Sphk    }
6020104349Sphk    if (!createSize)
6021104349Sphk      return NULL;
6022178848Scokane
6023178848Scokane    /* check for overflow (table is half full) */
6024178848Scokane    if (table->used >> (table->power - 1)) {
6025178848Scokane      unsigned char newPower = table->power + 1;
6026178848Scokane      size_t newSize = (size_t)1 << newPower;
6027178848Scokane      unsigned long newMask = (unsigned long)newSize - 1;
6028104349Sphk      size_t tsize = newSize * sizeof(NAMED *);
6029178848Scokane      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
6030104349Sphk      if (!newV)
6031104349Sphk        return NULL;
6032104349Sphk      memset(newV, 0, tsize);
6033104349Sphk      for (i = 0; i < table->size; i++)
6034104349Sphk        if (table->v[i]) {
6035247513Sdelphij          unsigned long newHash = hash(parser, table->v[i]->name);
6036178848Scokane          size_t j = newHash & newMask;
6037178848Scokane          step = 0;
6038178848Scokane          while (newV[j]) {
6039178848Scokane            if (!step)
6040178848Scokane              step = PROBE_STEP(newHash, newMask, newPower);
6041178848Scokane            j < step ? (j += newSize - step) : (j -= step);
6042178848Scokane          }
6043104349Sphk          newV[j] = table->v[i];
6044104349Sphk        }
6045104349Sphk      table->mem->free_fcn(table->v);
6046104349Sphk      table->v = newV;
6047178848Scokane      table->power = newPower;
6048104349Sphk      table->size = newSize;
6049178848Scokane      i = h & newMask;
6050178848Scokane      step = 0;
6051178848Scokane      while (table->v[i]) {
6052178848Scokane        if (!step)
6053178848Scokane          step = PROBE_STEP(h, newMask, newPower);
6054178848Scokane        i < step ? (i += newSize - step) : (i -= step);
6055178848Scokane      }
6056104349Sphk    }
6057104349Sphk  }
6058178848Scokane  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize);
6059104349Sphk  if (!table->v[i])
6060104349Sphk    return NULL;
6061104349Sphk  memset(table->v[i], 0, createSize);
6062104349Sphk  table->v[i]->name = name;
6063104349Sphk  (table->used)++;
6064104349Sphk  return table->v[i];
6065104349Sphk}
6066104349Sphk
6067104349Sphkstatic void FASTCALL
6068104349SphkhashTableClear(HASH_TABLE *table)
6069104349Sphk{
6070104349Sphk  size_t i;
6071104349Sphk  for (i = 0; i < table->size; i++) {
6072178848Scokane    table->mem->free_fcn(table->v[i]);
6073178848Scokane    table->v[i] = NULL;
6074104349Sphk  }
6075104349Sphk  table->used = 0;
6076104349Sphk}
6077104349Sphk
6078104349Sphkstatic void FASTCALL
6079104349SphkhashTableDestroy(HASH_TABLE *table)
6080104349Sphk{
6081104349Sphk  size_t i;
6082178848Scokane  for (i = 0; i < table->size; i++)
6083178848Scokane    table->mem->free_fcn(table->v[i]);
6084178848Scokane  table->mem->free_fcn(table->v);
6085104349Sphk}
6086104349Sphk
6087104349Sphkstatic void FASTCALL
6088178848ScokanehashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
6089104349Sphk{
6090178848Scokane  p->power = 0;
6091104349Sphk  p->size = 0;
6092104349Sphk  p->used = 0;
6093104349Sphk  p->v = NULL;
6094104349Sphk  p->mem = ms;
6095104349Sphk}
6096104349Sphk
6097104349Sphkstatic void FASTCALL
6098104349SphkhashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
6099104349Sphk{
6100104349Sphk  iter->p = table->v;
6101104349Sphk  iter->end = iter->p + table->size;
6102104349Sphk}
6103104349Sphk
6104104349Sphkstatic NAMED * FASTCALL
6105104349SphkhashTableIterNext(HASH_TABLE_ITER *iter)
6106104349Sphk{
6107104349Sphk  while (iter->p != iter->end) {
6108104349Sphk    NAMED *tem = *(iter->p)++;
6109104349Sphk    if (tem)
6110104349Sphk      return tem;
6111104349Sphk  }
6112104349Sphk  return NULL;
6113104349Sphk}
6114104349Sphk
6115104349Sphkstatic void FASTCALL
6116178848ScokanepoolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
6117104349Sphk{
6118104349Sphk  pool->blocks = NULL;
6119104349Sphk  pool->freeBlocks = NULL;
6120104349Sphk  pool->start = NULL;
6121104349Sphk  pool->ptr = NULL;
6122104349Sphk  pool->end = NULL;
6123104349Sphk  pool->mem = ms;
6124104349Sphk}
6125104349Sphk
6126104349Sphkstatic void FASTCALL
6127104349SphkpoolClear(STRING_POOL *pool)
6128104349Sphk{
6129104349Sphk  if (!pool->freeBlocks)
6130104349Sphk    pool->freeBlocks = pool->blocks;
6131104349Sphk  else {
6132104349Sphk    BLOCK *p = pool->blocks;
6133104349Sphk    while (p) {
6134104349Sphk      BLOCK *tem = p->next;
6135104349Sphk      p->next = pool->freeBlocks;
6136104349Sphk      pool->freeBlocks = p;
6137104349Sphk      p = tem;
6138104349Sphk    }
6139104349Sphk  }
6140104349Sphk  pool->blocks = NULL;
6141104349Sphk  pool->start = NULL;
6142104349Sphk  pool->ptr = NULL;
6143104349Sphk  pool->end = NULL;
6144104349Sphk}
6145104349Sphk
6146104349Sphkstatic void FASTCALL
6147104349SphkpoolDestroy(STRING_POOL *pool)
6148104349Sphk{
6149104349Sphk  BLOCK *p = pool->blocks;
6150104349Sphk  while (p) {
6151104349Sphk    BLOCK *tem = p->next;
6152104349Sphk    pool->mem->free_fcn(p);
6153104349Sphk    p = tem;
6154104349Sphk  }
6155104349Sphk  p = pool->freeBlocks;
6156104349Sphk  while (p) {
6157104349Sphk    BLOCK *tem = p->next;
6158104349Sphk    pool->mem->free_fcn(p);
6159104349Sphk    p = tem;
6160104349Sphk  }
6161104349Sphk}
6162104349Sphk
6163178848Scokanestatic XML_Char *
6164104349SphkpoolAppend(STRING_POOL *pool, const ENCODING *enc,
6165104349Sphk           const char *ptr, const char *end)
6166104349Sphk{
6167104349Sphk  if (!pool->ptr && !poolGrow(pool))
6168104349Sphk    return NULL;
6169104349Sphk  for (;;) {
6170104349Sphk    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
6171104349Sphk    if (ptr == end)
6172104349Sphk      break;
6173104349Sphk    if (!poolGrow(pool))
6174104349Sphk      return NULL;
6175104349Sphk  }
6176104349Sphk  return pool->start;
6177104349Sphk}
6178104349Sphk
6179104349Sphkstatic const XML_Char * FASTCALL
6180104349SphkpoolCopyString(STRING_POOL *pool, const XML_Char *s)
6181104349Sphk{
6182104349Sphk  do {
6183104349Sphk    if (!poolAppendChar(pool, *s))
6184104349Sphk      return NULL;
6185104349Sphk  } while (*s++);
6186104349Sphk  s = pool->start;
6187104349Sphk  poolFinish(pool);
6188104349Sphk  return s;
6189104349Sphk}
6190104349Sphk
6191178848Scokanestatic const XML_Char *
6192104349SphkpoolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
6193104349Sphk{
6194104349Sphk  if (!pool->ptr && !poolGrow(pool))
6195104349Sphk    return NULL;
6196104349Sphk  for (; n > 0; --n, s++) {
6197104349Sphk    if (!poolAppendChar(pool, *s))
6198104349Sphk      return NULL;
6199104349Sphk  }
6200104349Sphk  s = pool->start;
6201104349Sphk  poolFinish(pool);
6202104349Sphk  return s;
6203104349Sphk}
6204104349Sphk
6205104349Sphkstatic const XML_Char * FASTCALL
6206104349SphkpoolAppendString(STRING_POOL *pool, const XML_Char *s)
6207104349Sphk{
6208104349Sphk  while (*s) {
6209104349Sphk    if (!poolAppendChar(pool, *s))
6210104349Sphk      return NULL;
6211104349Sphk    s++;
6212104349Sphk  }
6213104349Sphk  return pool->start;
6214104349Sphk}
6215104349Sphk
6216178848Scokanestatic XML_Char *
6217104349SphkpoolStoreString(STRING_POOL *pool, const ENCODING *enc,
6218104349Sphk                const char *ptr, const char *end)
6219104349Sphk{
6220104349Sphk  if (!poolAppend(pool, enc, ptr, end))
6221104349Sphk    return NULL;
6222104349Sphk  if (pool->ptr == pool->end && !poolGrow(pool))
6223104349Sphk    return NULL;
6224104349Sphk  *(pool->ptr)++ = 0;
6225104349Sphk  return pool->start;
6226104349Sphk}
6227104349Sphk
6228104349Sphkstatic XML_Bool FASTCALL
6229104349SphkpoolGrow(STRING_POOL *pool)
6230104349Sphk{
6231104349Sphk  if (pool->freeBlocks) {
6232104349Sphk    if (pool->start == 0) {
6233104349Sphk      pool->blocks = pool->freeBlocks;
6234104349Sphk      pool->freeBlocks = pool->freeBlocks->next;
6235104349Sphk      pool->blocks->next = NULL;
6236104349Sphk      pool->start = pool->blocks->s;
6237104349Sphk      pool->end = pool->start + pool->blocks->size;
6238104349Sphk      pool->ptr = pool->start;
6239104349Sphk      return XML_TRUE;
6240104349Sphk    }
6241104349Sphk    if (pool->end - pool->start < pool->freeBlocks->size) {
6242104349Sphk      BLOCK *tem = pool->freeBlocks->next;
6243104349Sphk      pool->freeBlocks->next = pool->blocks;
6244104349Sphk      pool->blocks = pool->freeBlocks;
6245104349Sphk      pool->freeBlocks = tem;
6246104349Sphk      memcpy(pool->blocks->s, pool->start,
6247104349Sphk             (pool->end - pool->start) * sizeof(XML_Char));
6248104349Sphk      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6249104349Sphk      pool->start = pool->blocks->s;
6250104349Sphk      pool->end = pool->start + pool->blocks->size;
6251104349Sphk      return XML_TRUE;
6252104349Sphk    }
6253104349Sphk  }
6254104349Sphk  if (pool->blocks && pool->start == pool->blocks->s) {
6255178848Scokane    int blockSize = (int)(pool->end - pool->start)*2;
6256247513Sdelphij    BLOCK *temp = (BLOCK *)
6257178848Scokane      pool->mem->realloc_fcn(pool->blocks,
6258178848Scokane                             (offsetof(BLOCK, s)
6259178848Scokane                              + blockSize * sizeof(XML_Char)));
6260247513Sdelphij    if (temp == NULL)
6261104349Sphk      return XML_FALSE;
6262247513Sdelphij    pool->blocks = temp;
6263104349Sphk    pool->blocks->size = blockSize;
6264104349Sphk    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
6265104349Sphk    pool->start = pool->blocks->s;
6266104349Sphk    pool->end = pool->start + blockSize;
6267104349Sphk  }
6268104349Sphk  else {
6269104349Sphk    BLOCK *tem;
6270178848Scokane    int blockSize = (int)(pool->end - pool->start);
6271104349Sphk    if (blockSize < INIT_BLOCK_SIZE)
6272104349Sphk      blockSize = INIT_BLOCK_SIZE;
6273104349Sphk    else
6274104349Sphk      blockSize *= 2;
6275178848Scokane    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
6276178848Scokane                                        + blockSize * sizeof(XML_Char));
6277104349Sphk    if (!tem)
6278104349Sphk      return XML_FALSE;
6279104349Sphk    tem->size = blockSize;
6280104349Sphk    tem->next = pool->blocks;
6281104349Sphk    pool->blocks = tem;
6282104349Sphk    if (pool->ptr != pool->start)
6283104349Sphk      memcpy(tem->s, pool->start,
6284104349Sphk             (pool->ptr - pool->start) * sizeof(XML_Char));
6285104349Sphk    pool->ptr = tem->s + (pool->ptr - pool->start);
6286104349Sphk    pool->start = tem->s;
6287104349Sphk    pool->end = tem->s + blockSize;
6288104349Sphk  }
6289104349Sphk  return XML_TRUE;
6290104349Sphk}
6291104349Sphk
6292104349Sphkstatic int FASTCALL
6293104349SphknextScaffoldPart(XML_Parser parser)
6294104349Sphk{
6295178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
6296104349Sphk  CONTENT_SCAFFOLD * me;
6297104349Sphk  int next;
6298104349Sphk
6299178848Scokane  if (!dtd->scaffIndex) {
6300178848Scokane    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
6301178848Scokane    if (!dtd->scaffIndex)
6302104349Sphk      return -1;
6303178848Scokane    dtd->scaffIndex[0] = 0;
6304104349Sphk  }
6305104349Sphk
6306178848Scokane  if (dtd->scaffCount >= dtd->scaffSize) {
6307104349Sphk    CONTENT_SCAFFOLD *temp;
6308178848Scokane    if (dtd->scaffold) {
6309104349Sphk      temp = (CONTENT_SCAFFOLD *)
6310178848Scokane        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
6311104349Sphk      if (temp == NULL)
6312104349Sphk        return -1;
6313178848Scokane      dtd->scaffSize *= 2;
6314104349Sphk    }
6315104349Sphk    else {
6316178848Scokane      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
6317178848Scokane                                        * sizeof(CONTENT_SCAFFOLD));
6318104349Sphk      if (temp == NULL)
6319104349Sphk        return -1;
6320178848Scokane      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
6321104349Sphk    }
6322178848Scokane    dtd->scaffold = temp;
6323104349Sphk  }
6324178848Scokane  next = dtd->scaffCount++;
6325178848Scokane  me = &dtd->scaffold[next];
6326178848Scokane  if (dtd->scaffLevel) {
6327178848Scokane    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
6328104349Sphk    if (parent->lastchild) {
6329178848Scokane      dtd->scaffold[parent->lastchild].nextsib = next;
6330104349Sphk    }
6331104349Sphk    if (!parent->childcnt)
6332104349Sphk      parent->firstchild = next;
6333104349Sphk    parent->lastchild = next;
6334104349Sphk    parent->childcnt++;
6335104349Sphk  }
6336104349Sphk  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
6337104349Sphk  return next;
6338104349Sphk}
6339104349Sphk
6340178848Scokanestatic void
6341104349Sphkbuild_node(XML_Parser parser,
6342104349Sphk           int src_node,
6343104349Sphk           XML_Content *dest,
6344104349Sphk           XML_Content **contpos,
6345104349Sphk           XML_Char **strpos)
6346104349Sphk{
6347178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
6348178848Scokane  dest->type = dtd->scaffold[src_node].type;
6349178848Scokane  dest->quant = dtd->scaffold[src_node].quant;
6350104349Sphk  if (dest->type == XML_CTYPE_NAME) {
6351104349Sphk    const XML_Char *src;
6352104349Sphk    dest->name = *strpos;
6353178848Scokane    src = dtd->scaffold[src_node].name;
6354104349Sphk    for (;;) {
6355104349Sphk      *(*strpos)++ = *src;
6356104349Sphk      if (!*src)
6357104349Sphk        break;
6358104349Sphk      src++;
6359104349Sphk    }
6360104349Sphk    dest->numchildren = 0;
6361104349Sphk    dest->children = NULL;
6362104349Sphk  }
6363104349Sphk  else {
6364104349Sphk    unsigned int i;
6365104349Sphk    int cn;
6366178848Scokane    dest->numchildren = dtd->scaffold[src_node].childcnt;
6367104349Sphk    dest->children = *contpos;
6368104349Sphk    *contpos += dest->numchildren;
6369178848Scokane    for (i = 0, cn = dtd->scaffold[src_node].firstchild;
6370104349Sphk         i < dest->numchildren;
6371178848Scokane         i++, cn = dtd->scaffold[cn].nextsib) {
6372104349Sphk      build_node(parser, cn, &(dest->children[i]), contpos, strpos);
6373104349Sphk    }
6374104349Sphk    dest->name = NULL;
6375104349Sphk  }
6376104349Sphk}
6377104349Sphk
6378178848Scokanestatic XML_Content *
6379104349Sphkbuild_model (XML_Parser parser)
6380104349Sphk{
6381178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
6382104349Sphk  XML_Content *ret;
6383104349Sphk  XML_Content *cpos;
6384104349Sphk  XML_Char * str;
6385178848Scokane  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
6386178848Scokane                   + (dtd->contentStringLen * sizeof(XML_Char)));
6387104349Sphk
6388178848Scokane  ret = (XML_Content *)MALLOC(allocsize);
6389104349Sphk  if (!ret)
6390104349Sphk    return NULL;
6391104349Sphk
6392178848Scokane  str =  (XML_Char *) (&ret[dtd->scaffCount]);
6393104349Sphk  cpos = &ret[1];
6394104349Sphk
6395104349Sphk  build_node(parser, 0, ret, &cpos, &str);
6396104349Sphk  return ret;
6397104349Sphk}
6398104349Sphk
6399178848Scokanestatic ELEMENT_TYPE *
6400104349SphkgetElementType(XML_Parser parser,
6401104349Sphk               const ENCODING *enc,
6402104349Sphk               const char *ptr,
6403104349Sphk               const char *end)
6404104349Sphk{
6405178848Scokane  DTD * const dtd = _dtd;  /* save one level of indirection */
6406178848Scokane  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
6407104349Sphk  ELEMENT_TYPE *ret;
6408104349Sphk
6409104349Sphk  if (!name)
6410104349Sphk    return NULL;
6411247513Sdelphij  ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
6412104349Sphk  if (!ret)
6413104349Sphk    return NULL;
6414104349Sphk  if (ret->name != name)
6415178848Scokane    poolDiscard(&dtd->pool);
6416104349Sphk  else {
6417178848Scokane    poolFinish(&dtd->pool);
6418104349Sphk    if (!setElementTypePrefix(parser, ret))
6419104349Sphk      return NULL;
6420104349Sphk  }
6421104349Sphk  return ret;
6422104349Sphk}
6423