6914 lines · 233.3 KB · C
RawDownload
/* 5cd169f2942b85c05e0b1b96f9990f91ac3d07e470ad7ce906ac8590c8ed4f35 (2.2.10+)                            __  __            _                         ___\ \/ /_ __   __ _| |_                        / _ \\  /| '_ \ / _` | __|                       |  __//  \| |_) | (_| | |_                        \___/_/\_\ .__/ \__,_|\__|                                 |_| XML parser    Copyright (c) 1997-2000 Thai Open Source Software Center Ltd   Copyright (c) 2000-2017 Expat development team   Licensed under the MIT license:    Permission is  hereby granted,  free of charge,  to any  person obtaining   a  copy  of  this  software   and  associated  documentation  files  (the   "Software"),  to  deal in  the  Software  without restriction,  including   without  limitation the  rights  to use,  copy,  modify, merge,  publish,   distribute, sublicense, and/or sell copies of the Software, and to permit   persons  to whom  the Software  is  furnished to  do so,  subject to  the   following conditions:    The above copyright  notice and this permission notice  shall be included   in all copies or substantial portions of the Software.    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE   USE OR OTHER DEALINGS IN THE SOFTWARE.*/ #if ! defined(_GNU_SOURCE)#  define _GNU_SOURCE 1 /* syscall prototype */#endif #ifdef _WIN32/* force stdlib to define rand_s() */#  if ! defined(_CRT_RAND_S)#    define _CRT_RAND_S#  endif#endif #include <stddef.h>#include <string.h> /* memset(), memcpy() */#include <assert.h>#include <limits.h> /* UINT_MAX */#include <stdio.h>  /* fprintf */#include <stdlib.h> /* getenv, rand_s */ #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600)/* vs2008/9.0 and earlier lack stdint.h; _MSC_VER 1600 is vs2010/10.0 */#  if defined(_WIN64)typedef unsigned __int64 uintptr_t;#  elsetypedef unsigned __int32 uintptr_t;#  endif#else#  include <stdint.h> /* uintptr_t */#endif #ifdef _WIN32#  define getpid GetCurrentProcessId#else#  include <sys/time.h>  /* gettimeofday() */#  include <sys/types.h> /* getpid() */#  include <unistd.h>    /* getpid() */#  include <fcntl.h>     /* O_RDONLY */#  include <errno.h>#endif #define XML_BUILDING_EXPAT 1 #ifdef _WIN32#  include "winconfig.h"#elif defined(HAVE_EXPAT_CONFIG_H)#  include <expat_config.h>#endif /* ndef _WIN32 */ #include "ascii.h"#include "expat.h"#include "siphash.h" #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)#  if defined(HAVE_GETRANDOM)#    include <sys/random.h> /* getrandom */#  else#    include <unistd.h>      /* syscall */#    include <sys/syscall.h> /* SYS_getrandom */#  endif#  if ! defined(GRND_NONBLOCK)#    define GRND_NONBLOCK 0x0001#  endif /* defined(GRND_NONBLOCK) */#endif   /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ #if defined(HAVE_LIBBSD)                                                       \    && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))#  include <bsd/stdlib.h>#endif #if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32)#  define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800#endif #if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM)             \    && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)            \    && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32)                         \    && ! defined(XML_POOR_ENTROPY)#  error You do not have support for any sources of high quality entropy \    enabled.  For end user security, that is probably not what you want. \    \    Your options include: \      * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \      * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \      * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \      * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \      * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \      * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \      * Linux (including <3.17) / BSD / macOS (including <10.7) (/dev/urandom): XML_DEV_URANDOM, \      * Windows >=Vista (rand_s): _WIN32. \    \    If insist on not using any of these, bypass this error by defining \    XML_POOR_ENTROPY; you have been warned. \    \    If you have reasons to patch this detection code away or need changes \    to the build system, please open a bug.  Thank you!#endif #ifdef XML_UNICODE#  define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX#  define XmlConvert XmlUtf16Convert#  define XmlGetInternalEncoding XmlGetUtf16InternalEncoding#  define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS#  define XmlEncode XmlUtf16Encode#  define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))typedef unsigned short ICHAR;#else#  define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX#  define XmlConvert XmlUtf8Convert#  define XmlGetInternalEncoding XmlGetUtf8InternalEncoding#  define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS#  define XmlEncode XmlUtf8Encode#  define MUST_CONVERT(enc, s) (! (enc)->isUtf8)typedef char ICHAR;#endif #ifndef XML_NS #  define XmlInitEncodingNS XmlInitEncoding#  define XmlInitUnknownEncodingNS XmlInitUnknownEncoding#  undef XmlGetInternalEncodingNS#  define XmlGetInternalEncodingNS XmlGetInternalEncoding#  define XmlParseXmlDeclNS XmlParseXmlDecl #endif #ifdef XML_UNICODE #  ifdef XML_UNICODE_WCHAR_T#    define XML_T(x) (const wchar_t) x#    define XML_L(x) L##x#  else#    define XML_T(x) (const unsigned short)x#    define XML_L(x) x#  endif #else #  define XML_T(x) x#  define XML_L(x) x #endif /* Round up n to be a multiple of sz, where sz is a power of 2. */#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1)) /* Do safe (NULL-aware) pointer arithmetic */#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) #include "internal.h"#include "xmltok.h"#include "xmlrole.h" typedef const XML_Char *KEY; typedef struct {  KEY name;} NAMED; typedef struct {  NAMED **v;  unsigned char power;  size_t size;  size_t used;  const XML_Memory_Handling_Suite *mem;} HASH_TABLE; static size_t keylen(KEY s); static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key); /* For probing (after a collision) we need a step size relative prime   to the hash table size, which is a power of 2. We use double-hashing,   since we can calculate a second hash value cheaply by taking those bits   of the first hash value that were discarded (masked out) when the table   index was calculated: index = hash & mask, where mask = table->size - 1.   We limit the maximum step size to table->size / 4 (mask >> 2) and make   it odd, since odd numbers are always relative prime to a power of 2.*/#define SECOND_HASH(hash, mask, power)                                         \  ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2))#define PROBE_STEP(hash, mask, power)                                          \  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) typedef struct {  NAMED **p;  NAMED **end;} HASH_TABLE_ITER; #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */#define INIT_DATA_BUF_SIZE 1024#define INIT_ATTS_SIZE 16#define INIT_ATTS_VERSION 0xFFFFFFFF#define INIT_BLOCK_SIZE 1024#define INIT_BUFFER_SIZE 1024 #define EXPAND_SPARE 24 typedef struct binding {  struct prefix *prefix;  struct binding *nextTagBinding;  struct binding *prevPrefixBinding;  const struct attribute_id *attId;  XML_Char *uri;  int uriLen;  int uriAlloc;} BINDING; typedef struct prefix {  const XML_Char *name;  BINDING *binding;} PREFIX; typedef struct {  const XML_Char *str;  const XML_Char *localPart;  const XML_Char *prefix;  int strLen;  int uriLen;  int prefixLen;} TAG_NAME; /* TAG represents an open element.   The name of the element is stored in both the document and API   encodings.  The memory buffer 'buf' is a separately-allocated   memory area which stores the name.  During the XML_Parse()/   XMLParseBuffer() when the element is open, the memory for the 'raw'   version of the name (in the document encoding) is shared with the   document buffer.  If the element is open across calls to   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to   contain the 'raw' name as well.    A parser re-uses these structures, maintaining a list of allocated   TAG objects in a free list.*/typedef struct tag {  struct tag *parent;  /* parent of this element */  const char *rawName; /* tagName in the original encoding */  int rawNameLength;  TAG_NAME name; /* tagName in the API encoding */  char *buf;     /* buffer for name components */  char *bufEnd;  /* end of the buffer */  BINDING *bindings;} TAG; typedef struct {  const XML_Char *name;  const XML_Char *textPtr;  int textLen;   /* length in XML_Chars */  int processed; /* # of processed bytes - when suspended */  const XML_Char *systemId;  const XML_Char *base;  const XML_Char *publicId;  const XML_Char *notation;  XML_Bool open;  XML_Bool is_param;  XML_Bool is_internal; /* true if declared in internal subset outside PE */} ENTITY; typedef struct {  enum XML_Content_Type type;  enum XML_Content_Quant quant;  const XML_Char *name;  int firstchild;  int lastchild;  int childcnt;  int nextsib;} CONTENT_SCAFFOLD; #define INIT_SCAFFOLD_ELEMENTS 32 typedef struct block {  struct block *next;  int size;  XML_Char s[1];} BLOCK; typedef struct {  BLOCK *blocks;  BLOCK *freeBlocks;  const XML_Char *end;  XML_Char *ptr;  XML_Char *start;  const XML_Memory_Handling_Suite *mem;} STRING_POOL; /* The XML_Char before the name is used to determine whether   an attribute has been specified. */typedef struct attribute_id {  XML_Char *name;  PREFIX *prefix;  XML_Bool maybeTokenized;  XML_Bool xmlns;} ATTRIBUTE_ID; typedef struct {  const ATTRIBUTE_ID *id;  XML_Bool isCdata;  const XML_Char *value;} DEFAULT_ATTRIBUTE; typedef struct {  unsigned long version;  unsigned long hash;  const XML_Char *uriName;} NS_ATT; typedef struct {  const XML_Char *name;  PREFIX *prefix;  const ATTRIBUTE_ID *idAtt;  int nDefaultAtts;  int allocDefaultAtts;  DEFAULT_ATTRIBUTE *defaultAtts;} ELEMENT_TYPE; typedef struct {  HASH_TABLE generalEntities;  HASH_TABLE elementTypes;  HASH_TABLE attributeIds;  HASH_TABLE prefixes;  STRING_POOL pool;  STRING_POOL entityValuePool;  /* false once a parameter entity reference has been skipped */  XML_Bool keepProcessing;  /* true once an internal or external PE reference has been encountered;     this includes the reference to an external subset */  XML_Bool hasParamEntityRefs;  XML_Bool standalone;#ifdef XML_DTD  /* indicates if external PE has been read */  XML_Bool paramEntityRead;  HASH_TABLE paramEntities;#endif /* XML_DTD */  PREFIX defaultPrefix;  /* === scaffolding for building content model === */  XML_Bool in_eldecl;  CONTENT_SCAFFOLD *scaffold;  unsigned contentStringLen;  unsigned scaffSize;  unsigned scaffCount;  int scaffLevel;  int *scaffIndex;} DTD; typedef struct open_internal_entity {  const char *internalEventPtr;  const char *internalEventEndPtr;  struct open_internal_entity *next;  ENTITY *entity;  int startTagLevel;  XML_Bool betweenDecl; /* WFC: PE Between Declarations */} OPEN_INTERNAL_ENTITY; typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,                                         const char *end, const char **endPtr); static Processor prologProcessor;static Processor prologInitProcessor;static Processor contentProcessor;static Processor cdataSectionProcessor;#ifdef XML_DTDstatic Processor ignoreSectionProcessor;static Processor externalParEntProcessor;static Processor externalParEntInitProcessor;static Processor entityValueProcessor;static Processor entityValueInitProcessor;#endif /* XML_DTD */static Processor epilogProcessor;static Processor errorProcessor;static Processor externalEntityInitProcessor;static Processor externalEntityInitProcessor2;static Processor externalEntityInitProcessor3;static Processor externalEntityContentProcessor;static Processor internalEntityProcessor; static enum XML_Error handleUnknownEncoding(XML_Parser parser,                                            const XML_Char *encodingName);static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,                                     const char *s, const char *next);static enum XML_Error initializeEncoding(XML_Parser parser);static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,                               const char *s, const char *end, int tok,                               const char *next, const char **nextPtr,                               XML_Bool haveMore, XML_Bool allowClosingDoctype);static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity,                                            XML_Bool betweenDecl);static enum XML_Error doContent(XML_Parser parser, int startTagLevel,                                const ENCODING *enc, const char *start,                                const char *end, const char **endPtr,                                XML_Bool haveMore);static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *,                                     const char **startPtr, const char *end,                                     const char **nextPtr, XML_Bool haveMore);#ifdef XML_DTDstatic enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *,                                      const char **startPtr, const char *end,                                      const char **nextPtr, XML_Bool haveMore);#endif /* XML_DTD */ static void freeBindings(XML_Parser parser, BINDING *bindings);static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *,                                const char *s, TAG_NAME *tagNamePtr,                                BINDING **bindingsPtr);static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,                                 const ATTRIBUTE_ID *attId, const XML_Char *uri,                                 BINDING **bindingsPtr);static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,                           XML_Bool isId, const XML_Char *dfltValue,                           XML_Parser parser);static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *,                                          XML_Bool isCdata, const char *,                                          const char *, STRING_POOL *);static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,                                           XML_Bool isCdata, const char *,                                           const char *, STRING_POOL *);static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,                                    const char *start, const char *end);static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,                                       const char *start, const char *end);static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,                                       const char *start, const char *end);static int reportComment(XML_Parser parser, const ENCODING *enc,                         const char *start, const char *end);static void reportDefault(XML_Parser parser, const ENCODING *enc,                          const char *start, const char *end); static const XML_Char *getContext(XML_Parser parser);static XML_Bool setContext(XML_Parser parser, const XML_Char *context); static void FASTCALL normalizePublicId(XML_Char *s); static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms);/* do not call if m_parentParser != NULL */static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);static void dtdDestroy(DTD *p, XML_Bool isDocEntity,                       const XML_Memory_Handling_Suite *ms);static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,                   const XML_Memory_Handling_Suite *ms);static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *,                           const HASH_TABLE *);static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,                     size_t createSize);static void FASTCALL hashTableInit(HASH_TABLE *,                                   const XML_Memory_Handling_Suite *ms);static void FASTCALL hashTableClear(HASH_TABLE *);static void FASTCALL hashTableDestroy(HASH_TABLE *);static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *); static void FASTCALL poolInit(STRING_POOL *,                              const XML_Memory_Handling_Suite *ms);static void FASTCALL poolClear(STRING_POOL *);static void FASTCALL poolDestroy(STRING_POOL *);static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,                            const char *ptr, const char *end);static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,                                 const char *ptr, const char *end);static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,                                               const XML_Char *s);static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,                                       int n);static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,                                                 const XML_Char *s); static int FASTCALL nextScaffoldPart(XML_Parser parser);static XML_Content *build_model(XML_Parser parser);static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,

Lines 1–500 of 6914.