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