File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / expat / lib / xmlparse.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:09:43 2014 UTC (10 years ago) by misho
Branches: expat, MAIN
CVS tags: v2_1_0, HEAD
expat 2.1.0

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>