ยปCore Development>Code coverage>Modules/expat/xmlparse.c

Python code coverage for Modules/expat/xmlparse.c

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