17db96d56Sopenharmony_ci/* 5ab094ffadd6edfc94c3eee53af44a86951f9f1f0933ada3114bbce2bfb02c99 (2.5.0+) 27db96d56Sopenharmony_ci __ __ _ 37db96d56Sopenharmony_ci ___\ \/ /_ __ __ _| |_ 47db96d56Sopenharmony_ci / _ \\ /| '_ \ / _` | __| 57db96d56Sopenharmony_ci | __// \| |_) | (_| | |_ 67db96d56Sopenharmony_ci \___/_/\_\ .__/ \__,_|\__| 77db96d56Sopenharmony_ci |_| XML parser 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 107db96d56Sopenharmony_ci Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 117db96d56Sopenharmony_ci Copyright (c) 2000-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 127db96d56Sopenharmony_ci Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net> 137db96d56Sopenharmony_ci Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> 147db96d56Sopenharmony_ci Copyright (c) 2005-2009 Steven Solie <steven@solie.ca> 157db96d56Sopenharmony_ci Copyright (c) 2016 Eric Rahm <erahm@mozilla.com> 167db96d56Sopenharmony_ci Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org> 177db96d56Sopenharmony_ci Copyright (c) 2016 Gaurav <g.gupta@samsung.com> 187db96d56Sopenharmony_ci Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de> 197db96d56Sopenharmony_ci Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr> 207db96d56Sopenharmony_ci Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com> 217db96d56Sopenharmony_ci Copyright (c) 2016 Ed Schouten <ed@nuxi.nl> 227db96d56Sopenharmony_ci Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> 237db96d56Sopenharmony_ci Copyright (c) 2017 Václav Slavík <vaclav@slavik.io> 247db96d56Sopenharmony_ci Copyright (c) 2017 Viktor Szakats <commit@vsz.me> 257db96d56Sopenharmony_ci Copyright (c) 2017 Chanho Park <chanho61.park@samsung.com> 267db96d56Sopenharmony_ci Copyright (c) 2017 Rolf Eike Beer <eike@sf-mail.de> 277db96d56Sopenharmony_ci Copyright (c) 2017 Hans Wennborg <hans@chromium.org> 287db96d56Sopenharmony_ci Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com> 297db96d56Sopenharmony_ci Copyright (c) 2018 Benjamin Peterson <benjamin@python.org> 307db96d56Sopenharmony_ci Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it> 317db96d56Sopenharmony_ci Copyright (c) 2018 Mariusz Zaborski <oshogbo@vexillium.org> 327db96d56Sopenharmony_ci Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 337db96d56Sopenharmony_ci Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org> 347db96d56Sopenharmony_ci Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org> 357db96d56Sopenharmony_ci Copyright (c) 2021 Dong-hee Na <donghee.na@python.org> 367db96d56Sopenharmony_ci Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net> 377db96d56Sopenharmony_ci Copyright (c) 2022 Jeffrey Walton <noloader@gmail.com> 387db96d56Sopenharmony_ci Copyright (c) 2022 Jann Horn <jannh@google.com> 397db96d56Sopenharmony_ci Licensed under the MIT license: 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_ci Permission is hereby granted, free of charge, to any person obtaining 427db96d56Sopenharmony_ci a copy of this software and associated documentation files (the 437db96d56Sopenharmony_ci "Software"), to deal in the Software without restriction, including 447db96d56Sopenharmony_ci without limitation the rights to use, copy, modify, merge, publish, 457db96d56Sopenharmony_ci distribute, sublicense, and/or sell copies of the Software, and to permit 467db96d56Sopenharmony_ci persons to whom the Software is furnished to do so, subject to the 477db96d56Sopenharmony_ci following conditions: 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci The above copyright notice and this permission notice shall be included 507db96d56Sopenharmony_ci in all copies or substantial portions of the Software. 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 537db96d56Sopenharmony_ci EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 547db96d56Sopenharmony_ci MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 557db96d56Sopenharmony_ci NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 567db96d56Sopenharmony_ci DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 577db96d56Sopenharmony_ci OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 587db96d56Sopenharmony_ci USE OR OTHER DEALINGS IN THE SOFTWARE. 597db96d56Sopenharmony_ci*/ 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci#define XML_BUILDING_EXPAT 1 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci#include <expat_config.h> 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci#if ! defined(_GNU_SOURCE) 667db96d56Sopenharmony_ci# define _GNU_SOURCE 1 /* syscall prototype */ 677db96d56Sopenharmony_ci#endif 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci#ifdef _WIN32 707db96d56Sopenharmony_ci/* force stdlib to define rand_s() */ 717db96d56Sopenharmony_ci# if ! defined(_CRT_RAND_S) 727db96d56Sopenharmony_ci# define _CRT_RAND_S 737db96d56Sopenharmony_ci# endif 747db96d56Sopenharmony_ci#endif 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci#include <stddef.h> 777db96d56Sopenharmony_ci#include <string.h> /* memset(), memcpy() */ 787db96d56Sopenharmony_ci#include <assert.h> 797db96d56Sopenharmony_ci#include <limits.h> /* UINT_MAX */ 807db96d56Sopenharmony_ci#include <stdio.h> /* fprintf */ 817db96d56Sopenharmony_ci#include <stdlib.h> /* getenv, rand_s */ 827db96d56Sopenharmony_ci#include <stdint.h> /* uintptr_t */ 837db96d56Sopenharmony_ci#include <math.h> /* isnan */ 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci#ifdef _WIN32 867db96d56Sopenharmony_ci# define getpid GetCurrentProcessId 877db96d56Sopenharmony_ci#else 887db96d56Sopenharmony_ci# include <sys/time.h> /* gettimeofday() */ 897db96d56Sopenharmony_ci# include <sys/types.h> /* getpid() */ 907db96d56Sopenharmony_ci# include <unistd.h> /* getpid() */ 917db96d56Sopenharmony_ci# include <fcntl.h> /* O_RDONLY */ 927db96d56Sopenharmony_ci# include <errno.h> 937db96d56Sopenharmony_ci#endif 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci#ifdef _WIN32 967db96d56Sopenharmony_ci# include "winconfig.h" 977db96d56Sopenharmony_ci#endif 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci#include "ascii.h" 1007db96d56Sopenharmony_ci#include "expat.h" 1017db96d56Sopenharmony_ci#include "siphash.h" 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 1047db96d56Sopenharmony_ci# if defined(HAVE_GETRANDOM) 1057db96d56Sopenharmony_ci# include <sys/random.h> /* getrandom */ 1067db96d56Sopenharmony_ci# else 1077db96d56Sopenharmony_ci# include <unistd.h> /* syscall */ 1087db96d56Sopenharmony_ci# include <sys/syscall.h> /* SYS_getrandom */ 1097db96d56Sopenharmony_ci# endif 1107db96d56Sopenharmony_ci# if ! defined(GRND_NONBLOCK) 1117db96d56Sopenharmony_ci# define GRND_NONBLOCK 0x0001 1127db96d56Sopenharmony_ci# endif /* defined(GRND_NONBLOCK) */ 1137db96d56Sopenharmony_ci#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci#if defined(HAVE_LIBBSD) \ 1167db96d56Sopenharmony_ci && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) 1177db96d56Sopenharmony_ci# include <bsd/stdlib.h> 1187db96d56Sopenharmony_ci#endif 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci#if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) 1217db96d56Sopenharmony_ci# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 1227db96d56Sopenharmony_ci#endif 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \ 1257db96d56Sopenharmony_ci && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \ 1267db96d56Sopenharmony_ci && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \ 1277db96d56Sopenharmony_ci && ! defined(XML_POOR_ENTROPY) 1287db96d56Sopenharmony_ci# error You do not have support for any sources of high quality entropy \ 1297db96d56Sopenharmony_ci enabled. For end user security, that is probably not what you want. \ 1307db96d56Sopenharmony_ci \ 1317db96d56Sopenharmony_ci Your options include: \ 1327db96d56Sopenharmony_ci * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \ 1337db96d56Sopenharmony_ci * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ 1347db96d56Sopenharmony_ci * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ 1357db96d56Sopenharmony_ci * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \ 1367db96d56Sopenharmony_ci * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ 1377db96d56Sopenharmony_ci * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ 1387db96d56Sopenharmony_ci * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ 1397db96d56Sopenharmony_ci * Windows >=Vista (rand_s): _WIN32. \ 1407db96d56Sopenharmony_ci \ 1417db96d56Sopenharmony_ci If insist on not using any of these, bypass this error by defining \ 1427db96d56Sopenharmony_ci XML_POOR_ENTROPY; you have been warned. \ 1437db96d56Sopenharmony_ci \ 1447db96d56Sopenharmony_ci If you have reasons to patch this detection code away or need changes \ 1457db96d56Sopenharmony_ci to the build system, please open a bug. Thank you! 1467db96d56Sopenharmony_ci#endif 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ci#ifdef XML_UNICODE 1497db96d56Sopenharmony_ci# define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX 1507db96d56Sopenharmony_ci# define XmlConvert XmlUtf16Convert 1517db96d56Sopenharmony_ci# define XmlGetInternalEncoding XmlGetUtf16InternalEncoding 1527db96d56Sopenharmony_ci# define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS 1537db96d56Sopenharmony_ci# define XmlEncode XmlUtf16Encode 1547db96d56Sopenharmony_ci# define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1)) 1557db96d56Sopenharmony_citypedef unsigned short ICHAR; 1567db96d56Sopenharmony_ci#else 1577db96d56Sopenharmony_ci# define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX 1587db96d56Sopenharmony_ci# define XmlConvert XmlUtf8Convert 1597db96d56Sopenharmony_ci# define XmlGetInternalEncoding XmlGetUtf8InternalEncoding 1607db96d56Sopenharmony_ci# define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS 1617db96d56Sopenharmony_ci# define XmlEncode XmlUtf8Encode 1627db96d56Sopenharmony_ci# define MUST_CONVERT(enc, s) (! (enc)->isUtf8) 1637db96d56Sopenharmony_citypedef char ICHAR; 1647db96d56Sopenharmony_ci#endif 1657db96d56Sopenharmony_ci 1667db96d56Sopenharmony_ci#ifndef XML_NS 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci# define XmlInitEncodingNS XmlInitEncoding 1697db96d56Sopenharmony_ci# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding 1707db96d56Sopenharmony_ci# undef XmlGetInternalEncodingNS 1717db96d56Sopenharmony_ci# define XmlGetInternalEncodingNS XmlGetInternalEncoding 1727db96d56Sopenharmony_ci# define XmlParseXmlDeclNS XmlParseXmlDecl 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci#endif 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_ci#ifdef XML_UNICODE 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci# ifdef XML_UNICODE_WCHAR_T 1797db96d56Sopenharmony_ci# define XML_T(x) (const wchar_t) x 1807db96d56Sopenharmony_ci# define XML_L(x) L##x 1817db96d56Sopenharmony_ci# else 1827db96d56Sopenharmony_ci# define XML_T(x) (const unsigned short)x 1837db96d56Sopenharmony_ci# define XML_L(x) x 1847db96d56Sopenharmony_ci# endif 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci#else 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci# define XML_T(x) x 1897db96d56Sopenharmony_ci# define XML_L(x) x 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ci#endif 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci/* Round up n to be a multiple of sz, where sz is a power of 2. */ 1947db96d56Sopenharmony_ci#define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1)) 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci/* Do safe (NULL-aware) pointer arithmetic */ 1977db96d56Sopenharmony_ci#define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci#include "internal.h" 2007db96d56Sopenharmony_ci#include "xmltok.h" 2017db96d56Sopenharmony_ci#include "xmlrole.h" 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_citypedef const XML_Char *KEY; 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_citypedef struct { 2067db96d56Sopenharmony_ci KEY name; 2077db96d56Sopenharmony_ci} NAMED; 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_citypedef struct { 2107db96d56Sopenharmony_ci NAMED **v; 2117db96d56Sopenharmony_ci unsigned char power; 2127db96d56Sopenharmony_ci size_t size; 2137db96d56Sopenharmony_ci size_t used; 2147db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *mem; 2157db96d56Sopenharmony_ci} HASH_TABLE; 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_cistatic size_t keylen(KEY s); 2187db96d56Sopenharmony_ci 2197db96d56Sopenharmony_cistatic void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key); 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_ci/* For probing (after a collision) we need a step size relative prime 2227db96d56Sopenharmony_ci to the hash table size, which is a power of 2. We use double-hashing, 2237db96d56Sopenharmony_ci since we can calculate a second hash value cheaply by taking those bits 2247db96d56Sopenharmony_ci of the first hash value that were discarded (masked out) when the table 2257db96d56Sopenharmony_ci index was calculated: index = hash & mask, where mask = table->size - 1. 2267db96d56Sopenharmony_ci We limit the maximum step size to table->size / 4 (mask >> 2) and make 2277db96d56Sopenharmony_ci it odd, since odd numbers are always relative prime to a power of 2. 2287db96d56Sopenharmony_ci*/ 2297db96d56Sopenharmony_ci#define SECOND_HASH(hash, mask, power) \ 2307db96d56Sopenharmony_ci ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2)) 2317db96d56Sopenharmony_ci#define PROBE_STEP(hash, mask, power) \ 2327db96d56Sopenharmony_ci ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_citypedef struct { 2357db96d56Sopenharmony_ci NAMED **p; 2367db96d56Sopenharmony_ci NAMED **end; 2377db96d56Sopenharmony_ci} HASH_TABLE_ITER; 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ 2407db96d56Sopenharmony_ci#define INIT_DATA_BUF_SIZE 1024 2417db96d56Sopenharmony_ci#define INIT_ATTS_SIZE 16 2427db96d56Sopenharmony_ci#define INIT_ATTS_VERSION 0xFFFFFFFF 2437db96d56Sopenharmony_ci#define INIT_BLOCK_SIZE 1024 2447db96d56Sopenharmony_ci#define INIT_BUFFER_SIZE 1024 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci#define EXPAND_SPARE 24 2477db96d56Sopenharmony_ci 2487db96d56Sopenharmony_citypedef struct binding { 2497db96d56Sopenharmony_ci struct prefix *prefix; 2507db96d56Sopenharmony_ci struct binding *nextTagBinding; 2517db96d56Sopenharmony_ci struct binding *prevPrefixBinding; 2527db96d56Sopenharmony_ci const struct attribute_id *attId; 2537db96d56Sopenharmony_ci XML_Char *uri; 2547db96d56Sopenharmony_ci int uriLen; 2557db96d56Sopenharmony_ci int uriAlloc; 2567db96d56Sopenharmony_ci} BINDING; 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_citypedef struct prefix { 2597db96d56Sopenharmony_ci const XML_Char *name; 2607db96d56Sopenharmony_ci BINDING *binding; 2617db96d56Sopenharmony_ci} PREFIX; 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_citypedef struct { 2647db96d56Sopenharmony_ci const XML_Char *str; 2657db96d56Sopenharmony_ci const XML_Char *localPart; 2667db96d56Sopenharmony_ci const XML_Char *prefix; 2677db96d56Sopenharmony_ci int strLen; 2687db96d56Sopenharmony_ci int uriLen; 2697db96d56Sopenharmony_ci int prefixLen; 2707db96d56Sopenharmony_ci} TAG_NAME; 2717db96d56Sopenharmony_ci 2727db96d56Sopenharmony_ci/* TAG represents an open element. 2737db96d56Sopenharmony_ci The name of the element is stored in both the document and API 2747db96d56Sopenharmony_ci encodings. The memory buffer 'buf' is a separately-allocated 2757db96d56Sopenharmony_ci memory area which stores the name. During the XML_Parse()/ 2767db96d56Sopenharmony_ci XMLParseBuffer() when the element is open, the memory for the 'raw' 2777db96d56Sopenharmony_ci version of the name (in the document encoding) is shared with the 2787db96d56Sopenharmony_ci document buffer. If the element is open across calls to 2797db96d56Sopenharmony_ci XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to 2807db96d56Sopenharmony_ci contain the 'raw' name as well. 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_ci A parser re-uses these structures, maintaining a list of allocated 2837db96d56Sopenharmony_ci TAG objects in a free list. 2847db96d56Sopenharmony_ci*/ 2857db96d56Sopenharmony_citypedef struct tag { 2867db96d56Sopenharmony_ci struct tag *parent; /* parent of this element */ 2877db96d56Sopenharmony_ci const char *rawName; /* tagName in the original encoding */ 2887db96d56Sopenharmony_ci int rawNameLength; 2897db96d56Sopenharmony_ci TAG_NAME name; /* tagName in the API encoding */ 2907db96d56Sopenharmony_ci char *buf; /* buffer for name components */ 2917db96d56Sopenharmony_ci char *bufEnd; /* end of the buffer */ 2927db96d56Sopenharmony_ci BINDING *bindings; 2937db96d56Sopenharmony_ci} TAG; 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_citypedef struct { 2967db96d56Sopenharmony_ci const XML_Char *name; 2977db96d56Sopenharmony_ci const XML_Char *textPtr; 2987db96d56Sopenharmony_ci int textLen; /* length in XML_Chars */ 2997db96d56Sopenharmony_ci int processed; /* # of processed bytes - when suspended */ 3007db96d56Sopenharmony_ci const XML_Char *systemId; 3017db96d56Sopenharmony_ci const XML_Char *base; 3027db96d56Sopenharmony_ci const XML_Char *publicId; 3037db96d56Sopenharmony_ci const XML_Char *notation; 3047db96d56Sopenharmony_ci XML_Bool open; 3057db96d56Sopenharmony_ci XML_Bool is_param; 3067db96d56Sopenharmony_ci XML_Bool is_internal; /* true if declared in internal subset outside PE */ 3077db96d56Sopenharmony_ci} ENTITY; 3087db96d56Sopenharmony_ci 3097db96d56Sopenharmony_citypedef struct { 3107db96d56Sopenharmony_ci enum XML_Content_Type type; 3117db96d56Sopenharmony_ci enum XML_Content_Quant quant; 3127db96d56Sopenharmony_ci const XML_Char *name; 3137db96d56Sopenharmony_ci int firstchild; 3147db96d56Sopenharmony_ci int lastchild; 3157db96d56Sopenharmony_ci int childcnt; 3167db96d56Sopenharmony_ci int nextsib; 3177db96d56Sopenharmony_ci} CONTENT_SCAFFOLD; 3187db96d56Sopenharmony_ci 3197db96d56Sopenharmony_ci#define INIT_SCAFFOLD_ELEMENTS 32 3207db96d56Sopenharmony_ci 3217db96d56Sopenharmony_citypedef struct block { 3227db96d56Sopenharmony_ci struct block *next; 3237db96d56Sopenharmony_ci int size; 3247db96d56Sopenharmony_ci XML_Char s[1]; 3257db96d56Sopenharmony_ci} BLOCK; 3267db96d56Sopenharmony_ci 3277db96d56Sopenharmony_citypedef struct { 3287db96d56Sopenharmony_ci BLOCK *blocks; 3297db96d56Sopenharmony_ci BLOCK *freeBlocks; 3307db96d56Sopenharmony_ci const XML_Char *end; 3317db96d56Sopenharmony_ci XML_Char *ptr; 3327db96d56Sopenharmony_ci XML_Char *start; 3337db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *mem; 3347db96d56Sopenharmony_ci} STRING_POOL; 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_ci/* The XML_Char before the name is used to determine whether 3377db96d56Sopenharmony_ci an attribute has been specified. */ 3387db96d56Sopenharmony_citypedef struct attribute_id { 3397db96d56Sopenharmony_ci XML_Char *name; 3407db96d56Sopenharmony_ci PREFIX *prefix; 3417db96d56Sopenharmony_ci XML_Bool maybeTokenized; 3427db96d56Sopenharmony_ci XML_Bool xmlns; 3437db96d56Sopenharmony_ci} ATTRIBUTE_ID; 3447db96d56Sopenharmony_ci 3457db96d56Sopenharmony_citypedef struct { 3467db96d56Sopenharmony_ci const ATTRIBUTE_ID *id; 3477db96d56Sopenharmony_ci XML_Bool isCdata; 3487db96d56Sopenharmony_ci const XML_Char *value; 3497db96d56Sopenharmony_ci} DEFAULT_ATTRIBUTE; 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_citypedef struct { 3527db96d56Sopenharmony_ci unsigned long version; 3537db96d56Sopenharmony_ci unsigned long hash; 3547db96d56Sopenharmony_ci const XML_Char *uriName; 3557db96d56Sopenharmony_ci} NS_ATT; 3567db96d56Sopenharmony_ci 3577db96d56Sopenharmony_citypedef struct { 3587db96d56Sopenharmony_ci const XML_Char *name; 3597db96d56Sopenharmony_ci PREFIX *prefix; 3607db96d56Sopenharmony_ci const ATTRIBUTE_ID *idAtt; 3617db96d56Sopenharmony_ci int nDefaultAtts; 3627db96d56Sopenharmony_ci int allocDefaultAtts; 3637db96d56Sopenharmony_ci DEFAULT_ATTRIBUTE *defaultAtts; 3647db96d56Sopenharmony_ci} ELEMENT_TYPE; 3657db96d56Sopenharmony_ci 3667db96d56Sopenharmony_citypedef struct { 3677db96d56Sopenharmony_ci HASH_TABLE generalEntities; 3687db96d56Sopenharmony_ci HASH_TABLE elementTypes; 3697db96d56Sopenharmony_ci HASH_TABLE attributeIds; 3707db96d56Sopenharmony_ci HASH_TABLE prefixes; 3717db96d56Sopenharmony_ci STRING_POOL pool; 3727db96d56Sopenharmony_ci STRING_POOL entityValuePool; 3737db96d56Sopenharmony_ci /* false once a parameter entity reference has been skipped */ 3747db96d56Sopenharmony_ci XML_Bool keepProcessing; 3757db96d56Sopenharmony_ci /* true once an internal or external PE reference has been encountered; 3767db96d56Sopenharmony_ci this includes the reference to an external subset */ 3777db96d56Sopenharmony_ci XML_Bool hasParamEntityRefs; 3787db96d56Sopenharmony_ci XML_Bool standalone; 3797db96d56Sopenharmony_ci#ifdef XML_DTD 3807db96d56Sopenharmony_ci /* indicates if external PE has been read */ 3817db96d56Sopenharmony_ci XML_Bool paramEntityRead; 3827db96d56Sopenharmony_ci HASH_TABLE paramEntities; 3837db96d56Sopenharmony_ci#endif /* XML_DTD */ 3847db96d56Sopenharmony_ci PREFIX defaultPrefix; 3857db96d56Sopenharmony_ci /* === scaffolding for building content model === */ 3867db96d56Sopenharmony_ci XML_Bool in_eldecl; 3877db96d56Sopenharmony_ci CONTENT_SCAFFOLD *scaffold; 3887db96d56Sopenharmony_ci unsigned contentStringLen; 3897db96d56Sopenharmony_ci unsigned scaffSize; 3907db96d56Sopenharmony_ci unsigned scaffCount; 3917db96d56Sopenharmony_ci int scaffLevel; 3927db96d56Sopenharmony_ci int *scaffIndex; 3937db96d56Sopenharmony_ci} DTD; 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_citypedef struct open_internal_entity { 3967db96d56Sopenharmony_ci const char *internalEventPtr; 3977db96d56Sopenharmony_ci const char *internalEventEndPtr; 3987db96d56Sopenharmony_ci struct open_internal_entity *next; 3997db96d56Sopenharmony_ci ENTITY *entity; 4007db96d56Sopenharmony_ci int startTagLevel; 4017db96d56Sopenharmony_ci XML_Bool betweenDecl; /* WFC: PE Between Declarations */ 4027db96d56Sopenharmony_ci} OPEN_INTERNAL_ENTITY; 4037db96d56Sopenharmony_ci 4047db96d56Sopenharmony_cienum XML_Account { 4057db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser */ 4067db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity 4077db96d56Sopenharmony_ci expansion */ 4087db96d56Sopenharmony_ci XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */ 4097db96d56Sopenharmony_ci}; 4107db96d56Sopenharmony_ci 4117db96d56Sopenharmony_ci#ifdef XML_DTD 4127db96d56Sopenharmony_citypedef unsigned long long XmlBigCount; 4137db96d56Sopenharmony_citypedef struct accounting { 4147db96d56Sopenharmony_ci XmlBigCount countBytesDirect; 4157db96d56Sopenharmony_ci XmlBigCount countBytesIndirect; 4167db96d56Sopenharmony_ci int debugLevel; 4177db96d56Sopenharmony_ci float maximumAmplificationFactor; // >=1.0 4187db96d56Sopenharmony_ci unsigned long long activationThresholdBytes; 4197db96d56Sopenharmony_ci} ACCOUNTING; 4207db96d56Sopenharmony_ci 4217db96d56Sopenharmony_citypedef struct entity_stats { 4227db96d56Sopenharmony_ci unsigned int countEverOpened; 4237db96d56Sopenharmony_ci unsigned int currentDepth; 4247db96d56Sopenharmony_ci unsigned int maximumDepthSeen; 4257db96d56Sopenharmony_ci int debugLevel; 4267db96d56Sopenharmony_ci} ENTITY_STATS; 4277db96d56Sopenharmony_ci#endif /* XML_DTD */ 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_citypedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start, 4307db96d56Sopenharmony_ci const char *end, const char **endPtr); 4317db96d56Sopenharmony_ci 4327db96d56Sopenharmony_cistatic Processor prologProcessor; 4337db96d56Sopenharmony_cistatic Processor prologInitProcessor; 4347db96d56Sopenharmony_cistatic Processor contentProcessor; 4357db96d56Sopenharmony_cistatic Processor cdataSectionProcessor; 4367db96d56Sopenharmony_ci#ifdef XML_DTD 4377db96d56Sopenharmony_cistatic Processor ignoreSectionProcessor; 4387db96d56Sopenharmony_cistatic Processor externalParEntProcessor; 4397db96d56Sopenharmony_cistatic Processor externalParEntInitProcessor; 4407db96d56Sopenharmony_cistatic Processor entityValueProcessor; 4417db96d56Sopenharmony_cistatic Processor entityValueInitProcessor; 4427db96d56Sopenharmony_ci#endif /* XML_DTD */ 4437db96d56Sopenharmony_cistatic Processor epilogProcessor; 4447db96d56Sopenharmony_cistatic Processor errorProcessor; 4457db96d56Sopenharmony_cistatic Processor externalEntityInitProcessor; 4467db96d56Sopenharmony_cistatic Processor externalEntityInitProcessor2; 4477db96d56Sopenharmony_cistatic Processor externalEntityInitProcessor3; 4487db96d56Sopenharmony_cistatic Processor externalEntityContentProcessor; 4497db96d56Sopenharmony_cistatic Processor internalEntityProcessor; 4507db96d56Sopenharmony_ci 4517db96d56Sopenharmony_cistatic enum XML_Error handleUnknownEncoding(XML_Parser parser, 4527db96d56Sopenharmony_ci const XML_Char *encodingName); 4537db96d56Sopenharmony_cistatic enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, 4547db96d56Sopenharmony_ci const char *s, const char *next); 4557db96d56Sopenharmony_cistatic enum XML_Error initializeEncoding(XML_Parser parser); 4567db96d56Sopenharmony_cistatic enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, 4577db96d56Sopenharmony_ci const char *s, const char *end, int tok, 4587db96d56Sopenharmony_ci const char *next, const char **nextPtr, 4597db96d56Sopenharmony_ci XML_Bool haveMore, XML_Bool allowClosingDoctype, 4607db96d56Sopenharmony_ci enum XML_Account account); 4617db96d56Sopenharmony_cistatic enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, 4627db96d56Sopenharmony_ci XML_Bool betweenDecl); 4637db96d56Sopenharmony_cistatic enum XML_Error doContent(XML_Parser parser, int startTagLevel, 4647db96d56Sopenharmony_ci const ENCODING *enc, const char *start, 4657db96d56Sopenharmony_ci const char *end, const char **endPtr, 4667db96d56Sopenharmony_ci XML_Bool haveMore, enum XML_Account account); 4677db96d56Sopenharmony_cistatic enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, 4687db96d56Sopenharmony_ci const char **startPtr, const char *end, 4697db96d56Sopenharmony_ci const char **nextPtr, XML_Bool haveMore, 4707db96d56Sopenharmony_ci enum XML_Account account); 4717db96d56Sopenharmony_ci#ifdef XML_DTD 4727db96d56Sopenharmony_cistatic enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *, 4737db96d56Sopenharmony_ci const char **startPtr, const char *end, 4747db96d56Sopenharmony_ci const char **nextPtr, XML_Bool haveMore); 4757db96d56Sopenharmony_ci#endif /* XML_DTD */ 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_cistatic void freeBindings(XML_Parser parser, BINDING *bindings); 4787db96d56Sopenharmony_cistatic enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, 4797db96d56Sopenharmony_ci const char *s, TAG_NAME *tagNamePtr, 4807db96d56Sopenharmony_ci BINDING **bindingsPtr, 4817db96d56Sopenharmony_ci enum XML_Account account); 4827db96d56Sopenharmony_cistatic enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, 4837db96d56Sopenharmony_ci const ATTRIBUTE_ID *attId, const XML_Char *uri, 4847db96d56Sopenharmony_ci BINDING **bindingsPtr); 4857db96d56Sopenharmony_cistatic int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 4867db96d56Sopenharmony_ci XML_Bool isId, const XML_Char *dfltValue, 4877db96d56Sopenharmony_ci XML_Parser parser); 4887db96d56Sopenharmony_cistatic enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *, 4897db96d56Sopenharmony_ci XML_Bool isCdata, const char *, 4907db96d56Sopenharmony_ci const char *, STRING_POOL *, 4917db96d56Sopenharmony_ci enum XML_Account account); 4927db96d56Sopenharmony_cistatic enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *, 4937db96d56Sopenharmony_ci XML_Bool isCdata, const char *, 4947db96d56Sopenharmony_ci const char *, STRING_POOL *, 4957db96d56Sopenharmony_ci enum XML_Account account); 4967db96d56Sopenharmony_cistatic ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, 4977db96d56Sopenharmony_ci const char *start, const char *end); 4987db96d56Sopenharmony_cistatic int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); 4997db96d56Sopenharmony_cistatic enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, 5007db96d56Sopenharmony_ci const char *start, const char *end, 5017db96d56Sopenharmony_ci enum XML_Account account); 5027db96d56Sopenharmony_cistatic int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, 5037db96d56Sopenharmony_ci const char *start, const char *end); 5047db96d56Sopenharmony_cistatic int reportComment(XML_Parser parser, const ENCODING *enc, 5057db96d56Sopenharmony_ci const char *start, const char *end); 5067db96d56Sopenharmony_cistatic void reportDefault(XML_Parser parser, const ENCODING *enc, 5077db96d56Sopenharmony_ci const char *start, const char *end); 5087db96d56Sopenharmony_ci 5097db96d56Sopenharmony_cistatic const XML_Char *getContext(XML_Parser parser); 5107db96d56Sopenharmony_cistatic XML_Bool setContext(XML_Parser parser, const XML_Char *context); 5117db96d56Sopenharmony_ci 5127db96d56Sopenharmony_cistatic void FASTCALL normalizePublicId(XML_Char *s); 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_cistatic DTD *dtdCreate(const XML_Memory_Handling_Suite *ms); 5157db96d56Sopenharmony_ci/* do not call if m_parentParser != NULL */ 5167db96d56Sopenharmony_cistatic void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); 5177db96d56Sopenharmony_cistatic void dtdDestroy(DTD *p, XML_Bool isDocEntity, 5187db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *ms); 5197db96d56Sopenharmony_cistatic int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, 5207db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *ms); 5217db96d56Sopenharmony_cistatic int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *, 5227db96d56Sopenharmony_ci const HASH_TABLE *); 5237db96d56Sopenharmony_cistatic NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, 5247db96d56Sopenharmony_ci size_t createSize); 5257db96d56Sopenharmony_cistatic void FASTCALL hashTableInit(HASH_TABLE *, 5267db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *ms); 5277db96d56Sopenharmony_cistatic void FASTCALL hashTableClear(HASH_TABLE *); 5287db96d56Sopenharmony_cistatic void FASTCALL hashTableDestroy(HASH_TABLE *); 5297db96d56Sopenharmony_cistatic void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); 5307db96d56Sopenharmony_cistatic NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *); 5317db96d56Sopenharmony_ci 5327db96d56Sopenharmony_cistatic void FASTCALL poolInit(STRING_POOL *, 5337db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *ms); 5347db96d56Sopenharmony_cistatic void FASTCALL poolClear(STRING_POOL *); 5357db96d56Sopenharmony_cistatic void FASTCALL poolDestroy(STRING_POOL *); 5367db96d56Sopenharmony_cistatic XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, 5377db96d56Sopenharmony_ci const char *ptr, const char *end); 5387db96d56Sopenharmony_cistatic XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, 5397db96d56Sopenharmony_ci const char *ptr, const char *end); 5407db96d56Sopenharmony_cistatic XML_Bool FASTCALL poolGrow(STRING_POOL *pool); 5417db96d56Sopenharmony_cistatic const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, 5427db96d56Sopenharmony_ci const XML_Char *s); 5437db96d56Sopenharmony_cistatic const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, 5447db96d56Sopenharmony_ci int n); 5457db96d56Sopenharmony_cistatic const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, 5467db96d56Sopenharmony_ci const XML_Char *s); 5477db96d56Sopenharmony_ci 5487db96d56Sopenharmony_cistatic int FASTCALL nextScaffoldPart(XML_Parser parser); 5497db96d56Sopenharmony_cistatic XML_Content *build_model(XML_Parser parser); 5507db96d56Sopenharmony_cistatic ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc, 5517db96d56Sopenharmony_ci const char *ptr, const char *end); 5527db96d56Sopenharmony_ci 5537db96d56Sopenharmony_cistatic XML_Char *copyString(const XML_Char *s, 5547db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *memsuite); 5557db96d56Sopenharmony_ci 5567db96d56Sopenharmony_cistatic unsigned long generate_hash_secret_salt(XML_Parser parser); 5577db96d56Sopenharmony_cistatic XML_Bool startParsing(XML_Parser parser); 5587db96d56Sopenharmony_ci 5597db96d56Sopenharmony_cistatic XML_Parser parserCreate(const XML_Char *encodingName, 5607db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *memsuite, 5617db96d56Sopenharmony_ci const XML_Char *nameSep, DTD *dtd); 5627db96d56Sopenharmony_ci 5637db96d56Sopenharmony_cistatic void parserInit(XML_Parser parser, const XML_Char *encodingName); 5647db96d56Sopenharmony_ci 5657db96d56Sopenharmony_ci#ifdef XML_DTD 5667db96d56Sopenharmony_cistatic float accountingGetCurrentAmplification(XML_Parser rootParser); 5677db96d56Sopenharmony_cistatic void accountingReportStats(XML_Parser originParser, const char *epilog); 5687db96d56Sopenharmony_cistatic void accountingOnAbort(XML_Parser originParser); 5697db96d56Sopenharmony_cistatic void accountingReportDiff(XML_Parser rootParser, 5707db96d56Sopenharmony_ci unsigned int levelsAwayFromRootParser, 5717db96d56Sopenharmony_ci const char *before, const char *after, 5727db96d56Sopenharmony_ci ptrdiff_t bytesMore, int source_line, 5737db96d56Sopenharmony_ci enum XML_Account account); 5747db96d56Sopenharmony_cistatic XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok, 5757db96d56Sopenharmony_ci const char *before, const char *after, 5767db96d56Sopenharmony_ci int source_line, 5777db96d56Sopenharmony_ci enum XML_Account account); 5787db96d56Sopenharmony_ci 5797db96d56Sopenharmony_cistatic void entityTrackingReportStats(XML_Parser parser, ENTITY *entity, 5807db96d56Sopenharmony_ci const char *action, int sourceLine); 5817db96d56Sopenharmony_cistatic void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity, 5827db96d56Sopenharmony_ci int sourceLine); 5837db96d56Sopenharmony_cistatic void entityTrackingOnClose(XML_Parser parser, ENTITY *entity, 5847db96d56Sopenharmony_ci int sourceLine); 5857db96d56Sopenharmony_ci 5867db96d56Sopenharmony_cistatic XML_Parser getRootParserOf(XML_Parser parser, 5877db96d56Sopenharmony_ci unsigned int *outLevelDiff); 5887db96d56Sopenharmony_ci#endif /* XML_DTD */ 5897db96d56Sopenharmony_ci 5907db96d56Sopenharmony_cistatic unsigned long getDebugLevel(const char *variableName, 5917db96d56Sopenharmony_ci unsigned long defaultDebugLevel); 5927db96d56Sopenharmony_ci 5937db96d56Sopenharmony_ci#define poolStart(pool) ((pool)->start) 5947db96d56Sopenharmony_ci#define poolEnd(pool) ((pool)->ptr) 5957db96d56Sopenharmony_ci#define poolLength(pool) ((pool)->ptr - (pool)->start) 5967db96d56Sopenharmony_ci#define poolChop(pool) ((void)--(pool->ptr)) 5977db96d56Sopenharmony_ci#define poolLastChar(pool) (((pool)->ptr)[-1]) 5987db96d56Sopenharmony_ci#define poolDiscard(pool) ((pool)->ptr = (pool)->start) 5997db96d56Sopenharmony_ci#define poolFinish(pool) ((pool)->start = (pool)->ptr) 6007db96d56Sopenharmony_ci#define poolAppendChar(pool, c) \ 6017db96d56Sopenharmony_ci (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \ 6027db96d56Sopenharmony_ci ? 0 \ 6037db96d56Sopenharmony_ci : ((*((pool)->ptr)++ = c), 1)) 6047db96d56Sopenharmony_ci 6057db96d56Sopenharmony_cistruct XML_ParserStruct { 6067db96d56Sopenharmony_ci /* The first member must be m_userData so that the XML_GetUserData 6077db96d56Sopenharmony_ci macro works. */ 6087db96d56Sopenharmony_ci void *m_userData; 6097db96d56Sopenharmony_ci void *m_handlerArg; 6107db96d56Sopenharmony_ci char *m_buffer; 6117db96d56Sopenharmony_ci const XML_Memory_Handling_Suite m_mem; 6127db96d56Sopenharmony_ci /* first character to be parsed */ 6137db96d56Sopenharmony_ci const char *m_bufferPtr; 6147db96d56Sopenharmony_ci /* past last character to be parsed */ 6157db96d56Sopenharmony_ci char *m_bufferEnd; 6167db96d56Sopenharmony_ci /* allocated end of m_buffer */ 6177db96d56Sopenharmony_ci const char *m_bufferLim; 6187db96d56Sopenharmony_ci XML_Index m_parseEndByteIndex; 6197db96d56Sopenharmony_ci const char *m_parseEndPtr; 6207db96d56Sopenharmony_ci XML_Char *m_dataBuf; 6217db96d56Sopenharmony_ci XML_Char *m_dataBufEnd; 6227db96d56Sopenharmony_ci XML_StartElementHandler m_startElementHandler; 6237db96d56Sopenharmony_ci XML_EndElementHandler m_endElementHandler; 6247db96d56Sopenharmony_ci XML_CharacterDataHandler m_characterDataHandler; 6257db96d56Sopenharmony_ci XML_ProcessingInstructionHandler m_processingInstructionHandler; 6267db96d56Sopenharmony_ci XML_CommentHandler m_commentHandler; 6277db96d56Sopenharmony_ci XML_StartCdataSectionHandler m_startCdataSectionHandler; 6287db96d56Sopenharmony_ci XML_EndCdataSectionHandler m_endCdataSectionHandler; 6297db96d56Sopenharmony_ci XML_DefaultHandler m_defaultHandler; 6307db96d56Sopenharmony_ci XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; 6317db96d56Sopenharmony_ci XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; 6327db96d56Sopenharmony_ci XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; 6337db96d56Sopenharmony_ci XML_NotationDeclHandler m_notationDeclHandler; 6347db96d56Sopenharmony_ci XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; 6357db96d56Sopenharmony_ci XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; 6367db96d56Sopenharmony_ci XML_NotStandaloneHandler m_notStandaloneHandler; 6377db96d56Sopenharmony_ci XML_ExternalEntityRefHandler m_externalEntityRefHandler; 6387db96d56Sopenharmony_ci XML_Parser m_externalEntityRefHandlerArg; 6397db96d56Sopenharmony_ci XML_SkippedEntityHandler m_skippedEntityHandler; 6407db96d56Sopenharmony_ci XML_UnknownEncodingHandler m_unknownEncodingHandler; 6417db96d56Sopenharmony_ci XML_ElementDeclHandler m_elementDeclHandler; 6427db96d56Sopenharmony_ci XML_AttlistDeclHandler m_attlistDeclHandler; 6437db96d56Sopenharmony_ci XML_EntityDeclHandler m_entityDeclHandler; 6447db96d56Sopenharmony_ci XML_XmlDeclHandler m_xmlDeclHandler; 6457db96d56Sopenharmony_ci const ENCODING *m_encoding; 6467db96d56Sopenharmony_ci INIT_ENCODING m_initEncoding; 6477db96d56Sopenharmony_ci const ENCODING *m_internalEncoding; 6487db96d56Sopenharmony_ci const XML_Char *m_protocolEncodingName; 6497db96d56Sopenharmony_ci XML_Bool m_ns; 6507db96d56Sopenharmony_ci XML_Bool m_ns_triplets; 6517db96d56Sopenharmony_ci void *m_unknownEncodingMem; 6527db96d56Sopenharmony_ci void *m_unknownEncodingData; 6537db96d56Sopenharmony_ci void *m_unknownEncodingHandlerData; 6547db96d56Sopenharmony_ci void(XMLCALL *m_unknownEncodingRelease)(void *); 6557db96d56Sopenharmony_ci PROLOG_STATE m_prologState; 6567db96d56Sopenharmony_ci Processor *m_processor; 6577db96d56Sopenharmony_ci enum XML_Error m_errorCode; 6587db96d56Sopenharmony_ci const char *m_eventPtr; 6597db96d56Sopenharmony_ci const char *m_eventEndPtr; 6607db96d56Sopenharmony_ci const char *m_positionPtr; 6617db96d56Sopenharmony_ci OPEN_INTERNAL_ENTITY *m_openInternalEntities; 6627db96d56Sopenharmony_ci OPEN_INTERNAL_ENTITY *m_freeInternalEntities; 6637db96d56Sopenharmony_ci XML_Bool m_defaultExpandInternalEntities; 6647db96d56Sopenharmony_ci int m_tagLevel; 6657db96d56Sopenharmony_ci ENTITY *m_declEntity; 6667db96d56Sopenharmony_ci const XML_Char *m_doctypeName; 6677db96d56Sopenharmony_ci const XML_Char *m_doctypeSysid; 6687db96d56Sopenharmony_ci const XML_Char *m_doctypePubid; 6697db96d56Sopenharmony_ci const XML_Char *m_declAttributeType; 6707db96d56Sopenharmony_ci const XML_Char *m_declNotationName; 6717db96d56Sopenharmony_ci const XML_Char *m_declNotationPublicId; 6727db96d56Sopenharmony_ci ELEMENT_TYPE *m_declElementType; 6737db96d56Sopenharmony_ci ATTRIBUTE_ID *m_declAttributeId; 6747db96d56Sopenharmony_ci XML_Bool m_declAttributeIsCdata; 6757db96d56Sopenharmony_ci XML_Bool m_declAttributeIsId; 6767db96d56Sopenharmony_ci DTD *m_dtd; 6777db96d56Sopenharmony_ci const XML_Char *m_curBase; 6787db96d56Sopenharmony_ci TAG *m_tagStack; 6797db96d56Sopenharmony_ci TAG *m_freeTagList; 6807db96d56Sopenharmony_ci BINDING *m_inheritedBindings; 6817db96d56Sopenharmony_ci BINDING *m_freeBindingList; 6827db96d56Sopenharmony_ci int m_attsSize; 6837db96d56Sopenharmony_ci int m_nSpecifiedAtts; 6847db96d56Sopenharmony_ci int m_idAttIndex; 6857db96d56Sopenharmony_ci ATTRIBUTE *m_atts; 6867db96d56Sopenharmony_ci NS_ATT *m_nsAtts; 6877db96d56Sopenharmony_ci unsigned long m_nsAttsVersion; 6887db96d56Sopenharmony_ci unsigned char m_nsAttsPower; 6897db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 6907db96d56Sopenharmony_ci XML_AttrInfo *m_attInfo; 6917db96d56Sopenharmony_ci#endif 6927db96d56Sopenharmony_ci POSITION m_position; 6937db96d56Sopenharmony_ci STRING_POOL m_tempPool; 6947db96d56Sopenharmony_ci STRING_POOL m_temp2Pool; 6957db96d56Sopenharmony_ci char *m_groupConnector; 6967db96d56Sopenharmony_ci unsigned int m_groupSize; 6977db96d56Sopenharmony_ci XML_Char m_namespaceSeparator; 6987db96d56Sopenharmony_ci XML_Parser m_parentParser; 6997db96d56Sopenharmony_ci XML_ParsingStatus m_parsingStatus; 7007db96d56Sopenharmony_ci#ifdef XML_DTD 7017db96d56Sopenharmony_ci XML_Bool m_isParamEntity; 7027db96d56Sopenharmony_ci XML_Bool m_useForeignDTD; 7037db96d56Sopenharmony_ci enum XML_ParamEntityParsing m_paramEntityParsing; 7047db96d56Sopenharmony_ci#endif 7057db96d56Sopenharmony_ci unsigned long m_hash_secret_salt; 7067db96d56Sopenharmony_ci#ifdef XML_DTD 7077db96d56Sopenharmony_ci ACCOUNTING m_accounting; 7087db96d56Sopenharmony_ci ENTITY_STATS m_entity_stats; 7097db96d56Sopenharmony_ci#endif 7107db96d56Sopenharmony_ci}; 7117db96d56Sopenharmony_ci 7127db96d56Sopenharmony_ci#define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) 7137db96d56Sopenharmony_ci#define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s))) 7147db96d56Sopenharmony_ci#define FREE(parser, p) (parser->m_mem.free_fcn((p))) 7157db96d56Sopenharmony_ci 7167db96d56Sopenharmony_ciXML_Parser XMLCALL 7177db96d56Sopenharmony_ciXML_ParserCreate(const XML_Char *encodingName) { 7187db96d56Sopenharmony_ci return XML_ParserCreate_MM(encodingName, NULL, NULL); 7197db96d56Sopenharmony_ci} 7207db96d56Sopenharmony_ci 7217db96d56Sopenharmony_ciXML_Parser XMLCALL 7227db96d56Sopenharmony_ciXML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { 7237db96d56Sopenharmony_ci XML_Char tmp[2] = {nsSep, 0}; 7247db96d56Sopenharmony_ci return XML_ParserCreate_MM(encodingName, NULL, tmp); 7257db96d56Sopenharmony_ci} 7267db96d56Sopenharmony_ci 7277db96d56Sopenharmony_ci// "xml=http://www.w3.org/XML/1998/namespace" 7287db96d56Sopenharmony_cistatic const XML_Char implicitContext[] 7297db96d56Sopenharmony_ci = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, 7307db96d56Sopenharmony_ci ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, 7317db96d56Sopenharmony_ci ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, 7327db96d56Sopenharmony_ci ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, 7337db96d56Sopenharmony_ci ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, 7347db96d56Sopenharmony_ci ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, 7357db96d56Sopenharmony_ci ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, 7367db96d56Sopenharmony_ci ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, 7377db96d56Sopenharmony_ci '\0'}; 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci/* To avoid warnings about unused functions: */ 7407db96d56Sopenharmony_ci#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) 7417db96d56Sopenharmony_ci 7427db96d56Sopenharmony_ci# if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 7437db96d56Sopenharmony_ci 7447db96d56Sopenharmony_ci/* Obtain entropy on Linux 3.17+ */ 7457db96d56Sopenharmony_cistatic int 7467db96d56Sopenharmony_ciwriteRandomBytes_getrandom_nonblock(void *target, size_t count) { 7477db96d56Sopenharmony_ci int success = 0; /* full count bytes written? */ 7487db96d56Sopenharmony_ci size_t bytesWrittenTotal = 0; 7497db96d56Sopenharmony_ci const unsigned int getrandomFlags = GRND_NONBLOCK; 7507db96d56Sopenharmony_ci 7517db96d56Sopenharmony_ci do { 7527db96d56Sopenharmony_ci void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); 7537db96d56Sopenharmony_ci const size_t bytesToWrite = count - bytesWrittenTotal; 7547db96d56Sopenharmony_ci 7557db96d56Sopenharmony_ci const int bytesWrittenMore = 7567db96d56Sopenharmony_ci# if defined(HAVE_GETRANDOM) 7577db96d56Sopenharmony_ci getrandom(currentTarget, bytesToWrite, getrandomFlags); 7587db96d56Sopenharmony_ci# else 7597db96d56Sopenharmony_ci syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); 7607db96d56Sopenharmony_ci# endif 7617db96d56Sopenharmony_ci 7627db96d56Sopenharmony_ci if (bytesWrittenMore > 0) { 7637db96d56Sopenharmony_ci bytesWrittenTotal += bytesWrittenMore; 7647db96d56Sopenharmony_ci if (bytesWrittenTotal >= count) 7657db96d56Sopenharmony_ci success = 1; 7667db96d56Sopenharmony_ci } 7677db96d56Sopenharmony_ci } while (! success && (errno == EINTR)); 7687db96d56Sopenharmony_ci 7697db96d56Sopenharmony_ci return success; 7707db96d56Sopenharmony_ci} 7717db96d56Sopenharmony_ci 7727db96d56Sopenharmony_ci# endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ 7737db96d56Sopenharmony_ci 7747db96d56Sopenharmony_ci# if ! defined(_WIN32) && defined(XML_DEV_URANDOM) 7757db96d56Sopenharmony_ci 7767db96d56Sopenharmony_ci/* Extract entropy from /dev/urandom */ 7777db96d56Sopenharmony_cistatic int 7787db96d56Sopenharmony_ciwriteRandomBytes_dev_urandom(void *target, size_t count) { 7797db96d56Sopenharmony_ci int success = 0; /* full count bytes written? */ 7807db96d56Sopenharmony_ci size_t bytesWrittenTotal = 0; 7817db96d56Sopenharmony_ci 7827db96d56Sopenharmony_ci const int fd = open("/dev/urandom", O_RDONLY); 7837db96d56Sopenharmony_ci if (fd < 0) { 7847db96d56Sopenharmony_ci return 0; 7857db96d56Sopenharmony_ci } 7867db96d56Sopenharmony_ci 7877db96d56Sopenharmony_ci do { 7887db96d56Sopenharmony_ci void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); 7897db96d56Sopenharmony_ci const size_t bytesToWrite = count - bytesWrittenTotal; 7907db96d56Sopenharmony_ci 7917db96d56Sopenharmony_ci const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); 7927db96d56Sopenharmony_ci 7937db96d56Sopenharmony_ci if (bytesWrittenMore > 0) { 7947db96d56Sopenharmony_ci bytesWrittenTotal += bytesWrittenMore; 7957db96d56Sopenharmony_ci if (bytesWrittenTotal >= count) 7967db96d56Sopenharmony_ci success = 1; 7977db96d56Sopenharmony_ci } 7987db96d56Sopenharmony_ci } while (! success && (errno == EINTR)); 7997db96d56Sopenharmony_ci 8007db96d56Sopenharmony_ci close(fd); 8017db96d56Sopenharmony_ci return success; 8027db96d56Sopenharmony_ci} 8037db96d56Sopenharmony_ci 8047db96d56Sopenharmony_ci# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ 8057db96d56Sopenharmony_ci 8067db96d56Sopenharmony_ci#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ 8077db96d56Sopenharmony_ci 8087db96d56Sopenharmony_ci#if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) 8097db96d56Sopenharmony_ci 8107db96d56Sopenharmony_cistatic void 8117db96d56Sopenharmony_ciwriteRandomBytes_arc4random(void *target, size_t count) { 8127db96d56Sopenharmony_ci size_t bytesWrittenTotal = 0; 8137db96d56Sopenharmony_ci 8147db96d56Sopenharmony_ci while (bytesWrittenTotal < count) { 8157db96d56Sopenharmony_ci const uint32_t random32 = arc4random(); 8167db96d56Sopenharmony_ci size_t i = 0; 8177db96d56Sopenharmony_ci 8187db96d56Sopenharmony_ci for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); 8197db96d56Sopenharmony_ci i++, bytesWrittenTotal++) { 8207db96d56Sopenharmony_ci const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); 8217db96d56Sopenharmony_ci ((uint8_t *)target)[bytesWrittenTotal] = random8; 8227db96d56Sopenharmony_ci } 8237db96d56Sopenharmony_ci } 8247db96d56Sopenharmony_ci} 8257db96d56Sopenharmony_ci 8267db96d56Sopenharmony_ci#endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */ 8277db96d56Sopenharmony_ci 8287db96d56Sopenharmony_ci#ifdef _WIN32 8297db96d56Sopenharmony_ci 8307db96d56Sopenharmony_ci/* Provide declaration of rand_s() for MinGW-32 (not 64, which has it), 8317db96d56Sopenharmony_ci as it didn't declare it in its header prior to version 5.3.0 of its 8327db96d56Sopenharmony_ci runtime package (mingwrt, containing stdlib.h). The upstream fix 8337db96d56Sopenharmony_ci was introduced at https://osdn.net/projects/mingw/ticket/39658 . */ 8347db96d56Sopenharmony_ci# if defined(__MINGW32__) && defined(__MINGW32_VERSION) \ 8357db96d56Sopenharmony_ci && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR) 8367db96d56Sopenharmony_ci__declspec(dllimport) int rand_s(unsigned int *); 8377db96d56Sopenharmony_ci# endif 8387db96d56Sopenharmony_ci 8397db96d56Sopenharmony_ci/* Obtain entropy on Windows using the rand_s() function which 8407db96d56Sopenharmony_ci * generates cryptographically secure random numbers. Internally it 8417db96d56Sopenharmony_ci * uses RtlGenRandom API which is present in Windows XP and later. 8427db96d56Sopenharmony_ci */ 8437db96d56Sopenharmony_cistatic int 8447db96d56Sopenharmony_ciwriteRandomBytes_rand_s(void *target, size_t count) { 8457db96d56Sopenharmony_ci size_t bytesWrittenTotal = 0; 8467db96d56Sopenharmony_ci 8477db96d56Sopenharmony_ci while (bytesWrittenTotal < count) { 8487db96d56Sopenharmony_ci unsigned int random32 = 0; 8497db96d56Sopenharmony_ci size_t i = 0; 8507db96d56Sopenharmony_ci 8517db96d56Sopenharmony_ci if (rand_s(&random32)) 8527db96d56Sopenharmony_ci return 0; /* failure */ 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_ci for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); 8557db96d56Sopenharmony_ci i++, bytesWrittenTotal++) { 8567db96d56Sopenharmony_ci const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); 8577db96d56Sopenharmony_ci ((uint8_t *)target)[bytesWrittenTotal] = random8; 8587db96d56Sopenharmony_ci } 8597db96d56Sopenharmony_ci } 8607db96d56Sopenharmony_ci return 1; /* success */ 8617db96d56Sopenharmony_ci} 8627db96d56Sopenharmony_ci 8637db96d56Sopenharmony_ci#endif /* _WIN32 */ 8647db96d56Sopenharmony_ci 8657db96d56Sopenharmony_ci#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) 8667db96d56Sopenharmony_ci 8677db96d56Sopenharmony_cistatic unsigned long 8687db96d56Sopenharmony_cigather_time_entropy(void) { 8697db96d56Sopenharmony_ci# ifdef _WIN32 8707db96d56Sopenharmony_ci FILETIME ft; 8717db96d56Sopenharmony_ci GetSystemTimeAsFileTime(&ft); /* never fails */ 8727db96d56Sopenharmony_ci return ft.dwHighDateTime ^ ft.dwLowDateTime; 8737db96d56Sopenharmony_ci# else 8747db96d56Sopenharmony_ci struct timeval tv; 8757db96d56Sopenharmony_ci int gettimeofday_res; 8767db96d56Sopenharmony_ci 8777db96d56Sopenharmony_ci gettimeofday_res = gettimeofday(&tv, NULL); 8787db96d56Sopenharmony_ci 8797db96d56Sopenharmony_ci# if defined(NDEBUG) 8807db96d56Sopenharmony_ci (void)gettimeofday_res; 8817db96d56Sopenharmony_ci# else 8827db96d56Sopenharmony_ci assert(gettimeofday_res == 0); 8837db96d56Sopenharmony_ci# endif /* defined(NDEBUG) */ 8847db96d56Sopenharmony_ci 8857db96d56Sopenharmony_ci /* Microseconds time is <20 bits entropy */ 8867db96d56Sopenharmony_ci return tv.tv_usec; 8877db96d56Sopenharmony_ci# endif 8887db96d56Sopenharmony_ci} 8897db96d56Sopenharmony_ci 8907db96d56Sopenharmony_ci#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ 8917db96d56Sopenharmony_ci 8927db96d56Sopenharmony_cistatic unsigned long 8937db96d56Sopenharmony_ciENTROPY_DEBUG(const char *label, unsigned long entropy) { 8947db96d56Sopenharmony_ci if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) { 8957db96d56Sopenharmony_ci fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, 8967db96d56Sopenharmony_ci (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy)); 8977db96d56Sopenharmony_ci } 8987db96d56Sopenharmony_ci return entropy; 8997db96d56Sopenharmony_ci} 9007db96d56Sopenharmony_ci 9017db96d56Sopenharmony_cistatic unsigned long 9027db96d56Sopenharmony_cigenerate_hash_secret_salt(XML_Parser parser) { 9037db96d56Sopenharmony_ci unsigned long entropy; 9047db96d56Sopenharmony_ci (void)parser; 9057db96d56Sopenharmony_ci 9067db96d56Sopenharmony_ci /* "Failproof" high quality providers: */ 9077db96d56Sopenharmony_ci#if defined(HAVE_ARC4RANDOM_BUF) 9087db96d56Sopenharmony_ci arc4random_buf(&entropy, sizeof(entropy)); 9097db96d56Sopenharmony_ci return ENTROPY_DEBUG("arc4random_buf", entropy); 9107db96d56Sopenharmony_ci#elif defined(HAVE_ARC4RANDOM) 9117db96d56Sopenharmony_ci writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy)); 9127db96d56Sopenharmony_ci return ENTROPY_DEBUG("arc4random", entropy); 9137db96d56Sopenharmony_ci#else 9147db96d56Sopenharmony_ci /* Try high quality providers first .. */ 9157db96d56Sopenharmony_ci# ifdef _WIN32 9167db96d56Sopenharmony_ci if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) { 9177db96d56Sopenharmony_ci return ENTROPY_DEBUG("rand_s", entropy); 9187db96d56Sopenharmony_ci } 9197db96d56Sopenharmony_ci# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 9207db96d56Sopenharmony_ci if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { 9217db96d56Sopenharmony_ci return ENTROPY_DEBUG("getrandom", entropy); 9227db96d56Sopenharmony_ci } 9237db96d56Sopenharmony_ci# endif 9247db96d56Sopenharmony_ci# if ! defined(_WIN32) && defined(XML_DEV_URANDOM) 9257db96d56Sopenharmony_ci if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { 9267db96d56Sopenharmony_ci return ENTROPY_DEBUG("/dev/urandom", entropy); 9277db96d56Sopenharmony_ci } 9287db96d56Sopenharmony_ci# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ 9297db96d56Sopenharmony_ci /* .. and self-made low quality for backup: */ 9307db96d56Sopenharmony_ci 9317db96d56Sopenharmony_ci /* Process ID is 0 bits entropy if attacker has local access */ 9327db96d56Sopenharmony_ci entropy = gather_time_entropy() ^ getpid(); 9337db96d56Sopenharmony_ci 9347db96d56Sopenharmony_ci /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ 9357db96d56Sopenharmony_ci if (sizeof(unsigned long) == 4) { 9367db96d56Sopenharmony_ci return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); 9377db96d56Sopenharmony_ci } else { 9387db96d56Sopenharmony_ci return ENTROPY_DEBUG("fallback(8)", 9397db96d56Sopenharmony_ci entropy * (unsigned long)2305843009213693951ULL); 9407db96d56Sopenharmony_ci } 9417db96d56Sopenharmony_ci#endif 9427db96d56Sopenharmony_ci} 9437db96d56Sopenharmony_ci 9447db96d56Sopenharmony_cistatic unsigned long 9457db96d56Sopenharmony_ciget_hash_secret_salt(XML_Parser parser) { 9467db96d56Sopenharmony_ci if (parser->m_parentParser != NULL) 9477db96d56Sopenharmony_ci return get_hash_secret_salt(parser->m_parentParser); 9487db96d56Sopenharmony_ci return parser->m_hash_secret_salt; 9497db96d56Sopenharmony_ci} 9507db96d56Sopenharmony_ci 9517db96d56Sopenharmony_cistatic XML_Bool /* only valid for root parser */ 9527db96d56Sopenharmony_cistartParsing(XML_Parser parser) { 9537db96d56Sopenharmony_ci /* hash functions must be initialized before setContext() is called */ 9547db96d56Sopenharmony_ci if (parser->m_hash_secret_salt == 0) 9557db96d56Sopenharmony_ci parser->m_hash_secret_salt = generate_hash_secret_salt(parser); 9567db96d56Sopenharmony_ci if (parser->m_ns) { 9577db96d56Sopenharmony_ci /* implicit context only set for root parser, since child 9587db96d56Sopenharmony_ci parsers (i.e. external entity parsers) will inherit it 9597db96d56Sopenharmony_ci */ 9607db96d56Sopenharmony_ci return setContext(parser, implicitContext); 9617db96d56Sopenharmony_ci } 9627db96d56Sopenharmony_ci return XML_TRUE; 9637db96d56Sopenharmony_ci} 9647db96d56Sopenharmony_ci 9657db96d56Sopenharmony_ciXML_Parser XMLCALL 9667db96d56Sopenharmony_ciXML_ParserCreate_MM(const XML_Char *encodingName, 9677db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *memsuite, 9687db96d56Sopenharmony_ci const XML_Char *nameSep) { 9697db96d56Sopenharmony_ci return parserCreate(encodingName, memsuite, nameSep, NULL); 9707db96d56Sopenharmony_ci} 9717db96d56Sopenharmony_ci 9727db96d56Sopenharmony_cistatic XML_Parser 9737db96d56Sopenharmony_ciparserCreate(const XML_Char *encodingName, 9747db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, 9757db96d56Sopenharmony_ci DTD *dtd) { 9767db96d56Sopenharmony_ci XML_Parser parser; 9777db96d56Sopenharmony_ci 9787db96d56Sopenharmony_ci if (memsuite) { 9797db96d56Sopenharmony_ci XML_Memory_Handling_Suite *mtemp; 9807db96d56Sopenharmony_ci parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); 9817db96d56Sopenharmony_ci if (parser != NULL) { 9827db96d56Sopenharmony_ci mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); 9837db96d56Sopenharmony_ci mtemp->malloc_fcn = memsuite->malloc_fcn; 9847db96d56Sopenharmony_ci mtemp->realloc_fcn = memsuite->realloc_fcn; 9857db96d56Sopenharmony_ci mtemp->free_fcn = memsuite->free_fcn; 9867db96d56Sopenharmony_ci } 9877db96d56Sopenharmony_ci } else { 9887db96d56Sopenharmony_ci XML_Memory_Handling_Suite *mtemp; 9897db96d56Sopenharmony_ci parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); 9907db96d56Sopenharmony_ci if (parser != NULL) { 9917db96d56Sopenharmony_ci mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); 9927db96d56Sopenharmony_ci mtemp->malloc_fcn = malloc; 9937db96d56Sopenharmony_ci mtemp->realloc_fcn = realloc; 9947db96d56Sopenharmony_ci mtemp->free_fcn = free; 9957db96d56Sopenharmony_ci } 9967db96d56Sopenharmony_ci } 9977db96d56Sopenharmony_ci 9987db96d56Sopenharmony_ci if (! parser) 9997db96d56Sopenharmony_ci return parser; 10007db96d56Sopenharmony_ci 10017db96d56Sopenharmony_ci parser->m_buffer = NULL; 10027db96d56Sopenharmony_ci parser->m_bufferLim = NULL; 10037db96d56Sopenharmony_ci 10047db96d56Sopenharmony_ci parser->m_attsSize = INIT_ATTS_SIZE; 10057db96d56Sopenharmony_ci parser->m_atts 10067db96d56Sopenharmony_ci = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); 10077db96d56Sopenharmony_ci if (parser->m_atts == NULL) { 10087db96d56Sopenharmony_ci FREE(parser, parser); 10097db96d56Sopenharmony_ci return NULL; 10107db96d56Sopenharmony_ci } 10117db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 10127db96d56Sopenharmony_ci parser->m_attInfo = (XML_AttrInfo *)MALLOC( 10137db96d56Sopenharmony_ci parser, parser->m_attsSize * sizeof(XML_AttrInfo)); 10147db96d56Sopenharmony_ci if (parser->m_attInfo == NULL) { 10157db96d56Sopenharmony_ci FREE(parser, parser->m_atts); 10167db96d56Sopenharmony_ci FREE(parser, parser); 10177db96d56Sopenharmony_ci return NULL; 10187db96d56Sopenharmony_ci } 10197db96d56Sopenharmony_ci#endif 10207db96d56Sopenharmony_ci parser->m_dataBuf 10217db96d56Sopenharmony_ci = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); 10227db96d56Sopenharmony_ci if (parser->m_dataBuf == NULL) { 10237db96d56Sopenharmony_ci FREE(parser, parser->m_atts); 10247db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 10257db96d56Sopenharmony_ci FREE(parser, parser->m_attInfo); 10267db96d56Sopenharmony_ci#endif 10277db96d56Sopenharmony_ci FREE(parser, parser); 10287db96d56Sopenharmony_ci return NULL; 10297db96d56Sopenharmony_ci } 10307db96d56Sopenharmony_ci parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; 10317db96d56Sopenharmony_ci 10327db96d56Sopenharmony_ci if (dtd) 10337db96d56Sopenharmony_ci parser->m_dtd = dtd; 10347db96d56Sopenharmony_ci else { 10357db96d56Sopenharmony_ci parser->m_dtd = dtdCreate(&parser->m_mem); 10367db96d56Sopenharmony_ci if (parser->m_dtd == NULL) { 10377db96d56Sopenharmony_ci FREE(parser, parser->m_dataBuf); 10387db96d56Sopenharmony_ci FREE(parser, parser->m_atts); 10397db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 10407db96d56Sopenharmony_ci FREE(parser, parser->m_attInfo); 10417db96d56Sopenharmony_ci#endif 10427db96d56Sopenharmony_ci FREE(parser, parser); 10437db96d56Sopenharmony_ci return NULL; 10447db96d56Sopenharmony_ci } 10457db96d56Sopenharmony_ci } 10467db96d56Sopenharmony_ci 10477db96d56Sopenharmony_ci parser->m_freeBindingList = NULL; 10487db96d56Sopenharmony_ci parser->m_freeTagList = NULL; 10497db96d56Sopenharmony_ci parser->m_freeInternalEntities = NULL; 10507db96d56Sopenharmony_ci 10517db96d56Sopenharmony_ci parser->m_groupSize = 0; 10527db96d56Sopenharmony_ci parser->m_groupConnector = NULL; 10537db96d56Sopenharmony_ci 10547db96d56Sopenharmony_ci parser->m_unknownEncodingHandler = NULL; 10557db96d56Sopenharmony_ci parser->m_unknownEncodingHandlerData = NULL; 10567db96d56Sopenharmony_ci 10577db96d56Sopenharmony_ci parser->m_namespaceSeparator = ASCII_EXCL; 10587db96d56Sopenharmony_ci parser->m_ns = XML_FALSE; 10597db96d56Sopenharmony_ci parser->m_ns_triplets = XML_FALSE; 10607db96d56Sopenharmony_ci 10617db96d56Sopenharmony_ci parser->m_nsAtts = NULL; 10627db96d56Sopenharmony_ci parser->m_nsAttsVersion = 0; 10637db96d56Sopenharmony_ci parser->m_nsAttsPower = 0; 10647db96d56Sopenharmony_ci 10657db96d56Sopenharmony_ci parser->m_protocolEncodingName = NULL; 10667db96d56Sopenharmony_ci 10677db96d56Sopenharmony_ci poolInit(&parser->m_tempPool, &(parser->m_mem)); 10687db96d56Sopenharmony_ci poolInit(&parser->m_temp2Pool, &(parser->m_mem)); 10697db96d56Sopenharmony_ci parserInit(parser, encodingName); 10707db96d56Sopenharmony_ci 10717db96d56Sopenharmony_ci if (encodingName && ! parser->m_protocolEncodingName) { 10727db96d56Sopenharmony_ci if (dtd) { 10737db96d56Sopenharmony_ci // We need to stop the upcoming call to XML_ParserFree from happily 10747db96d56Sopenharmony_ci // destroying parser->m_dtd because the DTD is shared with the parent 10757db96d56Sopenharmony_ci // parser and the only guard that keeps XML_ParserFree from destroying 10767db96d56Sopenharmony_ci // parser->m_dtd is parser->m_isParamEntity but it will be set to 10777db96d56Sopenharmony_ci // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all). 10787db96d56Sopenharmony_ci parser->m_dtd = NULL; 10797db96d56Sopenharmony_ci } 10807db96d56Sopenharmony_ci XML_ParserFree(parser); 10817db96d56Sopenharmony_ci return NULL; 10827db96d56Sopenharmony_ci } 10837db96d56Sopenharmony_ci 10847db96d56Sopenharmony_ci if (nameSep) { 10857db96d56Sopenharmony_ci parser->m_ns = XML_TRUE; 10867db96d56Sopenharmony_ci parser->m_internalEncoding = XmlGetInternalEncodingNS(); 10877db96d56Sopenharmony_ci parser->m_namespaceSeparator = *nameSep; 10887db96d56Sopenharmony_ci } else { 10897db96d56Sopenharmony_ci parser->m_internalEncoding = XmlGetInternalEncoding(); 10907db96d56Sopenharmony_ci } 10917db96d56Sopenharmony_ci 10927db96d56Sopenharmony_ci return parser; 10937db96d56Sopenharmony_ci} 10947db96d56Sopenharmony_ci 10957db96d56Sopenharmony_cistatic void 10967db96d56Sopenharmony_ciparserInit(XML_Parser parser, const XML_Char *encodingName) { 10977db96d56Sopenharmony_ci parser->m_processor = prologInitProcessor; 10987db96d56Sopenharmony_ci XmlPrologStateInit(&parser->m_prologState); 10997db96d56Sopenharmony_ci if (encodingName != NULL) { 11007db96d56Sopenharmony_ci parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); 11017db96d56Sopenharmony_ci } 11027db96d56Sopenharmony_ci parser->m_curBase = NULL; 11037db96d56Sopenharmony_ci XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0); 11047db96d56Sopenharmony_ci parser->m_userData = NULL; 11057db96d56Sopenharmony_ci parser->m_handlerArg = NULL; 11067db96d56Sopenharmony_ci parser->m_startElementHandler = NULL; 11077db96d56Sopenharmony_ci parser->m_endElementHandler = NULL; 11087db96d56Sopenharmony_ci parser->m_characterDataHandler = NULL; 11097db96d56Sopenharmony_ci parser->m_processingInstructionHandler = NULL; 11107db96d56Sopenharmony_ci parser->m_commentHandler = NULL; 11117db96d56Sopenharmony_ci parser->m_startCdataSectionHandler = NULL; 11127db96d56Sopenharmony_ci parser->m_endCdataSectionHandler = NULL; 11137db96d56Sopenharmony_ci parser->m_defaultHandler = NULL; 11147db96d56Sopenharmony_ci parser->m_startDoctypeDeclHandler = NULL; 11157db96d56Sopenharmony_ci parser->m_endDoctypeDeclHandler = NULL; 11167db96d56Sopenharmony_ci parser->m_unparsedEntityDeclHandler = NULL; 11177db96d56Sopenharmony_ci parser->m_notationDeclHandler = NULL; 11187db96d56Sopenharmony_ci parser->m_startNamespaceDeclHandler = NULL; 11197db96d56Sopenharmony_ci parser->m_endNamespaceDeclHandler = NULL; 11207db96d56Sopenharmony_ci parser->m_notStandaloneHandler = NULL; 11217db96d56Sopenharmony_ci parser->m_externalEntityRefHandler = NULL; 11227db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg = parser; 11237db96d56Sopenharmony_ci parser->m_skippedEntityHandler = NULL; 11247db96d56Sopenharmony_ci parser->m_elementDeclHandler = NULL; 11257db96d56Sopenharmony_ci parser->m_attlistDeclHandler = NULL; 11267db96d56Sopenharmony_ci parser->m_entityDeclHandler = NULL; 11277db96d56Sopenharmony_ci parser->m_xmlDeclHandler = NULL; 11287db96d56Sopenharmony_ci parser->m_bufferPtr = parser->m_buffer; 11297db96d56Sopenharmony_ci parser->m_bufferEnd = parser->m_buffer; 11307db96d56Sopenharmony_ci parser->m_parseEndByteIndex = 0; 11317db96d56Sopenharmony_ci parser->m_parseEndPtr = NULL; 11327db96d56Sopenharmony_ci parser->m_declElementType = NULL; 11337db96d56Sopenharmony_ci parser->m_declAttributeId = NULL; 11347db96d56Sopenharmony_ci parser->m_declEntity = NULL; 11357db96d56Sopenharmony_ci parser->m_doctypeName = NULL; 11367db96d56Sopenharmony_ci parser->m_doctypeSysid = NULL; 11377db96d56Sopenharmony_ci parser->m_doctypePubid = NULL; 11387db96d56Sopenharmony_ci parser->m_declAttributeType = NULL; 11397db96d56Sopenharmony_ci parser->m_declNotationName = NULL; 11407db96d56Sopenharmony_ci parser->m_declNotationPublicId = NULL; 11417db96d56Sopenharmony_ci parser->m_declAttributeIsCdata = XML_FALSE; 11427db96d56Sopenharmony_ci parser->m_declAttributeIsId = XML_FALSE; 11437db96d56Sopenharmony_ci memset(&parser->m_position, 0, sizeof(POSITION)); 11447db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NONE; 11457db96d56Sopenharmony_ci parser->m_eventPtr = NULL; 11467db96d56Sopenharmony_ci parser->m_eventEndPtr = NULL; 11477db96d56Sopenharmony_ci parser->m_positionPtr = NULL; 11487db96d56Sopenharmony_ci parser->m_openInternalEntities = NULL; 11497db96d56Sopenharmony_ci parser->m_defaultExpandInternalEntities = XML_TRUE; 11507db96d56Sopenharmony_ci parser->m_tagLevel = 0; 11517db96d56Sopenharmony_ci parser->m_tagStack = NULL; 11527db96d56Sopenharmony_ci parser->m_inheritedBindings = NULL; 11537db96d56Sopenharmony_ci parser->m_nSpecifiedAtts = 0; 11547db96d56Sopenharmony_ci parser->m_unknownEncodingMem = NULL; 11557db96d56Sopenharmony_ci parser->m_unknownEncodingRelease = NULL; 11567db96d56Sopenharmony_ci parser->m_unknownEncodingData = NULL; 11577db96d56Sopenharmony_ci parser->m_parentParser = NULL; 11587db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_INITIALIZED; 11597db96d56Sopenharmony_ci#ifdef XML_DTD 11607db96d56Sopenharmony_ci parser->m_isParamEntity = XML_FALSE; 11617db96d56Sopenharmony_ci parser->m_useForeignDTD = XML_FALSE; 11627db96d56Sopenharmony_ci parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 11637db96d56Sopenharmony_ci#endif 11647db96d56Sopenharmony_ci parser->m_hash_secret_salt = 0; 11657db96d56Sopenharmony_ci 11667db96d56Sopenharmony_ci#ifdef XML_DTD 11677db96d56Sopenharmony_ci memset(&parser->m_accounting, 0, sizeof(ACCOUNTING)); 11687db96d56Sopenharmony_ci parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u); 11697db96d56Sopenharmony_ci parser->m_accounting.maximumAmplificationFactor 11707db96d56Sopenharmony_ci = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT; 11717db96d56Sopenharmony_ci parser->m_accounting.activationThresholdBytes 11727db96d56Sopenharmony_ci = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT; 11737db96d56Sopenharmony_ci 11747db96d56Sopenharmony_ci memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS)); 11757db96d56Sopenharmony_ci parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u); 11767db96d56Sopenharmony_ci#endif 11777db96d56Sopenharmony_ci} 11787db96d56Sopenharmony_ci 11797db96d56Sopenharmony_ci/* moves list of bindings to m_freeBindingList */ 11807db96d56Sopenharmony_cistatic void FASTCALL 11817db96d56Sopenharmony_cimoveToFreeBindingList(XML_Parser parser, BINDING *bindings) { 11827db96d56Sopenharmony_ci while (bindings) { 11837db96d56Sopenharmony_ci BINDING *b = bindings; 11847db96d56Sopenharmony_ci bindings = bindings->nextTagBinding; 11857db96d56Sopenharmony_ci b->nextTagBinding = parser->m_freeBindingList; 11867db96d56Sopenharmony_ci parser->m_freeBindingList = b; 11877db96d56Sopenharmony_ci } 11887db96d56Sopenharmony_ci} 11897db96d56Sopenharmony_ci 11907db96d56Sopenharmony_ciXML_Bool XMLCALL 11917db96d56Sopenharmony_ciXML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { 11927db96d56Sopenharmony_ci TAG *tStk; 11937db96d56Sopenharmony_ci OPEN_INTERNAL_ENTITY *openEntityList; 11947db96d56Sopenharmony_ci 11957db96d56Sopenharmony_ci if (parser == NULL) 11967db96d56Sopenharmony_ci return XML_FALSE; 11977db96d56Sopenharmony_ci 11987db96d56Sopenharmony_ci if (parser->m_parentParser) 11997db96d56Sopenharmony_ci return XML_FALSE; 12007db96d56Sopenharmony_ci /* move m_tagStack to m_freeTagList */ 12017db96d56Sopenharmony_ci tStk = parser->m_tagStack; 12027db96d56Sopenharmony_ci while (tStk) { 12037db96d56Sopenharmony_ci TAG *tag = tStk; 12047db96d56Sopenharmony_ci tStk = tStk->parent; 12057db96d56Sopenharmony_ci tag->parent = parser->m_freeTagList; 12067db96d56Sopenharmony_ci moveToFreeBindingList(parser, tag->bindings); 12077db96d56Sopenharmony_ci tag->bindings = NULL; 12087db96d56Sopenharmony_ci parser->m_freeTagList = tag; 12097db96d56Sopenharmony_ci } 12107db96d56Sopenharmony_ci /* move m_openInternalEntities to m_freeInternalEntities */ 12117db96d56Sopenharmony_ci openEntityList = parser->m_openInternalEntities; 12127db96d56Sopenharmony_ci while (openEntityList) { 12137db96d56Sopenharmony_ci OPEN_INTERNAL_ENTITY *openEntity = openEntityList; 12147db96d56Sopenharmony_ci openEntityList = openEntity->next; 12157db96d56Sopenharmony_ci openEntity->next = parser->m_freeInternalEntities; 12167db96d56Sopenharmony_ci parser->m_freeInternalEntities = openEntity; 12177db96d56Sopenharmony_ci } 12187db96d56Sopenharmony_ci moveToFreeBindingList(parser, parser->m_inheritedBindings); 12197db96d56Sopenharmony_ci FREE(parser, parser->m_unknownEncodingMem); 12207db96d56Sopenharmony_ci if (parser->m_unknownEncodingRelease) 12217db96d56Sopenharmony_ci parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); 12227db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 12237db96d56Sopenharmony_ci poolClear(&parser->m_temp2Pool); 12247db96d56Sopenharmony_ci FREE(parser, (void *)parser->m_protocolEncodingName); 12257db96d56Sopenharmony_ci parser->m_protocolEncodingName = NULL; 12267db96d56Sopenharmony_ci parserInit(parser, encodingName); 12277db96d56Sopenharmony_ci dtdReset(parser->m_dtd, &parser->m_mem); 12287db96d56Sopenharmony_ci return XML_TRUE; 12297db96d56Sopenharmony_ci} 12307db96d56Sopenharmony_ci 12317db96d56Sopenharmony_cienum XML_Status XMLCALL 12327db96d56Sopenharmony_ciXML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { 12337db96d56Sopenharmony_ci if (parser == NULL) 12347db96d56Sopenharmony_ci return XML_STATUS_ERROR; 12357db96d56Sopenharmony_ci /* Block after XML_Parse()/XML_ParseBuffer() has been called. 12367db96d56Sopenharmony_ci XXX There's no way for the caller to determine which of the 12377db96d56Sopenharmony_ci XXX possible error cases caused the XML_STATUS_ERROR return. 12387db96d56Sopenharmony_ci */ 12397db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_PARSING 12407db96d56Sopenharmony_ci || parser->m_parsingStatus.parsing == XML_SUSPENDED) 12417db96d56Sopenharmony_ci return XML_STATUS_ERROR; 12427db96d56Sopenharmony_ci 12437db96d56Sopenharmony_ci /* Get rid of any previous encoding name */ 12447db96d56Sopenharmony_ci FREE(parser, (void *)parser->m_protocolEncodingName); 12457db96d56Sopenharmony_ci 12467db96d56Sopenharmony_ci if (encodingName == NULL) 12477db96d56Sopenharmony_ci /* No new encoding name */ 12487db96d56Sopenharmony_ci parser->m_protocolEncodingName = NULL; 12497db96d56Sopenharmony_ci else { 12507db96d56Sopenharmony_ci /* Copy the new encoding name into allocated memory */ 12517db96d56Sopenharmony_ci parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); 12527db96d56Sopenharmony_ci if (! parser->m_protocolEncodingName) 12537db96d56Sopenharmony_ci return XML_STATUS_ERROR; 12547db96d56Sopenharmony_ci } 12557db96d56Sopenharmony_ci return XML_STATUS_OK; 12567db96d56Sopenharmony_ci} 12577db96d56Sopenharmony_ci 12587db96d56Sopenharmony_ciXML_Parser XMLCALL 12597db96d56Sopenharmony_ciXML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, 12607db96d56Sopenharmony_ci const XML_Char *encodingName) { 12617db96d56Sopenharmony_ci XML_Parser parser = oldParser; 12627db96d56Sopenharmony_ci DTD *newDtd = NULL; 12637db96d56Sopenharmony_ci DTD *oldDtd; 12647db96d56Sopenharmony_ci XML_StartElementHandler oldStartElementHandler; 12657db96d56Sopenharmony_ci XML_EndElementHandler oldEndElementHandler; 12667db96d56Sopenharmony_ci XML_CharacterDataHandler oldCharacterDataHandler; 12677db96d56Sopenharmony_ci XML_ProcessingInstructionHandler oldProcessingInstructionHandler; 12687db96d56Sopenharmony_ci XML_CommentHandler oldCommentHandler; 12697db96d56Sopenharmony_ci XML_StartCdataSectionHandler oldStartCdataSectionHandler; 12707db96d56Sopenharmony_ci XML_EndCdataSectionHandler oldEndCdataSectionHandler; 12717db96d56Sopenharmony_ci XML_DefaultHandler oldDefaultHandler; 12727db96d56Sopenharmony_ci XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; 12737db96d56Sopenharmony_ci XML_NotationDeclHandler oldNotationDeclHandler; 12747db96d56Sopenharmony_ci XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; 12757db96d56Sopenharmony_ci XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; 12767db96d56Sopenharmony_ci XML_NotStandaloneHandler oldNotStandaloneHandler; 12777db96d56Sopenharmony_ci XML_ExternalEntityRefHandler oldExternalEntityRefHandler; 12787db96d56Sopenharmony_ci XML_SkippedEntityHandler oldSkippedEntityHandler; 12797db96d56Sopenharmony_ci XML_UnknownEncodingHandler oldUnknownEncodingHandler; 12807db96d56Sopenharmony_ci XML_ElementDeclHandler oldElementDeclHandler; 12817db96d56Sopenharmony_ci XML_AttlistDeclHandler oldAttlistDeclHandler; 12827db96d56Sopenharmony_ci XML_EntityDeclHandler oldEntityDeclHandler; 12837db96d56Sopenharmony_ci XML_XmlDeclHandler oldXmlDeclHandler; 12847db96d56Sopenharmony_ci ELEMENT_TYPE *oldDeclElementType; 12857db96d56Sopenharmony_ci 12867db96d56Sopenharmony_ci void *oldUserData; 12877db96d56Sopenharmony_ci void *oldHandlerArg; 12887db96d56Sopenharmony_ci XML_Bool oldDefaultExpandInternalEntities; 12897db96d56Sopenharmony_ci XML_Parser oldExternalEntityRefHandlerArg; 12907db96d56Sopenharmony_ci#ifdef XML_DTD 12917db96d56Sopenharmony_ci enum XML_ParamEntityParsing oldParamEntityParsing; 12927db96d56Sopenharmony_ci int oldInEntityValue; 12937db96d56Sopenharmony_ci#endif 12947db96d56Sopenharmony_ci XML_Bool oldns_triplets; 12957db96d56Sopenharmony_ci /* Note that the new parser shares the same hash secret as the old 12967db96d56Sopenharmony_ci parser, so that dtdCopy and copyEntityTable can lookup values 12977db96d56Sopenharmony_ci from hash tables associated with either parser without us having 12987db96d56Sopenharmony_ci to worry which hash secrets each table has. 12997db96d56Sopenharmony_ci */ 13007db96d56Sopenharmony_ci unsigned long oldhash_secret_salt; 13017db96d56Sopenharmony_ci 13027db96d56Sopenharmony_ci /* Validate the oldParser parameter before we pull everything out of it */ 13037db96d56Sopenharmony_ci if (oldParser == NULL) 13047db96d56Sopenharmony_ci return NULL; 13057db96d56Sopenharmony_ci 13067db96d56Sopenharmony_ci /* Stash the original parser contents on the stack */ 13077db96d56Sopenharmony_ci oldDtd = parser->m_dtd; 13087db96d56Sopenharmony_ci oldStartElementHandler = parser->m_startElementHandler; 13097db96d56Sopenharmony_ci oldEndElementHandler = parser->m_endElementHandler; 13107db96d56Sopenharmony_ci oldCharacterDataHandler = parser->m_characterDataHandler; 13117db96d56Sopenharmony_ci oldProcessingInstructionHandler = parser->m_processingInstructionHandler; 13127db96d56Sopenharmony_ci oldCommentHandler = parser->m_commentHandler; 13137db96d56Sopenharmony_ci oldStartCdataSectionHandler = parser->m_startCdataSectionHandler; 13147db96d56Sopenharmony_ci oldEndCdataSectionHandler = parser->m_endCdataSectionHandler; 13157db96d56Sopenharmony_ci oldDefaultHandler = parser->m_defaultHandler; 13167db96d56Sopenharmony_ci oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler; 13177db96d56Sopenharmony_ci oldNotationDeclHandler = parser->m_notationDeclHandler; 13187db96d56Sopenharmony_ci oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler; 13197db96d56Sopenharmony_ci oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler; 13207db96d56Sopenharmony_ci oldNotStandaloneHandler = parser->m_notStandaloneHandler; 13217db96d56Sopenharmony_ci oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; 13227db96d56Sopenharmony_ci oldSkippedEntityHandler = parser->m_skippedEntityHandler; 13237db96d56Sopenharmony_ci oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; 13247db96d56Sopenharmony_ci oldElementDeclHandler = parser->m_elementDeclHandler; 13257db96d56Sopenharmony_ci oldAttlistDeclHandler = parser->m_attlistDeclHandler; 13267db96d56Sopenharmony_ci oldEntityDeclHandler = parser->m_entityDeclHandler; 13277db96d56Sopenharmony_ci oldXmlDeclHandler = parser->m_xmlDeclHandler; 13287db96d56Sopenharmony_ci oldDeclElementType = parser->m_declElementType; 13297db96d56Sopenharmony_ci 13307db96d56Sopenharmony_ci oldUserData = parser->m_userData; 13317db96d56Sopenharmony_ci oldHandlerArg = parser->m_handlerArg; 13327db96d56Sopenharmony_ci oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities; 13337db96d56Sopenharmony_ci oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg; 13347db96d56Sopenharmony_ci#ifdef XML_DTD 13357db96d56Sopenharmony_ci oldParamEntityParsing = parser->m_paramEntityParsing; 13367db96d56Sopenharmony_ci oldInEntityValue = parser->m_prologState.inEntityValue; 13377db96d56Sopenharmony_ci#endif 13387db96d56Sopenharmony_ci oldns_triplets = parser->m_ns_triplets; 13397db96d56Sopenharmony_ci /* Note that the new parser shares the same hash secret as the old 13407db96d56Sopenharmony_ci parser, so that dtdCopy and copyEntityTable can lookup values 13417db96d56Sopenharmony_ci from hash tables associated with either parser without us having 13427db96d56Sopenharmony_ci to worry which hash secrets each table has. 13437db96d56Sopenharmony_ci */ 13447db96d56Sopenharmony_ci oldhash_secret_salt = parser->m_hash_secret_salt; 13457db96d56Sopenharmony_ci 13467db96d56Sopenharmony_ci#ifdef XML_DTD 13477db96d56Sopenharmony_ci if (! context) 13487db96d56Sopenharmony_ci newDtd = oldDtd; 13497db96d56Sopenharmony_ci#endif /* XML_DTD */ 13507db96d56Sopenharmony_ci 13517db96d56Sopenharmony_ci /* Note that the magical uses of the pre-processor to make field 13527db96d56Sopenharmony_ci access look more like C++ require that `parser' be overwritten 13537db96d56Sopenharmony_ci here. This makes this function more painful to follow than it 13547db96d56Sopenharmony_ci would be otherwise. 13557db96d56Sopenharmony_ci */ 13567db96d56Sopenharmony_ci if (parser->m_ns) { 13577db96d56Sopenharmony_ci XML_Char tmp[2] = {parser->m_namespaceSeparator, 0}; 13587db96d56Sopenharmony_ci parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); 13597db96d56Sopenharmony_ci } else { 13607db96d56Sopenharmony_ci parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); 13617db96d56Sopenharmony_ci } 13627db96d56Sopenharmony_ci 13637db96d56Sopenharmony_ci if (! parser) 13647db96d56Sopenharmony_ci return NULL; 13657db96d56Sopenharmony_ci 13667db96d56Sopenharmony_ci parser->m_startElementHandler = oldStartElementHandler; 13677db96d56Sopenharmony_ci parser->m_endElementHandler = oldEndElementHandler; 13687db96d56Sopenharmony_ci parser->m_characterDataHandler = oldCharacterDataHandler; 13697db96d56Sopenharmony_ci parser->m_processingInstructionHandler = oldProcessingInstructionHandler; 13707db96d56Sopenharmony_ci parser->m_commentHandler = oldCommentHandler; 13717db96d56Sopenharmony_ci parser->m_startCdataSectionHandler = oldStartCdataSectionHandler; 13727db96d56Sopenharmony_ci parser->m_endCdataSectionHandler = oldEndCdataSectionHandler; 13737db96d56Sopenharmony_ci parser->m_defaultHandler = oldDefaultHandler; 13747db96d56Sopenharmony_ci parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; 13757db96d56Sopenharmony_ci parser->m_notationDeclHandler = oldNotationDeclHandler; 13767db96d56Sopenharmony_ci parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler; 13777db96d56Sopenharmony_ci parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler; 13787db96d56Sopenharmony_ci parser->m_notStandaloneHandler = oldNotStandaloneHandler; 13797db96d56Sopenharmony_ci parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; 13807db96d56Sopenharmony_ci parser->m_skippedEntityHandler = oldSkippedEntityHandler; 13817db96d56Sopenharmony_ci parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; 13827db96d56Sopenharmony_ci parser->m_elementDeclHandler = oldElementDeclHandler; 13837db96d56Sopenharmony_ci parser->m_attlistDeclHandler = oldAttlistDeclHandler; 13847db96d56Sopenharmony_ci parser->m_entityDeclHandler = oldEntityDeclHandler; 13857db96d56Sopenharmony_ci parser->m_xmlDeclHandler = oldXmlDeclHandler; 13867db96d56Sopenharmony_ci parser->m_declElementType = oldDeclElementType; 13877db96d56Sopenharmony_ci parser->m_userData = oldUserData; 13887db96d56Sopenharmony_ci if (oldUserData == oldHandlerArg) 13897db96d56Sopenharmony_ci parser->m_handlerArg = parser->m_userData; 13907db96d56Sopenharmony_ci else 13917db96d56Sopenharmony_ci parser->m_handlerArg = parser; 13927db96d56Sopenharmony_ci if (oldExternalEntityRefHandlerArg != oldParser) 13937db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; 13947db96d56Sopenharmony_ci parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; 13957db96d56Sopenharmony_ci parser->m_ns_triplets = oldns_triplets; 13967db96d56Sopenharmony_ci parser->m_hash_secret_salt = oldhash_secret_salt; 13977db96d56Sopenharmony_ci parser->m_parentParser = oldParser; 13987db96d56Sopenharmony_ci#ifdef XML_DTD 13997db96d56Sopenharmony_ci parser->m_paramEntityParsing = oldParamEntityParsing; 14007db96d56Sopenharmony_ci parser->m_prologState.inEntityValue = oldInEntityValue; 14017db96d56Sopenharmony_ci if (context) { 14027db96d56Sopenharmony_ci#endif /* XML_DTD */ 14037db96d56Sopenharmony_ci if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) 14047db96d56Sopenharmony_ci || ! setContext(parser, context)) { 14057db96d56Sopenharmony_ci XML_ParserFree(parser); 14067db96d56Sopenharmony_ci return NULL; 14077db96d56Sopenharmony_ci } 14087db96d56Sopenharmony_ci parser->m_processor = externalEntityInitProcessor; 14097db96d56Sopenharmony_ci#ifdef XML_DTD 14107db96d56Sopenharmony_ci } else { 14117db96d56Sopenharmony_ci /* The DTD instance referenced by parser->m_dtd is shared between the 14127db96d56Sopenharmony_ci document's root parser and external PE parsers, therefore one does not 14137db96d56Sopenharmony_ci need to call setContext. In addition, one also *must* not call 14147db96d56Sopenharmony_ci setContext, because this would overwrite existing prefix->binding 14157db96d56Sopenharmony_ci pointers in parser->m_dtd with ones that get destroyed with the external 14167db96d56Sopenharmony_ci PE parser. This would leave those prefixes with dangling pointers. 14177db96d56Sopenharmony_ci */ 14187db96d56Sopenharmony_ci parser->m_isParamEntity = XML_TRUE; 14197db96d56Sopenharmony_ci XmlPrologStateInitExternalEntity(&parser->m_prologState); 14207db96d56Sopenharmony_ci parser->m_processor = externalParEntInitProcessor; 14217db96d56Sopenharmony_ci } 14227db96d56Sopenharmony_ci#endif /* XML_DTD */ 14237db96d56Sopenharmony_ci return parser; 14247db96d56Sopenharmony_ci} 14257db96d56Sopenharmony_ci 14267db96d56Sopenharmony_cistatic void FASTCALL 14277db96d56Sopenharmony_cidestroyBindings(BINDING *bindings, XML_Parser parser) { 14287db96d56Sopenharmony_ci for (;;) { 14297db96d56Sopenharmony_ci BINDING *b = bindings; 14307db96d56Sopenharmony_ci if (! b) 14317db96d56Sopenharmony_ci break; 14327db96d56Sopenharmony_ci bindings = b->nextTagBinding; 14337db96d56Sopenharmony_ci FREE(parser, b->uri); 14347db96d56Sopenharmony_ci FREE(parser, b); 14357db96d56Sopenharmony_ci } 14367db96d56Sopenharmony_ci} 14377db96d56Sopenharmony_ci 14387db96d56Sopenharmony_civoid XMLCALL 14397db96d56Sopenharmony_ciXML_ParserFree(XML_Parser parser) { 14407db96d56Sopenharmony_ci TAG *tagList; 14417db96d56Sopenharmony_ci OPEN_INTERNAL_ENTITY *entityList; 14427db96d56Sopenharmony_ci if (parser == NULL) 14437db96d56Sopenharmony_ci return; 14447db96d56Sopenharmony_ci /* free m_tagStack and m_freeTagList */ 14457db96d56Sopenharmony_ci tagList = parser->m_tagStack; 14467db96d56Sopenharmony_ci for (;;) { 14477db96d56Sopenharmony_ci TAG *p; 14487db96d56Sopenharmony_ci if (tagList == NULL) { 14497db96d56Sopenharmony_ci if (parser->m_freeTagList == NULL) 14507db96d56Sopenharmony_ci break; 14517db96d56Sopenharmony_ci tagList = parser->m_freeTagList; 14527db96d56Sopenharmony_ci parser->m_freeTagList = NULL; 14537db96d56Sopenharmony_ci } 14547db96d56Sopenharmony_ci p = tagList; 14557db96d56Sopenharmony_ci tagList = tagList->parent; 14567db96d56Sopenharmony_ci FREE(parser, p->buf); 14577db96d56Sopenharmony_ci destroyBindings(p->bindings, parser); 14587db96d56Sopenharmony_ci FREE(parser, p); 14597db96d56Sopenharmony_ci } 14607db96d56Sopenharmony_ci /* free m_openInternalEntities and m_freeInternalEntities */ 14617db96d56Sopenharmony_ci entityList = parser->m_openInternalEntities; 14627db96d56Sopenharmony_ci for (;;) { 14637db96d56Sopenharmony_ci OPEN_INTERNAL_ENTITY *openEntity; 14647db96d56Sopenharmony_ci if (entityList == NULL) { 14657db96d56Sopenharmony_ci if (parser->m_freeInternalEntities == NULL) 14667db96d56Sopenharmony_ci break; 14677db96d56Sopenharmony_ci entityList = parser->m_freeInternalEntities; 14687db96d56Sopenharmony_ci parser->m_freeInternalEntities = NULL; 14697db96d56Sopenharmony_ci } 14707db96d56Sopenharmony_ci openEntity = entityList; 14717db96d56Sopenharmony_ci entityList = entityList->next; 14727db96d56Sopenharmony_ci FREE(parser, openEntity); 14737db96d56Sopenharmony_ci } 14747db96d56Sopenharmony_ci 14757db96d56Sopenharmony_ci destroyBindings(parser->m_freeBindingList, parser); 14767db96d56Sopenharmony_ci destroyBindings(parser->m_inheritedBindings, parser); 14777db96d56Sopenharmony_ci poolDestroy(&parser->m_tempPool); 14787db96d56Sopenharmony_ci poolDestroy(&parser->m_temp2Pool); 14797db96d56Sopenharmony_ci FREE(parser, (void *)parser->m_protocolEncodingName); 14807db96d56Sopenharmony_ci#ifdef XML_DTD 14817db96d56Sopenharmony_ci /* external parameter entity parsers share the DTD structure 14827db96d56Sopenharmony_ci parser->m_dtd with the root parser, so we must not destroy it 14837db96d56Sopenharmony_ci */ 14847db96d56Sopenharmony_ci if (! parser->m_isParamEntity && parser->m_dtd) 14857db96d56Sopenharmony_ci#else 14867db96d56Sopenharmony_ci if (parser->m_dtd) 14877db96d56Sopenharmony_ci#endif /* XML_DTD */ 14887db96d56Sopenharmony_ci dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, 14897db96d56Sopenharmony_ci &parser->m_mem); 14907db96d56Sopenharmony_ci FREE(parser, (void *)parser->m_atts); 14917db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 14927db96d56Sopenharmony_ci FREE(parser, (void *)parser->m_attInfo); 14937db96d56Sopenharmony_ci#endif 14947db96d56Sopenharmony_ci FREE(parser, parser->m_groupConnector); 14957db96d56Sopenharmony_ci FREE(parser, parser->m_buffer); 14967db96d56Sopenharmony_ci FREE(parser, parser->m_dataBuf); 14977db96d56Sopenharmony_ci FREE(parser, parser->m_nsAtts); 14987db96d56Sopenharmony_ci FREE(parser, parser->m_unknownEncodingMem); 14997db96d56Sopenharmony_ci if (parser->m_unknownEncodingRelease) 15007db96d56Sopenharmony_ci parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); 15017db96d56Sopenharmony_ci FREE(parser, parser); 15027db96d56Sopenharmony_ci} 15037db96d56Sopenharmony_ci 15047db96d56Sopenharmony_civoid XMLCALL 15057db96d56Sopenharmony_ciXML_UseParserAsHandlerArg(XML_Parser parser) { 15067db96d56Sopenharmony_ci if (parser != NULL) 15077db96d56Sopenharmony_ci parser->m_handlerArg = parser; 15087db96d56Sopenharmony_ci} 15097db96d56Sopenharmony_ci 15107db96d56Sopenharmony_cienum XML_Error XMLCALL 15117db96d56Sopenharmony_ciXML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { 15127db96d56Sopenharmony_ci if (parser == NULL) 15137db96d56Sopenharmony_ci return XML_ERROR_INVALID_ARGUMENT; 15147db96d56Sopenharmony_ci#ifdef XML_DTD 15157db96d56Sopenharmony_ci /* block after XML_Parse()/XML_ParseBuffer() has been called */ 15167db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_PARSING 15177db96d56Sopenharmony_ci || parser->m_parsingStatus.parsing == XML_SUSPENDED) 15187db96d56Sopenharmony_ci return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; 15197db96d56Sopenharmony_ci parser->m_useForeignDTD = useDTD; 15207db96d56Sopenharmony_ci return XML_ERROR_NONE; 15217db96d56Sopenharmony_ci#else 15227db96d56Sopenharmony_ci UNUSED_P(useDTD); 15237db96d56Sopenharmony_ci return XML_ERROR_FEATURE_REQUIRES_XML_DTD; 15247db96d56Sopenharmony_ci#endif 15257db96d56Sopenharmony_ci} 15267db96d56Sopenharmony_ci 15277db96d56Sopenharmony_civoid XMLCALL 15287db96d56Sopenharmony_ciXML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { 15297db96d56Sopenharmony_ci if (parser == NULL) 15307db96d56Sopenharmony_ci return; 15317db96d56Sopenharmony_ci /* block after XML_Parse()/XML_ParseBuffer() has been called */ 15327db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_PARSING 15337db96d56Sopenharmony_ci || parser->m_parsingStatus.parsing == XML_SUSPENDED) 15347db96d56Sopenharmony_ci return; 15357db96d56Sopenharmony_ci parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; 15367db96d56Sopenharmony_ci} 15377db96d56Sopenharmony_ci 15387db96d56Sopenharmony_civoid XMLCALL 15397db96d56Sopenharmony_ciXML_SetUserData(XML_Parser parser, void *p) { 15407db96d56Sopenharmony_ci if (parser == NULL) 15417db96d56Sopenharmony_ci return; 15427db96d56Sopenharmony_ci if (parser->m_handlerArg == parser->m_userData) 15437db96d56Sopenharmony_ci parser->m_handlerArg = parser->m_userData = p; 15447db96d56Sopenharmony_ci else 15457db96d56Sopenharmony_ci parser->m_userData = p; 15467db96d56Sopenharmony_ci} 15477db96d56Sopenharmony_ci 15487db96d56Sopenharmony_cienum XML_Status XMLCALL 15497db96d56Sopenharmony_ciXML_SetBase(XML_Parser parser, const XML_Char *p) { 15507db96d56Sopenharmony_ci if (parser == NULL) 15517db96d56Sopenharmony_ci return XML_STATUS_ERROR; 15527db96d56Sopenharmony_ci if (p) { 15537db96d56Sopenharmony_ci p = poolCopyString(&parser->m_dtd->pool, p); 15547db96d56Sopenharmony_ci if (! p) 15557db96d56Sopenharmony_ci return XML_STATUS_ERROR; 15567db96d56Sopenharmony_ci parser->m_curBase = p; 15577db96d56Sopenharmony_ci } else 15587db96d56Sopenharmony_ci parser->m_curBase = NULL; 15597db96d56Sopenharmony_ci return XML_STATUS_OK; 15607db96d56Sopenharmony_ci} 15617db96d56Sopenharmony_ci 15627db96d56Sopenharmony_ciconst XML_Char *XMLCALL 15637db96d56Sopenharmony_ciXML_GetBase(XML_Parser parser) { 15647db96d56Sopenharmony_ci if (parser == NULL) 15657db96d56Sopenharmony_ci return NULL; 15667db96d56Sopenharmony_ci return parser->m_curBase; 15677db96d56Sopenharmony_ci} 15687db96d56Sopenharmony_ci 15697db96d56Sopenharmony_ciint XMLCALL 15707db96d56Sopenharmony_ciXML_GetSpecifiedAttributeCount(XML_Parser parser) { 15717db96d56Sopenharmony_ci if (parser == NULL) 15727db96d56Sopenharmony_ci return -1; 15737db96d56Sopenharmony_ci return parser->m_nSpecifiedAtts; 15747db96d56Sopenharmony_ci} 15757db96d56Sopenharmony_ci 15767db96d56Sopenharmony_ciint XMLCALL 15777db96d56Sopenharmony_ciXML_GetIdAttributeIndex(XML_Parser parser) { 15787db96d56Sopenharmony_ci if (parser == NULL) 15797db96d56Sopenharmony_ci return -1; 15807db96d56Sopenharmony_ci return parser->m_idAttIndex; 15817db96d56Sopenharmony_ci} 15827db96d56Sopenharmony_ci 15837db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 15847db96d56Sopenharmony_ciconst XML_AttrInfo *XMLCALL 15857db96d56Sopenharmony_ciXML_GetAttributeInfo(XML_Parser parser) { 15867db96d56Sopenharmony_ci if (parser == NULL) 15877db96d56Sopenharmony_ci return NULL; 15887db96d56Sopenharmony_ci return parser->m_attInfo; 15897db96d56Sopenharmony_ci} 15907db96d56Sopenharmony_ci#endif 15917db96d56Sopenharmony_ci 15927db96d56Sopenharmony_civoid XMLCALL 15937db96d56Sopenharmony_ciXML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, 15947db96d56Sopenharmony_ci XML_EndElementHandler end) { 15957db96d56Sopenharmony_ci if (parser == NULL) 15967db96d56Sopenharmony_ci return; 15977db96d56Sopenharmony_ci parser->m_startElementHandler = start; 15987db96d56Sopenharmony_ci parser->m_endElementHandler = end; 15997db96d56Sopenharmony_ci} 16007db96d56Sopenharmony_ci 16017db96d56Sopenharmony_civoid XMLCALL 16027db96d56Sopenharmony_ciXML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { 16037db96d56Sopenharmony_ci if (parser != NULL) 16047db96d56Sopenharmony_ci parser->m_startElementHandler = start; 16057db96d56Sopenharmony_ci} 16067db96d56Sopenharmony_ci 16077db96d56Sopenharmony_civoid XMLCALL 16087db96d56Sopenharmony_ciXML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { 16097db96d56Sopenharmony_ci if (parser != NULL) 16107db96d56Sopenharmony_ci parser->m_endElementHandler = end; 16117db96d56Sopenharmony_ci} 16127db96d56Sopenharmony_ci 16137db96d56Sopenharmony_civoid XMLCALL 16147db96d56Sopenharmony_ciXML_SetCharacterDataHandler(XML_Parser parser, 16157db96d56Sopenharmony_ci XML_CharacterDataHandler handler) { 16167db96d56Sopenharmony_ci if (parser != NULL) 16177db96d56Sopenharmony_ci parser->m_characterDataHandler = handler; 16187db96d56Sopenharmony_ci} 16197db96d56Sopenharmony_ci 16207db96d56Sopenharmony_civoid XMLCALL 16217db96d56Sopenharmony_ciXML_SetProcessingInstructionHandler(XML_Parser parser, 16227db96d56Sopenharmony_ci XML_ProcessingInstructionHandler handler) { 16237db96d56Sopenharmony_ci if (parser != NULL) 16247db96d56Sopenharmony_ci parser->m_processingInstructionHandler = handler; 16257db96d56Sopenharmony_ci} 16267db96d56Sopenharmony_ci 16277db96d56Sopenharmony_civoid XMLCALL 16287db96d56Sopenharmony_ciXML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { 16297db96d56Sopenharmony_ci if (parser != NULL) 16307db96d56Sopenharmony_ci parser->m_commentHandler = handler; 16317db96d56Sopenharmony_ci} 16327db96d56Sopenharmony_ci 16337db96d56Sopenharmony_civoid XMLCALL 16347db96d56Sopenharmony_ciXML_SetCdataSectionHandler(XML_Parser parser, 16357db96d56Sopenharmony_ci XML_StartCdataSectionHandler start, 16367db96d56Sopenharmony_ci XML_EndCdataSectionHandler end) { 16377db96d56Sopenharmony_ci if (parser == NULL) 16387db96d56Sopenharmony_ci return; 16397db96d56Sopenharmony_ci parser->m_startCdataSectionHandler = start; 16407db96d56Sopenharmony_ci parser->m_endCdataSectionHandler = end; 16417db96d56Sopenharmony_ci} 16427db96d56Sopenharmony_ci 16437db96d56Sopenharmony_civoid XMLCALL 16447db96d56Sopenharmony_ciXML_SetStartCdataSectionHandler(XML_Parser parser, 16457db96d56Sopenharmony_ci XML_StartCdataSectionHandler start) { 16467db96d56Sopenharmony_ci if (parser != NULL) 16477db96d56Sopenharmony_ci parser->m_startCdataSectionHandler = start; 16487db96d56Sopenharmony_ci} 16497db96d56Sopenharmony_ci 16507db96d56Sopenharmony_civoid XMLCALL 16517db96d56Sopenharmony_ciXML_SetEndCdataSectionHandler(XML_Parser parser, 16527db96d56Sopenharmony_ci XML_EndCdataSectionHandler end) { 16537db96d56Sopenharmony_ci if (parser != NULL) 16547db96d56Sopenharmony_ci parser->m_endCdataSectionHandler = end; 16557db96d56Sopenharmony_ci} 16567db96d56Sopenharmony_ci 16577db96d56Sopenharmony_civoid XMLCALL 16587db96d56Sopenharmony_ciXML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { 16597db96d56Sopenharmony_ci if (parser == NULL) 16607db96d56Sopenharmony_ci return; 16617db96d56Sopenharmony_ci parser->m_defaultHandler = handler; 16627db96d56Sopenharmony_ci parser->m_defaultExpandInternalEntities = XML_FALSE; 16637db96d56Sopenharmony_ci} 16647db96d56Sopenharmony_ci 16657db96d56Sopenharmony_civoid XMLCALL 16667db96d56Sopenharmony_ciXML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { 16677db96d56Sopenharmony_ci if (parser == NULL) 16687db96d56Sopenharmony_ci return; 16697db96d56Sopenharmony_ci parser->m_defaultHandler = handler; 16707db96d56Sopenharmony_ci parser->m_defaultExpandInternalEntities = XML_TRUE; 16717db96d56Sopenharmony_ci} 16727db96d56Sopenharmony_ci 16737db96d56Sopenharmony_civoid XMLCALL 16747db96d56Sopenharmony_ciXML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, 16757db96d56Sopenharmony_ci XML_EndDoctypeDeclHandler end) { 16767db96d56Sopenharmony_ci if (parser == NULL) 16777db96d56Sopenharmony_ci return; 16787db96d56Sopenharmony_ci parser->m_startDoctypeDeclHandler = start; 16797db96d56Sopenharmony_ci parser->m_endDoctypeDeclHandler = end; 16807db96d56Sopenharmony_ci} 16817db96d56Sopenharmony_ci 16827db96d56Sopenharmony_civoid XMLCALL 16837db96d56Sopenharmony_ciXML_SetStartDoctypeDeclHandler(XML_Parser parser, 16847db96d56Sopenharmony_ci XML_StartDoctypeDeclHandler start) { 16857db96d56Sopenharmony_ci if (parser != NULL) 16867db96d56Sopenharmony_ci parser->m_startDoctypeDeclHandler = start; 16877db96d56Sopenharmony_ci} 16887db96d56Sopenharmony_ci 16897db96d56Sopenharmony_civoid XMLCALL 16907db96d56Sopenharmony_ciXML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { 16917db96d56Sopenharmony_ci if (parser != NULL) 16927db96d56Sopenharmony_ci parser->m_endDoctypeDeclHandler = end; 16937db96d56Sopenharmony_ci} 16947db96d56Sopenharmony_ci 16957db96d56Sopenharmony_civoid XMLCALL 16967db96d56Sopenharmony_ciXML_SetUnparsedEntityDeclHandler(XML_Parser parser, 16977db96d56Sopenharmony_ci XML_UnparsedEntityDeclHandler handler) { 16987db96d56Sopenharmony_ci if (parser != NULL) 16997db96d56Sopenharmony_ci parser->m_unparsedEntityDeclHandler = handler; 17007db96d56Sopenharmony_ci} 17017db96d56Sopenharmony_ci 17027db96d56Sopenharmony_civoid XMLCALL 17037db96d56Sopenharmony_ciXML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { 17047db96d56Sopenharmony_ci if (parser != NULL) 17057db96d56Sopenharmony_ci parser->m_notationDeclHandler = handler; 17067db96d56Sopenharmony_ci} 17077db96d56Sopenharmony_ci 17087db96d56Sopenharmony_civoid XMLCALL 17097db96d56Sopenharmony_ciXML_SetNamespaceDeclHandler(XML_Parser parser, 17107db96d56Sopenharmony_ci XML_StartNamespaceDeclHandler start, 17117db96d56Sopenharmony_ci XML_EndNamespaceDeclHandler end) { 17127db96d56Sopenharmony_ci if (parser == NULL) 17137db96d56Sopenharmony_ci return; 17147db96d56Sopenharmony_ci parser->m_startNamespaceDeclHandler = start; 17157db96d56Sopenharmony_ci parser->m_endNamespaceDeclHandler = end; 17167db96d56Sopenharmony_ci} 17177db96d56Sopenharmony_ci 17187db96d56Sopenharmony_civoid XMLCALL 17197db96d56Sopenharmony_ciXML_SetStartNamespaceDeclHandler(XML_Parser parser, 17207db96d56Sopenharmony_ci XML_StartNamespaceDeclHandler start) { 17217db96d56Sopenharmony_ci if (parser != NULL) 17227db96d56Sopenharmony_ci parser->m_startNamespaceDeclHandler = start; 17237db96d56Sopenharmony_ci} 17247db96d56Sopenharmony_ci 17257db96d56Sopenharmony_civoid XMLCALL 17267db96d56Sopenharmony_ciXML_SetEndNamespaceDeclHandler(XML_Parser parser, 17277db96d56Sopenharmony_ci XML_EndNamespaceDeclHandler end) { 17287db96d56Sopenharmony_ci if (parser != NULL) 17297db96d56Sopenharmony_ci parser->m_endNamespaceDeclHandler = end; 17307db96d56Sopenharmony_ci} 17317db96d56Sopenharmony_ci 17327db96d56Sopenharmony_civoid XMLCALL 17337db96d56Sopenharmony_ciXML_SetNotStandaloneHandler(XML_Parser parser, 17347db96d56Sopenharmony_ci XML_NotStandaloneHandler handler) { 17357db96d56Sopenharmony_ci if (parser != NULL) 17367db96d56Sopenharmony_ci parser->m_notStandaloneHandler = handler; 17377db96d56Sopenharmony_ci} 17387db96d56Sopenharmony_ci 17397db96d56Sopenharmony_civoid XMLCALL 17407db96d56Sopenharmony_ciXML_SetExternalEntityRefHandler(XML_Parser parser, 17417db96d56Sopenharmony_ci XML_ExternalEntityRefHandler handler) { 17427db96d56Sopenharmony_ci if (parser != NULL) 17437db96d56Sopenharmony_ci parser->m_externalEntityRefHandler = handler; 17447db96d56Sopenharmony_ci} 17457db96d56Sopenharmony_ci 17467db96d56Sopenharmony_civoid XMLCALL 17477db96d56Sopenharmony_ciXML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { 17487db96d56Sopenharmony_ci if (parser == NULL) 17497db96d56Sopenharmony_ci return; 17507db96d56Sopenharmony_ci if (arg) 17517db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg = (XML_Parser)arg; 17527db96d56Sopenharmony_ci else 17537db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg = parser; 17547db96d56Sopenharmony_ci} 17557db96d56Sopenharmony_ci 17567db96d56Sopenharmony_civoid XMLCALL 17577db96d56Sopenharmony_ciXML_SetSkippedEntityHandler(XML_Parser parser, 17587db96d56Sopenharmony_ci XML_SkippedEntityHandler handler) { 17597db96d56Sopenharmony_ci if (parser != NULL) 17607db96d56Sopenharmony_ci parser->m_skippedEntityHandler = handler; 17617db96d56Sopenharmony_ci} 17627db96d56Sopenharmony_ci 17637db96d56Sopenharmony_civoid XMLCALL 17647db96d56Sopenharmony_ciXML_SetUnknownEncodingHandler(XML_Parser parser, 17657db96d56Sopenharmony_ci XML_UnknownEncodingHandler handler, void *data) { 17667db96d56Sopenharmony_ci if (parser == NULL) 17677db96d56Sopenharmony_ci return; 17687db96d56Sopenharmony_ci parser->m_unknownEncodingHandler = handler; 17697db96d56Sopenharmony_ci parser->m_unknownEncodingHandlerData = data; 17707db96d56Sopenharmony_ci} 17717db96d56Sopenharmony_ci 17727db96d56Sopenharmony_civoid XMLCALL 17737db96d56Sopenharmony_ciXML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { 17747db96d56Sopenharmony_ci if (parser != NULL) 17757db96d56Sopenharmony_ci parser->m_elementDeclHandler = eldecl; 17767db96d56Sopenharmony_ci} 17777db96d56Sopenharmony_ci 17787db96d56Sopenharmony_civoid XMLCALL 17797db96d56Sopenharmony_ciXML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { 17807db96d56Sopenharmony_ci if (parser != NULL) 17817db96d56Sopenharmony_ci parser->m_attlistDeclHandler = attdecl; 17827db96d56Sopenharmony_ci} 17837db96d56Sopenharmony_ci 17847db96d56Sopenharmony_civoid XMLCALL 17857db96d56Sopenharmony_ciXML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { 17867db96d56Sopenharmony_ci if (parser != NULL) 17877db96d56Sopenharmony_ci parser->m_entityDeclHandler = handler; 17887db96d56Sopenharmony_ci} 17897db96d56Sopenharmony_ci 17907db96d56Sopenharmony_civoid XMLCALL 17917db96d56Sopenharmony_ciXML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { 17927db96d56Sopenharmony_ci if (parser != NULL) 17937db96d56Sopenharmony_ci parser->m_xmlDeclHandler = handler; 17947db96d56Sopenharmony_ci} 17957db96d56Sopenharmony_ci 17967db96d56Sopenharmony_ciint XMLCALL 17977db96d56Sopenharmony_ciXML_SetParamEntityParsing(XML_Parser parser, 17987db96d56Sopenharmony_ci enum XML_ParamEntityParsing peParsing) { 17997db96d56Sopenharmony_ci if (parser == NULL) 18007db96d56Sopenharmony_ci return 0; 18017db96d56Sopenharmony_ci /* block after XML_Parse()/XML_ParseBuffer() has been called */ 18027db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_PARSING 18037db96d56Sopenharmony_ci || parser->m_parsingStatus.parsing == XML_SUSPENDED) 18047db96d56Sopenharmony_ci return 0; 18057db96d56Sopenharmony_ci#ifdef XML_DTD 18067db96d56Sopenharmony_ci parser->m_paramEntityParsing = peParsing; 18077db96d56Sopenharmony_ci return 1; 18087db96d56Sopenharmony_ci#else 18097db96d56Sopenharmony_ci return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; 18107db96d56Sopenharmony_ci#endif 18117db96d56Sopenharmony_ci} 18127db96d56Sopenharmony_ci 18137db96d56Sopenharmony_ciint XMLCALL 18147db96d56Sopenharmony_ciXML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { 18157db96d56Sopenharmony_ci if (parser == NULL) 18167db96d56Sopenharmony_ci return 0; 18177db96d56Sopenharmony_ci if (parser->m_parentParser) 18187db96d56Sopenharmony_ci return XML_SetHashSalt(parser->m_parentParser, hash_salt); 18197db96d56Sopenharmony_ci /* block after XML_Parse()/XML_ParseBuffer() has been called */ 18207db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_PARSING 18217db96d56Sopenharmony_ci || parser->m_parsingStatus.parsing == XML_SUSPENDED) 18227db96d56Sopenharmony_ci return 0; 18237db96d56Sopenharmony_ci parser->m_hash_secret_salt = hash_salt; 18247db96d56Sopenharmony_ci return 1; 18257db96d56Sopenharmony_ci} 18267db96d56Sopenharmony_ci 18277db96d56Sopenharmony_cienum XML_Status XMLCALL 18287db96d56Sopenharmony_ciXML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { 18297db96d56Sopenharmony_ci if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { 18307db96d56Sopenharmony_ci if (parser != NULL) 18317db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; 18327db96d56Sopenharmony_ci return XML_STATUS_ERROR; 18337db96d56Sopenharmony_ci } 18347db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 18357db96d56Sopenharmony_ci case XML_SUSPENDED: 18367db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_SUSPENDED; 18377db96d56Sopenharmony_ci return XML_STATUS_ERROR; 18387db96d56Sopenharmony_ci case XML_FINISHED: 18397db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_FINISHED; 18407db96d56Sopenharmony_ci return XML_STATUS_ERROR; 18417db96d56Sopenharmony_ci case XML_INITIALIZED: 18427db96d56Sopenharmony_ci if (parser->m_parentParser == NULL && ! startParsing(parser)) { 18437db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 18447db96d56Sopenharmony_ci return XML_STATUS_ERROR; 18457db96d56Sopenharmony_ci } 18467db96d56Sopenharmony_ci /* fall through */ 18477db96d56Sopenharmony_ci default: 18487db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_PARSING; 18497db96d56Sopenharmony_ci } 18507db96d56Sopenharmony_ci 18517db96d56Sopenharmony_ci if (len == 0) { 18527db96d56Sopenharmony_ci parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; 18537db96d56Sopenharmony_ci if (! isFinal) 18547db96d56Sopenharmony_ci return XML_STATUS_OK; 18557db96d56Sopenharmony_ci parser->m_positionPtr = parser->m_bufferPtr; 18567db96d56Sopenharmony_ci parser->m_parseEndPtr = parser->m_bufferEnd; 18577db96d56Sopenharmony_ci 18587db96d56Sopenharmony_ci /* If data are left over from last buffer, and we now know that these 18597db96d56Sopenharmony_ci data are the final chunk of input, then we have to check them again 18607db96d56Sopenharmony_ci to detect errors based on that fact. 18617db96d56Sopenharmony_ci */ 18627db96d56Sopenharmony_ci parser->m_errorCode 18637db96d56Sopenharmony_ci = parser->m_processor(parser, parser->m_bufferPtr, 18647db96d56Sopenharmony_ci parser->m_parseEndPtr, &parser->m_bufferPtr); 18657db96d56Sopenharmony_ci 18667db96d56Sopenharmony_ci if (parser->m_errorCode == XML_ERROR_NONE) { 18677db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 18687db96d56Sopenharmony_ci case XML_SUSPENDED: 18697db96d56Sopenharmony_ci /* It is hard to be certain, but it seems that this case 18707db96d56Sopenharmony_ci * cannot occur. This code is cleaning up a previous parse 18717db96d56Sopenharmony_ci * with no new data (since len == 0). Changing the parsing 18727db96d56Sopenharmony_ci * state requires getting to execute a handler function, and 18737db96d56Sopenharmony_ci * there doesn't seem to be an opportunity for that while in 18747db96d56Sopenharmony_ci * this circumstance. 18757db96d56Sopenharmony_ci * 18767db96d56Sopenharmony_ci * Given the uncertainty, we retain the code but exclude it 18777db96d56Sopenharmony_ci * from coverage tests. 18787db96d56Sopenharmony_ci * 18797db96d56Sopenharmony_ci * LCOV_EXCL_START 18807db96d56Sopenharmony_ci */ 18817db96d56Sopenharmony_ci XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 18827db96d56Sopenharmony_ci parser->m_bufferPtr, &parser->m_position); 18837db96d56Sopenharmony_ci parser->m_positionPtr = parser->m_bufferPtr; 18847db96d56Sopenharmony_ci return XML_STATUS_SUSPENDED; 18857db96d56Sopenharmony_ci /* LCOV_EXCL_STOP */ 18867db96d56Sopenharmony_ci case XML_INITIALIZED: 18877db96d56Sopenharmony_ci case XML_PARSING: 18887db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_FINISHED; 18897db96d56Sopenharmony_ci /* fall through */ 18907db96d56Sopenharmony_ci default: 18917db96d56Sopenharmony_ci return XML_STATUS_OK; 18927db96d56Sopenharmony_ci } 18937db96d56Sopenharmony_ci } 18947db96d56Sopenharmony_ci parser->m_eventEndPtr = parser->m_eventPtr; 18957db96d56Sopenharmony_ci parser->m_processor = errorProcessor; 18967db96d56Sopenharmony_ci return XML_STATUS_ERROR; 18977db96d56Sopenharmony_ci } 18987db96d56Sopenharmony_ci#ifndef XML_CONTEXT_BYTES 18997db96d56Sopenharmony_ci else if (parser->m_bufferPtr == parser->m_bufferEnd) { 19007db96d56Sopenharmony_ci const char *end; 19017db96d56Sopenharmony_ci int nLeftOver; 19027db96d56Sopenharmony_ci enum XML_Status result; 19037db96d56Sopenharmony_ci /* Detect overflow (a+b > MAX <==> b > MAX-a) */ 19047db96d56Sopenharmony_ci if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { 19057db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 19067db96d56Sopenharmony_ci parser->m_eventPtr = parser->m_eventEndPtr = NULL; 19077db96d56Sopenharmony_ci parser->m_processor = errorProcessor; 19087db96d56Sopenharmony_ci return XML_STATUS_ERROR; 19097db96d56Sopenharmony_ci } 19107db96d56Sopenharmony_ci parser->m_parseEndByteIndex += len; 19117db96d56Sopenharmony_ci parser->m_positionPtr = s; 19127db96d56Sopenharmony_ci parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; 19137db96d56Sopenharmony_ci 19147db96d56Sopenharmony_ci parser->m_errorCode 19157db96d56Sopenharmony_ci = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); 19167db96d56Sopenharmony_ci 19177db96d56Sopenharmony_ci if (parser->m_errorCode != XML_ERROR_NONE) { 19187db96d56Sopenharmony_ci parser->m_eventEndPtr = parser->m_eventPtr; 19197db96d56Sopenharmony_ci parser->m_processor = errorProcessor; 19207db96d56Sopenharmony_ci return XML_STATUS_ERROR; 19217db96d56Sopenharmony_ci } else { 19227db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 19237db96d56Sopenharmony_ci case XML_SUSPENDED: 19247db96d56Sopenharmony_ci result = XML_STATUS_SUSPENDED; 19257db96d56Sopenharmony_ci break; 19267db96d56Sopenharmony_ci case XML_INITIALIZED: 19277db96d56Sopenharmony_ci case XML_PARSING: 19287db96d56Sopenharmony_ci if (isFinal) { 19297db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_FINISHED; 19307db96d56Sopenharmony_ci return XML_STATUS_OK; 19317db96d56Sopenharmony_ci } 19327db96d56Sopenharmony_ci /* fall through */ 19337db96d56Sopenharmony_ci default: 19347db96d56Sopenharmony_ci result = XML_STATUS_OK; 19357db96d56Sopenharmony_ci } 19367db96d56Sopenharmony_ci } 19377db96d56Sopenharmony_ci 19387db96d56Sopenharmony_ci XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, 19397db96d56Sopenharmony_ci &parser->m_position); 19407db96d56Sopenharmony_ci nLeftOver = s + len - end; 19417db96d56Sopenharmony_ci if (nLeftOver) { 19427db96d56Sopenharmony_ci if (parser->m_buffer == NULL 19437db96d56Sopenharmony_ci || nLeftOver > parser->m_bufferLim - parser->m_buffer) { 19447db96d56Sopenharmony_ci /* avoid _signed_ integer overflow */ 19457db96d56Sopenharmony_ci char *temp = NULL; 19467db96d56Sopenharmony_ci const int bytesToAllocate = (int)((unsigned)len * 2U); 19477db96d56Sopenharmony_ci if (bytesToAllocate > 0) { 19487db96d56Sopenharmony_ci temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate); 19497db96d56Sopenharmony_ci } 19507db96d56Sopenharmony_ci if (temp == NULL) { 19517db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 19527db96d56Sopenharmony_ci parser->m_eventPtr = parser->m_eventEndPtr = NULL; 19537db96d56Sopenharmony_ci parser->m_processor = errorProcessor; 19547db96d56Sopenharmony_ci return XML_STATUS_ERROR; 19557db96d56Sopenharmony_ci } 19567db96d56Sopenharmony_ci parser->m_buffer = temp; 19577db96d56Sopenharmony_ci parser->m_bufferLim = parser->m_buffer + bytesToAllocate; 19587db96d56Sopenharmony_ci } 19597db96d56Sopenharmony_ci memcpy(parser->m_buffer, end, nLeftOver); 19607db96d56Sopenharmony_ci } 19617db96d56Sopenharmony_ci parser->m_bufferPtr = parser->m_buffer; 19627db96d56Sopenharmony_ci parser->m_bufferEnd = parser->m_buffer + nLeftOver; 19637db96d56Sopenharmony_ci parser->m_positionPtr = parser->m_bufferPtr; 19647db96d56Sopenharmony_ci parser->m_parseEndPtr = parser->m_bufferEnd; 19657db96d56Sopenharmony_ci parser->m_eventPtr = parser->m_bufferPtr; 19667db96d56Sopenharmony_ci parser->m_eventEndPtr = parser->m_bufferPtr; 19677db96d56Sopenharmony_ci return result; 19687db96d56Sopenharmony_ci } 19697db96d56Sopenharmony_ci#endif /* not defined XML_CONTEXT_BYTES */ 19707db96d56Sopenharmony_ci else { 19717db96d56Sopenharmony_ci void *buff = XML_GetBuffer(parser, len); 19727db96d56Sopenharmony_ci if (buff == NULL) 19737db96d56Sopenharmony_ci return XML_STATUS_ERROR; 19747db96d56Sopenharmony_ci else { 19757db96d56Sopenharmony_ci memcpy(buff, s, len); 19767db96d56Sopenharmony_ci return XML_ParseBuffer(parser, len, isFinal); 19777db96d56Sopenharmony_ci } 19787db96d56Sopenharmony_ci } 19797db96d56Sopenharmony_ci} 19807db96d56Sopenharmony_ci 19817db96d56Sopenharmony_cienum XML_Status XMLCALL 19827db96d56Sopenharmony_ciXML_ParseBuffer(XML_Parser parser, int len, int isFinal) { 19837db96d56Sopenharmony_ci const char *start; 19847db96d56Sopenharmony_ci enum XML_Status result = XML_STATUS_OK; 19857db96d56Sopenharmony_ci 19867db96d56Sopenharmony_ci if (parser == NULL) 19877db96d56Sopenharmony_ci return XML_STATUS_ERROR; 19887db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 19897db96d56Sopenharmony_ci case XML_SUSPENDED: 19907db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_SUSPENDED; 19917db96d56Sopenharmony_ci return XML_STATUS_ERROR; 19927db96d56Sopenharmony_ci case XML_FINISHED: 19937db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_FINISHED; 19947db96d56Sopenharmony_ci return XML_STATUS_ERROR; 19957db96d56Sopenharmony_ci case XML_INITIALIZED: 19967db96d56Sopenharmony_ci /* Has someone called XML_GetBuffer successfully before? */ 19977db96d56Sopenharmony_ci if (! parser->m_bufferPtr) { 19987db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_BUFFER; 19997db96d56Sopenharmony_ci return XML_STATUS_ERROR; 20007db96d56Sopenharmony_ci } 20017db96d56Sopenharmony_ci 20027db96d56Sopenharmony_ci if (parser->m_parentParser == NULL && ! startParsing(parser)) { 20037db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 20047db96d56Sopenharmony_ci return XML_STATUS_ERROR; 20057db96d56Sopenharmony_ci } 20067db96d56Sopenharmony_ci /* fall through */ 20077db96d56Sopenharmony_ci default: 20087db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_PARSING; 20097db96d56Sopenharmony_ci } 20107db96d56Sopenharmony_ci 20117db96d56Sopenharmony_ci start = parser->m_bufferPtr; 20127db96d56Sopenharmony_ci parser->m_positionPtr = start; 20137db96d56Sopenharmony_ci parser->m_bufferEnd += len; 20147db96d56Sopenharmony_ci parser->m_parseEndPtr = parser->m_bufferEnd; 20157db96d56Sopenharmony_ci parser->m_parseEndByteIndex += len; 20167db96d56Sopenharmony_ci parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; 20177db96d56Sopenharmony_ci 20187db96d56Sopenharmony_ci parser->m_errorCode = parser->m_processor( 20197db96d56Sopenharmony_ci parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); 20207db96d56Sopenharmony_ci 20217db96d56Sopenharmony_ci if (parser->m_errorCode != XML_ERROR_NONE) { 20227db96d56Sopenharmony_ci parser->m_eventEndPtr = parser->m_eventPtr; 20237db96d56Sopenharmony_ci parser->m_processor = errorProcessor; 20247db96d56Sopenharmony_ci return XML_STATUS_ERROR; 20257db96d56Sopenharmony_ci } else { 20267db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 20277db96d56Sopenharmony_ci case XML_SUSPENDED: 20287db96d56Sopenharmony_ci result = XML_STATUS_SUSPENDED; 20297db96d56Sopenharmony_ci break; 20307db96d56Sopenharmony_ci case XML_INITIALIZED: 20317db96d56Sopenharmony_ci case XML_PARSING: 20327db96d56Sopenharmony_ci if (isFinal) { 20337db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_FINISHED; 20347db96d56Sopenharmony_ci return result; 20357db96d56Sopenharmony_ci } 20367db96d56Sopenharmony_ci default:; /* should not happen */ 20377db96d56Sopenharmony_ci } 20387db96d56Sopenharmony_ci } 20397db96d56Sopenharmony_ci 20407db96d56Sopenharmony_ci XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 20417db96d56Sopenharmony_ci parser->m_bufferPtr, &parser->m_position); 20427db96d56Sopenharmony_ci parser->m_positionPtr = parser->m_bufferPtr; 20437db96d56Sopenharmony_ci return result; 20447db96d56Sopenharmony_ci} 20457db96d56Sopenharmony_ci 20467db96d56Sopenharmony_civoid *XMLCALL 20477db96d56Sopenharmony_ciXML_GetBuffer(XML_Parser parser, int len) { 20487db96d56Sopenharmony_ci if (parser == NULL) 20497db96d56Sopenharmony_ci return NULL; 20507db96d56Sopenharmony_ci if (len < 0) { 20517db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 20527db96d56Sopenharmony_ci return NULL; 20537db96d56Sopenharmony_ci } 20547db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 20557db96d56Sopenharmony_ci case XML_SUSPENDED: 20567db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_SUSPENDED; 20577db96d56Sopenharmony_ci return NULL; 20587db96d56Sopenharmony_ci case XML_FINISHED: 20597db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_FINISHED; 20607db96d56Sopenharmony_ci return NULL; 20617db96d56Sopenharmony_ci default:; 20627db96d56Sopenharmony_ci } 20637db96d56Sopenharmony_ci 20647db96d56Sopenharmony_ci if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) { 20657db96d56Sopenharmony_ci#ifdef XML_CONTEXT_BYTES 20667db96d56Sopenharmony_ci int keep; 20677db96d56Sopenharmony_ci#endif /* defined XML_CONTEXT_BYTES */ 20687db96d56Sopenharmony_ci /* Do not invoke signed arithmetic overflow: */ 20697db96d56Sopenharmony_ci int neededSize = (int)((unsigned)len 20707db96d56Sopenharmony_ci + (unsigned)EXPAT_SAFE_PTR_DIFF( 20717db96d56Sopenharmony_ci parser->m_bufferEnd, parser->m_bufferPtr)); 20727db96d56Sopenharmony_ci if (neededSize < 0) { 20737db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 20747db96d56Sopenharmony_ci return NULL; 20757db96d56Sopenharmony_ci } 20767db96d56Sopenharmony_ci#ifdef XML_CONTEXT_BYTES 20777db96d56Sopenharmony_ci keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); 20787db96d56Sopenharmony_ci if (keep > XML_CONTEXT_BYTES) 20797db96d56Sopenharmony_ci keep = XML_CONTEXT_BYTES; 20807db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 20817db96d56Sopenharmony_ci if (keep > INT_MAX - neededSize) { 20827db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 20837db96d56Sopenharmony_ci return NULL; 20847db96d56Sopenharmony_ci } 20857db96d56Sopenharmony_ci neededSize += keep; 20867db96d56Sopenharmony_ci#endif /* defined XML_CONTEXT_BYTES */ 20877db96d56Sopenharmony_ci if (neededSize 20887db96d56Sopenharmony_ci <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { 20897db96d56Sopenharmony_ci#ifdef XML_CONTEXT_BYTES 20907db96d56Sopenharmony_ci if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { 20917db96d56Sopenharmony_ci int offset 20927db96d56Sopenharmony_ci = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) 20937db96d56Sopenharmony_ci - keep; 20947db96d56Sopenharmony_ci /* The buffer pointers cannot be NULL here; we have at least some bytes 20957db96d56Sopenharmony_ci * in the buffer */ 20967db96d56Sopenharmony_ci memmove(parser->m_buffer, &parser->m_buffer[offset], 20977db96d56Sopenharmony_ci parser->m_bufferEnd - parser->m_bufferPtr + keep); 20987db96d56Sopenharmony_ci parser->m_bufferEnd -= offset; 20997db96d56Sopenharmony_ci parser->m_bufferPtr -= offset; 21007db96d56Sopenharmony_ci } 21017db96d56Sopenharmony_ci#else 21027db96d56Sopenharmony_ci if (parser->m_buffer && parser->m_bufferPtr) { 21037db96d56Sopenharmony_ci memmove(parser->m_buffer, parser->m_bufferPtr, 21047db96d56Sopenharmony_ci EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); 21057db96d56Sopenharmony_ci parser->m_bufferEnd 21067db96d56Sopenharmony_ci = parser->m_buffer 21077db96d56Sopenharmony_ci + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); 21087db96d56Sopenharmony_ci parser->m_bufferPtr = parser->m_buffer; 21097db96d56Sopenharmony_ci } 21107db96d56Sopenharmony_ci#endif /* not defined XML_CONTEXT_BYTES */ 21117db96d56Sopenharmony_ci } else { 21127db96d56Sopenharmony_ci char *newBuf; 21137db96d56Sopenharmony_ci int bufferSize 21147db96d56Sopenharmony_ci = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr); 21157db96d56Sopenharmony_ci if (bufferSize == 0) 21167db96d56Sopenharmony_ci bufferSize = INIT_BUFFER_SIZE; 21177db96d56Sopenharmony_ci do { 21187db96d56Sopenharmony_ci /* Do not invoke signed arithmetic overflow: */ 21197db96d56Sopenharmony_ci bufferSize = (int)(2U * (unsigned)bufferSize); 21207db96d56Sopenharmony_ci } while (bufferSize < neededSize && bufferSize > 0); 21217db96d56Sopenharmony_ci if (bufferSize <= 0) { 21227db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 21237db96d56Sopenharmony_ci return NULL; 21247db96d56Sopenharmony_ci } 21257db96d56Sopenharmony_ci newBuf = (char *)MALLOC(parser, bufferSize); 21267db96d56Sopenharmony_ci if (newBuf == 0) { 21277db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NO_MEMORY; 21287db96d56Sopenharmony_ci return NULL; 21297db96d56Sopenharmony_ci } 21307db96d56Sopenharmony_ci parser->m_bufferLim = newBuf + bufferSize; 21317db96d56Sopenharmony_ci#ifdef XML_CONTEXT_BYTES 21327db96d56Sopenharmony_ci if (parser->m_bufferPtr) { 21337db96d56Sopenharmony_ci memcpy(newBuf, &parser->m_bufferPtr[-keep], 21347db96d56Sopenharmony_ci EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) 21357db96d56Sopenharmony_ci + keep); 21367db96d56Sopenharmony_ci FREE(parser, parser->m_buffer); 21377db96d56Sopenharmony_ci parser->m_buffer = newBuf; 21387db96d56Sopenharmony_ci parser->m_bufferEnd 21397db96d56Sopenharmony_ci = parser->m_buffer 21407db96d56Sopenharmony_ci + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) 21417db96d56Sopenharmony_ci + keep; 21427db96d56Sopenharmony_ci parser->m_bufferPtr = parser->m_buffer + keep; 21437db96d56Sopenharmony_ci } else { 21447db96d56Sopenharmony_ci /* This must be a brand new buffer with no data in it yet */ 21457db96d56Sopenharmony_ci parser->m_bufferEnd = newBuf; 21467db96d56Sopenharmony_ci parser->m_bufferPtr = parser->m_buffer = newBuf; 21477db96d56Sopenharmony_ci } 21487db96d56Sopenharmony_ci#else 21497db96d56Sopenharmony_ci if (parser->m_bufferPtr) { 21507db96d56Sopenharmony_ci memcpy(newBuf, parser->m_bufferPtr, 21517db96d56Sopenharmony_ci EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); 21527db96d56Sopenharmony_ci FREE(parser, parser->m_buffer); 21537db96d56Sopenharmony_ci parser->m_bufferEnd 21547db96d56Sopenharmony_ci = newBuf 21557db96d56Sopenharmony_ci + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); 21567db96d56Sopenharmony_ci } else { 21577db96d56Sopenharmony_ci /* This must be a brand new buffer with no data in it yet */ 21587db96d56Sopenharmony_ci parser->m_bufferEnd = newBuf; 21597db96d56Sopenharmony_ci } 21607db96d56Sopenharmony_ci parser->m_bufferPtr = parser->m_buffer = newBuf; 21617db96d56Sopenharmony_ci#endif /* not defined XML_CONTEXT_BYTES */ 21627db96d56Sopenharmony_ci } 21637db96d56Sopenharmony_ci parser->m_eventPtr = parser->m_eventEndPtr = NULL; 21647db96d56Sopenharmony_ci parser->m_positionPtr = NULL; 21657db96d56Sopenharmony_ci } 21667db96d56Sopenharmony_ci return parser->m_bufferEnd; 21677db96d56Sopenharmony_ci} 21687db96d56Sopenharmony_ci 21697db96d56Sopenharmony_cienum XML_Status XMLCALL 21707db96d56Sopenharmony_ciXML_StopParser(XML_Parser parser, XML_Bool resumable) { 21717db96d56Sopenharmony_ci if (parser == NULL) 21727db96d56Sopenharmony_ci return XML_STATUS_ERROR; 21737db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 21747db96d56Sopenharmony_ci case XML_SUSPENDED: 21757db96d56Sopenharmony_ci if (resumable) { 21767db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_SUSPENDED; 21777db96d56Sopenharmony_ci return XML_STATUS_ERROR; 21787db96d56Sopenharmony_ci } 21797db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_FINISHED; 21807db96d56Sopenharmony_ci break; 21817db96d56Sopenharmony_ci case XML_FINISHED: 21827db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_FINISHED; 21837db96d56Sopenharmony_ci return XML_STATUS_ERROR; 21847db96d56Sopenharmony_ci default: 21857db96d56Sopenharmony_ci if (resumable) { 21867db96d56Sopenharmony_ci#ifdef XML_DTD 21877db96d56Sopenharmony_ci if (parser->m_isParamEntity) { 21887db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_SUSPEND_PE; 21897db96d56Sopenharmony_ci return XML_STATUS_ERROR; 21907db96d56Sopenharmony_ci } 21917db96d56Sopenharmony_ci#endif 21927db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_SUSPENDED; 21937db96d56Sopenharmony_ci } else 21947db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_FINISHED; 21957db96d56Sopenharmony_ci } 21967db96d56Sopenharmony_ci return XML_STATUS_OK; 21977db96d56Sopenharmony_ci} 21987db96d56Sopenharmony_ci 21997db96d56Sopenharmony_cienum XML_Status XMLCALL 22007db96d56Sopenharmony_ciXML_ResumeParser(XML_Parser parser) { 22017db96d56Sopenharmony_ci enum XML_Status result = XML_STATUS_OK; 22027db96d56Sopenharmony_ci 22037db96d56Sopenharmony_ci if (parser == NULL) 22047db96d56Sopenharmony_ci return XML_STATUS_ERROR; 22057db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing != XML_SUSPENDED) { 22067db96d56Sopenharmony_ci parser->m_errorCode = XML_ERROR_NOT_SUSPENDED; 22077db96d56Sopenharmony_ci return XML_STATUS_ERROR; 22087db96d56Sopenharmony_ci } 22097db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_PARSING; 22107db96d56Sopenharmony_ci 22117db96d56Sopenharmony_ci parser->m_errorCode = parser->m_processor( 22127db96d56Sopenharmony_ci parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); 22137db96d56Sopenharmony_ci 22147db96d56Sopenharmony_ci if (parser->m_errorCode != XML_ERROR_NONE) { 22157db96d56Sopenharmony_ci parser->m_eventEndPtr = parser->m_eventPtr; 22167db96d56Sopenharmony_ci parser->m_processor = errorProcessor; 22177db96d56Sopenharmony_ci return XML_STATUS_ERROR; 22187db96d56Sopenharmony_ci } else { 22197db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 22207db96d56Sopenharmony_ci case XML_SUSPENDED: 22217db96d56Sopenharmony_ci result = XML_STATUS_SUSPENDED; 22227db96d56Sopenharmony_ci break; 22237db96d56Sopenharmony_ci case XML_INITIALIZED: 22247db96d56Sopenharmony_ci case XML_PARSING: 22257db96d56Sopenharmony_ci if (parser->m_parsingStatus.finalBuffer) { 22267db96d56Sopenharmony_ci parser->m_parsingStatus.parsing = XML_FINISHED; 22277db96d56Sopenharmony_ci return result; 22287db96d56Sopenharmony_ci } 22297db96d56Sopenharmony_ci default:; 22307db96d56Sopenharmony_ci } 22317db96d56Sopenharmony_ci } 22327db96d56Sopenharmony_ci 22337db96d56Sopenharmony_ci XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 22347db96d56Sopenharmony_ci parser->m_bufferPtr, &parser->m_position); 22357db96d56Sopenharmony_ci parser->m_positionPtr = parser->m_bufferPtr; 22367db96d56Sopenharmony_ci return result; 22377db96d56Sopenharmony_ci} 22387db96d56Sopenharmony_ci 22397db96d56Sopenharmony_civoid XMLCALL 22407db96d56Sopenharmony_ciXML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { 22417db96d56Sopenharmony_ci if (parser == NULL) 22427db96d56Sopenharmony_ci return; 22437db96d56Sopenharmony_ci assert(status != NULL); 22447db96d56Sopenharmony_ci *status = parser->m_parsingStatus; 22457db96d56Sopenharmony_ci} 22467db96d56Sopenharmony_ci 22477db96d56Sopenharmony_cienum XML_Error XMLCALL 22487db96d56Sopenharmony_ciXML_GetErrorCode(XML_Parser parser) { 22497db96d56Sopenharmony_ci if (parser == NULL) 22507db96d56Sopenharmony_ci return XML_ERROR_INVALID_ARGUMENT; 22517db96d56Sopenharmony_ci return parser->m_errorCode; 22527db96d56Sopenharmony_ci} 22537db96d56Sopenharmony_ci 22547db96d56Sopenharmony_ciXML_Index XMLCALL 22557db96d56Sopenharmony_ciXML_GetCurrentByteIndex(XML_Parser parser) { 22567db96d56Sopenharmony_ci if (parser == NULL) 22577db96d56Sopenharmony_ci return -1; 22587db96d56Sopenharmony_ci if (parser->m_eventPtr) 22597db96d56Sopenharmony_ci return (XML_Index)(parser->m_parseEndByteIndex 22607db96d56Sopenharmony_ci - (parser->m_parseEndPtr - parser->m_eventPtr)); 22617db96d56Sopenharmony_ci return -1; 22627db96d56Sopenharmony_ci} 22637db96d56Sopenharmony_ci 22647db96d56Sopenharmony_ciint XMLCALL 22657db96d56Sopenharmony_ciXML_GetCurrentByteCount(XML_Parser parser) { 22667db96d56Sopenharmony_ci if (parser == NULL) 22677db96d56Sopenharmony_ci return 0; 22687db96d56Sopenharmony_ci if (parser->m_eventEndPtr && parser->m_eventPtr) 22697db96d56Sopenharmony_ci return (int)(parser->m_eventEndPtr - parser->m_eventPtr); 22707db96d56Sopenharmony_ci return 0; 22717db96d56Sopenharmony_ci} 22727db96d56Sopenharmony_ci 22737db96d56Sopenharmony_ciconst char *XMLCALL 22747db96d56Sopenharmony_ciXML_GetInputContext(XML_Parser parser, int *offset, int *size) { 22757db96d56Sopenharmony_ci#ifdef XML_CONTEXT_BYTES 22767db96d56Sopenharmony_ci if (parser == NULL) 22777db96d56Sopenharmony_ci return NULL; 22787db96d56Sopenharmony_ci if (parser->m_eventPtr && parser->m_buffer) { 22797db96d56Sopenharmony_ci if (offset != NULL) 22807db96d56Sopenharmony_ci *offset = (int)(parser->m_eventPtr - parser->m_buffer); 22817db96d56Sopenharmony_ci if (size != NULL) 22827db96d56Sopenharmony_ci *size = (int)(parser->m_bufferEnd - parser->m_buffer); 22837db96d56Sopenharmony_ci return parser->m_buffer; 22847db96d56Sopenharmony_ci } 22857db96d56Sopenharmony_ci#else 22867db96d56Sopenharmony_ci (void)parser; 22877db96d56Sopenharmony_ci (void)offset; 22887db96d56Sopenharmony_ci (void)size; 22897db96d56Sopenharmony_ci#endif /* defined XML_CONTEXT_BYTES */ 22907db96d56Sopenharmony_ci return (const char *)0; 22917db96d56Sopenharmony_ci} 22927db96d56Sopenharmony_ci 22937db96d56Sopenharmony_ciXML_Size XMLCALL 22947db96d56Sopenharmony_ciXML_GetCurrentLineNumber(XML_Parser parser) { 22957db96d56Sopenharmony_ci if (parser == NULL) 22967db96d56Sopenharmony_ci return 0; 22977db96d56Sopenharmony_ci if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { 22987db96d56Sopenharmony_ci XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 22997db96d56Sopenharmony_ci parser->m_eventPtr, &parser->m_position); 23007db96d56Sopenharmony_ci parser->m_positionPtr = parser->m_eventPtr; 23017db96d56Sopenharmony_ci } 23027db96d56Sopenharmony_ci return parser->m_position.lineNumber + 1; 23037db96d56Sopenharmony_ci} 23047db96d56Sopenharmony_ci 23057db96d56Sopenharmony_ciXML_Size XMLCALL 23067db96d56Sopenharmony_ciXML_GetCurrentColumnNumber(XML_Parser parser) { 23077db96d56Sopenharmony_ci if (parser == NULL) 23087db96d56Sopenharmony_ci return 0; 23097db96d56Sopenharmony_ci if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { 23107db96d56Sopenharmony_ci XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 23117db96d56Sopenharmony_ci parser->m_eventPtr, &parser->m_position); 23127db96d56Sopenharmony_ci parser->m_positionPtr = parser->m_eventPtr; 23137db96d56Sopenharmony_ci } 23147db96d56Sopenharmony_ci return parser->m_position.columnNumber; 23157db96d56Sopenharmony_ci} 23167db96d56Sopenharmony_ci 23177db96d56Sopenharmony_civoid XMLCALL 23187db96d56Sopenharmony_ciXML_FreeContentModel(XML_Parser parser, XML_Content *model) { 23197db96d56Sopenharmony_ci if (parser != NULL) 23207db96d56Sopenharmony_ci FREE(parser, model); 23217db96d56Sopenharmony_ci} 23227db96d56Sopenharmony_ci 23237db96d56Sopenharmony_civoid *XMLCALL 23247db96d56Sopenharmony_ciXML_MemMalloc(XML_Parser parser, size_t size) { 23257db96d56Sopenharmony_ci if (parser == NULL) 23267db96d56Sopenharmony_ci return NULL; 23277db96d56Sopenharmony_ci return MALLOC(parser, size); 23287db96d56Sopenharmony_ci} 23297db96d56Sopenharmony_ci 23307db96d56Sopenharmony_civoid *XMLCALL 23317db96d56Sopenharmony_ciXML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { 23327db96d56Sopenharmony_ci if (parser == NULL) 23337db96d56Sopenharmony_ci return NULL; 23347db96d56Sopenharmony_ci return REALLOC(parser, ptr, size); 23357db96d56Sopenharmony_ci} 23367db96d56Sopenharmony_ci 23377db96d56Sopenharmony_civoid XMLCALL 23387db96d56Sopenharmony_ciXML_MemFree(XML_Parser parser, void *ptr) { 23397db96d56Sopenharmony_ci if (parser != NULL) 23407db96d56Sopenharmony_ci FREE(parser, ptr); 23417db96d56Sopenharmony_ci} 23427db96d56Sopenharmony_ci 23437db96d56Sopenharmony_civoid XMLCALL 23447db96d56Sopenharmony_ciXML_DefaultCurrent(XML_Parser parser) { 23457db96d56Sopenharmony_ci if (parser == NULL) 23467db96d56Sopenharmony_ci return; 23477db96d56Sopenharmony_ci if (parser->m_defaultHandler) { 23487db96d56Sopenharmony_ci if (parser->m_openInternalEntities) 23497db96d56Sopenharmony_ci reportDefault(parser, parser->m_internalEncoding, 23507db96d56Sopenharmony_ci parser->m_openInternalEntities->internalEventPtr, 23517db96d56Sopenharmony_ci parser->m_openInternalEntities->internalEventEndPtr); 23527db96d56Sopenharmony_ci else 23537db96d56Sopenharmony_ci reportDefault(parser, parser->m_encoding, parser->m_eventPtr, 23547db96d56Sopenharmony_ci parser->m_eventEndPtr); 23557db96d56Sopenharmony_ci } 23567db96d56Sopenharmony_ci} 23577db96d56Sopenharmony_ci 23587db96d56Sopenharmony_ciconst XML_LChar *XMLCALL 23597db96d56Sopenharmony_ciXML_ErrorString(enum XML_Error code) { 23607db96d56Sopenharmony_ci switch (code) { 23617db96d56Sopenharmony_ci case XML_ERROR_NONE: 23627db96d56Sopenharmony_ci return NULL; 23637db96d56Sopenharmony_ci case XML_ERROR_NO_MEMORY: 23647db96d56Sopenharmony_ci return XML_L("out of memory"); 23657db96d56Sopenharmony_ci case XML_ERROR_SYNTAX: 23667db96d56Sopenharmony_ci return XML_L("syntax error"); 23677db96d56Sopenharmony_ci case XML_ERROR_NO_ELEMENTS: 23687db96d56Sopenharmony_ci return XML_L("no element found"); 23697db96d56Sopenharmony_ci case XML_ERROR_INVALID_TOKEN: 23707db96d56Sopenharmony_ci return XML_L("not well-formed (invalid token)"); 23717db96d56Sopenharmony_ci case XML_ERROR_UNCLOSED_TOKEN: 23727db96d56Sopenharmony_ci return XML_L("unclosed token"); 23737db96d56Sopenharmony_ci case XML_ERROR_PARTIAL_CHAR: 23747db96d56Sopenharmony_ci return XML_L("partial character"); 23757db96d56Sopenharmony_ci case XML_ERROR_TAG_MISMATCH: 23767db96d56Sopenharmony_ci return XML_L("mismatched tag"); 23777db96d56Sopenharmony_ci case XML_ERROR_DUPLICATE_ATTRIBUTE: 23787db96d56Sopenharmony_ci return XML_L("duplicate attribute"); 23797db96d56Sopenharmony_ci case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: 23807db96d56Sopenharmony_ci return XML_L("junk after document element"); 23817db96d56Sopenharmony_ci case XML_ERROR_PARAM_ENTITY_REF: 23827db96d56Sopenharmony_ci return XML_L("illegal parameter entity reference"); 23837db96d56Sopenharmony_ci case XML_ERROR_UNDEFINED_ENTITY: 23847db96d56Sopenharmony_ci return XML_L("undefined entity"); 23857db96d56Sopenharmony_ci case XML_ERROR_RECURSIVE_ENTITY_REF: 23867db96d56Sopenharmony_ci return XML_L("recursive entity reference"); 23877db96d56Sopenharmony_ci case XML_ERROR_ASYNC_ENTITY: 23887db96d56Sopenharmony_ci return XML_L("asynchronous entity"); 23897db96d56Sopenharmony_ci case XML_ERROR_BAD_CHAR_REF: 23907db96d56Sopenharmony_ci return XML_L("reference to invalid character number"); 23917db96d56Sopenharmony_ci case XML_ERROR_BINARY_ENTITY_REF: 23927db96d56Sopenharmony_ci return XML_L("reference to binary entity"); 23937db96d56Sopenharmony_ci case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: 23947db96d56Sopenharmony_ci return XML_L("reference to external entity in attribute"); 23957db96d56Sopenharmony_ci case XML_ERROR_MISPLACED_XML_PI: 23967db96d56Sopenharmony_ci return XML_L("XML or text declaration not at start of entity"); 23977db96d56Sopenharmony_ci case XML_ERROR_UNKNOWN_ENCODING: 23987db96d56Sopenharmony_ci return XML_L("unknown encoding"); 23997db96d56Sopenharmony_ci case XML_ERROR_INCORRECT_ENCODING: 24007db96d56Sopenharmony_ci return XML_L("encoding specified in XML declaration is incorrect"); 24017db96d56Sopenharmony_ci case XML_ERROR_UNCLOSED_CDATA_SECTION: 24027db96d56Sopenharmony_ci return XML_L("unclosed CDATA section"); 24037db96d56Sopenharmony_ci case XML_ERROR_EXTERNAL_ENTITY_HANDLING: 24047db96d56Sopenharmony_ci return XML_L("error in processing external entity reference"); 24057db96d56Sopenharmony_ci case XML_ERROR_NOT_STANDALONE: 24067db96d56Sopenharmony_ci return XML_L("document is not standalone"); 24077db96d56Sopenharmony_ci case XML_ERROR_UNEXPECTED_STATE: 24087db96d56Sopenharmony_ci return XML_L("unexpected parser state - please send a bug report"); 24097db96d56Sopenharmony_ci case XML_ERROR_ENTITY_DECLARED_IN_PE: 24107db96d56Sopenharmony_ci return XML_L("entity declared in parameter entity"); 24117db96d56Sopenharmony_ci case XML_ERROR_FEATURE_REQUIRES_XML_DTD: 24127db96d56Sopenharmony_ci return XML_L("requested feature requires XML_DTD support in Expat"); 24137db96d56Sopenharmony_ci case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: 24147db96d56Sopenharmony_ci return XML_L("cannot change setting once parsing has begun"); 24157db96d56Sopenharmony_ci /* Added in 1.95.7. */ 24167db96d56Sopenharmony_ci case XML_ERROR_UNBOUND_PREFIX: 24177db96d56Sopenharmony_ci return XML_L("unbound prefix"); 24187db96d56Sopenharmony_ci /* Added in 1.95.8. */ 24197db96d56Sopenharmony_ci case XML_ERROR_UNDECLARING_PREFIX: 24207db96d56Sopenharmony_ci return XML_L("must not undeclare prefix"); 24217db96d56Sopenharmony_ci case XML_ERROR_INCOMPLETE_PE: 24227db96d56Sopenharmony_ci return XML_L("incomplete markup in parameter entity"); 24237db96d56Sopenharmony_ci case XML_ERROR_XML_DECL: 24247db96d56Sopenharmony_ci return XML_L("XML declaration not well-formed"); 24257db96d56Sopenharmony_ci case XML_ERROR_TEXT_DECL: 24267db96d56Sopenharmony_ci return XML_L("text declaration not well-formed"); 24277db96d56Sopenharmony_ci case XML_ERROR_PUBLICID: 24287db96d56Sopenharmony_ci return XML_L("illegal character(s) in public id"); 24297db96d56Sopenharmony_ci case XML_ERROR_SUSPENDED: 24307db96d56Sopenharmony_ci return XML_L("parser suspended"); 24317db96d56Sopenharmony_ci case XML_ERROR_NOT_SUSPENDED: 24327db96d56Sopenharmony_ci return XML_L("parser not suspended"); 24337db96d56Sopenharmony_ci case XML_ERROR_ABORTED: 24347db96d56Sopenharmony_ci return XML_L("parsing aborted"); 24357db96d56Sopenharmony_ci case XML_ERROR_FINISHED: 24367db96d56Sopenharmony_ci return XML_L("parsing finished"); 24377db96d56Sopenharmony_ci case XML_ERROR_SUSPEND_PE: 24387db96d56Sopenharmony_ci return XML_L("cannot suspend in external parameter entity"); 24397db96d56Sopenharmony_ci /* Added in 2.0.0. */ 24407db96d56Sopenharmony_ci case XML_ERROR_RESERVED_PREFIX_XML: 24417db96d56Sopenharmony_ci return XML_L( 24427db96d56Sopenharmony_ci "reserved prefix (xml) must not be undeclared or bound to another namespace name"); 24437db96d56Sopenharmony_ci case XML_ERROR_RESERVED_PREFIX_XMLNS: 24447db96d56Sopenharmony_ci return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); 24457db96d56Sopenharmony_ci case XML_ERROR_RESERVED_NAMESPACE_URI: 24467db96d56Sopenharmony_ci return XML_L( 24477db96d56Sopenharmony_ci "prefix must not be bound to one of the reserved namespace names"); 24487db96d56Sopenharmony_ci /* Added in 2.2.5. */ 24497db96d56Sopenharmony_ci case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ 24507db96d56Sopenharmony_ci return XML_L("invalid argument"); 24517db96d56Sopenharmony_ci /* Added in 2.3.0. */ 24527db96d56Sopenharmony_ci case XML_ERROR_NO_BUFFER: 24537db96d56Sopenharmony_ci return XML_L( 24547db96d56Sopenharmony_ci "a successful prior call to function XML_GetBuffer is required"); 24557db96d56Sopenharmony_ci /* Added in 2.4.0. */ 24567db96d56Sopenharmony_ci case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: 24577db96d56Sopenharmony_ci return XML_L( 24587db96d56Sopenharmony_ci "limit on input amplification factor (from DTD and entities) breached"); 24597db96d56Sopenharmony_ci } 24607db96d56Sopenharmony_ci return NULL; 24617db96d56Sopenharmony_ci} 24627db96d56Sopenharmony_ci 24637db96d56Sopenharmony_ciconst XML_LChar *XMLCALL 24647db96d56Sopenharmony_ciXML_ExpatVersion(void) { 24657db96d56Sopenharmony_ci /* V1 is used to string-ize the version number. However, it would 24667db96d56Sopenharmony_ci string-ize the actual version macro *names* unless we get them 24677db96d56Sopenharmony_ci substituted before being passed to V1. CPP is defined to expand 24687db96d56Sopenharmony_ci a macro, then rescan for more expansions. Thus, we use V2 to expand 24697db96d56Sopenharmony_ci the version macros, then CPP will expand the resulting V1() macro 24707db96d56Sopenharmony_ci with the correct numerals. */ 24717db96d56Sopenharmony_ci /* ### I'm assuming cpp is portable in this respect... */ 24727db96d56Sopenharmony_ci 24737db96d56Sopenharmony_ci#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c) 24747db96d56Sopenharmony_ci#define V2(a, b, c) XML_L("expat_") V1(a, b, c) 24757db96d56Sopenharmony_ci 24767db96d56Sopenharmony_ci return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); 24777db96d56Sopenharmony_ci 24787db96d56Sopenharmony_ci#undef V1 24797db96d56Sopenharmony_ci#undef V2 24807db96d56Sopenharmony_ci} 24817db96d56Sopenharmony_ci 24827db96d56Sopenharmony_ciXML_Expat_Version XMLCALL 24837db96d56Sopenharmony_ciXML_ExpatVersionInfo(void) { 24847db96d56Sopenharmony_ci XML_Expat_Version version; 24857db96d56Sopenharmony_ci 24867db96d56Sopenharmony_ci version.major = XML_MAJOR_VERSION; 24877db96d56Sopenharmony_ci version.minor = XML_MINOR_VERSION; 24887db96d56Sopenharmony_ci version.micro = XML_MICRO_VERSION; 24897db96d56Sopenharmony_ci 24907db96d56Sopenharmony_ci return version; 24917db96d56Sopenharmony_ci} 24927db96d56Sopenharmony_ci 24937db96d56Sopenharmony_ciconst XML_Feature *XMLCALL 24947db96d56Sopenharmony_ciXML_GetFeatureList(void) { 24957db96d56Sopenharmony_ci static const XML_Feature features[] = { 24967db96d56Sopenharmony_ci {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 24977db96d56Sopenharmony_ci sizeof(XML_Char)}, 24987db96d56Sopenharmony_ci {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 24997db96d56Sopenharmony_ci sizeof(XML_LChar)}, 25007db96d56Sopenharmony_ci#ifdef XML_UNICODE 25017db96d56Sopenharmony_ci {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, 25027db96d56Sopenharmony_ci#endif 25037db96d56Sopenharmony_ci#ifdef XML_UNICODE_WCHAR_T 25047db96d56Sopenharmony_ci {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, 25057db96d56Sopenharmony_ci#endif 25067db96d56Sopenharmony_ci#ifdef XML_DTD 25077db96d56Sopenharmony_ci {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, 25087db96d56Sopenharmony_ci#endif 25097db96d56Sopenharmony_ci#ifdef XML_CONTEXT_BYTES 25107db96d56Sopenharmony_ci {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), 25117db96d56Sopenharmony_ci XML_CONTEXT_BYTES}, 25127db96d56Sopenharmony_ci#endif 25137db96d56Sopenharmony_ci#ifdef XML_MIN_SIZE 25147db96d56Sopenharmony_ci {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, 25157db96d56Sopenharmony_ci#endif 25167db96d56Sopenharmony_ci#ifdef XML_NS 25177db96d56Sopenharmony_ci {XML_FEATURE_NS, XML_L("XML_NS"), 0}, 25187db96d56Sopenharmony_ci#endif 25197db96d56Sopenharmony_ci#ifdef XML_LARGE_SIZE 25207db96d56Sopenharmony_ci {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, 25217db96d56Sopenharmony_ci#endif 25227db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 25237db96d56Sopenharmony_ci {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, 25247db96d56Sopenharmony_ci#endif 25257db96d56Sopenharmony_ci#ifdef XML_DTD 25267db96d56Sopenharmony_ci /* Added in Expat 2.4.0. */ 25277db96d56Sopenharmony_ci {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, 25287db96d56Sopenharmony_ci XML_L("XML_BLAP_MAX_AMP"), 25297db96d56Sopenharmony_ci (long int) 25307db96d56Sopenharmony_ci EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT}, 25317db96d56Sopenharmony_ci {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, 25327db96d56Sopenharmony_ci XML_L("XML_BLAP_ACT_THRES"), 25337db96d56Sopenharmony_ci EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT}, 25347db96d56Sopenharmony_ci#endif 25357db96d56Sopenharmony_ci {XML_FEATURE_END, NULL, 0}}; 25367db96d56Sopenharmony_ci 25377db96d56Sopenharmony_ci return features; 25387db96d56Sopenharmony_ci} 25397db96d56Sopenharmony_ci 25407db96d56Sopenharmony_ci#ifdef XML_DTD 25417db96d56Sopenharmony_ciXML_Bool XMLCALL 25427db96d56Sopenharmony_ciXML_SetBillionLaughsAttackProtectionMaximumAmplification( 25437db96d56Sopenharmony_ci XML_Parser parser, float maximumAmplificationFactor) { 25447db96d56Sopenharmony_ci if ((parser == NULL) || (parser->m_parentParser != NULL) 25457db96d56Sopenharmony_ci || isnan(maximumAmplificationFactor) 25467db96d56Sopenharmony_ci || (maximumAmplificationFactor < 1.0f)) { 25477db96d56Sopenharmony_ci return XML_FALSE; 25487db96d56Sopenharmony_ci } 25497db96d56Sopenharmony_ci parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor; 25507db96d56Sopenharmony_ci return XML_TRUE; 25517db96d56Sopenharmony_ci} 25527db96d56Sopenharmony_ci 25537db96d56Sopenharmony_ciXML_Bool XMLCALL 25547db96d56Sopenharmony_ciXML_SetBillionLaughsAttackProtectionActivationThreshold( 25557db96d56Sopenharmony_ci XML_Parser parser, unsigned long long activationThresholdBytes) { 25567db96d56Sopenharmony_ci if ((parser == NULL) || (parser->m_parentParser != NULL)) { 25577db96d56Sopenharmony_ci return XML_FALSE; 25587db96d56Sopenharmony_ci } 25597db96d56Sopenharmony_ci parser->m_accounting.activationThresholdBytes = activationThresholdBytes; 25607db96d56Sopenharmony_ci return XML_TRUE; 25617db96d56Sopenharmony_ci} 25627db96d56Sopenharmony_ci#endif /* XML_DTD */ 25637db96d56Sopenharmony_ci 25647db96d56Sopenharmony_ci/* Initially tag->rawName always points into the parse buffer; 25657db96d56Sopenharmony_ci for those TAG instances opened while the current parse buffer was 25667db96d56Sopenharmony_ci processed, and not yet closed, we need to store tag->rawName in a more 25677db96d56Sopenharmony_ci permanent location, since the parse buffer is about to be discarded. 25687db96d56Sopenharmony_ci*/ 25697db96d56Sopenharmony_cistatic XML_Bool 25707db96d56Sopenharmony_cistoreRawNames(XML_Parser parser) { 25717db96d56Sopenharmony_ci TAG *tag = parser->m_tagStack; 25727db96d56Sopenharmony_ci while (tag) { 25737db96d56Sopenharmony_ci int bufSize; 25747db96d56Sopenharmony_ci int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); 25757db96d56Sopenharmony_ci size_t rawNameLen; 25767db96d56Sopenharmony_ci char *rawNameBuf = tag->buf + nameLen; 25777db96d56Sopenharmony_ci /* Stop if already stored. Since m_tagStack is a stack, we can stop 25787db96d56Sopenharmony_ci at the first entry that has already been copied; everything 25797db96d56Sopenharmony_ci below it in the stack is already been accounted for in a 25807db96d56Sopenharmony_ci previous call to this function. 25817db96d56Sopenharmony_ci */ 25827db96d56Sopenharmony_ci if (tag->rawName == rawNameBuf) 25837db96d56Sopenharmony_ci break; 25847db96d56Sopenharmony_ci /* For re-use purposes we need to ensure that the 25857db96d56Sopenharmony_ci size of tag->buf is a multiple of sizeof(XML_Char). 25867db96d56Sopenharmony_ci */ 25877db96d56Sopenharmony_ci rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); 25887db96d56Sopenharmony_ci /* Detect and prevent integer overflow. */ 25897db96d56Sopenharmony_ci if (rawNameLen > (size_t)INT_MAX - nameLen) 25907db96d56Sopenharmony_ci return XML_FALSE; 25917db96d56Sopenharmony_ci bufSize = nameLen + (int)rawNameLen; 25927db96d56Sopenharmony_ci if (bufSize > tag->bufEnd - tag->buf) { 25937db96d56Sopenharmony_ci char *temp = (char *)REALLOC(parser, tag->buf, bufSize); 25947db96d56Sopenharmony_ci if (temp == NULL) 25957db96d56Sopenharmony_ci return XML_FALSE; 25967db96d56Sopenharmony_ci /* if tag->name.str points to tag->buf (only when namespace 25977db96d56Sopenharmony_ci processing is off) then we have to update it 25987db96d56Sopenharmony_ci */ 25997db96d56Sopenharmony_ci if (tag->name.str == (XML_Char *)tag->buf) 26007db96d56Sopenharmony_ci tag->name.str = (XML_Char *)temp; 26017db96d56Sopenharmony_ci /* if tag->name.localPart is set (when namespace processing is on) 26027db96d56Sopenharmony_ci then update it as well, since it will always point into tag->buf 26037db96d56Sopenharmony_ci */ 26047db96d56Sopenharmony_ci if (tag->name.localPart) 26057db96d56Sopenharmony_ci tag->name.localPart 26067db96d56Sopenharmony_ci = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf); 26077db96d56Sopenharmony_ci tag->buf = temp; 26087db96d56Sopenharmony_ci tag->bufEnd = temp + bufSize; 26097db96d56Sopenharmony_ci rawNameBuf = temp + nameLen; 26107db96d56Sopenharmony_ci } 26117db96d56Sopenharmony_ci memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); 26127db96d56Sopenharmony_ci tag->rawName = rawNameBuf; 26137db96d56Sopenharmony_ci tag = tag->parent; 26147db96d56Sopenharmony_ci } 26157db96d56Sopenharmony_ci return XML_TRUE; 26167db96d56Sopenharmony_ci} 26177db96d56Sopenharmony_ci 26187db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 26197db96d56Sopenharmony_cicontentProcessor(XML_Parser parser, const char *start, const char *end, 26207db96d56Sopenharmony_ci const char **endPtr) { 26217db96d56Sopenharmony_ci enum XML_Error result = doContent( 26227db96d56Sopenharmony_ci parser, 0, parser->m_encoding, start, end, endPtr, 26237db96d56Sopenharmony_ci (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); 26247db96d56Sopenharmony_ci if (result == XML_ERROR_NONE) { 26257db96d56Sopenharmony_ci if (! storeRawNames(parser)) 26267db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 26277db96d56Sopenharmony_ci } 26287db96d56Sopenharmony_ci return result; 26297db96d56Sopenharmony_ci} 26307db96d56Sopenharmony_ci 26317db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 26327db96d56Sopenharmony_ciexternalEntityInitProcessor(XML_Parser parser, const char *start, 26337db96d56Sopenharmony_ci const char *end, const char **endPtr) { 26347db96d56Sopenharmony_ci enum XML_Error result = initializeEncoding(parser); 26357db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 26367db96d56Sopenharmony_ci return result; 26377db96d56Sopenharmony_ci parser->m_processor = externalEntityInitProcessor2; 26387db96d56Sopenharmony_ci return externalEntityInitProcessor2(parser, start, end, endPtr); 26397db96d56Sopenharmony_ci} 26407db96d56Sopenharmony_ci 26417db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 26427db96d56Sopenharmony_ciexternalEntityInitProcessor2(XML_Parser parser, const char *start, 26437db96d56Sopenharmony_ci const char *end, const char **endPtr) { 26447db96d56Sopenharmony_ci const char *next = start; /* XmlContentTok doesn't always set the last arg */ 26457db96d56Sopenharmony_ci int tok = XmlContentTok(parser->m_encoding, start, end, &next); 26467db96d56Sopenharmony_ci switch (tok) { 26477db96d56Sopenharmony_ci case XML_TOK_BOM: 26487db96d56Sopenharmony_ci#ifdef XML_DTD 26497db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, start, next, __LINE__, 26507db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT)) { 26517db96d56Sopenharmony_ci accountingOnAbort(parser); 26527db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 26537db96d56Sopenharmony_ci } 26547db96d56Sopenharmony_ci#endif /* XML_DTD */ 26557db96d56Sopenharmony_ci 26567db96d56Sopenharmony_ci /* If we are at the end of the buffer, this would cause the next stage, 26577db96d56Sopenharmony_ci i.e. externalEntityInitProcessor3, to pass control directly to 26587db96d56Sopenharmony_ci doContent (by detecting XML_TOK_NONE) without processing any xml text 26597db96d56Sopenharmony_ci declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. 26607db96d56Sopenharmony_ci */ 26617db96d56Sopenharmony_ci if (next == end && ! parser->m_parsingStatus.finalBuffer) { 26627db96d56Sopenharmony_ci *endPtr = next; 26637db96d56Sopenharmony_ci return XML_ERROR_NONE; 26647db96d56Sopenharmony_ci } 26657db96d56Sopenharmony_ci start = next; 26667db96d56Sopenharmony_ci break; 26677db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 26687db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer) { 26697db96d56Sopenharmony_ci *endPtr = start; 26707db96d56Sopenharmony_ci return XML_ERROR_NONE; 26717db96d56Sopenharmony_ci } 26727db96d56Sopenharmony_ci parser->m_eventPtr = start; 26737db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_TOKEN; 26747db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 26757db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer) { 26767db96d56Sopenharmony_ci *endPtr = start; 26777db96d56Sopenharmony_ci return XML_ERROR_NONE; 26787db96d56Sopenharmony_ci } 26797db96d56Sopenharmony_ci parser->m_eventPtr = start; 26807db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 26817db96d56Sopenharmony_ci } 26827db96d56Sopenharmony_ci parser->m_processor = externalEntityInitProcessor3; 26837db96d56Sopenharmony_ci return externalEntityInitProcessor3(parser, start, end, endPtr); 26847db96d56Sopenharmony_ci} 26857db96d56Sopenharmony_ci 26867db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 26877db96d56Sopenharmony_ciexternalEntityInitProcessor3(XML_Parser parser, const char *start, 26887db96d56Sopenharmony_ci const char *end, const char **endPtr) { 26897db96d56Sopenharmony_ci int tok; 26907db96d56Sopenharmony_ci const char *next = start; /* XmlContentTok doesn't always set the last arg */ 26917db96d56Sopenharmony_ci parser->m_eventPtr = start; 26927db96d56Sopenharmony_ci tok = XmlContentTok(parser->m_encoding, start, end, &next); 26937db96d56Sopenharmony_ci /* Note: These bytes are accounted later in: 26947db96d56Sopenharmony_ci - processXmlDecl 26957db96d56Sopenharmony_ci - externalEntityContentProcessor 26967db96d56Sopenharmony_ci */ 26977db96d56Sopenharmony_ci parser->m_eventEndPtr = next; 26987db96d56Sopenharmony_ci 26997db96d56Sopenharmony_ci switch (tok) { 27007db96d56Sopenharmony_ci case XML_TOK_XML_DECL: { 27017db96d56Sopenharmony_ci enum XML_Error result; 27027db96d56Sopenharmony_ci result = processXmlDecl(parser, 1, start, next); 27037db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 27047db96d56Sopenharmony_ci return result; 27057db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 27067db96d56Sopenharmony_ci case XML_SUSPENDED: 27077db96d56Sopenharmony_ci *endPtr = next; 27087db96d56Sopenharmony_ci return XML_ERROR_NONE; 27097db96d56Sopenharmony_ci case XML_FINISHED: 27107db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 27117db96d56Sopenharmony_ci default: 27127db96d56Sopenharmony_ci start = next; 27137db96d56Sopenharmony_ci } 27147db96d56Sopenharmony_ci } break; 27157db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 27167db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer) { 27177db96d56Sopenharmony_ci *endPtr = start; 27187db96d56Sopenharmony_ci return XML_ERROR_NONE; 27197db96d56Sopenharmony_ci } 27207db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_TOKEN; 27217db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 27227db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer) { 27237db96d56Sopenharmony_ci *endPtr = start; 27247db96d56Sopenharmony_ci return XML_ERROR_NONE; 27257db96d56Sopenharmony_ci } 27267db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 27277db96d56Sopenharmony_ci } 27287db96d56Sopenharmony_ci parser->m_processor = externalEntityContentProcessor; 27297db96d56Sopenharmony_ci parser->m_tagLevel = 1; 27307db96d56Sopenharmony_ci return externalEntityContentProcessor(parser, start, end, endPtr); 27317db96d56Sopenharmony_ci} 27327db96d56Sopenharmony_ci 27337db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 27347db96d56Sopenharmony_ciexternalEntityContentProcessor(XML_Parser parser, const char *start, 27357db96d56Sopenharmony_ci const char *end, const char **endPtr) { 27367db96d56Sopenharmony_ci enum XML_Error result 27377db96d56Sopenharmony_ci = doContent(parser, 1, parser->m_encoding, start, end, endPtr, 27387db96d56Sopenharmony_ci (XML_Bool)! parser->m_parsingStatus.finalBuffer, 27397db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION); 27407db96d56Sopenharmony_ci if (result == XML_ERROR_NONE) { 27417db96d56Sopenharmony_ci if (! storeRawNames(parser)) 27427db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 27437db96d56Sopenharmony_ci } 27447db96d56Sopenharmony_ci return result; 27457db96d56Sopenharmony_ci} 27467db96d56Sopenharmony_ci 27477db96d56Sopenharmony_cistatic enum XML_Error 27487db96d56Sopenharmony_cidoContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, 27497db96d56Sopenharmony_ci const char *s, const char *end, const char **nextPtr, 27507db96d56Sopenharmony_ci XML_Bool haveMore, enum XML_Account account) { 27517db96d56Sopenharmony_ci /* save one level of indirection */ 27527db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; 27537db96d56Sopenharmony_ci 27547db96d56Sopenharmony_ci const char **eventPP; 27557db96d56Sopenharmony_ci const char **eventEndPP; 27567db96d56Sopenharmony_ci if (enc == parser->m_encoding) { 27577db96d56Sopenharmony_ci eventPP = &parser->m_eventPtr; 27587db96d56Sopenharmony_ci eventEndPP = &parser->m_eventEndPtr; 27597db96d56Sopenharmony_ci } else { 27607db96d56Sopenharmony_ci eventPP = &(parser->m_openInternalEntities->internalEventPtr); 27617db96d56Sopenharmony_ci eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 27627db96d56Sopenharmony_ci } 27637db96d56Sopenharmony_ci *eventPP = s; 27647db96d56Sopenharmony_ci 27657db96d56Sopenharmony_ci for (;;) { 27667db96d56Sopenharmony_ci const char *next = s; /* XmlContentTok doesn't always set the last arg */ 27677db96d56Sopenharmony_ci int tok = XmlContentTok(enc, s, end, &next); 27687db96d56Sopenharmony_ci#ifdef XML_DTD 27697db96d56Sopenharmony_ci const char *accountAfter 27707db96d56Sopenharmony_ci = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR)) 27717db96d56Sopenharmony_ci ? (haveMore ? s /* i.e. 0 bytes */ : end) 27727db96d56Sopenharmony_ci : next; 27737db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__, 27747db96d56Sopenharmony_ci account)) { 27757db96d56Sopenharmony_ci accountingOnAbort(parser); 27767db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 27777db96d56Sopenharmony_ci } 27787db96d56Sopenharmony_ci#endif 27797db96d56Sopenharmony_ci *eventEndPP = next; 27807db96d56Sopenharmony_ci switch (tok) { 27817db96d56Sopenharmony_ci case XML_TOK_TRAILING_CR: 27827db96d56Sopenharmony_ci if (haveMore) { 27837db96d56Sopenharmony_ci *nextPtr = s; 27847db96d56Sopenharmony_ci return XML_ERROR_NONE; 27857db96d56Sopenharmony_ci } 27867db96d56Sopenharmony_ci *eventEndPP = end; 27877db96d56Sopenharmony_ci if (parser->m_characterDataHandler) { 27887db96d56Sopenharmony_ci XML_Char c = 0xA; 27897db96d56Sopenharmony_ci parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); 27907db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 27917db96d56Sopenharmony_ci reportDefault(parser, enc, s, end); 27927db96d56Sopenharmony_ci /* We are at the end of the final buffer, should we check for 27937db96d56Sopenharmony_ci XML_SUSPENDED, XML_FINISHED? 27947db96d56Sopenharmony_ci */ 27957db96d56Sopenharmony_ci if (startTagLevel == 0) 27967db96d56Sopenharmony_ci return XML_ERROR_NO_ELEMENTS; 27977db96d56Sopenharmony_ci if (parser->m_tagLevel != startTagLevel) 27987db96d56Sopenharmony_ci return XML_ERROR_ASYNC_ENTITY; 27997db96d56Sopenharmony_ci *nextPtr = end; 28007db96d56Sopenharmony_ci return XML_ERROR_NONE; 28017db96d56Sopenharmony_ci case XML_TOK_NONE: 28027db96d56Sopenharmony_ci if (haveMore) { 28037db96d56Sopenharmony_ci *nextPtr = s; 28047db96d56Sopenharmony_ci return XML_ERROR_NONE; 28057db96d56Sopenharmony_ci } 28067db96d56Sopenharmony_ci if (startTagLevel > 0) { 28077db96d56Sopenharmony_ci if (parser->m_tagLevel != startTagLevel) 28087db96d56Sopenharmony_ci return XML_ERROR_ASYNC_ENTITY; 28097db96d56Sopenharmony_ci *nextPtr = s; 28107db96d56Sopenharmony_ci return XML_ERROR_NONE; 28117db96d56Sopenharmony_ci } 28127db96d56Sopenharmony_ci return XML_ERROR_NO_ELEMENTS; 28137db96d56Sopenharmony_ci case XML_TOK_INVALID: 28147db96d56Sopenharmony_ci *eventPP = next; 28157db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 28167db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 28177db96d56Sopenharmony_ci if (haveMore) { 28187db96d56Sopenharmony_ci *nextPtr = s; 28197db96d56Sopenharmony_ci return XML_ERROR_NONE; 28207db96d56Sopenharmony_ci } 28217db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_TOKEN; 28227db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 28237db96d56Sopenharmony_ci if (haveMore) { 28247db96d56Sopenharmony_ci *nextPtr = s; 28257db96d56Sopenharmony_ci return XML_ERROR_NONE; 28267db96d56Sopenharmony_ci } 28277db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 28287db96d56Sopenharmony_ci case XML_TOK_ENTITY_REF: { 28297db96d56Sopenharmony_ci const XML_Char *name; 28307db96d56Sopenharmony_ci ENTITY *entity; 28317db96d56Sopenharmony_ci XML_Char ch = (XML_Char)XmlPredefinedEntityName( 28327db96d56Sopenharmony_ci enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); 28337db96d56Sopenharmony_ci if (ch) { 28347db96d56Sopenharmony_ci#ifdef XML_DTD 28357db96d56Sopenharmony_ci /* NOTE: We are replacing 4-6 characters original input for 1 character 28367db96d56Sopenharmony_ci * so there is no amplification and hence recording without 28377db96d56Sopenharmony_ci * protection. */ 28387db96d56Sopenharmony_ci accountingDiffTolerated(parser, tok, (char *)&ch, 28397db96d56Sopenharmony_ci ((char *)&ch) + sizeof(XML_Char), __LINE__, 28407db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION); 28417db96d56Sopenharmony_ci#endif /* XML_DTD */ 28427db96d56Sopenharmony_ci if (parser->m_characterDataHandler) 28437db96d56Sopenharmony_ci parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); 28447db96d56Sopenharmony_ci else if (parser->m_defaultHandler) 28457db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 28467db96d56Sopenharmony_ci break; 28477db96d56Sopenharmony_ci } 28487db96d56Sopenharmony_ci name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, 28497db96d56Sopenharmony_ci next - enc->minBytesPerChar); 28507db96d56Sopenharmony_ci if (! name) 28517db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 28527db96d56Sopenharmony_ci entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); 28537db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 28547db96d56Sopenharmony_ci /* First, determine if a check for an existing declaration is needed; 28557db96d56Sopenharmony_ci if yes, check that the entity exists, and that it is internal, 28567db96d56Sopenharmony_ci otherwise call the skipped entity or default handler. 28577db96d56Sopenharmony_ci */ 28587db96d56Sopenharmony_ci if (! dtd->hasParamEntityRefs || dtd->standalone) { 28597db96d56Sopenharmony_ci if (! entity) 28607db96d56Sopenharmony_ci return XML_ERROR_UNDEFINED_ENTITY; 28617db96d56Sopenharmony_ci else if (! entity->is_internal) 28627db96d56Sopenharmony_ci return XML_ERROR_ENTITY_DECLARED_IN_PE; 28637db96d56Sopenharmony_ci } else if (! entity) { 28647db96d56Sopenharmony_ci if (parser->m_skippedEntityHandler) 28657db96d56Sopenharmony_ci parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); 28667db96d56Sopenharmony_ci else if (parser->m_defaultHandler) 28677db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 28687db96d56Sopenharmony_ci break; 28697db96d56Sopenharmony_ci } 28707db96d56Sopenharmony_ci if (entity->open) 28717db96d56Sopenharmony_ci return XML_ERROR_RECURSIVE_ENTITY_REF; 28727db96d56Sopenharmony_ci if (entity->notation) 28737db96d56Sopenharmony_ci return XML_ERROR_BINARY_ENTITY_REF; 28747db96d56Sopenharmony_ci if (entity->textPtr) { 28757db96d56Sopenharmony_ci enum XML_Error result; 28767db96d56Sopenharmony_ci if (! parser->m_defaultExpandInternalEntities) { 28777db96d56Sopenharmony_ci if (parser->m_skippedEntityHandler) 28787db96d56Sopenharmony_ci parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 28797db96d56Sopenharmony_ci 0); 28807db96d56Sopenharmony_ci else if (parser->m_defaultHandler) 28817db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 28827db96d56Sopenharmony_ci break; 28837db96d56Sopenharmony_ci } 28847db96d56Sopenharmony_ci result = processInternalEntity(parser, entity, XML_FALSE); 28857db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 28867db96d56Sopenharmony_ci return result; 28877db96d56Sopenharmony_ci } else if (parser->m_externalEntityRefHandler) { 28887db96d56Sopenharmony_ci const XML_Char *context; 28897db96d56Sopenharmony_ci entity->open = XML_TRUE; 28907db96d56Sopenharmony_ci context = getContext(parser); 28917db96d56Sopenharmony_ci entity->open = XML_FALSE; 28927db96d56Sopenharmony_ci if (! context) 28937db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 28947db96d56Sopenharmony_ci if (! parser->m_externalEntityRefHandler( 28957db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg, context, entity->base, 28967db96d56Sopenharmony_ci entity->systemId, entity->publicId)) 28977db96d56Sopenharmony_ci return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 28987db96d56Sopenharmony_ci poolDiscard(&parser->m_tempPool); 28997db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 29007db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 29017db96d56Sopenharmony_ci break; 29027db96d56Sopenharmony_ci } 29037db96d56Sopenharmony_ci case XML_TOK_START_TAG_NO_ATTS: 29047db96d56Sopenharmony_ci /* fall through */ 29057db96d56Sopenharmony_ci case XML_TOK_START_TAG_WITH_ATTS: { 29067db96d56Sopenharmony_ci TAG *tag; 29077db96d56Sopenharmony_ci enum XML_Error result; 29087db96d56Sopenharmony_ci XML_Char *toPtr; 29097db96d56Sopenharmony_ci if (parser->m_freeTagList) { 29107db96d56Sopenharmony_ci tag = parser->m_freeTagList; 29117db96d56Sopenharmony_ci parser->m_freeTagList = parser->m_freeTagList->parent; 29127db96d56Sopenharmony_ci } else { 29137db96d56Sopenharmony_ci tag = (TAG *)MALLOC(parser, sizeof(TAG)); 29147db96d56Sopenharmony_ci if (! tag) 29157db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 29167db96d56Sopenharmony_ci tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); 29177db96d56Sopenharmony_ci if (! tag->buf) { 29187db96d56Sopenharmony_ci FREE(parser, tag); 29197db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 29207db96d56Sopenharmony_ci } 29217db96d56Sopenharmony_ci tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; 29227db96d56Sopenharmony_ci } 29237db96d56Sopenharmony_ci tag->bindings = NULL; 29247db96d56Sopenharmony_ci tag->parent = parser->m_tagStack; 29257db96d56Sopenharmony_ci parser->m_tagStack = tag; 29267db96d56Sopenharmony_ci tag->name.localPart = NULL; 29277db96d56Sopenharmony_ci tag->name.prefix = NULL; 29287db96d56Sopenharmony_ci tag->rawName = s + enc->minBytesPerChar; 29297db96d56Sopenharmony_ci tag->rawNameLength = XmlNameLength(enc, tag->rawName); 29307db96d56Sopenharmony_ci ++parser->m_tagLevel; 29317db96d56Sopenharmony_ci { 29327db96d56Sopenharmony_ci const char *rawNameEnd = tag->rawName + tag->rawNameLength; 29337db96d56Sopenharmony_ci const char *fromPtr = tag->rawName; 29347db96d56Sopenharmony_ci toPtr = (XML_Char *)tag->buf; 29357db96d56Sopenharmony_ci for (;;) { 29367db96d56Sopenharmony_ci int bufSize; 29377db96d56Sopenharmony_ci int convLen; 29387db96d56Sopenharmony_ci const enum XML_Convert_Result convert_res 29397db96d56Sopenharmony_ci = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, 29407db96d56Sopenharmony_ci (ICHAR *)tag->bufEnd - 1); 29417db96d56Sopenharmony_ci convLen = (int)(toPtr - (XML_Char *)tag->buf); 29427db96d56Sopenharmony_ci if ((fromPtr >= rawNameEnd) 29437db96d56Sopenharmony_ci || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { 29447db96d56Sopenharmony_ci tag->name.strLen = convLen; 29457db96d56Sopenharmony_ci break; 29467db96d56Sopenharmony_ci } 29477db96d56Sopenharmony_ci bufSize = (int)(tag->bufEnd - tag->buf) << 1; 29487db96d56Sopenharmony_ci { 29497db96d56Sopenharmony_ci char *temp = (char *)REALLOC(parser, tag->buf, bufSize); 29507db96d56Sopenharmony_ci if (temp == NULL) 29517db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 29527db96d56Sopenharmony_ci tag->buf = temp; 29537db96d56Sopenharmony_ci tag->bufEnd = temp + bufSize; 29547db96d56Sopenharmony_ci toPtr = (XML_Char *)temp + convLen; 29557db96d56Sopenharmony_ci } 29567db96d56Sopenharmony_ci } 29577db96d56Sopenharmony_ci } 29587db96d56Sopenharmony_ci tag->name.str = (XML_Char *)tag->buf; 29597db96d56Sopenharmony_ci *toPtr = XML_T('\0'); 29607db96d56Sopenharmony_ci result 29617db96d56Sopenharmony_ci = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account); 29627db96d56Sopenharmony_ci if (result) 29637db96d56Sopenharmony_ci return result; 29647db96d56Sopenharmony_ci if (parser->m_startElementHandler) 29657db96d56Sopenharmony_ci parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, 29667db96d56Sopenharmony_ci (const XML_Char **)parser->m_atts); 29677db96d56Sopenharmony_ci else if (parser->m_defaultHandler) 29687db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 29697db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 29707db96d56Sopenharmony_ci break; 29717db96d56Sopenharmony_ci } 29727db96d56Sopenharmony_ci case XML_TOK_EMPTY_ELEMENT_NO_ATTS: 29737db96d56Sopenharmony_ci /* fall through */ 29747db96d56Sopenharmony_ci case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: { 29757db96d56Sopenharmony_ci const char *rawName = s + enc->minBytesPerChar; 29767db96d56Sopenharmony_ci enum XML_Error result; 29777db96d56Sopenharmony_ci BINDING *bindings = NULL; 29787db96d56Sopenharmony_ci XML_Bool noElmHandlers = XML_TRUE; 29797db96d56Sopenharmony_ci TAG_NAME name; 29807db96d56Sopenharmony_ci name.str = poolStoreString(&parser->m_tempPool, enc, rawName, 29817db96d56Sopenharmony_ci rawName + XmlNameLength(enc, rawName)); 29827db96d56Sopenharmony_ci if (! name.str) 29837db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 29847db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 29857db96d56Sopenharmony_ci result = storeAtts(parser, enc, s, &name, &bindings, 29867db96d56Sopenharmony_ci XML_ACCOUNT_NONE /* token spans whole start tag */); 29877db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) { 29887db96d56Sopenharmony_ci freeBindings(parser, bindings); 29897db96d56Sopenharmony_ci return result; 29907db96d56Sopenharmony_ci } 29917db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 29927db96d56Sopenharmony_ci if (parser->m_startElementHandler) { 29937db96d56Sopenharmony_ci parser->m_startElementHandler(parser->m_handlerArg, name.str, 29947db96d56Sopenharmony_ci (const XML_Char **)parser->m_atts); 29957db96d56Sopenharmony_ci noElmHandlers = XML_FALSE; 29967db96d56Sopenharmony_ci } 29977db96d56Sopenharmony_ci if (parser->m_endElementHandler) { 29987db96d56Sopenharmony_ci if (parser->m_startElementHandler) 29997db96d56Sopenharmony_ci *eventPP = *eventEndPP; 30007db96d56Sopenharmony_ci parser->m_endElementHandler(parser->m_handlerArg, name.str); 30017db96d56Sopenharmony_ci noElmHandlers = XML_FALSE; 30027db96d56Sopenharmony_ci } 30037db96d56Sopenharmony_ci if (noElmHandlers && parser->m_defaultHandler) 30047db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 30057db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 30067db96d56Sopenharmony_ci freeBindings(parser, bindings); 30077db96d56Sopenharmony_ci } 30087db96d56Sopenharmony_ci if ((parser->m_tagLevel == 0) 30097db96d56Sopenharmony_ci && (parser->m_parsingStatus.parsing != XML_FINISHED)) { 30107db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_SUSPENDED) 30117db96d56Sopenharmony_ci parser->m_processor = epilogProcessor; 30127db96d56Sopenharmony_ci else 30137db96d56Sopenharmony_ci return epilogProcessor(parser, next, end, nextPtr); 30147db96d56Sopenharmony_ci } 30157db96d56Sopenharmony_ci break; 30167db96d56Sopenharmony_ci case XML_TOK_END_TAG: 30177db96d56Sopenharmony_ci if (parser->m_tagLevel == startTagLevel) 30187db96d56Sopenharmony_ci return XML_ERROR_ASYNC_ENTITY; 30197db96d56Sopenharmony_ci else { 30207db96d56Sopenharmony_ci int len; 30217db96d56Sopenharmony_ci const char *rawName; 30227db96d56Sopenharmony_ci TAG *tag = parser->m_tagStack; 30237db96d56Sopenharmony_ci rawName = s + enc->minBytesPerChar * 2; 30247db96d56Sopenharmony_ci len = XmlNameLength(enc, rawName); 30257db96d56Sopenharmony_ci if (len != tag->rawNameLength 30267db96d56Sopenharmony_ci || memcmp(tag->rawName, rawName, len) != 0) { 30277db96d56Sopenharmony_ci *eventPP = rawName; 30287db96d56Sopenharmony_ci return XML_ERROR_TAG_MISMATCH; 30297db96d56Sopenharmony_ci } 30307db96d56Sopenharmony_ci parser->m_tagStack = tag->parent; 30317db96d56Sopenharmony_ci tag->parent = parser->m_freeTagList; 30327db96d56Sopenharmony_ci parser->m_freeTagList = tag; 30337db96d56Sopenharmony_ci --parser->m_tagLevel; 30347db96d56Sopenharmony_ci if (parser->m_endElementHandler) { 30357db96d56Sopenharmony_ci const XML_Char *localPart; 30367db96d56Sopenharmony_ci const XML_Char *prefix; 30377db96d56Sopenharmony_ci XML_Char *uri; 30387db96d56Sopenharmony_ci localPart = tag->name.localPart; 30397db96d56Sopenharmony_ci if (parser->m_ns && localPart) { 30407db96d56Sopenharmony_ci /* localPart and prefix may have been overwritten in 30417db96d56Sopenharmony_ci tag->name.str, since this points to the binding->uri 30427db96d56Sopenharmony_ci buffer which gets re-used; so we have to add them again 30437db96d56Sopenharmony_ci */ 30447db96d56Sopenharmony_ci uri = (XML_Char *)tag->name.str + tag->name.uriLen; 30457db96d56Sopenharmony_ci /* don't need to check for space - already done in storeAtts() */ 30467db96d56Sopenharmony_ci while (*localPart) 30477db96d56Sopenharmony_ci *uri++ = *localPart++; 30487db96d56Sopenharmony_ci prefix = (XML_Char *)tag->name.prefix; 30497db96d56Sopenharmony_ci if (parser->m_ns_triplets && prefix) { 30507db96d56Sopenharmony_ci *uri++ = parser->m_namespaceSeparator; 30517db96d56Sopenharmony_ci while (*prefix) 30527db96d56Sopenharmony_ci *uri++ = *prefix++; 30537db96d56Sopenharmony_ci } 30547db96d56Sopenharmony_ci *uri = XML_T('\0'); 30557db96d56Sopenharmony_ci } 30567db96d56Sopenharmony_ci parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); 30577db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 30587db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 30597db96d56Sopenharmony_ci while (tag->bindings) { 30607db96d56Sopenharmony_ci BINDING *b = tag->bindings; 30617db96d56Sopenharmony_ci if (parser->m_endNamespaceDeclHandler) 30627db96d56Sopenharmony_ci parser->m_endNamespaceDeclHandler(parser->m_handlerArg, 30637db96d56Sopenharmony_ci b->prefix->name); 30647db96d56Sopenharmony_ci tag->bindings = tag->bindings->nextTagBinding; 30657db96d56Sopenharmony_ci b->nextTagBinding = parser->m_freeBindingList; 30667db96d56Sopenharmony_ci parser->m_freeBindingList = b; 30677db96d56Sopenharmony_ci b->prefix->binding = b->prevPrefixBinding; 30687db96d56Sopenharmony_ci } 30697db96d56Sopenharmony_ci if ((parser->m_tagLevel == 0) 30707db96d56Sopenharmony_ci && (parser->m_parsingStatus.parsing != XML_FINISHED)) { 30717db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_SUSPENDED) 30727db96d56Sopenharmony_ci parser->m_processor = epilogProcessor; 30737db96d56Sopenharmony_ci else 30747db96d56Sopenharmony_ci return epilogProcessor(parser, next, end, nextPtr); 30757db96d56Sopenharmony_ci } 30767db96d56Sopenharmony_ci } 30777db96d56Sopenharmony_ci break; 30787db96d56Sopenharmony_ci case XML_TOK_CHAR_REF: { 30797db96d56Sopenharmony_ci int n = XmlCharRefNumber(enc, s); 30807db96d56Sopenharmony_ci if (n < 0) 30817db96d56Sopenharmony_ci return XML_ERROR_BAD_CHAR_REF; 30827db96d56Sopenharmony_ci if (parser->m_characterDataHandler) { 30837db96d56Sopenharmony_ci XML_Char buf[XML_ENCODE_MAX]; 30847db96d56Sopenharmony_ci parser->m_characterDataHandler(parser->m_handlerArg, buf, 30857db96d56Sopenharmony_ci XmlEncode(n, (ICHAR *)buf)); 30867db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 30877db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 30887db96d56Sopenharmony_ci } break; 30897db96d56Sopenharmony_ci case XML_TOK_XML_DECL: 30907db96d56Sopenharmony_ci return XML_ERROR_MISPLACED_XML_PI; 30917db96d56Sopenharmony_ci case XML_TOK_DATA_NEWLINE: 30927db96d56Sopenharmony_ci if (parser->m_characterDataHandler) { 30937db96d56Sopenharmony_ci XML_Char c = 0xA; 30947db96d56Sopenharmony_ci parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); 30957db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 30967db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 30977db96d56Sopenharmony_ci break; 30987db96d56Sopenharmony_ci case XML_TOK_CDATA_SECT_OPEN: { 30997db96d56Sopenharmony_ci enum XML_Error result; 31007db96d56Sopenharmony_ci if (parser->m_startCdataSectionHandler) 31017db96d56Sopenharmony_ci parser->m_startCdataSectionHandler(parser->m_handlerArg); 31027db96d56Sopenharmony_ci /* BEGIN disabled code */ 31037db96d56Sopenharmony_ci /* Suppose you doing a transformation on a document that involves 31047db96d56Sopenharmony_ci changing only the character data. You set up a defaultHandler 31057db96d56Sopenharmony_ci and a characterDataHandler. The defaultHandler simply copies 31067db96d56Sopenharmony_ci characters through. The characterDataHandler does the 31077db96d56Sopenharmony_ci transformation and writes the characters out escaping them as 31087db96d56Sopenharmony_ci necessary. This case will fail to work if we leave out the 31097db96d56Sopenharmony_ci following two lines (because & and < inside CDATA sections will 31107db96d56Sopenharmony_ci be incorrectly escaped). 31117db96d56Sopenharmony_ci 31127db96d56Sopenharmony_ci However, now we have a start/endCdataSectionHandler, so it seems 31137db96d56Sopenharmony_ci easier to let the user deal with this. 31147db96d56Sopenharmony_ci */ 31157db96d56Sopenharmony_ci else if (0 && parser->m_characterDataHandler) 31167db96d56Sopenharmony_ci parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 31177db96d56Sopenharmony_ci 0); 31187db96d56Sopenharmony_ci /* END disabled code */ 31197db96d56Sopenharmony_ci else if (parser->m_defaultHandler) 31207db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 31217db96d56Sopenharmony_ci result 31227db96d56Sopenharmony_ci = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account); 31237db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 31247db96d56Sopenharmony_ci return result; 31257db96d56Sopenharmony_ci else if (! next) { 31267db96d56Sopenharmony_ci parser->m_processor = cdataSectionProcessor; 31277db96d56Sopenharmony_ci return result; 31287db96d56Sopenharmony_ci } 31297db96d56Sopenharmony_ci } break; 31307db96d56Sopenharmony_ci case XML_TOK_TRAILING_RSQB: 31317db96d56Sopenharmony_ci if (haveMore) { 31327db96d56Sopenharmony_ci *nextPtr = s; 31337db96d56Sopenharmony_ci return XML_ERROR_NONE; 31347db96d56Sopenharmony_ci } 31357db96d56Sopenharmony_ci if (parser->m_characterDataHandler) { 31367db96d56Sopenharmony_ci if (MUST_CONVERT(enc, s)) { 31377db96d56Sopenharmony_ci ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; 31387db96d56Sopenharmony_ci XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); 31397db96d56Sopenharmony_ci parser->m_characterDataHandler( 31407db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_dataBuf, 31417db96d56Sopenharmony_ci (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); 31427db96d56Sopenharmony_ci } else 31437db96d56Sopenharmony_ci parser->m_characterDataHandler( 31447db96d56Sopenharmony_ci parser->m_handlerArg, (XML_Char *)s, 31457db96d56Sopenharmony_ci (int)((XML_Char *)end - (XML_Char *)s)); 31467db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 31477db96d56Sopenharmony_ci reportDefault(parser, enc, s, end); 31487db96d56Sopenharmony_ci /* We are at the end of the final buffer, should we check for 31497db96d56Sopenharmony_ci XML_SUSPENDED, XML_FINISHED? 31507db96d56Sopenharmony_ci */ 31517db96d56Sopenharmony_ci if (startTagLevel == 0) { 31527db96d56Sopenharmony_ci *eventPP = end; 31537db96d56Sopenharmony_ci return XML_ERROR_NO_ELEMENTS; 31547db96d56Sopenharmony_ci } 31557db96d56Sopenharmony_ci if (parser->m_tagLevel != startTagLevel) { 31567db96d56Sopenharmony_ci *eventPP = end; 31577db96d56Sopenharmony_ci return XML_ERROR_ASYNC_ENTITY; 31587db96d56Sopenharmony_ci } 31597db96d56Sopenharmony_ci *nextPtr = end; 31607db96d56Sopenharmony_ci return XML_ERROR_NONE; 31617db96d56Sopenharmony_ci case XML_TOK_DATA_CHARS: { 31627db96d56Sopenharmony_ci XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; 31637db96d56Sopenharmony_ci if (charDataHandler) { 31647db96d56Sopenharmony_ci if (MUST_CONVERT(enc, s)) { 31657db96d56Sopenharmony_ci for (;;) { 31667db96d56Sopenharmony_ci ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; 31677db96d56Sopenharmony_ci const enum XML_Convert_Result convert_res = XmlConvert( 31687db96d56Sopenharmony_ci enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); 31697db96d56Sopenharmony_ci *eventEndPP = s; 31707db96d56Sopenharmony_ci charDataHandler(parser->m_handlerArg, parser->m_dataBuf, 31717db96d56Sopenharmony_ci (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); 31727db96d56Sopenharmony_ci if ((convert_res == XML_CONVERT_COMPLETED) 31737db96d56Sopenharmony_ci || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) 31747db96d56Sopenharmony_ci break; 31757db96d56Sopenharmony_ci *eventPP = s; 31767db96d56Sopenharmony_ci } 31777db96d56Sopenharmony_ci } else 31787db96d56Sopenharmony_ci charDataHandler(parser->m_handlerArg, (XML_Char *)s, 31797db96d56Sopenharmony_ci (int)((XML_Char *)next - (XML_Char *)s)); 31807db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 31817db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 31827db96d56Sopenharmony_ci } break; 31837db96d56Sopenharmony_ci case XML_TOK_PI: 31847db96d56Sopenharmony_ci if (! reportProcessingInstruction(parser, enc, s, next)) 31857db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 31867db96d56Sopenharmony_ci break; 31877db96d56Sopenharmony_ci case XML_TOK_COMMENT: 31887db96d56Sopenharmony_ci if (! reportComment(parser, enc, s, next)) 31897db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 31907db96d56Sopenharmony_ci break; 31917db96d56Sopenharmony_ci default: 31927db96d56Sopenharmony_ci /* All of the tokens produced by XmlContentTok() have their own 31937db96d56Sopenharmony_ci * explicit cases, so this default is not strictly necessary. 31947db96d56Sopenharmony_ci * However it is a useful safety net, so we retain the code and 31957db96d56Sopenharmony_ci * simply exclude it from the coverage tests. 31967db96d56Sopenharmony_ci * 31977db96d56Sopenharmony_ci * LCOV_EXCL_START 31987db96d56Sopenharmony_ci */ 31997db96d56Sopenharmony_ci if (parser->m_defaultHandler) 32007db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 32017db96d56Sopenharmony_ci break; 32027db96d56Sopenharmony_ci /* LCOV_EXCL_STOP */ 32037db96d56Sopenharmony_ci } 32047db96d56Sopenharmony_ci *eventPP = s = next; 32057db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 32067db96d56Sopenharmony_ci case XML_SUSPENDED: 32077db96d56Sopenharmony_ci *nextPtr = next; 32087db96d56Sopenharmony_ci return XML_ERROR_NONE; 32097db96d56Sopenharmony_ci case XML_FINISHED: 32107db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 32117db96d56Sopenharmony_ci default:; 32127db96d56Sopenharmony_ci } 32137db96d56Sopenharmony_ci } 32147db96d56Sopenharmony_ci /* not reached */ 32157db96d56Sopenharmony_ci} 32167db96d56Sopenharmony_ci 32177db96d56Sopenharmony_ci/* This function does not call free() on the allocated memory, merely 32187db96d56Sopenharmony_ci * moving it to the parser's m_freeBindingList where it can be freed or 32197db96d56Sopenharmony_ci * reused as appropriate. 32207db96d56Sopenharmony_ci */ 32217db96d56Sopenharmony_cistatic void 32227db96d56Sopenharmony_cifreeBindings(XML_Parser parser, BINDING *bindings) { 32237db96d56Sopenharmony_ci while (bindings) { 32247db96d56Sopenharmony_ci BINDING *b = bindings; 32257db96d56Sopenharmony_ci 32267db96d56Sopenharmony_ci /* m_startNamespaceDeclHandler will have been called for this 32277db96d56Sopenharmony_ci * binding in addBindings(), so call the end handler now. 32287db96d56Sopenharmony_ci */ 32297db96d56Sopenharmony_ci if (parser->m_endNamespaceDeclHandler) 32307db96d56Sopenharmony_ci parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); 32317db96d56Sopenharmony_ci 32327db96d56Sopenharmony_ci bindings = bindings->nextTagBinding; 32337db96d56Sopenharmony_ci b->nextTagBinding = parser->m_freeBindingList; 32347db96d56Sopenharmony_ci parser->m_freeBindingList = b; 32357db96d56Sopenharmony_ci b->prefix->binding = b->prevPrefixBinding; 32367db96d56Sopenharmony_ci } 32377db96d56Sopenharmony_ci} 32387db96d56Sopenharmony_ci 32397db96d56Sopenharmony_ci/* Precondition: all arguments must be non-NULL; 32407db96d56Sopenharmony_ci Purpose: 32417db96d56Sopenharmony_ci - normalize attributes 32427db96d56Sopenharmony_ci - check attributes for well-formedness 32437db96d56Sopenharmony_ci - generate namespace aware attribute names (URI, prefix) 32447db96d56Sopenharmony_ci - build list of attributes for startElementHandler 32457db96d56Sopenharmony_ci - default attributes 32467db96d56Sopenharmony_ci - process namespace declarations (check and report them) 32477db96d56Sopenharmony_ci - generate namespace aware element name (URI, prefix) 32487db96d56Sopenharmony_ci*/ 32497db96d56Sopenharmony_cistatic enum XML_Error 32507db96d56Sopenharmony_cistoreAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, 32517db96d56Sopenharmony_ci TAG_NAME *tagNamePtr, BINDING **bindingsPtr, 32527db96d56Sopenharmony_ci enum XML_Account account) { 32537db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 32547db96d56Sopenharmony_ci ELEMENT_TYPE *elementType; 32557db96d56Sopenharmony_ci int nDefaultAtts; 32567db96d56Sopenharmony_ci const XML_Char **appAtts; /* the attribute list for the application */ 32577db96d56Sopenharmony_ci int attIndex = 0; 32587db96d56Sopenharmony_ci int prefixLen; 32597db96d56Sopenharmony_ci int i; 32607db96d56Sopenharmony_ci int n; 32617db96d56Sopenharmony_ci XML_Char *uri; 32627db96d56Sopenharmony_ci int nPrefixes = 0; 32637db96d56Sopenharmony_ci BINDING *binding; 32647db96d56Sopenharmony_ci const XML_Char *localPart; 32657db96d56Sopenharmony_ci 32667db96d56Sopenharmony_ci /* lookup the element type name */ 32677db96d56Sopenharmony_ci elementType 32687db96d56Sopenharmony_ci = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0); 32697db96d56Sopenharmony_ci if (! elementType) { 32707db96d56Sopenharmony_ci const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); 32717db96d56Sopenharmony_ci if (! name) 32727db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 32737db96d56Sopenharmony_ci elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, 32747db96d56Sopenharmony_ci sizeof(ELEMENT_TYPE)); 32757db96d56Sopenharmony_ci if (! elementType) 32767db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 32777db96d56Sopenharmony_ci if (parser->m_ns && ! setElementTypePrefix(parser, elementType)) 32787db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 32797db96d56Sopenharmony_ci } 32807db96d56Sopenharmony_ci nDefaultAtts = elementType->nDefaultAtts; 32817db96d56Sopenharmony_ci 32827db96d56Sopenharmony_ci /* get the attributes from the tokenizer */ 32837db96d56Sopenharmony_ci n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); 32847db96d56Sopenharmony_ci 32857db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 32867db96d56Sopenharmony_ci if (n > INT_MAX - nDefaultAtts) { 32877db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 32887db96d56Sopenharmony_ci } 32897db96d56Sopenharmony_ci 32907db96d56Sopenharmony_ci if (n + nDefaultAtts > parser->m_attsSize) { 32917db96d56Sopenharmony_ci int oldAttsSize = parser->m_attsSize; 32927db96d56Sopenharmony_ci ATTRIBUTE *temp; 32937db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 32947db96d56Sopenharmony_ci XML_AttrInfo *temp2; 32957db96d56Sopenharmony_ci#endif 32967db96d56Sopenharmony_ci 32977db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 32987db96d56Sopenharmony_ci if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE) 32997db96d56Sopenharmony_ci || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) { 33007db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 33017db96d56Sopenharmony_ci } 33027db96d56Sopenharmony_ci 33037db96d56Sopenharmony_ci parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; 33047db96d56Sopenharmony_ci 33057db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 33067db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 33077db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 33087db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 33097db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 33107db96d56Sopenharmony_ci if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) { 33117db96d56Sopenharmony_ci parser->m_attsSize = oldAttsSize; 33127db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 33137db96d56Sopenharmony_ci } 33147db96d56Sopenharmony_ci#endif 33157db96d56Sopenharmony_ci 33167db96d56Sopenharmony_ci temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, 33177db96d56Sopenharmony_ci parser->m_attsSize * sizeof(ATTRIBUTE)); 33187db96d56Sopenharmony_ci if (temp == NULL) { 33197db96d56Sopenharmony_ci parser->m_attsSize = oldAttsSize; 33207db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 33217db96d56Sopenharmony_ci } 33227db96d56Sopenharmony_ci parser->m_atts = temp; 33237db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 33247db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 33257db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 33267db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 33277db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 33287db96d56Sopenharmony_ci# if UINT_MAX >= SIZE_MAX 33297db96d56Sopenharmony_ci if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) { 33307db96d56Sopenharmony_ci parser->m_attsSize = oldAttsSize; 33317db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 33327db96d56Sopenharmony_ci } 33337db96d56Sopenharmony_ci# endif 33347db96d56Sopenharmony_ci 33357db96d56Sopenharmony_ci temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, 33367db96d56Sopenharmony_ci parser->m_attsSize * sizeof(XML_AttrInfo)); 33377db96d56Sopenharmony_ci if (temp2 == NULL) { 33387db96d56Sopenharmony_ci parser->m_attsSize = oldAttsSize; 33397db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 33407db96d56Sopenharmony_ci } 33417db96d56Sopenharmony_ci parser->m_attInfo = temp2; 33427db96d56Sopenharmony_ci#endif 33437db96d56Sopenharmony_ci if (n > oldAttsSize) 33447db96d56Sopenharmony_ci XmlGetAttributes(enc, attStr, n, parser->m_atts); 33457db96d56Sopenharmony_ci } 33467db96d56Sopenharmony_ci 33477db96d56Sopenharmony_ci appAtts = (const XML_Char **)parser->m_atts; 33487db96d56Sopenharmony_ci for (i = 0; i < n; i++) { 33497db96d56Sopenharmony_ci ATTRIBUTE *currAtt = &parser->m_atts[i]; 33507db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 33517db96d56Sopenharmony_ci XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; 33527db96d56Sopenharmony_ci#endif 33537db96d56Sopenharmony_ci /* add the name and value to the attribute list */ 33547db96d56Sopenharmony_ci ATTRIBUTE_ID *attId 33557db96d56Sopenharmony_ci = getAttributeId(parser, enc, currAtt->name, 33567db96d56Sopenharmony_ci currAtt->name + XmlNameLength(enc, currAtt->name)); 33577db96d56Sopenharmony_ci if (! attId) 33587db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 33597db96d56Sopenharmony_ci#ifdef XML_ATTR_INFO 33607db96d56Sopenharmony_ci currAttInfo->nameStart 33617db96d56Sopenharmony_ci = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); 33627db96d56Sopenharmony_ci currAttInfo->nameEnd 33637db96d56Sopenharmony_ci = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name); 33647db96d56Sopenharmony_ci currAttInfo->valueStart = parser->m_parseEndByteIndex 33657db96d56Sopenharmony_ci - (parser->m_parseEndPtr - currAtt->valuePtr); 33667db96d56Sopenharmony_ci currAttInfo->valueEnd = parser->m_parseEndByteIndex 33677db96d56Sopenharmony_ci - (parser->m_parseEndPtr - currAtt->valueEnd); 33687db96d56Sopenharmony_ci#endif 33697db96d56Sopenharmony_ci /* Detect duplicate attributes by their QNames. This does not work when 33707db96d56Sopenharmony_ci namespace processing is turned on and different prefixes for the same 33717db96d56Sopenharmony_ci namespace are used. For this case we have a check further down. 33727db96d56Sopenharmony_ci */ 33737db96d56Sopenharmony_ci if ((attId->name)[-1]) { 33747db96d56Sopenharmony_ci if (enc == parser->m_encoding) 33757db96d56Sopenharmony_ci parser->m_eventPtr = parser->m_atts[i].name; 33767db96d56Sopenharmony_ci return XML_ERROR_DUPLICATE_ATTRIBUTE; 33777db96d56Sopenharmony_ci } 33787db96d56Sopenharmony_ci (attId->name)[-1] = 1; 33797db96d56Sopenharmony_ci appAtts[attIndex++] = attId->name; 33807db96d56Sopenharmony_ci if (! parser->m_atts[i].normalized) { 33817db96d56Sopenharmony_ci enum XML_Error result; 33827db96d56Sopenharmony_ci XML_Bool isCdata = XML_TRUE; 33837db96d56Sopenharmony_ci 33847db96d56Sopenharmony_ci /* figure out whether declared as other than CDATA */ 33857db96d56Sopenharmony_ci if (attId->maybeTokenized) { 33867db96d56Sopenharmony_ci int j; 33877db96d56Sopenharmony_ci for (j = 0; j < nDefaultAtts; j++) { 33887db96d56Sopenharmony_ci if (attId == elementType->defaultAtts[j].id) { 33897db96d56Sopenharmony_ci isCdata = elementType->defaultAtts[j].isCdata; 33907db96d56Sopenharmony_ci break; 33917db96d56Sopenharmony_ci } 33927db96d56Sopenharmony_ci } 33937db96d56Sopenharmony_ci } 33947db96d56Sopenharmony_ci 33957db96d56Sopenharmony_ci /* normalize the attribute value */ 33967db96d56Sopenharmony_ci result = storeAttributeValue( 33977db96d56Sopenharmony_ci parser, enc, isCdata, parser->m_atts[i].valuePtr, 33987db96d56Sopenharmony_ci parser->m_atts[i].valueEnd, &parser->m_tempPool, account); 33997db96d56Sopenharmony_ci if (result) 34007db96d56Sopenharmony_ci return result; 34017db96d56Sopenharmony_ci appAtts[attIndex] = poolStart(&parser->m_tempPool); 34027db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 34037db96d56Sopenharmony_ci } else { 34047db96d56Sopenharmony_ci /* the value did not need normalizing */ 34057db96d56Sopenharmony_ci appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, 34067db96d56Sopenharmony_ci parser->m_atts[i].valuePtr, 34077db96d56Sopenharmony_ci parser->m_atts[i].valueEnd); 34087db96d56Sopenharmony_ci if (appAtts[attIndex] == 0) 34097db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 34107db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 34117db96d56Sopenharmony_ci } 34127db96d56Sopenharmony_ci /* handle prefixed attribute names */ 34137db96d56Sopenharmony_ci if (attId->prefix) { 34147db96d56Sopenharmony_ci if (attId->xmlns) { 34157db96d56Sopenharmony_ci /* deal with namespace declarations here */ 34167db96d56Sopenharmony_ci enum XML_Error result = addBinding(parser, attId->prefix, attId, 34177db96d56Sopenharmony_ci appAtts[attIndex], bindingsPtr); 34187db96d56Sopenharmony_ci if (result) 34197db96d56Sopenharmony_ci return result; 34207db96d56Sopenharmony_ci --attIndex; 34217db96d56Sopenharmony_ci } else { 34227db96d56Sopenharmony_ci /* deal with other prefixed names later */ 34237db96d56Sopenharmony_ci attIndex++; 34247db96d56Sopenharmony_ci nPrefixes++; 34257db96d56Sopenharmony_ci (attId->name)[-1] = 2; 34267db96d56Sopenharmony_ci } 34277db96d56Sopenharmony_ci } else 34287db96d56Sopenharmony_ci attIndex++; 34297db96d56Sopenharmony_ci } 34307db96d56Sopenharmony_ci 34317db96d56Sopenharmony_ci /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ 34327db96d56Sopenharmony_ci parser->m_nSpecifiedAtts = attIndex; 34337db96d56Sopenharmony_ci if (elementType->idAtt && (elementType->idAtt->name)[-1]) { 34347db96d56Sopenharmony_ci for (i = 0; i < attIndex; i += 2) 34357db96d56Sopenharmony_ci if (appAtts[i] == elementType->idAtt->name) { 34367db96d56Sopenharmony_ci parser->m_idAttIndex = i; 34377db96d56Sopenharmony_ci break; 34387db96d56Sopenharmony_ci } 34397db96d56Sopenharmony_ci } else 34407db96d56Sopenharmony_ci parser->m_idAttIndex = -1; 34417db96d56Sopenharmony_ci 34427db96d56Sopenharmony_ci /* do attribute defaulting */ 34437db96d56Sopenharmony_ci for (i = 0; i < nDefaultAtts; i++) { 34447db96d56Sopenharmony_ci const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; 34457db96d56Sopenharmony_ci if (! (da->id->name)[-1] && da->value) { 34467db96d56Sopenharmony_ci if (da->id->prefix) { 34477db96d56Sopenharmony_ci if (da->id->xmlns) { 34487db96d56Sopenharmony_ci enum XML_Error result = addBinding(parser, da->id->prefix, da->id, 34497db96d56Sopenharmony_ci da->value, bindingsPtr); 34507db96d56Sopenharmony_ci if (result) 34517db96d56Sopenharmony_ci return result; 34527db96d56Sopenharmony_ci } else { 34537db96d56Sopenharmony_ci (da->id->name)[-1] = 2; 34547db96d56Sopenharmony_ci nPrefixes++; 34557db96d56Sopenharmony_ci appAtts[attIndex++] = da->id->name; 34567db96d56Sopenharmony_ci appAtts[attIndex++] = da->value; 34577db96d56Sopenharmony_ci } 34587db96d56Sopenharmony_ci } else { 34597db96d56Sopenharmony_ci (da->id->name)[-1] = 1; 34607db96d56Sopenharmony_ci appAtts[attIndex++] = da->id->name; 34617db96d56Sopenharmony_ci appAtts[attIndex++] = da->value; 34627db96d56Sopenharmony_ci } 34637db96d56Sopenharmony_ci } 34647db96d56Sopenharmony_ci } 34657db96d56Sopenharmony_ci appAtts[attIndex] = 0; 34667db96d56Sopenharmony_ci 34677db96d56Sopenharmony_ci /* expand prefixed attribute names, check for duplicates, 34687db96d56Sopenharmony_ci and clear flags that say whether attributes were specified */ 34697db96d56Sopenharmony_ci i = 0; 34707db96d56Sopenharmony_ci if (nPrefixes) { 34717db96d56Sopenharmony_ci int j; /* hash table index */ 34727db96d56Sopenharmony_ci unsigned long version = parser->m_nsAttsVersion; 34737db96d56Sopenharmony_ci 34747db96d56Sopenharmony_ci /* Detect and prevent invalid shift */ 34757db96d56Sopenharmony_ci if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) { 34767db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 34777db96d56Sopenharmony_ci } 34787db96d56Sopenharmony_ci 34797db96d56Sopenharmony_ci unsigned int nsAttsSize = 1u << parser->m_nsAttsPower; 34807db96d56Sopenharmony_ci unsigned char oldNsAttsPower = parser->m_nsAttsPower; 34817db96d56Sopenharmony_ci /* size of hash table must be at least 2 * (# of prefixed attributes) */ 34827db96d56Sopenharmony_ci if ((nPrefixes << 1) 34837db96d56Sopenharmony_ci >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ 34847db96d56Sopenharmony_ci NS_ATT *temp; 34857db96d56Sopenharmony_ci /* hash table size must also be a power of 2 and >= 8 */ 34867db96d56Sopenharmony_ci while (nPrefixes >> parser->m_nsAttsPower++) 34877db96d56Sopenharmony_ci ; 34887db96d56Sopenharmony_ci if (parser->m_nsAttsPower < 3) 34897db96d56Sopenharmony_ci parser->m_nsAttsPower = 3; 34907db96d56Sopenharmony_ci 34917db96d56Sopenharmony_ci /* Detect and prevent invalid shift */ 34927db96d56Sopenharmony_ci if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) { 34937db96d56Sopenharmony_ci /* Restore actual size of memory in m_nsAtts */ 34947db96d56Sopenharmony_ci parser->m_nsAttsPower = oldNsAttsPower; 34957db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 34967db96d56Sopenharmony_ci } 34977db96d56Sopenharmony_ci 34987db96d56Sopenharmony_ci nsAttsSize = 1u << parser->m_nsAttsPower; 34997db96d56Sopenharmony_ci 35007db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 35017db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 35027db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 35037db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 35047db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 35057db96d56Sopenharmony_ci if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) { 35067db96d56Sopenharmony_ci /* Restore actual size of memory in m_nsAtts */ 35077db96d56Sopenharmony_ci parser->m_nsAttsPower = oldNsAttsPower; 35087db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 35097db96d56Sopenharmony_ci } 35107db96d56Sopenharmony_ci#endif 35117db96d56Sopenharmony_ci 35127db96d56Sopenharmony_ci temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, 35137db96d56Sopenharmony_ci nsAttsSize * sizeof(NS_ATT)); 35147db96d56Sopenharmony_ci if (! temp) { 35157db96d56Sopenharmony_ci /* Restore actual size of memory in m_nsAtts */ 35167db96d56Sopenharmony_ci parser->m_nsAttsPower = oldNsAttsPower; 35177db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 35187db96d56Sopenharmony_ci } 35197db96d56Sopenharmony_ci parser->m_nsAtts = temp; 35207db96d56Sopenharmony_ci version = 0; /* force re-initialization of m_nsAtts hash table */ 35217db96d56Sopenharmony_ci } 35227db96d56Sopenharmony_ci /* using a version flag saves us from initializing m_nsAtts every time */ 35237db96d56Sopenharmony_ci if (! version) { /* initialize version flags when version wraps around */ 35247db96d56Sopenharmony_ci version = INIT_ATTS_VERSION; 35257db96d56Sopenharmony_ci for (j = nsAttsSize; j != 0;) 35267db96d56Sopenharmony_ci parser->m_nsAtts[--j].version = version; 35277db96d56Sopenharmony_ci } 35287db96d56Sopenharmony_ci parser->m_nsAttsVersion = --version; 35297db96d56Sopenharmony_ci 35307db96d56Sopenharmony_ci /* expand prefixed names and check for duplicates */ 35317db96d56Sopenharmony_ci for (; i < attIndex; i += 2) { 35327db96d56Sopenharmony_ci const XML_Char *s = appAtts[i]; 35337db96d56Sopenharmony_ci if (s[-1] == 2) { /* prefixed */ 35347db96d56Sopenharmony_ci ATTRIBUTE_ID *id; 35357db96d56Sopenharmony_ci const BINDING *b; 35367db96d56Sopenharmony_ci unsigned long uriHash; 35377db96d56Sopenharmony_ci struct siphash sip_state; 35387db96d56Sopenharmony_ci struct sipkey sip_key; 35397db96d56Sopenharmony_ci 35407db96d56Sopenharmony_ci copy_salt_to_sipkey(parser, &sip_key); 35417db96d56Sopenharmony_ci sip24_init(&sip_state, &sip_key); 35427db96d56Sopenharmony_ci 35437db96d56Sopenharmony_ci ((XML_Char *)s)[-1] = 0; /* clear flag */ 35447db96d56Sopenharmony_ci id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); 35457db96d56Sopenharmony_ci if (! id || ! id->prefix) { 35467db96d56Sopenharmony_ci /* This code is walking through the appAtts array, dealing 35477db96d56Sopenharmony_ci * with (in this case) a prefixed attribute name. To be in 35487db96d56Sopenharmony_ci * the array, the attribute must have already been bound, so 35497db96d56Sopenharmony_ci * has to have passed through the hash table lookup once 35507db96d56Sopenharmony_ci * already. That implies that an entry for it already 35517db96d56Sopenharmony_ci * exists, so the lookup above will return a pointer to 35527db96d56Sopenharmony_ci * already allocated memory. There is no opportunaity for 35537db96d56Sopenharmony_ci * the allocator to fail, so the condition above cannot be 35547db96d56Sopenharmony_ci * fulfilled. 35557db96d56Sopenharmony_ci * 35567db96d56Sopenharmony_ci * Since it is difficult to be certain that the above 35577db96d56Sopenharmony_ci * analysis is complete, we retain the test and merely 35587db96d56Sopenharmony_ci * remove the code from coverage tests. 35597db96d56Sopenharmony_ci */ 35607db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ 35617db96d56Sopenharmony_ci } 35627db96d56Sopenharmony_ci b = id->prefix->binding; 35637db96d56Sopenharmony_ci if (! b) 35647db96d56Sopenharmony_ci return XML_ERROR_UNBOUND_PREFIX; 35657db96d56Sopenharmony_ci 35667db96d56Sopenharmony_ci for (j = 0; j < b->uriLen; j++) { 35677db96d56Sopenharmony_ci const XML_Char c = b->uri[j]; 35687db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, c)) 35697db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 35707db96d56Sopenharmony_ci } 35717db96d56Sopenharmony_ci 35727db96d56Sopenharmony_ci sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); 35737db96d56Sopenharmony_ci 35747db96d56Sopenharmony_ci while (*s++ != XML_T(ASCII_COLON)) 35757db96d56Sopenharmony_ci ; 35767db96d56Sopenharmony_ci 35777db96d56Sopenharmony_ci sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); 35787db96d56Sopenharmony_ci 35797db96d56Sopenharmony_ci do { /* copies null terminator */ 35807db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, *s)) 35817db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 35827db96d56Sopenharmony_ci } while (*s++); 35837db96d56Sopenharmony_ci 35847db96d56Sopenharmony_ci uriHash = (unsigned long)sip24_final(&sip_state); 35857db96d56Sopenharmony_ci 35867db96d56Sopenharmony_ci { /* Check hash table for duplicate of expanded name (uriName). 35877db96d56Sopenharmony_ci Derived from code in lookup(parser, HASH_TABLE *table, ...). 35887db96d56Sopenharmony_ci */ 35897db96d56Sopenharmony_ci unsigned char step = 0; 35907db96d56Sopenharmony_ci unsigned long mask = nsAttsSize - 1; 35917db96d56Sopenharmony_ci j = uriHash & mask; /* index into hash table */ 35927db96d56Sopenharmony_ci while (parser->m_nsAtts[j].version == version) { 35937db96d56Sopenharmony_ci /* for speed we compare stored hash values first */ 35947db96d56Sopenharmony_ci if (uriHash == parser->m_nsAtts[j].hash) { 35957db96d56Sopenharmony_ci const XML_Char *s1 = poolStart(&parser->m_tempPool); 35967db96d56Sopenharmony_ci const XML_Char *s2 = parser->m_nsAtts[j].uriName; 35977db96d56Sopenharmony_ci /* s1 is null terminated, but not s2 */ 35987db96d56Sopenharmony_ci for (; *s1 == *s2 && *s1 != 0; s1++, s2++) 35997db96d56Sopenharmony_ci ; 36007db96d56Sopenharmony_ci if (*s1 == 0) 36017db96d56Sopenharmony_ci return XML_ERROR_DUPLICATE_ATTRIBUTE; 36027db96d56Sopenharmony_ci } 36037db96d56Sopenharmony_ci if (! step) 36047db96d56Sopenharmony_ci step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); 36057db96d56Sopenharmony_ci j < step ? (j += nsAttsSize - step) : (j -= step); 36067db96d56Sopenharmony_ci } 36077db96d56Sopenharmony_ci } 36087db96d56Sopenharmony_ci 36097db96d56Sopenharmony_ci if (parser->m_ns_triplets) { /* append namespace separator and prefix */ 36107db96d56Sopenharmony_ci parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; 36117db96d56Sopenharmony_ci s = b->prefix->name; 36127db96d56Sopenharmony_ci do { 36137db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, *s)) 36147db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 36157db96d56Sopenharmony_ci } while (*s++); 36167db96d56Sopenharmony_ci } 36177db96d56Sopenharmony_ci 36187db96d56Sopenharmony_ci /* store expanded name in attribute list */ 36197db96d56Sopenharmony_ci s = poolStart(&parser->m_tempPool); 36207db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 36217db96d56Sopenharmony_ci appAtts[i] = s; 36227db96d56Sopenharmony_ci 36237db96d56Sopenharmony_ci /* fill empty slot with new version, uriName and hash value */ 36247db96d56Sopenharmony_ci parser->m_nsAtts[j].version = version; 36257db96d56Sopenharmony_ci parser->m_nsAtts[j].hash = uriHash; 36267db96d56Sopenharmony_ci parser->m_nsAtts[j].uriName = s; 36277db96d56Sopenharmony_ci 36287db96d56Sopenharmony_ci if (! --nPrefixes) { 36297db96d56Sopenharmony_ci i += 2; 36307db96d56Sopenharmony_ci break; 36317db96d56Sopenharmony_ci } 36327db96d56Sopenharmony_ci } else /* not prefixed */ 36337db96d56Sopenharmony_ci ((XML_Char *)s)[-1] = 0; /* clear flag */ 36347db96d56Sopenharmony_ci } 36357db96d56Sopenharmony_ci } 36367db96d56Sopenharmony_ci /* clear flags for the remaining attributes */ 36377db96d56Sopenharmony_ci for (; i < attIndex; i += 2) 36387db96d56Sopenharmony_ci ((XML_Char *)(appAtts[i]))[-1] = 0; 36397db96d56Sopenharmony_ci for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) 36407db96d56Sopenharmony_ci binding->attId->name[-1] = 0; 36417db96d56Sopenharmony_ci 36427db96d56Sopenharmony_ci if (! parser->m_ns) 36437db96d56Sopenharmony_ci return XML_ERROR_NONE; 36447db96d56Sopenharmony_ci 36457db96d56Sopenharmony_ci /* expand the element type name */ 36467db96d56Sopenharmony_ci if (elementType->prefix) { 36477db96d56Sopenharmony_ci binding = elementType->prefix->binding; 36487db96d56Sopenharmony_ci if (! binding) 36497db96d56Sopenharmony_ci return XML_ERROR_UNBOUND_PREFIX; 36507db96d56Sopenharmony_ci localPart = tagNamePtr->str; 36517db96d56Sopenharmony_ci while (*localPart++ != XML_T(ASCII_COLON)) 36527db96d56Sopenharmony_ci ; 36537db96d56Sopenharmony_ci } else if (dtd->defaultPrefix.binding) { 36547db96d56Sopenharmony_ci binding = dtd->defaultPrefix.binding; 36557db96d56Sopenharmony_ci localPart = tagNamePtr->str; 36567db96d56Sopenharmony_ci } else 36577db96d56Sopenharmony_ci return XML_ERROR_NONE; 36587db96d56Sopenharmony_ci prefixLen = 0; 36597db96d56Sopenharmony_ci if (parser->m_ns_triplets && binding->prefix->name) { 36607db96d56Sopenharmony_ci for (; binding->prefix->name[prefixLen++];) 36617db96d56Sopenharmony_ci ; /* prefixLen includes null terminator */ 36627db96d56Sopenharmony_ci } 36637db96d56Sopenharmony_ci tagNamePtr->localPart = localPart; 36647db96d56Sopenharmony_ci tagNamePtr->uriLen = binding->uriLen; 36657db96d56Sopenharmony_ci tagNamePtr->prefix = binding->prefix->name; 36667db96d56Sopenharmony_ci tagNamePtr->prefixLen = prefixLen; 36677db96d56Sopenharmony_ci for (i = 0; localPart[i++];) 36687db96d56Sopenharmony_ci ; /* i includes null terminator */ 36697db96d56Sopenharmony_ci 36707db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 36717db96d56Sopenharmony_ci if (binding->uriLen > INT_MAX - prefixLen 36727db96d56Sopenharmony_ci || i > INT_MAX - (binding->uriLen + prefixLen)) { 36737db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 36747db96d56Sopenharmony_ci } 36757db96d56Sopenharmony_ci 36767db96d56Sopenharmony_ci n = i + binding->uriLen + prefixLen; 36777db96d56Sopenharmony_ci if (n > binding->uriAlloc) { 36787db96d56Sopenharmony_ci TAG *p; 36797db96d56Sopenharmony_ci 36807db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 36817db96d56Sopenharmony_ci if (n > INT_MAX - EXPAND_SPARE) { 36827db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 36837db96d56Sopenharmony_ci } 36847db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 36857db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 36867db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 36877db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 36887db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 36897db96d56Sopenharmony_ci if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { 36907db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 36917db96d56Sopenharmony_ci } 36927db96d56Sopenharmony_ci#endif 36937db96d56Sopenharmony_ci 36947db96d56Sopenharmony_ci uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); 36957db96d56Sopenharmony_ci if (! uri) 36967db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 36977db96d56Sopenharmony_ci binding->uriAlloc = n + EXPAND_SPARE; 36987db96d56Sopenharmony_ci memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); 36997db96d56Sopenharmony_ci for (p = parser->m_tagStack; p; p = p->parent) 37007db96d56Sopenharmony_ci if (p->name.str == binding->uri) 37017db96d56Sopenharmony_ci p->name.str = uri; 37027db96d56Sopenharmony_ci FREE(parser, binding->uri); 37037db96d56Sopenharmony_ci binding->uri = uri; 37047db96d56Sopenharmony_ci } 37057db96d56Sopenharmony_ci /* if m_namespaceSeparator != '\0' then uri includes it already */ 37067db96d56Sopenharmony_ci uri = binding->uri + binding->uriLen; 37077db96d56Sopenharmony_ci memcpy(uri, localPart, i * sizeof(XML_Char)); 37087db96d56Sopenharmony_ci /* we always have a namespace separator between localPart and prefix */ 37097db96d56Sopenharmony_ci if (prefixLen) { 37107db96d56Sopenharmony_ci uri += i - 1; 37117db96d56Sopenharmony_ci *uri = parser->m_namespaceSeparator; /* replace null terminator */ 37127db96d56Sopenharmony_ci memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); 37137db96d56Sopenharmony_ci } 37147db96d56Sopenharmony_ci tagNamePtr->str = binding->uri; 37157db96d56Sopenharmony_ci return XML_ERROR_NONE; 37167db96d56Sopenharmony_ci} 37177db96d56Sopenharmony_ci 37187db96d56Sopenharmony_cistatic XML_Bool 37197db96d56Sopenharmony_ciis_rfc3986_uri_char(XML_Char candidate) { 37207db96d56Sopenharmony_ci // For the RFC 3986 ANBF grammar see 37217db96d56Sopenharmony_ci // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A 37227db96d56Sopenharmony_ci 37237db96d56Sopenharmony_ci switch (candidate) { 37247db96d56Sopenharmony_ci // From rule "ALPHA" (uppercase half) 37257db96d56Sopenharmony_ci case 'A': 37267db96d56Sopenharmony_ci case 'B': 37277db96d56Sopenharmony_ci case 'C': 37287db96d56Sopenharmony_ci case 'D': 37297db96d56Sopenharmony_ci case 'E': 37307db96d56Sopenharmony_ci case 'F': 37317db96d56Sopenharmony_ci case 'G': 37327db96d56Sopenharmony_ci case 'H': 37337db96d56Sopenharmony_ci case 'I': 37347db96d56Sopenharmony_ci case 'J': 37357db96d56Sopenharmony_ci case 'K': 37367db96d56Sopenharmony_ci case 'L': 37377db96d56Sopenharmony_ci case 'M': 37387db96d56Sopenharmony_ci case 'N': 37397db96d56Sopenharmony_ci case 'O': 37407db96d56Sopenharmony_ci case 'P': 37417db96d56Sopenharmony_ci case 'Q': 37427db96d56Sopenharmony_ci case 'R': 37437db96d56Sopenharmony_ci case 'S': 37447db96d56Sopenharmony_ci case 'T': 37457db96d56Sopenharmony_ci case 'U': 37467db96d56Sopenharmony_ci case 'V': 37477db96d56Sopenharmony_ci case 'W': 37487db96d56Sopenharmony_ci case 'X': 37497db96d56Sopenharmony_ci case 'Y': 37507db96d56Sopenharmony_ci case 'Z': 37517db96d56Sopenharmony_ci 37527db96d56Sopenharmony_ci // From rule "ALPHA" (lowercase half) 37537db96d56Sopenharmony_ci case 'a': 37547db96d56Sopenharmony_ci case 'b': 37557db96d56Sopenharmony_ci case 'c': 37567db96d56Sopenharmony_ci case 'd': 37577db96d56Sopenharmony_ci case 'e': 37587db96d56Sopenharmony_ci case 'f': 37597db96d56Sopenharmony_ci case 'g': 37607db96d56Sopenharmony_ci case 'h': 37617db96d56Sopenharmony_ci case 'i': 37627db96d56Sopenharmony_ci case 'j': 37637db96d56Sopenharmony_ci case 'k': 37647db96d56Sopenharmony_ci case 'l': 37657db96d56Sopenharmony_ci case 'm': 37667db96d56Sopenharmony_ci case 'n': 37677db96d56Sopenharmony_ci case 'o': 37687db96d56Sopenharmony_ci case 'p': 37697db96d56Sopenharmony_ci case 'q': 37707db96d56Sopenharmony_ci case 'r': 37717db96d56Sopenharmony_ci case 's': 37727db96d56Sopenharmony_ci case 't': 37737db96d56Sopenharmony_ci case 'u': 37747db96d56Sopenharmony_ci case 'v': 37757db96d56Sopenharmony_ci case 'w': 37767db96d56Sopenharmony_ci case 'x': 37777db96d56Sopenharmony_ci case 'y': 37787db96d56Sopenharmony_ci case 'z': 37797db96d56Sopenharmony_ci 37807db96d56Sopenharmony_ci // From rule "DIGIT" 37817db96d56Sopenharmony_ci case '0': 37827db96d56Sopenharmony_ci case '1': 37837db96d56Sopenharmony_ci case '2': 37847db96d56Sopenharmony_ci case '3': 37857db96d56Sopenharmony_ci case '4': 37867db96d56Sopenharmony_ci case '5': 37877db96d56Sopenharmony_ci case '6': 37887db96d56Sopenharmony_ci case '7': 37897db96d56Sopenharmony_ci case '8': 37907db96d56Sopenharmony_ci case '9': 37917db96d56Sopenharmony_ci 37927db96d56Sopenharmony_ci // From rule "pct-encoded" 37937db96d56Sopenharmony_ci case '%': 37947db96d56Sopenharmony_ci 37957db96d56Sopenharmony_ci // From rule "unreserved" 37967db96d56Sopenharmony_ci case '-': 37977db96d56Sopenharmony_ci case '.': 37987db96d56Sopenharmony_ci case '_': 37997db96d56Sopenharmony_ci case '~': 38007db96d56Sopenharmony_ci 38017db96d56Sopenharmony_ci // From rule "gen-delims" 38027db96d56Sopenharmony_ci case ':': 38037db96d56Sopenharmony_ci case '/': 38047db96d56Sopenharmony_ci case '?': 38057db96d56Sopenharmony_ci case '#': 38067db96d56Sopenharmony_ci case '[': 38077db96d56Sopenharmony_ci case ']': 38087db96d56Sopenharmony_ci case '@': 38097db96d56Sopenharmony_ci 38107db96d56Sopenharmony_ci // From rule "sub-delims" 38117db96d56Sopenharmony_ci case '!': 38127db96d56Sopenharmony_ci case '$': 38137db96d56Sopenharmony_ci case '&': 38147db96d56Sopenharmony_ci case '\'': 38157db96d56Sopenharmony_ci case '(': 38167db96d56Sopenharmony_ci case ')': 38177db96d56Sopenharmony_ci case '*': 38187db96d56Sopenharmony_ci case '+': 38197db96d56Sopenharmony_ci case ',': 38207db96d56Sopenharmony_ci case ';': 38217db96d56Sopenharmony_ci case '=': 38227db96d56Sopenharmony_ci return XML_TRUE; 38237db96d56Sopenharmony_ci 38247db96d56Sopenharmony_ci default: 38257db96d56Sopenharmony_ci return XML_FALSE; 38267db96d56Sopenharmony_ci } 38277db96d56Sopenharmony_ci} 38287db96d56Sopenharmony_ci 38297db96d56Sopenharmony_ci/* addBinding() overwrites the value of prefix->binding without checking. 38307db96d56Sopenharmony_ci Therefore one must keep track of the old value outside of addBinding(). 38317db96d56Sopenharmony_ci*/ 38327db96d56Sopenharmony_cistatic enum XML_Error 38337db96d56Sopenharmony_ciaddBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, 38347db96d56Sopenharmony_ci const XML_Char *uri, BINDING **bindingsPtr) { 38357db96d56Sopenharmony_ci // "http://www.w3.org/XML/1998/namespace" 38367db96d56Sopenharmony_ci static const XML_Char xmlNamespace[] 38377db96d56Sopenharmony_ci = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, 38387db96d56Sopenharmony_ci ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, 38397db96d56Sopenharmony_ci ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, 38407db96d56Sopenharmony_ci ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, 38417db96d56Sopenharmony_ci ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, 38427db96d56Sopenharmony_ci ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, 38437db96d56Sopenharmony_ci ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, 38447db96d56Sopenharmony_ci ASCII_e, '\0'}; 38457db96d56Sopenharmony_ci static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; 38467db96d56Sopenharmony_ci // "http://www.w3.org/2000/xmlns/" 38477db96d56Sopenharmony_ci static const XML_Char xmlnsNamespace[] 38487db96d56Sopenharmony_ci = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, 38497db96d56Sopenharmony_ci ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, 38507db96d56Sopenharmony_ci ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, 38517db96d56Sopenharmony_ci ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x, 38527db96d56Sopenharmony_ci ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'}; 38537db96d56Sopenharmony_ci static const int xmlnsLen 38547db96d56Sopenharmony_ci = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1; 38557db96d56Sopenharmony_ci 38567db96d56Sopenharmony_ci XML_Bool mustBeXML = XML_FALSE; 38577db96d56Sopenharmony_ci XML_Bool isXML = XML_TRUE; 38587db96d56Sopenharmony_ci XML_Bool isXMLNS = XML_TRUE; 38597db96d56Sopenharmony_ci 38607db96d56Sopenharmony_ci BINDING *b; 38617db96d56Sopenharmony_ci int len; 38627db96d56Sopenharmony_ci 38637db96d56Sopenharmony_ci /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ 38647db96d56Sopenharmony_ci if (*uri == XML_T('\0') && prefix->name) 38657db96d56Sopenharmony_ci return XML_ERROR_UNDECLARING_PREFIX; 38667db96d56Sopenharmony_ci 38677db96d56Sopenharmony_ci if (prefix->name && prefix->name[0] == XML_T(ASCII_x) 38687db96d56Sopenharmony_ci && prefix->name[1] == XML_T(ASCII_m) 38697db96d56Sopenharmony_ci && prefix->name[2] == XML_T(ASCII_l)) { 38707db96d56Sopenharmony_ci /* Not allowed to bind xmlns */ 38717db96d56Sopenharmony_ci if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s) 38727db96d56Sopenharmony_ci && prefix->name[5] == XML_T('\0')) 38737db96d56Sopenharmony_ci return XML_ERROR_RESERVED_PREFIX_XMLNS; 38747db96d56Sopenharmony_ci 38757db96d56Sopenharmony_ci if (prefix->name[3] == XML_T('\0')) 38767db96d56Sopenharmony_ci mustBeXML = XML_TRUE; 38777db96d56Sopenharmony_ci } 38787db96d56Sopenharmony_ci 38797db96d56Sopenharmony_ci for (len = 0; uri[len]; len++) { 38807db96d56Sopenharmony_ci if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) 38817db96d56Sopenharmony_ci isXML = XML_FALSE; 38827db96d56Sopenharmony_ci 38837db96d56Sopenharmony_ci if (! mustBeXML && isXMLNS 38847db96d56Sopenharmony_ci && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) 38857db96d56Sopenharmony_ci isXMLNS = XML_FALSE; 38867db96d56Sopenharmony_ci 38877db96d56Sopenharmony_ci // NOTE: While Expat does not validate namespace URIs against RFC 3986 38887db96d56Sopenharmony_ci // today (and is not REQUIRED to do so with regard to the XML 1.0 38897db96d56Sopenharmony_ci // namespaces specification) we have to at least make sure, that 38907db96d56Sopenharmony_ci // the application on top of Expat (that is likely splitting expanded 38917db96d56Sopenharmony_ci // element names ("qualified names") of form 38927db96d56Sopenharmony_ci // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces 38937db96d56Sopenharmony_ci // in its element handler code) cannot be confused by an attacker 38947db96d56Sopenharmony_ci // putting additional namespace separator characters into namespace 38957db96d56Sopenharmony_ci // declarations. That would be ambiguous and not to be expected. 38967db96d56Sopenharmony_ci // 38977db96d56Sopenharmony_ci // While the HTML API docs of function XML_ParserCreateNS have been 38987db96d56Sopenharmony_ci // advising against use of a namespace separator character that can 38997db96d56Sopenharmony_ci // appear in a URI for >20 years now, some widespread applications 39007db96d56Sopenharmony_ci // are using URI characters (':' (colon) in particular) for a 39017db96d56Sopenharmony_ci // namespace separator, in practice. To keep these applications 39027db96d56Sopenharmony_ci // functional, we only reject namespaces URIs containing the 39037db96d56Sopenharmony_ci // application-chosen namespace separator if the chosen separator 39047db96d56Sopenharmony_ci // is a non-URI character with regard to RFC 3986. 39057db96d56Sopenharmony_ci if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) 39067db96d56Sopenharmony_ci && ! is_rfc3986_uri_char(uri[len])) { 39077db96d56Sopenharmony_ci return XML_ERROR_SYNTAX; 39087db96d56Sopenharmony_ci } 39097db96d56Sopenharmony_ci } 39107db96d56Sopenharmony_ci isXML = isXML && len == xmlLen; 39117db96d56Sopenharmony_ci isXMLNS = isXMLNS && len == xmlnsLen; 39127db96d56Sopenharmony_ci 39137db96d56Sopenharmony_ci if (mustBeXML != isXML) 39147db96d56Sopenharmony_ci return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML 39157db96d56Sopenharmony_ci : XML_ERROR_RESERVED_NAMESPACE_URI; 39167db96d56Sopenharmony_ci 39177db96d56Sopenharmony_ci if (isXMLNS) 39187db96d56Sopenharmony_ci return XML_ERROR_RESERVED_NAMESPACE_URI; 39197db96d56Sopenharmony_ci 39207db96d56Sopenharmony_ci if (parser->m_namespaceSeparator) 39217db96d56Sopenharmony_ci len++; 39227db96d56Sopenharmony_ci if (parser->m_freeBindingList) { 39237db96d56Sopenharmony_ci b = parser->m_freeBindingList; 39247db96d56Sopenharmony_ci if (len > b->uriAlloc) { 39257db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 39267db96d56Sopenharmony_ci if (len > INT_MAX - EXPAND_SPARE) { 39277db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 39287db96d56Sopenharmony_ci } 39297db96d56Sopenharmony_ci 39307db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 39317db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 39327db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 39337db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 39347db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 39357db96d56Sopenharmony_ci if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { 39367db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 39377db96d56Sopenharmony_ci } 39387db96d56Sopenharmony_ci#endif 39397db96d56Sopenharmony_ci 39407db96d56Sopenharmony_ci XML_Char *temp = (XML_Char *)REALLOC( 39417db96d56Sopenharmony_ci parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); 39427db96d56Sopenharmony_ci if (temp == NULL) 39437db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 39447db96d56Sopenharmony_ci b->uri = temp; 39457db96d56Sopenharmony_ci b->uriAlloc = len + EXPAND_SPARE; 39467db96d56Sopenharmony_ci } 39477db96d56Sopenharmony_ci parser->m_freeBindingList = b->nextTagBinding; 39487db96d56Sopenharmony_ci } else { 39497db96d56Sopenharmony_ci b = (BINDING *)MALLOC(parser, sizeof(BINDING)); 39507db96d56Sopenharmony_ci if (! b) 39517db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 39527db96d56Sopenharmony_ci 39537db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 39547db96d56Sopenharmony_ci if (len > INT_MAX - EXPAND_SPARE) { 39557db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 39567db96d56Sopenharmony_ci } 39577db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 39587db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 39597db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 39607db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 39617db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 39627db96d56Sopenharmony_ci if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { 39637db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 39647db96d56Sopenharmony_ci } 39657db96d56Sopenharmony_ci#endif 39667db96d56Sopenharmony_ci 39677db96d56Sopenharmony_ci b->uri 39687db96d56Sopenharmony_ci = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); 39697db96d56Sopenharmony_ci if (! b->uri) { 39707db96d56Sopenharmony_ci FREE(parser, b); 39717db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 39727db96d56Sopenharmony_ci } 39737db96d56Sopenharmony_ci b->uriAlloc = len + EXPAND_SPARE; 39747db96d56Sopenharmony_ci } 39757db96d56Sopenharmony_ci b->uriLen = len; 39767db96d56Sopenharmony_ci memcpy(b->uri, uri, len * sizeof(XML_Char)); 39777db96d56Sopenharmony_ci if (parser->m_namespaceSeparator) 39787db96d56Sopenharmony_ci b->uri[len - 1] = parser->m_namespaceSeparator; 39797db96d56Sopenharmony_ci b->prefix = prefix; 39807db96d56Sopenharmony_ci b->attId = attId; 39817db96d56Sopenharmony_ci b->prevPrefixBinding = prefix->binding; 39827db96d56Sopenharmony_ci /* NULL binding when default namespace undeclared */ 39837db96d56Sopenharmony_ci if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix) 39847db96d56Sopenharmony_ci prefix->binding = NULL; 39857db96d56Sopenharmony_ci else 39867db96d56Sopenharmony_ci prefix->binding = b; 39877db96d56Sopenharmony_ci b->nextTagBinding = *bindingsPtr; 39887db96d56Sopenharmony_ci *bindingsPtr = b; 39897db96d56Sopenharmony_ci /* if attId == NULL then we are not starting a namespace scope */ 39907db96d56Sopenharmony_ci if (attId && parser->m_startNamespaceDeclHandler) 39917db96d56Sopenharmony_ci parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, 39927db96d56Sopenharmony_ci prefix->binding ? uri : 0); 39937db96d56Sopenharmony_ci return XML_ERROR_NONE; 39947db96d56Sopenharmony_ci} 39957db96d56Sopenharmony_ci 39967db96d56Sopenharmony_ci/* The idea here is to avoid using stack for each CDATA section when 39977db96d56Sopenharmony_ci the whole file is parsed with one call. 39987db96d56Sopenharmony_ci*/ 39997db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 40007db96d56Sopenharmony_cicdataSectionProcessor(XML_Parser parser, const char *start, const char *end, 40017db96d56Sopenharmony_ci const char **endPtr) { 40027db96d56Sopenharmony_ci enum XML_Error result = doCdataSection( 40037db96d56Sopenharmony_ci parser, parser->m_encoding, &start, end, endPtr, 40047db96d56Sopenharmony_ci (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); 40057db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 40067db96d56Sopenharmony_ci return result; 40077db96d56Sopenharmony_ci if (start) { 40087db96d56Sopenharmony_ci if (parser->m_parentParser) { /* we are parsing an external entity */ 40097db96d56Sopenharmony_ci parser->m_processor = externalEntityContentProcessor; 40107db96d56Sopenharmony_ci return externalEntityContentProcessor(parser, start, end, endPtr); 40117db96d56Sopenharmony_ci } else { 40127db96d56Sopenharmony_ci parser->m_processor = contentProcessor; 40137db96d56Sopenharmony_ci return contentProcessor(parser, start, end, endPtr); 40147db96d56Sopenharmony_ci } 40157db96d56Sopenharmony_ci } 40167db96d56Sopenharmony_ci return result; 40177db96d56Sopenharmony_ci} 40187db96d56Sopenharmony_ci 40197db96d56Sopenharmony_ci/* startPtr gets set to non-null if the section is closed, and to null if 40207db96d56Sopenharmony_ci the section is not yet closed. 40217db96d56Sopenharmony_ci*/ 40227db96d56Sopenharmony_cistatic enum XML_Error 40237db96d56Sopenharmony_cidoCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, 40247db96d56Sopenharmony_ci const char *end, const char **nextPtr, XML_Bool haveMore, 40257db96d56Sopenharmony_ci enum XML_Account account) { 40267db96d56Sopenharmony_ci const char *s = *startPtr; 40277db96d56Sopenharmony_ci const char **eventPP; 40287db96d56Sopenharmony_ci const char **eventEndPP; 40297db96d56Sopenharmony_ci if (enc == parser->m_encoding) { 40307db96d56Sopenharmony_ci eventPP = &parser->m_eventPtr; 40317db96d56Sopenharmony_ci *eventPP = s; 40327db96d56Sopenharmony_ci eventEndPP = &parser->m_eventEndPtr; 40337db96d56Sopenharmony_ci } else { 40347db96d56Sopenharmony_ci eventPP = &(parser->m_openInternalEntities->internalEventPtr); 40357db96d56Sopenharmony_ci eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 40367db96d56Sopenharmony_ci } 40377db96d56Sopenharmony_ci *eventPP = s; 40387db96d56Sopenharmony_ci *startPtr = NULL; 40397db96d56Sopenharmony_ci 40407db96d56Sopenharmony_ci for (;;) { 40417db96d56Sopenharmony_ci const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ 40427db96d56Sopenharmony_ci int tok = XmlCdataSectionTok(enc, s, end, &next); 40437db96d56Sopenharmony_ci#ifdef XML_DTD 40447db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { 40457db96d56Sopenharmony_ci accountingOnAbort(parser); 40467db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 40477db96d56Sopenharmony_ci } 40487db96d56Sopenharmony_ci#else 40497db96d56Sopenharmony_ci UNUSED_P(account); 40507db96d56Sopenharmony_ci#endif 40517db96d56Sopenharmony_ci *eventEndPP = next; 40527db96d56Sopenharmony_ci switch (tok) { 40537db96d56Sopenharmony_ci case XML_TOK_CDATA_SECT_CLOSE: 40547db96d56Sopenharmony_ci if (parser->m_endCdataSectionHandler) 40557db96d56Sopenharmony_ci parser->m_endCdataSectionHandler(parser->m_handlerArg); 40567db96d56Sopenharmony_ci /* BEGIN disabled code */ 40577db96d56Sopenharmony_ci /* see comment under XML_TOK_CDATA_SECT_OPEN */ 40587db96d56Sopenharmony_ci else if (0 && parser->m_characterDataHandler) 40597db96d56Sopenharmony_ci parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 40607db96d56Sopenharmony_ci 0); 40617db96d56Sopenharmony_ci /* END disabled code */ 40627db96d56Sopenharmony_ci else if (parser->m_defaultHandler) 40637db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 40647db96d56Sopenharmony_ci *startPtr = next; 40657db96d56Sopenharmony_ci *nextPtr = next; 40667db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_FINISHED) 40677db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 40687db96d56Sopenharmony_ci else 40697db96d56Sopenharmony_ci return XML_ERROR_NONE; 40707db96d56Sopenharmony_ci case XML_TOK_DATA_NEWLINE: 40717db96d56Sopenharmony_ci if (parser->m_characterDataHandler) { 40727db96d56Sopenharmony_ci XML_Char c = 0xA; 40737db96d56Sopenharmony_ci parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); 40747db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 40757db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 40767db96d56Sopenharmony_ci break; 40777db96d56Sopenharmony_ci case XML_TOK_DATA_CHARS: { 40787db96d56Sopenharmony_ci XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; 40797db96d56Sopenharmony_ci if (charDataHandler) { 40807db96d56Sopenharmony_ci if (MUST_CONVERT(enc, s)) { 40817db96d56Sopenharmony_ci for (;;) { 40827db96d56Sopenharmony_ci ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; 40837db96d56Sopenharmony_ci const enum XML_Convert_Result convert_res = XmlConvert( 40847db96d56Sopenharmony_ci enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); 40857db96d56Sopenharmony_ci *eventEndPP = next; 40867db96d56Sopenharmony_ci charDataHandler(parser->m_handlerArg, parser->m_dataBuf, 40877db96d56Sopenharmony_ci (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); 40887db96d56Sopenharmony_ci if ((convert_res == XML_CONVERT_COMPLETED) 40897db96d56Sopenharmony_ci || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) 40907db96d56Sopenharmony_ci break; 40917db96d56Sopenharmony_ci *eventPP = s; 40927db96d56Sopenharmony_ci } 40937db96d56Sopenharmony_ci } else 40947db96d56Sopenharmony_ci charDataHandler(parser->m_handlerArg, (XML_Char *)s, 40957db96d56Sopenharmony_ci (int)((XML_Char *)next - (XML_Char *)s)); 40967db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 40977db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 40987db96d56Sopenharmony_ci } break; 40997db96d56Sopenharmony_ci case XML_TOK_INVALID: 41007db96d56Sopenharmony_ci *eventPP = next; 41017db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 41027db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 41037db96d56Sopenharmony_ci if (haveMore) { 41047db96d56Sopenharmony_ci *nextPtr = s; 41057db96d56Sopenharmony_ci return XML_ERROR_NONE; 41067db96d56Sopenharmony_ci } 41077db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 41087db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 41097db96d56Sopenharmony_ci case XML_TOK_NONE: 41107db96d56Sopenharmony_ci if (haveMore) { 41117db96d56Sopenharmony_ci *nextPtr = s; 41127db96d56Sopenharmony_ci return XML_ERROR_NONE; 41137db96d56Sopenharmony_ci } 41147db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_CDATA_SECTION; 41157db96d56Sopenharmony_ci default: 41167db96d56Sopenharmony_ci /* Every token returned by XmlCdataSectionTok() has its own 41177db96d56Sopenharmony_ci * explicit case, so this default case will never be executed. 41187db96d56Sopenharmony_ci * We retain it as a safety net and exclude it from the coverage 41197db96d56Sopenharmony_ci * statistics. 41207db96d56Sopenharmony_ci * 41217db96d56Sopenharmony_ci * LCOV_EXCL_START 41227db96d56Sopenharmony_ci */ 41237db96d56Sopenharmony_ci *eventPP = next; 41247db96d56Sopenharmony_ci return XML_ERROR_UNEXPECTED_STATE; 41257db96d56Sopenharmony_ci /* LCOV_EXCL_STOP */ 41267db96d56Sopenharmony_ci } 41277db96d56Sopenharmony_ci 41287db96d56Sopenharmony_ci *eventPP = s = next; 41297db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 41307db96d56Sopenharmony_ci case XML_SUSPENDED: 41317db96d56Sopenharmony_ci *nextPtr = next; 41327db96d56Sopenharmony_ci return XML_ERROR_NONE; 41337db96d56Sopenharmony_ci case XML_FINISHED: 41347db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 41357db96d56Sopenharmony_ci default:; 41367db96d56Sopenharmony_ci } 41377db96d56Sopenharmony_ci } 41387db96d56Sopenharmony_ci /* not reached */ 41397db96d56Sopenharmony_ci} 41407db96d56Sopenharmony_ci 41417db96d56Sopenharmony_ci#ifdef XML_DTD 41427db96d56Sopenharmony_ci 41437db96d56Sopenharmony_ci/* The idea here is to avoid using stack for each IGNORE section when 41447db96d56Sopenharmony_ci the whole file is parsed with one call. 41457db96d56Sopenharmony_ci*/ 41467db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 41477db96d56Sopenharmony_ciignoreSectionProcessor(XML_Parser parser, const char *start, const char *end, 41487db96d56Sopenharmony_ci const char **endPtr) { 41497db96d56Sopenharmony_ci enum XML_Error result 41507db96d56Sopenharmony_ci = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr, 41517db96d56Sopenharmony_ci (XML_Bool)! parser->m_parsingStatus.finalBuffer); 41527db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 41537db96d56Sopenharmony_ci return result; 41547db96d56Sopenharmony_ci if (start) { 41557db96d56Sopenharmony_ci parser->m_processor = prologProcessor; 41567db96d56Sopenharmony_ci return prologProcessor(parser, start, end, endPtr); 41577db96d56Sopenharmony_ci } 41587db96d56Sopenharmony_ci return result; 41597db96d56Sopenharmony_ci} 41607db96d56Sopenharmony_ci 41617db96d56Sopenharmony_ci/* startPtr gets set to non-null is the section is closed, and to null 41627db96d56Sopenharmony_ci if the section is not yet closed. 41637db96d56Sopenharmony_ci*/ 41647db96d56Sopenharmony_cistatic enum XML_Error 41657db96d56Sopenharmony_cidoIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, 41667db96d56Sopenharmony_ci const char *end, const char **nextPtr, XML_Bool haveMore) { 41677db96d56Sopenharmony_ci const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ 41687db96d56Sopenharmony_ci int tok; 41697db96d56Sopenharmony_ci const char *s = *startPtr; 41707db96d56Sopenharmony_ci const char **eventPP; 41717db96d56Sopenharmony_ci const char **eventEndPP; 41727db96d56Sopenharmony_ci if (enc == parser->m_encoding) { 41737db96d56Sopenharmony_ci eventPP = &parser->m_eventPtr; 41747db96d56Sopenharmony_ci *eventPP = s; 41757db96d56Sopenharmony_ci eventEndPP = &parser->m_eventEndPtr; 41767db96d56Sopenharmony_ci } else { 41777db96d56Sopenharmony_ci /* It's not entirely clear, but it seems the following two lines 41787db96d56Sopenharmony_ci * of code cannot be executed. The only occasions on which 'enc' 41797db96d56Sopenharmony_ci * is not 'encoding' are when this function is called 41807db96d56Sopenharmony_ci * from the internal entity processing, and IGNORE sections are an 41817db96d56Sopenharmony_ci * error in internal entities. 41827db96d56Sopenharmony_ci * 41837db96d56Sopenharmony_ci * Since it really isn't clear that this is true, we keep the code 41847db96d56Sopenharmony_ci * and just remove it from our coverage tests. 41857db96d56Sopenharmony_ci * 41867db96d56Sopenharmony_ci * LCOV_EXCL_START 41877db96d56Sopenharmony_ci */ 41887db96d56Sopenharmony_ci eventPP = &(parser->m_openInternalEntities->internalEventPtr); 41897db96d56Sopenharmony_ci eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 41907db96d56Sopenharmony_ci /* LCOV_EXCL_STOP */ 41917db96d56Sopenharmony_ci } 41927db96d56Sopenharmony_ci *eventPP = s; 41937db96d56Sopenharmony_ci *startPtr = NULL; 41947db96d56Sopenharmony_ci tok = XmlIgnoreSectionTok(enc, s, end, &next); 41957db96d56Sopenharmony_ci# ifdef XML_DTD 41967db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 41977db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT)) { 41987db96d56Sopenharmony_ci accountingOnAbort(parser); 41997db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 42007db96d56Sopenharmony_ci } 42017db96d56Sopenharmony_ci# endif 42027db96d56Sopenharmony_ci *eventEndPP = next; 42037db96d56Sopenharmony_ci switch (tok) { 42047db96d56Sopenharmony_ci case XML_TOK_IGNORE_SECT: 42057db96d56Sopenharmony_ci if (parser->m_defaultHandler) 42067db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 42077db96d56Sopenharmony_ci *startPtr = next; 42087db96d56Sopenharmony_ci *nextPtr = next; 42097db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_FINISHED) 42107db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 42117db96d56Sopenharmony_ci else 42127db96d56Sopenharmony_ci return XML_ERROR_NONE; 42137db96d56Sopenharmony_ci case XML_TOK_INVALID: 42147db96d56Sopenharmony_ci *eventPP = next; 42157db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 42167db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 42177db96d56Sopenharmony_ci if (haveMore) { 42187db96d56Sopenharmony_ci *nextPtr = s; 42197db96d56Sopenharmony_ci return XML_ERROR_NONE; 42207db96d56Sopenharmony_ci } 42217db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 42227db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 42237db96d56Sopenharmony_ci case XML_TOK_NONE: 42247db96d56Sopenharmony_ci if (haveMore) { 42257db96d56Sopenharmony_ci *nextPtr = s; 42267db96d56Sopenharmony_ci return XML_ERROR_NONE; 42277db96d56Sopenharmony_ci } 42287db96d56Sopenharmony_ci return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ 42297db96d56Sopenharmony_ci default: 42307db96d56Sopenharmony_ci /* All of the tokens that XmlIgnoreSectionTok() returns have 42317db96d56Sopenharmony_ci * explicit cases to handle them, so this default case is never 42327db96d56Sopenharmony_ci * executed. We keep it as a safety net anyway, and remove it 42337db96d56Sopenharmony_ci * from our test coverage statistics. 42347db96d56Sopenharmony_ci * 42357db96d56Sopenharmony_ci * LCOV_EXCL_START 42367db96d56Sopenharmony_ci */ 42377db96d56Sopenharmony_ci *eventPP = next; 42387db96d56Sopenharmony_ci return XML_ERROR_UNEXPECTED_STATE; 42397db96d56Sopenharmony_ci /* LCOV_EXCL_STOP */ 42407db96d56Sopenharmony_ci } 42417db96d56Sopenharmony_ci /* not reached */ 42427db96d56Sopenharmony_ci} 42437db96d56Sopenharmony_ci 42447db96d56Sopenharmony_ci#endif /* XML_DTD */ 42457db96d56Sopenharmony_ci 42467db96d56Sopenharmony_cistatic enum XML_Error 42477db96d56Sopenharmony_ciinitializeEncoding(XML_Parser parser) { 42487db96d56Sopenharmony_ci const char *s; 42497db96d56Sopenharmony_ci#ifdef XML_UNICODE 42507db96d56Sopenharmony_ci char encodingBuf[128]; 42517db96d56Sopenharmony_ci /* See comments about `protocolEncodingName` in parserInit() */ 42527db96d56Sopenharmony_ci if (! parser->m_protocolEncodingName) 42537db96d56Sopenharmony_ci s = NULL; 42547db96d56Sopenharmony_ci else { 42557db96d56Sopenharmony_ci int i; 42567db96d56Sopenharmony_ci for (i = 0; parser->m_protocolEncodingName[i]; i++) { 42577db96d56Sopenharmony_ci if (i == sizeof(encodingBuf) - 1 42587db96d56Sopenharmony_ci || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) { 42597db96d56Sopenharmony_ci encodingBuf[0] = '\0'; 42607db96d56Sopenharmony_ci break; 42617db96d56Sopenharmony_ci } 42627db96d56Sopenharmony_ci encodingBuf[i] = (char)parser->m_protocolEncodingName[i]; 42637db96d56Sopenharmony_ci } 42647db96d56Sopenharmony_ci encodingBuf[i] = '\0'; 42657db96d56Sopenharmony_ci s = encodingBuf; 42667db96d56Sopenharmony_ci } 42677db96d56Sopenharmony_ci#else 42687db96d56Sopenharmony_ci s = parser->m_protocolEncodingName; 42697db96d56Sopenharmony_ci#endif 42707db96d56Sopenharmony_ci if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)( 42717db96d56Sopenharmony_ci &parser->m_initEncoding, &parser->m_encoding, s)) 42727db96d56Sopenharmony_ci return XML_ERROR_NONE; 42737db96d56Sopenharmony_ci return handleUnknownEncoding(parser, parser->m_protocolEncodingName); 42747db96d56Sopenharmony_ci} 42757db96d56Sopenharmony_ci 42767db96d56Sopenharmony_cistatic enum XML_Error 42777db96d56Sopenharmony_ciprocessXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, 42787db96d56Sopenharmony_ci const char *next) { 42797db96d56Sopenharmony_ci const char *encodingName = NULL; 42807db96d56Sopenharmony_ci const XML_Char *storedEncName = NULL; 42817db96d56Sopenharmony_ci const ENCODING *newEncoding = NULL; 42827db96d56Sopenharmony_ci const char *version = NULL; 42837db96d56Sopenharmony_ci const char *versionend = NULL; 42847db96d56Sopenharmony_ci const XML_Char *storedversion = NULL; 42857db96d56Sopenharmony_ci int standalone = -1; 42867db96d56Sopenharmony_ci 42877db96d56Sopenharmony_ci#ifdef XML_DTD 42887db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__, 42897db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT)) { 42907db96d56Sopenharmony_ci accountingOnAbort(parser); 42917db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 42927db96d56Sopenharmony_ci } 42937db96d56Sopenharmony_ci#endif 42947db96d56Sopenharmony_ci 42957db96d56Sopenharmony_ci if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)( 42967db96d56Sopenharmony_ci isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr, 42977db96d56Sopenharmony_ci &version, &versionend, &encodingName, &newEncoding, &standalone)) { 42987db96d56Sopenharmony_ci if (isGeneralTextEntity) 42997db96d56Sopenharmony_ci return XML_ERROR_TEXT_DECL; 43007db96d56Sopenharmony_ci else 43017db96d56Sopenharmony_ci return XML_ERROR_XML_DECL; 43027db96d56Sopenharmony_ci } 43037db96d56Sopenharmony_ci if (! isGeneralTextEntity && standalone == 1) { 43047db96d56Sopenharmony_ci parser->m_dtd->standalone = XML_TRUE; 43057db96d56Sopenharmony_ci#ifdef XML_DTD 43067db96d56Sopenharmony_ci if (parser->m_paramEntityParsing 43077db96d56Sopenharmony_ci == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) 43087db96d56Sopenharmony_ci parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 43097db96d56Sopenharmony_ci#endif /* XML_DTD */ 43107db96d56Sopenharmony_ci } 43117db96d56Sopenharmony_ci if (parser->m_xmlDeclHandler) { 43127db96d56Sopenharmony_ci if (encodingName != NULL) { 43137db96d56Sopenharmony_ci storedEncName = poolStoreString( 43147db96d56Sopenharmony_ci &parser->m_temp2Pool, parser->m_encoding, encodingName, 43157db96d56Sopenharmony_ci encodingName + XmlNameLength(parser->m_encoding, encodingName)); 43167db96d56Sopenharmony_ci if (! storedEncName) 43177db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 43187db96d56Sopenharmony_ci poolFinish(&parser->m_temp2Pool); 43197db96d56Sopenharmony_ci } 43207db96d56Sopenharmony_ci if (version) { 43217db96d56Sopenharmony_ci storedversion 43227db96d56Sopenharmony_ci = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version, 43237db96d56Sopenharmony_ci versionend - parser->m_encoding->minBytesPerChar); 43247db96d56Sopenharmony_ci if (! storedversion) 43257db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 43267db96d56Sopenharmony_ci } 43277db96d56Sopenharmony_ci parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, 43287db96d56Sopenharmony_ci standalone); 43297db96d56Sopenharmony_ci } else if (parser->m_defaultHandler) 43307db96d56Sopenharmony_ci reportDefault(parser, parser->m_encoding, s, next); 43317db96d56Sopenharmony_ci if (parser->m_protocolEncodingName == NULL) { 43327db96d56Sopenharmony_ci if (newEncoding) { 43337db96d56Sopenharmony_ci /* Check that the specified encoding does not conflict with what 43347db96d56Sopenharmony_ci * the parser has already deduced. Do we have the same number 43357db96d56Sopenharmony_ci * of bytes in the smallest representation of a character? If 43367db96d56Sopenharmony_ci * this is UTF-16, is it the same endianness? 43377db96d56Sopenharmony_ci */ 43387db96d56Sopenharmony_ci if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar 43397db96d56Sopenharmony_ci || (newEncoding->minBytesPerChar == 2 43407db96d56Sopenharmony_ci && newEncoding != parser->m_encoding)) { 43417db96d56Sopenharmony_ci parser->m_eventPtr = encodingName; 43427db96d56Sopenharmony_ci return XML_ERROR_INCORRECT_ENCODING; 43437db96d56Sopenharmony_ci } 43447db96d56Sopenharmony_ci parser->m_encoding = newEncoding; 43457db96d56Sopenharmony_ci } else if (encodingName) { 43467db96d56Sopenharmony_ci enum XML_Error result; 43477db96d56Sopenharmony_ci if (! storedEncName) { 43487db96d56Sopenharmony_ci storedEncName = poolStoreString( 43497db96d56Sopenharmony_ci &parser->m_temp2Pool, parser->m_encoding, encodingName, 43507db96d56Sopenharmony_ci encodingName + XmlNameLength(parser->m_encoding, encodingName)); 43517db96d56Sopenharmony_ci if (! storedEncName) 43527db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 43537db96d56Sopenharmony_ci } 43547db96d56Sopenharmony_ci result = handleUnknownEncoding(parser, storedEncName); 43557db96d56Sopenharmony_ci poolClear(&parser->m_temp2Pool); 43567db96d56Sopenharmony_ci if (result == XML_ERROR_UNKNOWN_ENCODING) 43577db96d56Sopenharmony_ci parser->m_eventPtr = encodingName; 43587db96d56Sopenharmony_ci return result; 43597db96d56Sopenharmony_ci } 43607db96d56Sopenharmony_ci } 43617db96d56Sopenharmony_ci 43627db96d56Sopenharmony_ci if (storedEncName || storedversion) 43637db96d56Sopenharmony_ci poolClear(&parser->m_temp2Pool); 43647db96d56Sopenharmony_ci 43657db96d56Sopenharmony_ci return XML_ERROR_NONE; 43667db96d56Sopenharmony_ci} 43677db96d56Sopenharmony_ci 43687db96d56Sopenharmony_cistatic enum XML_Error 43697db96d56Sopenharmony_cihandleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { 43707db96d56Sopenharmony_ci if (parser->m_unknownEncodingHandler) { 43717db96d56Sopenharmony_ci XML_Encoding info; 43727db96d56Sopenharmony_ci int i; 43737db96d56Sopenharmony_ci for (i = 0; i < 256; i++) 43747db96d56Sopenharmony_ci info.map[i] = -1; 43757db96d56Sopenharmony_ci info.convert = NULL; 43767db96d56Sopenharmony_ci info.data = NULL; 43777db96d56Sopenharmony_ci info.release = NULL; 43787db96d56Sopenharmony_ci if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, 43797db96d56Sopenharmony_ci encodingName, &info)) { 43807db96d56Sopenharmony_ci ENCODING *enc; 43817db96d56Sopenharmony_ci parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); 43827db96d56Sopenharmony_ci if (! parser->m_unknownEncodingMem) { 43837db96d56Sopenharmony_ci if (info.release) 43847db96d56Sopenharmony_ci info.release(info.data); 43857db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 43867db96d56Sopenharmony_ci } 43877db96d56Sopenharmony_ci enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)( 43887db96d56Sopenharmony_ci parser->m_unknownEncodingMem, info.map, info.convert, info.data); 43897db96d56Sopenharmony_ci if (enc) { 43907db96d56Sopenharmony_ci parser->m_unknownEncodingData = info.data; 43917db96d56Sopenharmony_ci parser->m_unknownEncodingRelease = info.release; 43927db96d56Sopenharmony_ci parser->m_encoding = enc; 43937db96d56Sopenharmony_ci return XML_ERROR_NONE; 43947db96d56Sopenharmony_ci } 43957db96d56Sopenharmony_ci } 43967db96d56Sopenharmony_ci if (info.release != NULL) 43977db96d56Sopenharmony_ci info.release(info.data); 43987db96d56Sopenharmony_ci } 43997db96d56Sopenharmony_ci return XML_ERROR_UNKNOWN_ENCODING; 44007db96d56Sopenharmony_ci} 44017db96d56Sopenharmony_ci 44027db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 44037db96d56Sopenharmony_ciprologInitProcessor(XML_Parser parser, const char *s, const char *end, 44047db96d56Sopenharmony_ci const char **nextPtr) { 44057db96d56Sopenharmony_ci enum XML_Error result = initializeEncoding(parser); 44067db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 44077db96d56Sopenharmony_ci return result; 44087db96d56Sopenharmony_ci parser->m_processor = prologProcessor; 44097db96d56Sopenharmony_ci return prologProcessor(parser, s, end, nextPtr); 44107db96d56Sopenharmony_ci} 44117db96d56Sopenharmony_ci 44127db96d56Sopenharmony_ci#ifdef XML_DTD 44137db96d56Sopenharmony_ci 44147db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 44157db96d56Sopenharmony_ciexternalParEntInitProcessor(XML_Parser parser, const char *s, const char *end, 44167db96d56Sopenharmony_ci const char **nextPtr) { 44177db96d56Sopenharmony_ci enum XML_Error result = initializeEncoding(parser); 44187db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 44197db96d56Sopenharmony_ci return result; 44207db96d56Sopenharmony_ci 44217db96d56Sopenharmony_ci /* we know now that XML_Parse(Buffer) has been called, 44227db96d56Sopenharmony_ci so we consider the external parameter entity read */ 44237db96d56Sopenharmony_ci parser->m_dtd->paramEntityRead = XML_TRUE; 44247db96d56Sopenharmony_ci 44257db96d56Sopenharmony_ci if (parser->m_prologState.inEntityValue) { 44267db96d56Sopenharmony_ci parser->m_processor = entityValueInitProcessor; 44277db96d56Sopenharmony_ci return entityValueInitProcessor(parser, s, end, nextPtr); 44287db96d56Sopenharmony_ci } else { 44297db96d56Sopenharmony_ci parser->m_processor = externalParEntProcessor; 44307db96d56Sopenharmony_ci return externalParEntProcessor(parser, s, end, nextPtr); 44317db96d56Sopenharmony_ci } 44327db96d56Sopenharmony_ci} 44337db96d56Sopenharmony_ci 44347db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 44357db96d56Sopenharmony_cientityValueInitProcessor(XML_Parser parser, const char *s, const char *end, 44367db96d56Sopenharmony_ci const char **nextPtr) { 44377db96d56Sopenharmony_ci int tok; 44387db96d56Sopenharmony_ci const char *start = s; 44397db96d56Sopenharmony_ci const char *next = start; 44407db96d56Sopenharmony_ci parser->m_eventPtr = start; 44417db96d56Sopenharmony_ci 44427db96d56Sopenharmony_ci for (;;) { 44437db96d56Sopenharmony_ci tok = XmlPrologTok(parser->m_encoding, start, end, &next); 44447db96d56Sopenharmony_ci /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in: 44457db96d56Sopenharmony_ci - storeEntityValue 44467db96d56Sopenharmony_ci - processXmlDecl 44477db96d56Sopenharmony_ci */ 44487db96d56Sopenharmony_ci parser->m_eventEndPtr = next; 44497db96d56Sopenharmony_ci if (tok <= 0) { 44507db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { 44517db96d56Sopenharmony_ci *nextPtr = s; 44527db96d56Sopenharmony_ci return XML_ERROR_NONE; 44537db96d56Sopenharmony_ci } 44547db96d56Sopenharmony_ci switch (tok) { 44557db96d56Sopenharmony_ci case XML_TOK_INVALID: 44567db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 44577db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 44587db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_TOKEN; 44597db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 44607db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 44617db96d56Sopenharmony_ci case XML_TOK_NONE: /* start == end */ 44627db96d56Sopenharmony_ci default: 44637db96d56Sopenharmony_ci break; 44647db96d56Sopenharmony_ci } 44657db96d56Sopenharmony_ci /* found end of entity value - can store it now */ 44667db96d56Sopenharmony_ci return storeEntityValue(parser, parser->m_encoding, s, end, 44677db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT); 44687db96d56Sopenharmony_ci } else if (tok == XML_TOK_XML_DECL) { 44697db96d56Sopenharmony_ci enum XML_Error result; 44707db96d56Sopenharmony_ci result = processXmlDecl(parser, 0, start, next); 44717db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 44727db96d56Sopenharmony_ci return result; 44737db96d56Sopenharmony_ci /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For 44747db96d56Sopenharmony_ci * that to happen, a parameter entity parsing handler must have attempted 44757db96d56Sopenharmony_ci * to suspend the parser, which fails and raises an error. The parser can 44767db96d56Sopenharmony_ci * be aborted, but can't be suspended. 44777db96d56Sopenharmony_ci */ 44787db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_FINISHED) 44797db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 44807db96d56Sopenharmony_ci *nextPtr = next; 44817db96d56Sopenharmony_ci /* stop scanning for text declaration - we found one */ 44827db96d56Sopenharmony_ci parser->m_processor = entityValueProcessor; 44837db96d56Sopenharmony_ci return entityValueProcessor(parser, next, end, nextPtr); 44847db96d56Sopenharmony_ci } 44857db96d56Sopenharmony_ci /* If we are at the end of the buffer, this would cause XmlPrologTok to 44867db96d56Sopenharmony_ci return XML_TOK_NONE on the next call, which would then cause the 44877db96d56Sopenharmony_ci function to exit with *nextPtr set to s - that is what we want for other 44887db96d56Sopenharmony_ci tokens, but not for the BOM - we would rather like to skip it; 44897db96d56Sopenharmony_ci then, when this routine is entered the next time, XmlPrologTok will 44907db96d56Sopenharmony_ci return XML_TOK_INVALID, since the BOM is still in the buffer 44917db96d56Sopenharmony_ci */ 44927db96d56Sopenharmony_ci else if (tok == XML_TOK_BOM && next == end 44937db96d56Sopenharmony_ci && ! parser->m_parsingStatus.finalBuffer) { 44947db96d56Sopenharmony_ci# ifdef XML_DTD 44957db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 44967db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT)) { 44977db96d56Sopenharmony_ci accountingOnAbort(parser); 44987db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 44997db96d56Sopenharmony_ci } 45007db96d56Sopenharmony_ci# endif 45017db96d56Sopenharmony_ci 45027db96d56Sopenharmony_ci *nextPtr = next; 45037db96d56Sopenharmony_ci return XML_ERROR_NONE; 45047db96d56Sopenharmony_ci } 45057db96d56Sopenharmony_ci /* If we get this token, we have the start of what might be a 45067db96d56Sopenharmony_ci normal tag, but not a declaration (i.e. it doesn't begin with 45077db96d56Sopenharmony_ci "<!"). In a DTD context, that isn't legal. 45087db96d56Sopenharmony_ci */ 45097db96d56Sopenharmony_ci else if (tok == XML_TOK_INSTANCE_START) { 45107db96d56Sopenharmony_ci *nextPtr = next; 45117db96d56Sopenharmony_ci return XML_ERROR_SYNTAX; 45127db96d56Sopenharmony_ci } 45137db96d56Sopenharmony_ci start = next; 45147db96d56Sopenharmony_ci parser->m_eventPtr = start; 45157db96d56Sopenharmony_ci } 45167db96d56Sopenharmony_ci} 45177db96d56Sopenharmony_ci 45187db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 45197db96d56Sopenharmony_ciexternalParEntProcessor(XML_Parser parser, const char *s, const char *end, 45207db96d56Sopenharmony_ci const char **nextPtr) { 45217db96d56Sopenharmony_ci const char *next = s; 45227db96d56Sopenharmony_ci int tok; 45237db96d56Sopenharmony_ci 45247db96d56Sopenharmony_ci tok = XmlPrologTok(parser->m_encoding, s, end, &next); 45257db96d56Sopenharmony_ci if (tok <= 0) { 45267db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { 45277db96d56Sopenharmony_ci *nextPtr = s; 45287db96d56Sopenharmony_ci return XML_ERROR_NONE; 45297db96d56Sopenharmony_ci } 45307db96d56Sopenharmony_ci switch (tok) { 45317db96d56Sopenharmony_ci case XML_TOK_INVALID: 45327db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 45337db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 45347db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_TOKEN; 45357db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 45367db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 45377db96d56Sopenharmony_ci case XML_TOK_NONE: /* start == end */ 45387db96d56Sopenharmony_ci default: 45397db96d56Sopenharmony_ci break; 45407db96d56Sopenharmony_ci } 45417db96d56Sopenharmony_ci } 45427db96d56Sopenharmony_ci /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. 45437db96d56Sopenharmony_ci However, when parsing an external subset, doProlog will not accept a BOM 45447db96d56Sopenharmony_ci as valid, and report a syntax error, so we have to skip the BOM, and 45457db96d56Sopenharmony_ci account for the BOM bytes. 45467db96d56Sopenharmony_ci */ 45477db96d56Sopenharmony_ci else if (tok == XML_TOK_BOM) { 45487db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 45497db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT)) { 45507db96d56Sopenharmony_ci accountingOnAbort(parser); 45517db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 45527db96d56Sopenharmony_ci } 45537db96d56Sopenharmony_ci 45547db96d56Sopenharmony_ci s = next; 45557db96d56Sopenharmony_ci tok = XmlPrologTok(parser->m_encoding, s, end, &next); 45567db96d56Sopenharmony_ci } 45577db96d56Sopenharmony_ci 45587db96d56Sopenharmony_ci parser->m_processor = prologProcessor; 45597db96d56Sopenharmony_ci return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 45607db96d56Sopenharmony_ci (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 45617db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT); 45627db96d56Sopenharmony_ci} 45637db96d56Sopenharmony_ci 45647db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 45657db96d56Sopenharmony_cientityValueProcessor(XML_Parser parser, const char *s, const char *end, 45667db96d56Sopenharmony_ci const char **nextPtr) { 45677db96d56Sopenharmony_ci const char *start = s; 45687db96d56Sopenharmony_ci const char *next = s; 45697db96d56Sopenharmony_ci const ENCODING *enc = parser->m_encoding; 45707db96d56Sopenharmony_ci int tok; 45717db96d56Sopenharmony_ci 45727db96d56Sopenharmony_ci for (;;) { 45737db96d56Sopenharmony_ci tok = XmlPrologTok(enc, start, end, &next); 45747db96d56Sopenharmony_ci /* Note: These bytes are accounted later in: 45757db96d56Sopenharmony_ci - storeEntityValue 45767db96d56Sopenharmony_ci */ 45777db96d56Sopenharmony_ci if (tok <= 0) { 45787db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { 45797db96d56Sopenharmony_ci *nextPtr = s; 45807db96d56Sopenharmony_ci return XML_ERROR_NONE; 45817db96d56Sopenharmony_ci } 45827db96d56Sopenharmony_ci switch (tok) { 45837db96d56Sopenharmony_ci case XML_TOK_INVALID: 45847db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 45857db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 45867db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_TOKEN; 45877db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 45887db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 45897db96d56Sopenharmony_ci case XML_TOK_NONE: /* start == end */ 45907db96d56Sopenharmony_ci default: 45917db96d56Sopenharmony_ci break; 45927db96d56Sopenharmony_ci } 45937db96d56Sopenharmony_ci /* found end of entity value - can store it now */ 45947db96d56Sopenharmony_ci return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT); 45957db96d56Sopenharmony_ci } 45967db96d56Sopenharmony_ci start = next; 45977db96d56Sopenharmony_ci } 45987db96d56Sopenharmony_ci} 45997db96d56Sopenharmony_ci 46007db96d56Sopenharmony_ci#endif /* XML_DTD */ 46017db96d56Sopenharmony_ci 46027db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 46037db96d56Sopenharmony_ciprologProcessor(XML_Parser parser, const char *s, const char *end, 46047db96d56Sopenharmony_ci const char **nextPtr) { 46057db96d56Sopenharmony_ci const char *next = s; 46067db96d56Sopenharmony_ci int tok = XmlPrologTok(parser->m_encoding, s, end, &next); 46077db96d56Sopenharmony_ci return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 46087db96d56Sopenharmony_ci (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 46097db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT); 46107db96d56Sopenharmony_ci} 46117db96d56Sopenharmony_ci 46127db96d56Sopenharmony_cistatic enum XML_Error 46137db96d56Sopenharmony_cidoProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, 46147db96d56Sopenharmony_ci int tok, const char *next, const char **nextPtr, XML_Bool haveMore, 46157db96d56Sopenharmony_ci XML_Bool allowClosingDoctype, enum XML_Account account) { 46167db96d56Sopenharmony_ci#ifdef XML_DTD 46177db96d56Sopenharmony_ci static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'}; 46187db96d56Sopenharmony_ci#endif /* XML_DTD */ 46197db96d56Sopenharmony_ci static const XML_Char atypeCDATA[] 46207db96d56Sopenharmony_ci = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; 46217db96d56Sopenharmony_ci static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'}; 46227db96d56Sopenharmony_ci static const XML_Char atypeIDREF[] 46237db96d56Sopenharmony_ci = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; 46247db96d56Sopenharmony_ci static const XML_Char atypeIDREFS[] 46257db96d56Sopenharmony_ci = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; 46267db96d56Sopenharmony_ci static const XML_Char atypeENTITY[] 46277db96d56Sopenharmony_ci = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; 46287db96d56Sopenharmony_ci static const XML_Char atypeENTITIES[] 46297db96d56Sopenharmony_ci = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, 46307db96d56Sopenharmony_ci ASCII_I, ASCII_E, ASCII_S, '\0'}; 46317db96d56Sopenharmony_ci static const XML_Char atypeNMTOKEN[] 46327db96d56Sopenharmony_ci = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; 46337db96d56Sopenharmony_ci static const XML_Char atypeNMTOKENS[] 46347db96d56Sopenharmony_ci = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, 46357db96d56Sopenharmony_ci ASCII_E, ASCII_N, ASCII_S, '\0'}; 46367db96d56Sopenharmony_ci static const XML_Char notationPrefix[] 46377db96d56Sopenharmony_ci = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, 46387db96d56Sopenharmony_ci ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'}; 46397db96d56Sopenharmony_ci static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'}; 46407db96d56Sopenharmony_ci static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'}; 46417db96d56Sopenharmony_ci 46427db96d56Sopenharmony_ci#ifndef XML_DTD 46437db96d56Sopenharmony_ci UNUSED_P(account); 46447db96d56Sopenharmony_ci#endif 46457db96d56Sopenharmony_ci 46467db96d56Sopenharmony_ci /* save one level of indirection */ 46477db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; 46487db96d56Sopenharmony_ci 46497db96d56Sopenharmony_ci const char **eventPP; 46507db96d56Sopenharmony_ci const char **eventEndPP; 46517db96d56Sopenharmony_ci enum XML_Content_Quant quant; 46527db96d56Sopenharmony_ci 46537db96d56Sopenharmony_ci if (enc == parser->m_encoding) { 46547db96d56Sopenharmony_ci eventPP = &parser->m_eventPtr; 46557db96d56Sopenharmony_ci eventEndPP = &parser->m_eventEndPtr; 46567db96d56Sopenharmony_ci } else { 46577db96d56Sopenharmony_ci eventPP = &(parser->m_openInternalEntities->internalEventPtr); 46587db96d56Sopenharmony_ci eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 46597db96d56Sopenharmony_ci } 46607db96d56Sopenharmony_ci 46617db96d56Sopenharmony_ci for (;;) { 46627db96d56Sopenharmony_ci int role; 46637db96d56Sopenharmony_ci XML_Bool handleDefault = XML_TRUE; 46647db96d56Sopenharmony_ci *eventPP = s; 46657db96d56Sopenharmony_ci *eventEndPP = next; 46667db96d56Sopenharmony_ci if (tok <= 0) { 46677db96d56Sopenharmony_ci if (haveMore && tok != XML_TOK_INVALID) { 46687db96d56Sopenharmony_ci *nextPtr = s; 46697db96d56Sopenharmony_ci return XML_ERROR_NONE; 46707db96d56Sopenharmony_ci } 46717db96d56Sopenharmony_ci switch (tok) { 46727db96d56Sopenharmony_ci case XML_TOK_INVALID: 46737db96d56Sopenharmony_ci *eventPP = next; 46747db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 46757db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 46767db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_TOKEN; 46777db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 46787db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 46797db96d56Sopenharmony_ci case -XML_TOK_PROLOG_S: 46807db96d56Sopenharmony_ci tok = -tok; 46817db96d56Sopenharmony_ci break; 46827db96d56Sopenharmony_ci case XML_TOK_NONE: 46837db96d56Sopenharmony_ci#ifdef XML_DTD 46847db96d56Sopenharmony_ci /* for internal PE NOT referenced between declarations */ 46857db96d56Sopenharmony_ci if (enc != parser->m_encoding 46867db96d56Sopenharmony_ci && ! parser->m_openInternalEntities->betweenDecl) { 46877db96d56Sopenharmony_ci *nextPtr = s; 46887db96d56Sopenharmony_ci return XML_ERROR_NONE; 46897db96d56Sopenharmony_ci } 46907db96d56Sopenharmony_ci /* WFC: PE Between Declarations - must check that PE contains 46917db96d56Sopenharmony_ci complete markup, not only for external PEs, but also for 46927db96d56Sopenharmony_ci internal PEs if the reference occurs between declarations. 46937db96d56Sopenharmony_ci */ 46947db96d56Sopenharmony_ci if (parser->m_isParamEntity || enc != parser->m_encoding) { 46957db96d56Sopenharmony_ci if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc) 46967db96d56Sopenharmony_ci == XML_ROLE_ERROR) 46977db96d56Sopenharmony_ci return XML_ERROR_INCOMPLETE_PE; 46987db96d56Sopenharmony_ci *nextPtr = s; 46997db96d56Sopenharmony_ci return XML_ERROR_NONE; 47007db96d56Sopenharmony_ci } 47017db96d56Sopenharmony_ci#endif /* XML_DTD */ 47027db96d56Sopenharmony_ci return XML_ERROR_NO_ELEMENTS; 47037db96d56Sopenharmony_ci default: 47047db96d56Sopenharmony_ci tok = -tok; 47057db96d56Sopenharmony_ci next = end; 47067db96d56Sopenharmony_ci break; 47077db96d56Sopenharmony_ci } 47087db96d56Sopenharmony_ci } 47097db96d56Sopenharmony_ci role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); 47107db96d56Sopenharmony_ci#ifdef XML_DTD 47117db96d56Sopenharmony_ci switch (role) { 47127db96d56Sopenharmony_ci case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor 47137db96d56Sopenharmony_ci case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl 47147db96d56Sopenharmony_ci case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl 47157db96d56Sopenharmony_ci break; 47167db96d56Sopenharmony_ci default: 47177db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { 47187db96d56Sopenharmony_ci accountingOnAbort(parser); 47197db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 47207db96d56Sopenharmony_ci } 47217db96d56Sopenharmony_ci } 47227db96d56Sopenharmony_ci#endif 47237db96d56Sopenharmony_ci switch (role) { 47247db96d56Sopenharmony_ci case XML_ROLE_XML_DECL: { 47257db96d56Sopenharmony_ci enum XML_Error result = processXmlDecl(parser, 0, s, next); 47267db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 47277db96d56Sopenharmony_ci return result; 47287db96d56Sopenharmony_ci enc = parser->m_encoding; 47297db96d56Sopenharmony_ci handleDefault = XML_FALSE; 47307db96d56Sopenharmony_ci } break; 47317db96d56Sopenharmony_ci case XML_ROLE_DOCTYPE_NAME: 47327db96d56Sopenharmony_ci if (parser->m_startDoctypeDeclHandler) { 47337db96d56Sopenharmony_ci parser->m_doctypeName 47347db96d56Sopenharmony_ci = poolStoreString(&parser->m_tempPool, enc, s, next); 47357db96d56Sopenharmony_ci if (! parser->m_doctypeName) 47367db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 47377db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 47387db96d56Sopenharmony_ci parser->m_doctypePubid = NULL; 47397db96d56Sopenharmony_ci handleDefault = XML_FALSE; 47407db96d56Sopenharmony_ci } 47417db96d56Sopenharmony_ci parser->m_doctypeSysid = NULL; /* always initialize to NULL */ 47427db96d56Sopenharmony_ci break; 47437db96d56Sopenharmony_ci case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: 47447db96d56Sopenharmony_ci if (parser->m_startDoctypeDeclHandler) { 47457db96d56Sopenharmony_ci parser->m_startDoctypeDeclHandler( 47467db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, 47477db96d56Sopenharmony_ci parser->m_doctypePubid, 1); 47487db96d56Sopenharmony_ci parser->m_doctypeName = NULL; 47497db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 47507db96d56Sopenharmony_ci handleDefault = XML_FALSE; 47517db96d56Sopenharmony_ci } 47527db96d56Sopenharmony_ci break; 47537db96d56Sopenharmony_ci#ifdef XML_DTD 47547db96d56Sopenharmony_ci case XML_ROLE_TEXT_DECL: { 47557db96d56Sopenharmony_ci enum XML_Error result = processXmlDecl(parser, 1, s, next); 47567db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 47577db96d56Sopenharmony_ci return result; 47587db96d56Sopenharmony_ci enc = parser->m_encoding; 47597db96d56Sopenharmony_ci handleDefault = XML_FALSE; 47607db96d56Sopenharmony_ci } break; 47617db96d56Sopenharmony_ci#endif /* XML_DTD */ 47627db96d56Sopenharmony_ci case XML_ROLE_DOCTYPE_PUBLIC_ID: 47637db96d56Sopenharmony_ci#ifdef XML_DTD 47647db96d56Sopenharmony_ci parser->m_useForeignDTD = XML_FALSE; 47657db96d56Sopenharmony_ci parser->m_declEntity = (ENTITY *)lookup( 47667db96d56Sopenharmony_ci parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); 47677db96d56Sopenharmony_ci if (! parser->m_declEntity) 47687db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 47697db96d56Sopenharmony_ci#endif /* XML_DTD */ 47707db96d56Sopenharmony_ci dtd->hasParamEntityRefs = XML_TRUE; 47717db96d56Sopenharmony_ci if (parser->m_startDoctypeDeclHandler) { 47727db96d56Sopenharmony_ci XML_Char *pubId; 47737db96d56Sopenharmony_ci if (! XmlIsPublicId(enc, s, next, eventPP)) 47747db96d56Sopenharmony_ci return XML_ERROR_PUBLICID; 47757db96d56Sopenharmony_ci pubId = poolStoreString(&parser->m_tempPool, enc, 47767db96d56Sopenharmony_ci s + enc->minBytesPerChar, 47777db96d56Sopenharmony_ci next - enc->minBytesPerChar); 47787db96d56Sopenharmony_ci if (! pubId) 47797db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 47807db96d56Sopenharmony_ci normalizePublicId(pubId); 47817db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 47827db96d56Sopenharmony_ci parser->m_doctypePubid = pubId; 47837db96d56Sopenharmony_ci handleDefault = XML_FALSE; 47847db96d56Sopenharmony_ci goto alreadyChecked; 47857db96d56Sopenharmony_ci } 47867db96d56Sopenharmony_ci /* fall through */ 47877db96d56Sopenharmony_ci case XML_ROLE_ENTITY_PUBLIC_ID: 47887db96d56Sopenharmony_ci if (! XmlIsPublicId(enc, s, next, eventPP)) 47897db96d56Sopenharmony_ci return XML_ERROR_PUBLICID; 47907db96d56Sopenharmony_ci alreadyChecked: 47917db96d56Sopenharmony_ci if (dtd->keepProcessing && parser->m_declEntity) { 47927db96d56Sopenharmony_ci XML_Char *tem 47937db96d56Sopenharmony_ci = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, 47947db96d56Sopenharmony_ci next - enc->minBytesPerChar); 47957db96d56Sopenharmony_ci if (! tem) 47967db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 47977db96d56Sopenharmony_ci normalizePublicId(tem); 47987db96d56Sopenharmony_ci parser->m_declEntity->publicId = tem; 47997db96d56Sopenharmony_ci poolFinish(&dtd->pool); 48007db96d56Sopenharmony_ci /* Don't suppress the default handler if we fell through from 48017db96d56Sopenharmony_ci * the XML_ROLE_DOCTYPE_PUBLIC_ID case. 48027db96d56Sopenharmony_ci */ 48037db96d56Sopenharmony_ci if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID) 48047db96d56Sopenharmony_ci handleDefault = XML_FALSE; 48057db96d56Sopenharmony_ci } 48067db96d56Sopenharmony_ci break; 48077db96d56Sopenharmony_ci case XML_ROLE_DOCTYPE_CLOSE: 48087db96d56Sopenharmony_ci if (allowClosingDoctype != XML_TRUE) { 48097db96d56Sopenharmony_ci /* Must not close doctype from within expanded parameter entities */ 48107db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 48117db96d56Sopenharmony_ci } 48127db96d56Sopenharmony_ci 48137db96d56Sopenharmony_ci if (parser->m_doctypeName) { 48147db96d56Sopenharmony_ci parser->m_startDoctypeDeclHandler( 48157db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, 48167db96d56Sopenharmony_ci parser->m_doctypePubid, 0); 48177db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 48187db96d56Sopenharmony_ci handleDefault = XML_FALSE; 48197db96d56Sopenharmony_ci } 48207db96d56Sopenharmony_ci /* parser->m_doctypeSysid will be non-NULL in the case of a previous 48217db96d56Sopenharmony_ci XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler 48227db96d56Sopenharmony_ci was not set, indicating an external subset 48237db96d56Sopenharmony_ci */ 48247db96d56Sopenharmony_ci#ifdef XML_DTD 48257db96d56Sopenharmony_ci if (parser->m_doctypeSysid || parser->m_useForeignDTD) { 48267db96d56Sopenharmony_ci XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 48277db96d56Sopenharmony_ci dtd->hasParamEntityRefs = XML_TRUE; 48287db96d56Sopenharmony_ci if (parser->m_paramEntityParsing 48297db96d56Sopenharmony_ci && parser->m_externalEntityRefHandler) { 48307db96d56Sopenharmony_ci ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, 48317db96d56Sopenharmony_ci externalSubsetName, sizeof(ENTITY)); 48327db96d56Sopenharmony_ci if (! entity) { 48337db96d56Sopenharmony_ci /* The external subset name "#" will have already been 48347db96d56Sopenharmony_ci * inserted into the hash table at the start of the 48357db96d56Sopenharmony_ci * external entity parsing, so no allocation will happen 48367db96d56Sopenharmony_ci * and lookup() cannot fail. 48377db96d56Sopenharmony_ci */ 48387db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ 48397db96d56Sopenharmony_ci } 48407db96d56Sopenharmony_ci if (parser->m_useForeignDTD) 48417db96d56Sopenharmony_ci entity->base = parser->m_curBase; 48427db96d56Sopenharmony_ci dtd->paramEntityRead = XML_FALSE; 48437db96d56Sopenharmony_ci if (! parser->m_externalEntityRefHandler( 48447db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg, 0, entity->base, 48457db96d56Sopenharmony_ci entity->systemId, entity->publicId)) 48467db96d56Sopenharmony_ci return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 48477db96d56Sopenharmony_ci if (dtd->paramEntityRead) { 48487db96d56Sopenharmony_ci if (! dtd->standalone && parser->m_notStandaloneHandler 48497db96d56Sopenharmony_ci && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) 48507db96d56Sopenharmony_ci return XML_ERROR_NOT_STANDALONE; 48517db96d56Sopenharmony_ci } 48527db96d56Sopenharmony_ci /* if we didn't read the foreign DTD then this means that there 48537db96d56Sopenharmony_ci is no external subset and we must reset dtd->hasParamEntityRefs 48547db96d56Sopenharmony_ci */ 48557db96d56Sopenharmony_ci else if (! parser->m_doctypeSysid) 48567db96d56Sopenharmony_ci dtd->hasParamEntityRefs = hadParamEntityRefs; 48577db96d56Sopenharmony_ci /* end of DTD - no need to update dtd->keepProcessing */ 48587db96d56Sopenharmony_ci } 48597db96d56Sopenharmony_ci parser->m_useForeignDTD = XML_FALSE; 48607db96d56Sopenharmony_ci } 48617db96d56Sopenharmony_ci#endif /* XML_DTD */ 48627db96d56Sopenharmony_ci if (parser->m_endDoctypeDeclHandler) { 48637db96d56Sopenharmony_ci parser->m_endDoctypeDeclHandler(parser->m_handlerArg); 48647db96d56Sopenharmony_ci handleDefault = XML_FALSE; 48657db96d56Sopenharmony_ci } 48667db96d56Sopenharmony_ci break; 48677db96d56Sopenharmony_ci case XML_ROLE_INSTANCE_START: 48687db96d56Sopenharmony_ci#ifdef XML_DTD 48697db96d56Sopenharmony_ci /* if there is no DOCTYPE declaration then now is the 48707db96d56Sopenharmony_ci last chance to read the foreign DTD 48717db96d56Sopenharmony_ci */ 48727db96d56Sopenharmony_ci if (parser->m_useForeignDTD) { 48737db96d56Sopenharmony_ci XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 48747db96d56Sopenharmony_ci dtd->hasParamEntityRefs = XML_TRUE; 48757db96d56Sopenharmony_ci if (parser->m_paramEntityParsing 48767db96d56Sopenharmony_ci && parser->m_externalEntityRefHandler) { 48777db96d56Sopenharmony_ci ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, 48787db96d56Sopenharmony_ci externalSubsetName, sizeof(ENTITY)); 48797db96d56Sopenharmony_ci if (! entity) 48807db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 48817db96d56Sopenharmony_ci entity->base = parser->m_curBase; 48827db96d56Sopenharmony_ci dtd->paramEntityRead = XML_FALSE; 48837db96d56Sopenharmony_ci if (! parser->m_externalEntityRefHandler( 48847db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg, 0, entity->base, 48857db96d56Sopenharmony_ci entity->systemId, entity->publicId)) 48867db96d56Sopenharmony_ci return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 48877db96d56Sopenharmony_ci if (dtd->paramEntityRead) { 48887db96d56Sopenharmony_ci if (! dtd->standalone && parser->m_notStandaloneHandler 48897db96d56Sopenharmony_ci && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) 48907db96d56Sopenharmony_ci return XML_ERROR_NOT_STANDALONE; 48917db96d56Sopenharmony_ci } 48927db96d56Sopenharmony_ci /* if we didn't read the foreign DTD then this means that there 48937db96d56Sopenharmony_ci is no external subset and we must reset dtd->hasParamEntityRefs 48947db96d56Sopenharmony_ci */ 48957db96d56Sopenharmony_ci else 48967db96d56Sopenharmony_ci dtd->hasParamEntityRefs = hadParamEntityRefs; 48977db96d56Sopenharmony_ci /* end of DTD - no need to update dtd->keepProcessing */ 48987db96d56Sopenharmony_ci } 48997db96d56Sopenharmony_ci } 49007db96d56Sopenharmony_ci#endif /* XML_DTD */ 49017db96d56Sopenharmony_ci parser->m_processor = contentProcessor; 49027db96d56Sopenharmony_ci return contentProcessor(parser, s, end, nextPtr); 49037db96d56Sopenharmony_ci case XML_ROLE_ATTLIST_ELEMENT_NAME: 49047db96d56Sopenharmony_ci parser->m_declElementType = getElementType(parser, enc, s, next); 49057db96d56Sopenharmony_ci if (! parser->m_declElementType) 49067db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 49077db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49087db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_NAME: 49097db96d56Sopenharmony_ci parser->m_declAttributeId = getAttributeId(parser, enc, s, next); 49107db96d56Sopenharmony_ci if (! parser->m_declAttributeId) 49117db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 49127db96d56Sopenharmony_ci parser->m_declAttributeIsCdata = XML_FALSE; 49137db96d56Sopenharmony_ci parser->m_declAttributeType = NULL; 49147db96d56Sopenharmony_ci parser->m_declAttributeIsId = XML_FALSE; 49157db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49167db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_TYPE_CDATA: 49177db96d56Sopenharmony_ci parser->m_declAttributeIsCdata = XML_TRUE; 49187db96d56Sopenharmony_ci parser->m_declAttributeType = atypeCDATA; 49197db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49207db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_TYPE_ID: 49217db96d56Sopenharmony_ci parser->m_declAttributeIsId = XML_TRUE; 49227db96d56Sopenharmony_ci parser->m_declAttributeType = atypeID; 49237db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49247db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_TYPE_IDREF: 49257db96d56Sopenharmony_ci parser->m_declAttributeType = atypeIDREF; 49267db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49277db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: 49287db96d56Sopenharmony_ci parser->m_declAttributeType = atypeIDREFS; 49297db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49307db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: 49317db96d56Sopenharmony_ci parser->m_declAttributeType = atypeENTITY; 49327db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49337db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: 49347db96d56Sopenharmony_ci parser->m_declAttributeType = atypeENTITIES; 49357db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49367db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: 49377db96d56Sopenharmony_ci parser->m_declAttributeType = atypeNMTOKEN; 49387db96d56Sopenharmony_ci goto checkAttListDeclHandler; 49397db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: 49407db96d56Sopenharmony_ci parser->m_declAttributeType = atypeNMTOKENS; 49417db96d56Sopenharmony_ci checkAttListDeclHandler: 49427db96d56Sopenharmony_ci if (dtd->keepProcessing && parser->m_attlistDeclHandler) 49437db96d56Sopenharmony_ci handleDefault = XML_FALSE; 49447db96d56Sopenharmony_ci break; 49457db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_ENUM_VALUE: 49467db96d56Sopenharmony_ci case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: 49477db96d56Sopenharmony_ci if (dtd->keepProcessing && parser->m_attlistDeclHandler) { 49487db96d56Sopenharmony_ci const XML_Char *prefix; 49497db96d56Sopenharmony_ci if (parser->m_declAttributeType) { 49507db96d56Sopenharmony_ci prefix = enumValueSep; 49517db96d56Sopenharmony_ci } else { 49527db96d56Sopenharmony_ci prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix 49537db96d56Sopenharmony_ci : enumValueStart); 49547db96d56Sopenharmony_ci } 49557db96d56Sopenharmony_ci if (! poolAppendString(&parser->m_tempPool, prefix)) 49567db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 49577db96d56Sopenharmony_ci if (! poolAppend(&parser->m_tempPool, enc, s, next)) 49587db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 49597db96d56Sopenharmony_ci parser->m_declAttributeType = parser->m_tempPool.start; 49607db96d56Sopenharmony_ci handleDefault = XML_FALSE; 49617db96d56Sopenharmony_ci } 49627db96d56Sopenharmony_ci break; 49637db96d56Sopenharmony_ci case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: 49647db96d56Sopenharmony_ci case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: 49657db96d56Sopenharmony_ci if (dtd->keepProcessing) { 49667db96d56Sopenharmony_ci if (! defineAttribute(parser->m_declElementType, 49677db96d56Sopenharmony_ci parser->m_declAttributeId, 49687db96d56Sopenharmony_ci parser->m_declAttributeIsCdata, 49697db96d56Sopenharmony_ci parser->m_declAttributeIsId, 0, parser)) 49707db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 49717db96d56Sopenharmony_ci if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { 49727db96d56Sopenharmony_ci if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) 49737db96d56Sopenharmony_ci || (*parser->m_declAttributeType == XML_T(ASCII_N) 49747db96d56Sopenharmony_ci && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { 49757db96d56Sopenharmony_ci /* Enumerated or Notation type */ 49767db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) 49777db96d56Sopenharmony_ci || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 49787db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 49797db96d56Sopenharmony_ci parser->m_declAttributeType = parser->m_tempPool.start; 49807db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 49817db96d56Sopenharmony_ci } 49827db96d56Sopenharmony_ci *eventEndPP = s; 49837db96d56Sopenharmony_ci parser->m_attlistDeclHandler( 49847db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declElementType->name, 49857db96d56Sopenharmony_ci parser->m_declAttributeId->name, parser->m_declAttributeType, 0, 49867db96d56Sopenharmony_ci role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); 49877db96d56Sopenharmony_ci handleDefault = XML_FALSE; 49887db96d56Sopenharmony_ci } 49897db96d56Sopenharmony_ci } 49907db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 49917db96d56Sopenharmony_ci break; 49927db96d56Sopenharmony_ci case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: 49937db96d56Sopenharmony_ci case XML_ROLE_FIXED_ATTRIBUTE_VALUE: 49947db96d56Sopenharmony_ci if (dtd->keepProcessing) { 49957db96d56Sopenharmony_ci const XML_Char *attVal; 49967db96d56Sopenharmony_ci enum XML_Error result = storeAttributeValue( 49977db96d56Sopenharmony_ci parser, enc, parser->m_declAttributeIsCdata, 49987db96d56Sopenharmony_ci s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool, 49997db96d56Sopenharmony_ci XML_ACCOUNT_NONE); 50007db96d56Sopenharmony_ci if (result) 50017db96d56Sopenharmony_ci return result; 50027db96d56Sopenharmony_ci attVal = poolStart(&dtd->pool); 50037db96d56Sopenharmony_ci poolFinish(&dtd->pool); 50047db96d56Sopenharmony_ci /* ID attributes aren't allowed to have a default */ 50057db96d56Sopenharmony_ci if (! defineAttribute( 50067db96d56Sopenharmony_ci parser->m_declElementType, parser->m_declAttributeId, 50077db96d56Sopenharmony_ci parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) 50087db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 50097db96d56Sopenharmony_ci if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { 50107db96d56Sopenharmony_ci if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) 50117db96d56Sopenharmony_ci || (*parser->m_declAttributeType == XML_T(ASCII_N) 50127db96d56Sopenharmony_ci && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { 50137db96d56Sopenharmony_ci /* Enumerated or Notation type */ 50147db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) 50157db96d56Sopenharmony_ci || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 50167db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 50177db96d56Sopenharmony_ci parser->m_declAttributeType = parser->m_tempPool.start; 50187db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 50197db96d56Sopenharmony_ci } 50207db96d56Sopenharmony_ci *eventEndPP = s; 50217db96d56Sopenharmony_ci parser->m_attlistDeclHandler( 50227db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declElementType->name, 50237db96d56Sopenharmony_ci parser->m_declAttributeId->name, parser->m_declAttributeType, 50247db96d56Sopenharmony_ci attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); 50257db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 50267db96d56Sopenharmony_ci handleDefault = XML_FALSE; 50277db96d56Sopenharmony_ci } 50287db96d56Sopenharmony_ci } 50297db96d56Sopenharmony_ci break; 50307db96d56Sopenharmony_ci case XML_ROLE_ENTITY_VALUE: 50317db96d56Sopenharmony_ci if (dtd->keepProcessing) { 50327db96d56Sopenharmony_ci enum XML_Error result 50337db96d56Sopenharmony_ci = storeEntityValue(parser, enc, s + enc->minBytesPerChar, 50347db96d56Sopenharmony_ci next - enc->minBytesPerChar, XML_ACCOUNT_NONE); 50357db96d56Sopenharmony_ci if (parser->m_declEntity) { 50367db96d56Sopenharmony_ci parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); 50377db96d56Sopenharmony_ci parser->m_declEntity->textLen 50387db96d56Sopenharmony_ci = (int)(poolLength(&dtd->entityValuePool)); 50397db96d56Sopenharmony_ci poolFinish(&dtd->entityValuePool); 50407db96d56Sopenharmony_ci if (parser->m_entityDeclHandler) { 50417db96d56Sopenharmony_ci *eventEndPP = s; 50427db96d56Sopenharmony_ci parser->m_entityDeclHandler( 50437db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declEntity->name, 50447db96d56Sopenharmony_ci parser->m_declEntity->is_param, parser->m_declEntity->textPtr, 50457db96d56Sopenharmony_ci parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); 50467db96d56Sopenharmony_ci handleDefault = XML_FALSE; 50477db96d56Sopenharmony_ci } 50487db96d56Sopenharmony_ci } else 50497db96d56Sopenharmony_ci poolDiscard(&dtd->entityValuePool); 50507db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 50517db96d56Sopenharmony_ci return result; 50527db96d56Sopenharmony_ci } 50537db96d56Sopenharmony_ci break; 50547db96d56Sopenharmony_ci case XML_ROLE_DOCTYPE_SYSTEM_ID: 50557db96d56Sopenharmony_ci#ifdef XML_DTD 50567db96d56Sopenharmony_ci parser->m_useForeignDTD = XML_FALSE; 50577db96d56Sopenharmony_ci#endif /* XML_DTD */ 50587db96d56Sopenharmony_ci dtd->hasParamEntityRefs = XML_TRUE; 50597db96d56Sopenharmony_ci if (parser->m_startDoctypeDeclHandler) { 50607db96d56Sopenharmony_ci parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, 50617db96d56Sopenharmony_ci s + enc->minBytesPerChar, 50627db96d56Sopenharmony_ci next - enc->minBytesPerChar); 50637db96d56Sopenharmony_ci if (parser->m_doctypeSysid == NULL) 50647db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 50657db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 50667db96d56Sopenharmony_ci handleDefault = XML_FALSE; 50677db96d56Sopenharmony_ci } 50687db96d56Sopenharmony_ci#ifdef XML_DTD 50697db96d56Sopenharmony_ci else 50707db96d56Sopenharmony_ci /* use externalSubsetName to make parser->m_doctypeSysid non-NULL 50717db96d56Sopenharmony_ci for the case where no parser->m_startDoctypeDeclHandler is set */ 50727db96d56Sopenharmony_ci parser->m_doctypeSysid = externalSubsetName; 50737db96d56Sopenharmony_ci#endif /* XML_DTD */ 50747db96d56Sopenharmony_ci if (! dtd->standalone 50757db96d56Sopenharmony_ci#ifdef XML_DTD 50767db96d56Sopenharmony_ci && ! parser->m_paramEntityParsing 50777db96d56Sopenharmony_ci#endif /* XML_DTD */ 50787db96d56Sopenharmony_ci && parser->m_notStandaloneHandler 50797db96d56Sopenharmony_ci && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) 50807db96d56Sopenharmony_ci return XML_ERROR_NOT_STANDALONE; 50817db96d56Sopenharmony_ci#ifndef XML_DTD 50827db96d56Sopenharmony_ci break; 50837db96d56Sopenharmony_ci#else /* XML_DTD */ 50847db96d56Sopenharmony_ci if (! parser->m_declEntity) { 50857db96d56Sopenharmony_ci parser->m_declEntity = (ENTITY *)lookup( 50867db96d56Sopenharmony_ci parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); 50877db96d56Sopenharmony_ci if (! parser->m_declEntity) 50887db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 50897db96d56Sopenharmony_ci parser->m_declEntity->publicId = NULL; 50907db96d56Sopenharmony_ci } 50917db96d56Sopenharmony_ci#endif /* XML_DTD */ 50927db96d56Sopenharmony_ci /* fall through */ 50937db96d56Sopenharmony_ci case XML_ROLE_ENTITY_SYSTEM_ID: 50947db96d56Sopenharmony_ci if (dtd->keepProcessing && parser->m_declEntity) { 50957db96d56Sopenharmony_ci parser->m_declEntity->systemId 50967db96d56Sopenharmony_ci = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, 50977db96d56Sopenharmony_ci next - enc->minBytesPerChar); 50987db96d56Sopenharmony_ci if (! parser->m_declEntity->systemId) 50997db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 51007db96d56Sopenharmony_ci parser->m_declEntity->base = parser->m_curBase; 51017db96d56Sopenharmony_ci poolFinish(&dtd->pool); 51027db96d56Sopenharmony_ci /* Don't suppress the default handler if we fell through from 51037db96d56Sopenharmony_ci * the XML_ROLE_DOCTYPE_SYSTEM_ID case. 51047db96d56Sopenharmony_ci */ 51057db96d56Sopenharmony_ci if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID) 51067db96d56Sopenharmony_ci handleDefault = XML_FALSE; 51077db96d56Sopenharmony_ci } 51087db96d56Sopenharmony_ci break; 51097db96d56Sopenharmony_ci case XML_ROLE_ENTITY_COMPLETE: 51107db96d56Sopenharmony_ci if (dtd->keepProcessing && parser->m_declEntity 51117db96d56Sopenharmony_ci && parser->m_entityDeclHandler) { 51127db96d56Sopenharmony_ci *eventEndPP = s; 51137db96d56Sopenharmony_ci parser->m_entityDeclHandler( 51147db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declEntity->name, 51157db96d56Sopenharmony_ci parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base, 51167db96d56Sopenharmony_ci parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0); 51177db96d56Sopenharmony_ci handleDefault = XML_FALSE; 51187db96d56Sopenharmony_ci } 51197db96d56Sopenharmony_ci break; 51207db96d56Sopenharmony_ci case XML_ROLE_ENTITY_NOTATION_NAME: 51217db96d56Sopenharmony_ci if (dtd->keepProcessing && parser->m_declEntity) { 51227db96d56Sopenharmony_ci parser->m_declEntity->notation 51237db96d56Sopenharmony_ci = poolStoreString(&dtd->pool, enc, s, next); 51247db96d56Sopenharmony_ci if (! parser->m_declEntity->notation) 51257db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 51267db96d56Sopenharmony_ci poolFinish(&dtd->pool); 51277db96d56Sopenharmony_ci if (parser->m_unparsedEntityDeclHandler) { 51287db96d56Sopenharmony_ci *eventEndPP = s; 51297db96d56Sopenharmony_ci parser->m_unparsedEntityDeclHandler( 51307db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declEntity->name, 51317db96d56Sopenharmony_ci parser->m_declEntity->base, parser->m_declEntity->systemId, 51327db96d56Sopenharmony_ci parser->m_declEntity->publicId, parser->m_declEntity->notation); 51337db96d56Sopenharmony_ci handleDefault = XML_FALSE; 51347db96d56Sopenharmony_ci } else if (parser->m_entityDeclHandler) { 51357db96d56Sopenharmony_ci *eventEndPP = s; 51367db96d56Sopenharmony_ci parser->m_entityDeclHandler( 51377db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0, 51387db96d56Sopenharmony_ci parser->m_declEntity->base, parser->m_declEntity->systemId, 51397db96d56Sopenharmony_ci parser->m_declEntity->publicId, parser->m_declEntity->notation); 51407db96d56Sopenharmony_ci handleDefault = XML_FALSE; 51417db96d56Sopenharmony_ci } 51427db96d56Sopenharmony_ci } 51437db96d56Sopenharmony_ci break; 51447db96d56Sopenharmony_ci case XML_ROLE_GENERAL_ENTITY_NAME: { 51457db96d56Sopenharmony_ci if (XmlPredefinedEntityName(enc, s, next)) { 51467db96d56Sopenharmony_ci parser->m_declEntity = NULL; 51477db96d56Sopenharmony_ci break; 51487db96d56Sopenharmony_ci } 51497db96d56Sopenharmony_ci if (dtd->keepProcessing) { 51507db96d56Sopenharmony_ci const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); 51517db96d56Sopenharmony_ci if (! name) 51527db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 51537db96d56Sopenharmony_ci parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, 51547db96d56Sopenharmony_ci name, sizeof(ENTITY)); 51557db96d56Sopenharmony_ci if (! parser->m_declEntity) 51567db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 51577db96d56Sopenharmony_ci if (parser->m_declEntity->name != name) { 51587db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 51597db96d56Sopenharmony_ci parser->m_declEntity = NULL; 51607db96d56Sopenharmony_ci } else { 51617db96d56Sopenharmony_ci poolFinish(&dtd->pool); 51627db96d56Sopenharmony_ci parser->m_declEntity->publicId = NULL; 51637db96d56Sopenharmony_ci parser->m_declEntity->is_param = XML_FALSE; 51647db96d56Sopenharmony_ci /* if we have a parent parser or are reading an internal parameter 51657db96d56Sopenharmony_ci entity, then the entity declaration is not considered "internal" 51667db96d56Sopenharmony_ci */ 51677db96d56Sopenharmony_ci parser->m_declEntity->is_internal 51687db96d56Sopenharmony_ci = ! (parser->m_parentParser || parser->m_openInternalEntities); 51697db96d56Sopenharmony_ci if (parser->m_entityDeclHandler) 51707db96d56Sopenharmony_ci handleDefault = XML_FALSE; 51717db96d56Sopenharmony_ci } 51727db96d56Sopenharmony_ci } else { 51737db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 51747db96d56Sopenharmony_ci parser->m_declEntity = NULL; 51757db96d56Sopenharmony_ci } 51767db96d56Sopenharmony_ci } break; 51777db96d56Sopenharmony_ci case XML_ROLE_PARAM_ENTITY_NAME: 51787db96d56Sopenharmony_ci#ifdef XML_DTD 51797db96d56Sopenharmony_ci if (dtd->keepProcessing) { 51807db96d56Sopenharmony_ci const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); 51817db96d56Sopenharmony_ci if (! name) 51827db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 51837db96d56Sopenharmony_ci parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, 51847db96d56Sopenharmony_ci name, sizeof(ENTITY)); 51857db96d56Sopenharmony_ci if (! parser->m_declEntity) 51867db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 51877db96d56Sopenharmony_ci if (parser->m_declEntity->name != name) { 51887db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 51897db96d56Sopenharmony_ci parser->m_declEntity = NULL; 51907db96d56Sopenharmony_ci } else { 51917db96d56Sopenharmony_ci poolFinish(&dtd->pool); 51927db96d56Sopenharmony_ci parser->m_declEntity->publicId = NULL; 51937db96d56Sopenharmony_ci parser->m_declEntity->is_param = XML_TRUE; 51947db96d56Sopenharmony_ci /* if we have a parent parser or are reading an internal parameter 51957db96d56Sopenharmony_ci entity, then the entity declaration is not considered "internal" 51967db96d56Sopenharmony_ci */ 51977db96d56Sopenharmony_ci parser->m_declEntity->is_internal 51987db96d56Sopenharmony_ci = ! (parser->m_parentParser || parser->m_openInternalEntities); 51997db96d56Sopenharmony_ci if (parser->m_entityDeclHandler) 52007db96d56Sopenharmony_ci handleDefault = XML_FALSE; 52017db96d56Sopenharmony_ci } 52027db96d56Sopenharmony_ci } else { 52037db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 52047db96d56Sopenharmony_ci parser->m_declEntity = NULL; 52057db96d56Sopenharmony_ci } 52067db96d56Sopenharmony_ci#else /* not XML_DTD */ 52077db96d56Sopenharmony_ci parser->m_declEntity = NULL; 52087db96d56Sopenharmony_ci#endif /* XML_DTD */ 52097db96d56Sopenharmony_ci break; 52107db96d56Sopenharmony_ci case XML_ROLE_NOTATION_NAME: 52117db96d56Sopenharmony_ci parser->m_declNotationPublicId = NULL; 52127db96d56Sopenharmony_ci parser->m_declNotationName = NULL; 52137db96d56Sopenharmony_ci if (parser->m_notationDeclHandler) { 52147db96d56Sopenharmony_ci parser->m_declNotationName 52157db96d56Sopenharmony_ci = poolStoreString(&parser->m_tempPool, enc, s, next); 52167db96d56Sopenharmony_ci if (! parser->m_declNotationName) 52177db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 52187db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 52197db96d56Sopenharmony_ci handleDefault = XML_FALSE; 52207db96d56Sopenharmony_ci } 52217db96d56Sopenharmony_ci break; 52227db96d56Sopenharmony_ci case XML_ROLE_NOTATION_PUBLIC_ID: 52237db96d56Sopenharmony_ci if (! XmlIsPublicId(enc, s, next, eventPP)) 52247db96d56Sopenharmony_ci return XML_ERROR_PUBLICID; 52257db96d56Sopenharmony_ci if (parser 52267db96d56Sopenharmony_ci ->m_declNotationName) { /* means m_notationDeclHandler != NULL */ 52277db96d56Sopenharmony_ci XML_Char *tem = poolStoreString(&parser->m_tempPool, enc, 52287db96d56Sopenharmony_ci s + enc->minBytesPerChar, 52297db96d56Sopenharmony_ci next - enc->minBytesPerChar); 52307db96d56Sopenharmony_ci if (! tem) 52317db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 52327db96d56Sopenharmony_ci normalizePublicId(tem); 52337db96d56Sopenharmony_ci parser->m_declNotationPublicId = tem; 52347db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 52357db96d56Sopenharmony_ci handleDefault = XML_FALSE; 52367db96d56Sopenharmony_ci } 52377db96d56Sopenharmony_ci break; 52387db96d56Sopenharmony_ci case XML_ROLE_NOTATION_SYSTEM_ID: 52397db96d56Sopenharmony_ci if (parser->m_declNotationName && parser->m_notationDeclHandler) { 52407db96d56Sopenharmony_ci const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc, 52417db96d56Sopenharmony_ci s + enc->minBytesPerChar, 52427db96d56Sopenharmony_ci next - enc->minBytesPerChar); 52437db96d56Sopenharmony_ci if (! systemId) 52447db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 52457db96d56Sopenharmony_ci *eventEndPP = s; 52467db96d56Sopenharmony_ci parser->m_notationDeclHandler( 52477db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, 52487db96d56Sopenharmony_ci systemId, parser->m_declNotationPublicId); 52497db96d56Sopenharmony_ci handleDefault = XML_FALSE; 52507db96d56Sopenharmony_ci } 52517db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 52527db96d56Sopenharmony_ci break; 52537db96d56Sopenharmony_ci case XML_ROLE_NOTATION_NO_SYSTEM_ID: 52547db96d56Sopenharmony_ci if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { 52557db96d56Sopenharmony_ci *eventEndPP = s; 52567db96d56Sopenharmony_ci parser->m_notationDeclHandler( 52577db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, 52587db96d56Sopenharmony_ci 0, parser->m_declNotationPublicId); 52597db96d56Sopenharmony_ci handleDefault = XML_FALSE; 52607db96d56Sopenharmony_ci } 52617db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 52627db96d56Sopenharmony_ci break; 52637db96d56Sopenharmony_ci case XML_ROLE_ERROR: 52647db96d56Sopenharmony_ci switch (tok) { 52657db96d56Sopenharmony_ci case XML_TOK_PARAM_ENTITY_REF: 52667db96d56Sopenharmony_ci /* PE references in internal subset are 52677db96d56Sopenharmony_ci not allowed within declarations. */ 52687db96d56Sopenharmony_ci return XML_ERROR_PARAM_ENTITY_REF; 52697db96d56Sopenharmony_ci case XML_TOK_XML_DECL: 52707db96d56Sopenharmony_ci return XML_ERROR_MISPLACED_XML_PI; 52717db96d56Sopenharmony_ci default: 52727db96d56Sopenharmony_ci return XML_ERROR_SYNTAX; 52737db96d56Sopenharmony_ci } 52747db96d56Sopenharmony_ci#ifdef XML_DTD 52757db96d56Sopenharmony_ci case XML_ROLE_IGNORE_SECT: { 52767db96d56Sopenharmony_ci enum XML_Error result; 52777db96d56Sopenharmony_ci if (parser->m_defaultHandler) 52787db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 52797db96d56Sopenharmony_ci handleDefault = XML_FALSE; 52807db96d56Sopenharmony_ci result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); 52817db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 52827db96d56Sopenharmony_ci return result; 52837db96d56Sopenharmony_ci else if (! next) { 52847db96d56Sopenharmony_ci parser->m_processor = ignoreSectionProcessor; 52857db96d56Sopenharmony_ci return result; 52867db96d56Sopenharmony_ci } 52877db96d56Sopenharmony_ci } break; 52887db96d56Sopenharmony_ci#endif /* XML_DTD */ 52897db96d56Sopenharmony_ci case XML_ROLE_GROUP_OPEN: 52907db96d56Sopenharmony_ci if (parser->m_prologState.level >= parser->m_groupSize) { 52917db96d56Sopenharmony_ci if (parser->m_groupSize) { 52927db96d56Sopenharmony_ci { 52937db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 52947db96d56Sopenharmony_ci if (parser->m_groupSize > (unsigned int)(-1) / 2u) { 52957db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 52967db96d56Sopenharmony_ci } 52977db96d56Sopenharmony_ci 52987db96d56Sopenharmony_ci char *const new_connector = (char *)REALLOC( 52997db96d56Sopenharmony_ci parser, parser->m_groupConnector, parser->m_groupSize *= 2); 53007db96d56Sopenharmony_ci if (new_connector == NULL) { 53017db96d56Sopenharmony_ci parser->m_groupSize /= 2; 53027db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 53037db96d56Sopenharmony_ci } 53047db96d56Sopenharmony_ci parser->m_groupConnector = new_connector; 53057db96d56Sopenharmony_ci } 53067db96d56Sopenharmony_ci 53077db96d56Sopenharmony_ci if (dtd->scaffIndex) { 53087db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 53097db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 53107db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 53117db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 53127db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 53137db96d56Sopenharmony_ci if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) { 53147db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 53157db96d56Sopenharmony_ci } 53167db96d56Sopenharmony_ci#endif 53177db96d56Sopenharmony_ci 53187db96d56Sopenharmony_ci int *const new_scaff_index = (int *)REALLOC( 53197db96d56Sopenharmony_ci parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); 53207db96d56Sopenharmony_ci if (new_scaff_index == NULL) 53217db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 53227db96d56Sopenharmony_ci dtd->scaffIndex = new_scaff_index; 53237db96d56Sopenharmony_ci } 53247db96d56Sopenharmony_ci } else { 53257db96d56Sopenharmony_ci parser->m_groupConnector 53267db96d56Sopenharmony_ci = (char *)MALLOC(parser, parser->m_groupSize = 32); 53277db96d56Sopenharmony_ci if (! parser->m_groupConnector) { 53287db96d56Sopenharmony_ci parser->m_groupSize = 0; 53297db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 53307db96d56Sopenharmony_ci } 53317db96d56Sopenharmony_ci } 53327db96d56Sopenharmony_ci } 53337db96d56Sopenharmony_ci parser->m_groupConnector[parser->m_prologState.level] = 0; 53347db96d56Sopenharmony_ci if (dtd->in_eldecl) { 53357db96d56Sopenharmony_ci int myindex = nextScaffoldPart(parser); 53367db96d56Sopenharmony_ci if (myindex < 0) 53377db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 53387db96d56Sopenharmony_ci assert(dtd->scaffIndex != NULL); 53397db96d56Sopenharmony_ci dtd->scaffIndex[dtd->scaffLevel] = myindex; 53407db96d56Sopenharmony_ci dtd->scaffLevel++; 53417db96d56Sopenharmony_ci dtd->scaffold[myindex].type = XML_CTYPE_SEQ; 53427db96d56Sopenharmony_ci if (parser->m_elementDeclHandler) 53437db96d56Sopenharmony_ci handleDefault = XML_FALSE; 53447db96d56Sopenharmony_ci } 53457db96d56Sopenharmony_ci break; 53467db96d56Sopenharmony_ci case XML_ROLE_GROUP_SEQUENCE: 53477db96d56Sopenharmony_ci if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE) 53487db96d56Sopenharmony_ci return XML_ERROR_SYNTAX; 53497db96d56Sopenharmony_ci parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA; 53507db96d56Sopenharmony_ci if (dtd->in_eldecl && parser->m_elementDeclHandler) 53517db96d56Sopenharmony_ci handleDefault = XML_FALSE; 53527db96d56Sopenharmony_ci break; 53537db96d56Sopenharmony_ci case XML_ROLE_GROUP_CHOICE: 53547db96d56Sopenharmony_ci if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) 53557db96d56Sopenharmony_ci return XML_ERROR_SYNTAX; 53567db96d56Sopenharmony_ci if (dtd->in_eldecl 53577db96d56Sopenharmony_ci && ! parser->m_groupConnector[parser->m_prologState.level] 53587db96d56Sopenharmony_ci && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 53597db96d56Sopenharmony_ci != XML_CTYPE_MIXED)) { 53607db96d56Sopenharmony_ci dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 53617db96d56Sopenharmony_ci = XML_CTYPE_CHOICE; 53627db96d56Sopenharmony_ci if (parser->m_elementDeclHandler) 53637db96d56Sopenharmony_ci handleDefault = XML_FALSE; 53647db96d56Sopenharmony_ci } 53657db96d56Sopenharmony_ci parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE; 53667db96d56Sopenharmony_ci break; 53677db96d56Sopenharmony_ci case XML_ROLE_PARAM_ENTITY_REF: 53687db96d56Sopenharmony_ci#ifdef XML_DTD 53697db96d56Sopenharmony_ci case XML_ROLE_INNER_PARAM_ENTITY_REF: 53707db96d56Sopenharmony_ci dtd->hasParamEntityRefs = XML_TRUE; 53717db96d56Sopenharmony_ci if (! parser->m_paramEntityParsing) 53727db96d56Sopenharmony_ci dtd->keepProcessing = dtd->standalone; 53737db96d56Sopenharmony_ci else { 53747db96d56Sopenharmony_ci const XML_Char *name; 53757db96d56Sopenharmony_ci ENTITY *entity; 53767db96d56Sopenharmony_ci name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, 53777db96d56Sopenharmony_ci next - enc->minBytesPerChar); 53787db96d56Sopenharmony_ci if (! name) 53797db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 53807db96d56Sopenharmony_ci entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); 53817db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 53827db96d56Sopenharmony_ci /* first, determine if a check for an existing declaration is needed; 53837db96d56Sopenharmony_ci if yes, check that the entity exists, and that it is internal, 53847db96d56Sopenharmony_ci otherwise call the skipped entity handler 53857db96d56Sopenharmony_ci */ 53867db96d56Sopenharmony_ci if (parser->m_prologState.documentEntity 53877db96d56Sopenharmony_ci && (dtd->standalone ? ! parser->m_openInternalEntities 53887db96d56Sopenharmony_ci : ! dtd->hasParamEntityRefs)) { 53897db96d56Sopenharmony_ci if (! entity) 53907db96d56Sopenharmony_ci return XML_ERROR_UNDEFINED_ENTITY; 53917db96d56Sopenharmony_ci else if (! entity->is_internal) { 53927db96d56Sopenharmony_ci /* It's hard to exhaustively search the code to be sure, 53937db96d56Sopenharmony_ci * but there doesn't seem to be a way of executing the 53947db96d56Sopenharmony_ci * following line. There are two cases: 53957db96d56Sopenharmony_ci * 53967db96d56Sopenharmony_ci * If 'standalone' is false, the DTD must have no 53977db96d56Sopenharmony_ci * parameter entities or we wouldn't have passed the outer 53987db96d56Sopenharmony_ci * 'if' statement. That means the only entity in the hash 53997db96d56Sopenharmony_ci * table is the external subset name "#" which cannot be 54007db96d56Sopenharmony_ci * given as a parameter entity name in XML syntax, so the 54017db96d56Sopenharmony_ci * lookup must have returned NULL and we don't even reach 54027db96d56Sopenharmony_ci * the test for an internal entity. 54037db96d56Sopenharmony_ci * 54047db96d56Sopenharmony_ci * If 'standalone' is true, it does not seem to be 54057db96d56Sopenharmony_ci * possible to create entities taking this code path that 54067db96d56Sopenharmony_ci * are not internal entities, so fail the test above. 54077db96d56Sopenharmony_ci * 54087db96d56Sopenharmony_ci * Because this analysis is very uncertain, the code is 54097db96d56Sopenharmony_ci * being left in place and merely removed from the 54107db96d56Sopenharmony_ci * coverage test statistics. 54117db96d56Sopenharmony_ci */ 54127db96d56Sopenharmony_ci return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ 54137db96d56Sopenharmony_ci } 54147db96d56Sopenharmony_ci } else if (! entity) { 54157db96d56Sopenharmony_ci dtd->keepProcessing = dtd->standalone; 54167db96d56Sopenharmony_ci /* cannot report skipped entities in declarations */ 54177db96d56Sopenharmony_ci if ((role == XML_ROLE_PARAM_ENTITY_REF) 54187db96d56Sopenharmony_ci && parser->m_skippedEntityHandler) { 54197db96d56Sopenharmony_ci parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); 54207db96d56Sopenharmony_ci handleDefault = XML_FALSE; 54217db96d56Sopenharmony_ci } 54227db96d56Sopenharmony_ci break; 54237db96d56Sopenharmony_ci } 54247db96d56Sopenharmony_ci if (entity->open) 54257db96d56Sopenharmony_ci return XML_ERROR_RECURSIVE_ENTITY_REF; 54267db96d56Sopenharmony_ci if (entity->textPtr) { 54277db96d56Sopenharmony_ci enum XML_Error result; 54287db96d56Sopenharmony_ci XML_Bool betweenDecl 54297db96d56Sopenharmony_ci = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); 54307db96d56Sopenharmony_ci result = processInternalEntity(parser, entity, betweenDecl); 54317db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 54327db96d56Sopenharmony_ci return result; 54337db96d56Sopenharmony_ci handleDefault = XML_FALSE; 54347db96d56Sopenharmony_ci break; 54357db96d56Sopenharmony_ci } 54367db96d56Sopenharmony_ci if (parser->m_externalEntityRefHandler) { 54377db96d56Sopenharmony_ci dtd->paramEntityRead = XML_FALSE; 54387db96d56Sopenharmony_ci entity->open = XML_TRUE; 54397db96d56Sopenharmony_ci entityTrackingOnOpen(parser, entity, __LINE__); 54407db96d56Sopenharmony_ci if (! parser->m_externalEntityRefHandler( 54417db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg, 0, entity->base, 54427db96d56Sopenharmony_ci entity->systemId, entity->publicId)) { 54437db96d56Sopenharmony_ci entityTrackingOnClose(parser, entity, __LINE__); 54447db96d56Sopenharmony_ci entity->open = XML_FALSE; 54457db96d56Sopenharmony_ci return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 54467db96d56Sopenharmony_ci } 54477db96d56Sopenharmony_ci entityTrackingOnClose(parser, entity, __LINE__); 54487db96d56Sopenharmony_ci entity->open = XML_FALSE; 54497db96d56Sopenharmony_ci handleDefault = XML_FALSE; 54507db96d56Sopenharmony_ci if (! dtd->paramEntityRead) { 54517db96d56Sopenharmony_ci dtd->keepProcessing = dtd->standalone; 54527db96d56Sopenharmony_ci break; 54537db96d56Sopenharmony_ci } 54547db96d56Sopenharmony_ci } else { 54557db96d56Sopenharmony_ci dtd->keepProcessing = dtd->standalone; 54567db96d56Sopenharmony_ci break; 54577db96d56Sopenharmony_ci } 54587db96d56Sopenharmony_ci } 54597db96d56Sopenharmony_ci#endif /* XML_DTD */ 54607db96d56Sopenharmony_ci if (! dtd->standalone && parser->m_notStandaloneHandler 54617db96d56Sopenharmony_ci && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) 54627db96d56Sopenharmony_ci return XML_ERROR_NOT_STANDALONE; 54637db96d56Sopenharmony_ci break; 54647db96d56Sopenharmony_ci 54657db96d56Sopenharmony_ci /* Element declaration stuff */ 54667db96d56Sopenharmony_ci 54677db96d56Sopenharmony_ci case XML_ROLE_ELEMENT_NAME: 54687db96d56Sopenharmony_ci if (parser->m_elementDeclHandler) { 54697db96d56Sopenharmony_ci parser->m_declElementType = getElementType(parser, enc, s, next); 54707db96d56Sopenharmony_ci if (! parser->m_declElementType) 54717db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 54727db96d56Sopenharmony_ci dtd->scaffLevel = 0; 54737db96d56Sopenharmony_ci dtd->scaffCount = 0; 54747db96d56Sopenharmony_ci dtd->in_eldecl = XML_TRUE; 54757db96d56Sopenharmony_ci handleDefault = XML_FALSE; 54767db96d56Sopenharmony_ci } 54777db96d56Sopenharmony_ci break; 54787db96d56Sopenharmony_ci 54797db96d56Sopenharmony_ci case XML_ROLE_CONTENT_ANY: 54807db96d56Sopenharmony_ci case XML_ROLE_CONTENT_EMPTY: 54817db96d56Sopenharmony_ci if (dtd->in_eldecl) { 54827db96d56Sopenharmony_ci if (parser->m_elementDeclHandler) { 54837db96d56Sopenharmony_ci XML_Content *content 54847db96d56Sopenharmony_ci = (XML_Content *)MALLOC(parser, sizeof(XML_Content)); 54857db96d56Sopenharmony_ci if (! content) 54867db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 54877db96d56Sopenharmony_ci content->quant = XML_CQUANT_NONE; 54887db96d56Sopenharmony_ci content->name = NULL; 54897db96d56Sopenharmony_ci content->numchildren = 0; 54907db96d56Sopenharmony_ci content->children = NULL; 54917db96d56Sopenharmony_ci content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY 54927db96d56Sopenharmony_ci : XML_CTYPE_EMPTY); 54937db96d56Sopenharmony_ci *eventEndPP = s; 54947db96d56Sopenharmony_ci parser->m_elementDeclHandler( 54957db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declElementType->name, content); 54967db96d56Sopenharmony_ci handleDefault = XML_FALSE; 54977db96d56Sopenharmony_ci } 54987db96d56Sopenharmony_ci dtd->in_eldecl = XML_FALSE; 54997db96d56Sopenharmony_ci } 55007db96d56Sopenharmony_ci break; 55017db96d56Sopenharmony_ci 55027db96d56Sopenharmony_ci case XML_ROLE_CONTENT_PCDATA: 55037db96d56Sopenharmony_ci if (dtd->in_eldecl) { 55047db96d56Sopenharmony_ci dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 55057db96d56Sopenharmony_ci = XML_CTYPE_MIXED; 55067db96d56Sopenharmony_ci if (parser->m_elementDeclHandler) 55077db96d56Sopenharmony_ci handleDefault = XML_FALSE; 55087db96d56Sopenharmony_ci } 55097db96d56Sopenharmony_ci break; 55107db96d56Sopenharmony_ci 55117db96d56Sopenharmony_ci case XML_ROLE_CONTENT_ELEMENT: 55127db96d56Sopenharmony_ci quant = XML_CQUANT_NONE; 55137db96d56Sopenharmony_ci goto elementContent; 55147db96d56Sopenharmony_ci case XML_ROLE_CONTENT_ELEMENT_OPT: 55157db96d56Sopenharmony_ci quant = XML_CQUANT_OPT; 55167db96d56Sopenharmony_ci goto elementContent; 55177db96d56Sopenharmony_ci case XML_ROLE_CONTENT_ELEMENT_REP: 55187db96d56Sopenharmony_ci quant = XML_CQUANT_REP; 55197db96d56Sopenharmony_ci goto elementContent; 55207db96d56Sopenharmony_ci case XML_ROLE_CONTENT_ELEMENT_PLUS: 55217db96d56Sopenharmony_ci quant = XML_CQUANT_PLUS; 55227db96d56Sopenharmony_ci elementContent: 55237db96d56Sopenharmony_ci if (dtd->in_eldecl) { 55247db96d56Sopenharmony_ci ELEMENT_TYPE *el; 55257db96d56Sopenharmony_ci const XML_Char *name; 55267db96d56Sopenharmony_ci size_t nameLen; 55277db96d56Sopenharmony_ci const char *nxt 55287db96d56Sopenharmony_ci = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar); 55297db96d56Sopenharmony_ci int myindex = nextScaffoldPart(parser); 55307db96d56Sopenharmony_ci if (myindex < 0) 55317db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 55327db96d56Sopenharmony_ci dtd->scaffold[myindex].type = XML_CTYPE_NAME; 55337db96d56Sopenharmony_ci dtd->scaffold[myindex].quant = quant; 55347db96d56Sopenharmony_ci el = getElementType(parser, enc, s, nxt); 55357db96d56Sopenharmony_ci if (! el) 55367db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 55377db96d56Sopenharmony_ci name = el->name; 55387db96d56Sopenharmony_ci dtd->scaffold[myindex].name = name; 55397db96d56Sopenharmony_ci nameLen = 0; 55407db96d56Sopenharmony_ci for (; name[nameLen++];) 55417db96d56Sopenharmony_ci ; 55427db96d56Sopenharmony_ci 55437db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 55447db96d56Sopenharmony_ci if (nameLen > UINT_MAX - dtd->contentStringLen) { 55457db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 55467db96d56Sopenharmony_ci } 55477db96d56Sopenharmony_ci 55487db96d56Sopenharmony_ci dtd->contentStringLen += (unsigned)nameLen; 55497db96d56Sopenharmony_ci if (parser->m_elementDeclHandler) 55507db96d56Sopenharmony_ci handleDefault = XML_FALSE; 55517db96d56Sopenharmony_ci } 55527db96d56Sopenharmony_ci break; 55537db96d56Sopenharmony_ci 55547db96d56Sopenharmony_ci case XML_ROLE_GROUP_CLOSE: 55557db96d56Sopenharmony_ci quant = XML_CQUANT_NONE; 55567db96d56Sopenharmony_ci goto closeGroup; 55577db96d56Sopenharmony_ci case XML_ROLE_GROUP_CLOSE_OPT: 55587db96d56Sopenharmony_ci quant = XML_CQUANT_OPT; 55597db96d56Sopenharmony_ci goto closeGroup; 55607db96d56Sopenharmony_ci case XML_ROLE_GROUP_CLOSE_REP: 55617db96d56Sopenharmony_ci quant = XML_CQUANT_REP; 55627db96d56Sopenharmony_ci goto closeGroup; 55637db96d56Sopenharmony_ci case XML_ROLE_GROUP_CLOSE_PLUS: 55647db96d56Sopenharmony_ci quant = XML_CQUANT_PLUS; 55657db96d56Sopenharmony_ci closeGroup: 55667db96d56Sopenharmony_ci if (dtd->in_eldecl) { 55677db96d56Sopenharmony_ci if (parser->m_elementDeclHandler) 55687db96d56Sopenharmony_ci handleDefault = XML_FALSE; 55697db96d56Sopenharmony_ci dtd->scaffLevel--; 55707db96d56Sopenharmony_ci dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; 55717db96d56Sopenharmony_ci if (dtd->scaffLevel == 0) { 55727db96d56Sopenharmony_ci if (! handleDefault) { 55737db96d56Sopenharmony_ci XML_Content *model = build_model(parser); 55747db96d56Sopenharmony_ci if (! model) 55757db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 55767db96d56Sopenharmony_ci *eventEndPP = s; 55777db96d56Sopenharmony_ci parser->m_elementDeclHandler( 55787db96d56Sopenharmony_ci parser->m_handlerArg, parser->m_declElementType->name, model); 55797db96d56Sopenharmony_ci } 55807db96d56Sopenharmony_ci dtd->in_eldecl = XML_FALSE; 55817db96d56Sopenharmony_ci dtd->contentStringLen = 0; 55827db96d56Sopenharmony_ci } 55837db96d56Sopenharmony_ci } 55847db96d56Sopenharmony_ci break; 55857db96d56Sopenharmony_ci /* End element declaration stuff */ 55867db96d56Sopenharmony_ci 55877db96d56Sopenharmony_ci case XML_ROLE_PI: 55887db96d56Sopenharmony_ci if (! reportProcessingInstruction(parser, enc, s, next)) 55897db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 55907db96d56Sopenharmony_ci handleDefault = XML_FALSE; 55917db96d56Sopenharmony_ci break; 55927db96d56Sopenharmony_ci case XML_ROLE_COMMENT: 55937db96d56Sopenharmony_ci if (! reportComment(parser, enc, s, next)) 55947db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 55957db96d56Sopenharmony_ci handleDefault = XML_FALSE; 55967db96d56Sopenharmony_ci break; 55977db96d56Sopenharmony_ci case XML_ROLE_NONE: 55987db96d56Sopenharmony_ci switch (tok) { 55997db96d56Sopenharmony_ci case XML_TOK_BOM: 56007db96d56Sopenharmony_ci handleDefault = XML_FALSE; 56017db96d56Sopenharmony_ci break; 56027db96d56Sopenharmony_ci } 56037db96d56Sopenharmony_ci break; 56047db96d56Sopenharmony_ci case XML_ROLE_DOCTYPE_NONE: 56057db96d56Sopenharmony_ci if (parser->m_startDoctypeDeclHandler) 56067db96d56Sopenharmony_ci handleDefault = XML_FALSE; 56077db96d56Sopenharmony_ci break; 56087db96d56Sopenharmony_ci case XML_ROLE_ENTITY_NONE: 56097db96d56Sopenharmony_ci if (dtd->keepProcessing && parser->m_entityDeclHandler) 56107db96d56Sopenharmony_ci handleDefault = XML_FALSE; 56117db96d56Sopenharmony_ci break; 56127db96d56Sopenharmony_ci case XML_ROLE_NOTATION_NONE: 56137db96d56Sopenharmony_ci if (parser->m_notationDeclHandler) 56147db96d56Sopenharmony_ci handleDefault = XML_FALSE; 56157db96d56Sopenharmony_ci break; 56167db96d56Sopenharmony_ci case XML_ROLE_ATTLIST_NONE: 56177db96d56Sopenharmony_ci if (dtd->keepProcessing && parser->m_attlistDeclHandler) 56187db96d56Sopenharmony_ci handleDefault = XML_FALSE; 56197db96d56Sopenharmony_ci break; 56207db96d56Sopenharmony_ci case XML_ROLE_ELEMENT_NONE: 56217db96d56Sopenharmony_ci if (parser->m_elementDeclHandler) 56227db96d56Sopenharmony_ci handleDefault = XML_FALSE; 56237db96d56Sopenharmony_ci break; 56247db96d56Sopenharmony_ci } /* end of big switch */ 56257db96d56Sopenharmony_ci 56267db96d56Sopenharmony_ci if (handleDefault && parser->m_defaultHandler) 56277db96d56Sopenharmony_ci reportDefault(parser, enc, s, next); 56287db96d56Sopenharmony_ci 56297db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 56307db96d56Sopenharmony_ci case XML_SUSPENDED: 56317db96d56Sopenharmony_ci *nextPtr = next; 56327db96d56Sopenharmony_ci return XML_ERROR_NONE; 56337db96d56Sopenharmony_ci case XML_FINISHED: 56347db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 56357db96d56Sopenharmony_ci default: 56367db96d56Sopenharmony_ci s = next; 56377db96d56Sopenharmony_ci tok = XmlPrologTok(enc, s, end, &next); 56387db96d56Sopenharmony_ci } 56397db96d56Sopenharmony_ci } 56407db96d56Sopenharmony_ci /* not reached */ 56417db96d56Sopenharmony_ci} 56427db96d56Sopenharmony_ci 56437db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 56447db96d56Sopenharmony_ciepilogProcessor(XML_Parser parser, const char *s, const char *end, 56457db96d56Sopenharmony_ci const char **nextPtr) { 56467db96d56Sopenharmony_ci parser->m_processor = epilogProcessor; 56477db96d56Sopenharmony_ci parser->m_eventPtr = s; 56487db96d56Sopenharmony_ci for (;;) { 56497db96d56Sopenharmony_ci const char *next = NULL; 56507db96d56Sopenharmony_ci int tok = XmlPrologTok(parser->m_encoding, s, end, &next); 56517db96d56Sopenharmony_ci#ifdef XML_DTD 56527db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 56537db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT)) { 56547db96d56Sopenharmony_ci accountingOnAbort(parser); 56557db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 56567db96d56Sopenharmony_ci } 56577db96d56Sopenharmony_ci#endif 56587db96d56Sopenharmony_ci parser->m_eventEndPtr = next; 56597db96d56Sopenharmony_ci switch (tok) { 56607db96d56Sopenharmony_ci /* report partial linebreak - it might be the last token */ 56617db96d56Sopenharmony_ci case -XML_TOK_PROLOG_S: 56627db96d56Sopenharmony_ci if (parser->m_defaultHandler) { 56637db96d56Sopenharmony_ci reportDefault(parser, parser->m_encoding, s, next); 56647db96d56Sopenharmony_ci if (parser->m_parsingStatus.parsing == XML_FINISHED) 56657db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 56667db96d56Sopenharmony_ci } 56677db96d56Sopenharmony_ci *nextPtr = next; 56687db96d56Sopenharmony_ci return XML_ERROR_NONE; 56697db96d56Sopenharmony_ci case XML_TOK_NONE: 56707db96d56Sopenharmony_ci *nextPtr = s; 56717db96d56Sopenharmony_ci return XML_ERROR_NONE; 56727db96d56Sopenharmony_ci case XML_TOK_PROLOG_S: 56737db96d56Sopenharmony_ci if (parser->m_defaultHandler) 56747db96d56Sopenharmony_ci reportDefault(parser, parser->m_encoding, s, next); 56757db96d56Sopenharmony_ci break; 56767db96d56Sopenharmony_ci case XML_TOK_PI: 56777db96d56Sopenharmony_ci if (! reportProcessingInstruction(parser, parser->m_encoding, s, next)) 56787db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 56797db96d56Sopenharmony_ci break; 56807db96d56Sopenharmony_ci case XML_TOK_COMMENT: 56817db96d56Sopenharmony_ci if (! reportComment(parser, parser->m_encoding, s, next)) 56827db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 56837db96d56Sopenharmony_ci break; 56847db96d56Sopenharmony_ci case XML_TOK_INVALID: 56857db96d56Sopenharmony_ci parser->m_eventPtr = next; 56867db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 56877db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 56887db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer) { 56897db96d56Sopenharmony_ci *nextPtr = s; 56907db96d56Sopenharmony_ci return XML_ERROR_NONE; 56917db96d56Sopenharmony_ci } 56927db96d56Sopenharmony_ci return XML_ERROR_UNCLOSED_TOKEN; 56937db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 56947db96d56Sopenharmony_ci if (! parser->m_parsingStatus.finalBuffer) { 56957db96d56Sopenharmony_ci *nextPtr = s; 56967db96d56Sopenharmony_ci return XML_ERROR_NONE; 56977db96d56Sopenharmony_ci } 56987db96d56Sopenharmony_ci return XML_ERROR_PARTIAL_CHAR; 56997db96d56Sopenharmony_ci default: 57007db96d56Sopenharmony_ci return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; 57017db96d56Sopenharmony_ci } 57027db96d56Sopenharmony_ci parser->m_eventPtr = s = next; 57037db96d56Sopenharmony_ci switch (parser->m_parsingStatus.parsing) { 57047db96d56Sopenharmony_ci case XML_SUSPENDED: 57057db96d56Sopenharmony_ci *nextPtr = next; 57067db96d56Sopenharmony_ci return XML_ERROR_NONE; 57077db96d56Sopenharmony_ci case XML_FINISHED: 57087db96d56Sopenharmony_ci return XML_ERROR_ABORTED; 57097db96d56Sopenharmony_ci default:; 57107db96d56Sopenharmony_ci } 57117db96d56Sopenharmony_ci } 57127db96d56Sopenharmony_ci} 57137db96d56Sopenharmony_ci 57147db96d56Sopenharmony_cistatic enum XML_Error 57157db96d56Sopenharmony_ciprocessInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { 57167db96d56Sopenharmony_ci const char *textStart, *textEnd; 57177db96d56Sopenharmony_ci const char *next; 57187db96d56Sopenharmony_ci enum XML_Error result; 57197db96d56Sopenharmony_ci OPEN_INTERNAL_ENTITY *openEntity; 57207db96d56Sopenharmony_ci 57217db96d56Sopenharmony_ci if (parser->m_freeInternalEntities) { 57227db96d56Sopenharmony_ci openEntity = parser->m_freeInternalEntities; 57237db96d56Sopenharmony_ci parser->m_freeInternalEntities = openEntity->next; 57247db96d56Sopenharmony_ci } else { 57257db96d56Sopenharmony_ci openEntity 57267db96d56Sopenharmony_ci = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); 57277db96d56Sopenharmony_ci if (! openEntity) 57287db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 57297db96d56Sopenharmony_ci } 57307db96d56Sopenharmony_ci entity->open = XML_TRUE; 57317db96d56Sopenharmony_ci#ifdef XML_DTD 57327db96d56Sopenharmony_ci entityTrackingOnOpen(parser, entity, __LINE__); 57337db96d56Sopenharmony_ci#endif 57347db96d56Sopenharmony_ci entity->processed = 0; 57357db96d56Sopenharmony_ci openEntity->next = parser->m_openInternalEntities; 57367db96d56Sopenharmony_ci parser->m_openInternalEntities = openEntity; 57377db96d56Sopenharmony_ci openEntity->entity = entity; 57387db96d56Sopenharmony_ci openEntity->startTagLevel = parser->m_tagLevel; 57397db96d56Sopenharmony_ci openEntity->betweenDecl = betweenDecl; 57407db96d56Sopenharmony_ci openEntity->internalEventPtr = NULL; 57417db96d56Sopenharmony_ci openEntity->internalEventEndPtr = NULL; 57427db96d56Sopenharmony_ci textStart = (const char *)entity->textPtr; 57437db96d56Sopenharmony_ci textEnd = (const char *)(entity->textPtr + entity->textLen); 57447db96d56Sopenharmony_ci /* Set a safe default value in case 'next' does not get set */ 57457db96d56Sopenharmony_ci next = textStart; 57467db96d56Sopenharmony_ci 57477db96d56Sopenharmony_ci#ifdef XML_DTD 57487db96d56Sopenharmony_ci if (entity->is_param) { 57497db96d56Sopenharmony_ci int tok 57507db96d56Sopenharmony_ci = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); 57517db96d56Sopenharmony_ci result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, 57527db96d56Sopenharmony_ci tok, next, &next, XML_FALSE, XML_FALSE, 57537db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION); 57547db96d56Sopenharmony_ci } else 57557db96d56Sopenharmony_ci#endif /* XML_DTD */ 57567db96d56Sopenharmony_ci result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, 57577db96d56Sopenharmony_ci textStart, textEnd, &next, XML_FALSE, 57587db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION); 57597db96d56Sopenharmony_ci 57607db96d56Sopenharmony_ci if (result == XML_ERROR_NONE) { 57617db96d56Sopenharmony_ci if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { 57627db96d56Sopenharmony_ci entity->processed = (int)(next - textStart); 57637db96d56Sopenharmony_ci parser->m_processor = internalEntityProcessor; 57647db96d56Sopenharmony_ci } else { 57657db96d56Sopenharmony_ci#ifdef XML_DTD 57667db96d56Sopenharmony_ci entityTrackingOnClose(parser, entity, __LINE__); 57677db96d56Sopenharmony_ci#endif /* XML_DTD */ 57687db96d56Sopenharmony_ci entity->open = XML_FALSE; 57697db96d56Sopenharmony_ci parser->m_openInternalEntities = openEntity->next; 57707db96d56Sopenharmony_ci /* put openEntity back in list of free instances */ 57717db96d56Sopenharmony_ci openEntity->next = parser->m_freeInternalEntities; 57727db96d56Sopenharmony_ci parser->m_freeInternalEntities = openEntity; 57737db96d56Sopenharmony_ci } 57747db96d56Sopenharmony_ci } 57757db96d56Sopenharmony_ci return result; 57767db96d56Sopenharmony_ci} 57777db96d56Sopenharmony_ci 57787db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 57797db96d56Sopenharmony_ciinternalEntityProcessor(XML_Parser parser, const char *s, const char *end, 57807db96d56Sopenharmony_ci const char **nextPtr) { 57817db96d56Sopenharmony_ci ENTITY *entity; 57827db96d56Sopenharmony_ci const char *textStart, *textEnd; 57837db96d56Sopenharmony_ci const char *next; 57847db96d56Sopenharmony_ci enum XML_Error result; 57857db96d56Sopenharmony_ci OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; 57867db96d56Sopenharmony_ci if (! openEntity) 57877db96d56Sopenharmony_ci return XML_ERROR_UNEXPECTED_STATE; 57887db96d56Sopenharmony_ci 57897db96d56Sopenharmony_ci entity = openEntity->entity; 57907db96d56Sopenharmony_ci textStart = ((const char *)entity->textPtr) + entity->processed; 57917db96d56Sopenharmony_ci textEnd = (const char *)(entity->textPtr + entity->textLen); 57927db96d56Sopenharmony_ci /* Set a safe default value in case 'next' does not get set */ 57937db96d56Sopenharmony_ci next = textStart; 57947db96d56Sopenharmony_ci 57957db96d56Sopenharmony_ci#ifdef XML_DTD 57967db96d56Sopenharmony_ci if (entity->is_param) { 57977db96d56Sopenharmony_ci int tok 57987db96d56Sopenharmony_ci = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); 57997db96d56Sopenharmony_ci result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, 58007db96d56Sopenharmony_ci tok, next, &next, XML_FALSE, XML_TRUE, 58017db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION); 58027db96d56Sopenharmony_ci } else 58037db96d56Sopenharmony_ci#endif /* XML_DTD */ 58047db96d56Sopenharmony_ci result = doContent(parser, openEntity->startTagLevel, 58057db96d56Sopenharmony_ci parser->m_internalEncoding, textStart, textEnd, &next, 58067db96d56Sopenharmony_ci XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); 58077db96d56Sopenharmony_ci 58087db96d56Sopenharmony_ci if (result != XML_ERROR_NONE) 58097db96d56Sopenharmony_ci return result; 58107db96d56Sopenharmony_ci 58117db96d56Sopenharmony_ci if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { 58127db96d56Sopenharmony_ci entity->processed = (int)(next - (const char *)entity->textPtr); 58137db96d56Sopenharmony_ci return result; 58147db96d56Sopenharmony_ci } 58157db96d56Sopenharmony_ci 58167db96d56Sopenharmony_ci#ifdef XML_DTD 58177db96d56Sopenharmony_ci entityTrackingOnClose(parser, entity, __LINE__); 58187db96d56Sopenharmony_ci#endif 58197db96d56Sopenharmony_ci entity->open = XML_FALSE; 58207db96d56Sopenharmony_ci parser->m_openInternalEntities = openEntity->next; 58217db96d56Sopenharmony_ci /* put openEntity back in list of free instances */ 58227db96d56Sopenharmony_ci openEntity->next = parser->m_freeInternalEntities; 58237db96d56Sopenharmony_ci parser->m_freeInternalEntities = openEntity; 58247db96d56Sopenharmony_ci 58257db96d56Sopenharmony_ci // If there are more open entities we want to stop right here and have the 58267db96d56Sopenharmony_ci // upcoming call to XML_ResumeParser continue with entity content, or it would 58277db96d56Sopenharmony_ci // be ignored altogether. 58287db96d56Sopenharmony_ci if (parser->m_openInternalEntities != NULL 58297db96d56Sopenharmony_ci && parser->m_parsingStatus.parsing == XML_SUSPENDED) { 58307db96d56Sopenharmony_ci return XML_ERROR_NONE; 58317db96d56Sopenharmony_ci } 58327db96d56Sopenharmony_ci 58337db96d56Sopenharmony_ci#ifdef XML_DTD 58347db96d56Sopenharmony_ci if (entity->is_param) { 58357db96d56Sopenharmony_ci int tok; 58367db96d56Sopenharmony_ci parser->m_processor = prologProcessor; 58377db96d56Sopenharmony_ci tok = XmlPrologTok(parser->m_encoding, s, end, &next); 58387db96d56Sopenharmony_ci return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 58397db96d56Sopenharmony_ci (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 58407db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT); 58417db96d56Sopenharmony_ci } else 58427db96d56Sopenharmony_ci#endif /* XML_DTD */ 58437db96d56Sopenharmony_ci { 58447db96d56Sopenharmony_ci parser->m_processor = contentProcessor; 58457db96d56Sopenharmony_ci /* see externalEntityContentProcessor vs contentProcessor */ 58467db96d56Sopenharmony_ci result = doContent(parser, parser->m_parentParser ? 1 : 0, 58477db96d56Sopenharmony_ci parser->m_encoding, s, end, nextPtr, 58487db96d56Sopenharmony_ci (XML_Bool)! parser->m_parsingStatus.finalBuffer, 58497db96d56Sopenharmony_ci XML_ACCOUNT_DIRECT); 58507db96d56Sopenharmony_ci if (result == XML_ERROR_NONE) { 58517db96d56Sopenharmony_ci if (! storeRawNames(parser)) 58527db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 58537db96d56Sopenharmony_ci } 58547db96d56Sopenharmony_ci return result; 58557db96d56Sopenharmony_ci } 58567db96d56Sopenharmony_ci} 58577db96d56Sopenharmony_ci 58587db96d56Sopenharmony_cistatic enum XML_Error PTRCALL 58597db96d56Sopenharmony_cierrorProcessor(XML_Parser parser, const char *s, const char *end, 58607db96d56Sopenharmony_ci const char **nextPtr) { 58617db96d56Sopenharmony_ci UNUSED_P(s); 58627db96d56Sopenharmony_ci UNUSED_P(end); 58637db96d56Sopenharmony_ci UNUSED_P(nextPtr); 58647db96d56Sopenharmony_ci return parser->m_errorCode; 58657db96d56Sopenharmony_ci} 58667db96d56Sopenharmony_ci 58677db96d56Sopenharmony_cistatic enum XML_Error 58687db96d56Sopenharmony_cistoreAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 58697db96d56Sopenharmony_ci const char *ptr, const char *end, STRING_POOL *pool, 58707db96d56Sopenharmony_ci enum XML_Account account) { 58717db96d56Sopenharmony_ci enum XML_Error result 58727db96d56Sopenharmony_ci = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account); 58737db96d56Sopenharmony_ci if (result) 58747db96d56Sopenharmony_ci return result; 58757db96d56Sopenharmony_ci if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) 58767db96d56Sopenharmony_ci poolChop(pool); 58777db96d56Sopenharmony_ci if (! poolAppendChar(pool, XML_T('\0'))) 58787db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 58797db96d56Sopenharmony_ci return XML_ERROR_NONE; 58807db96d56Sopenharmony_ci} 58817db96d56Sopenharmony_ci 58827db96d56Sopenharmony_cistatic enum XML_Error 58837db96d56Sopenharmony_ciappendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 58847db96d56Sopenharmony_ci const char *ptr, const char *end, STRING_POOL *pool, 58857db96d56Sopenharmony_ci enum XML_Account account) { 58867db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 58877db96d56Sopenharmony_ci#ifndef XML_DTD 58887db96d56Sopenharmony_ci UNUSED_P(account); 58897db96d56Sopenharmony_ci#endif 58907db96d56Sopenharmony_ci 58917db96d56Sopenharmony_ci for (;;) { 58927db96d56Sopenharmony_ci const char *next 58937db96d56Sopenharmony_ci = ptr; /* XmlAttributeValueTok doesn't always set the last arg */ 58947db96d56Sopenharmony_ci int tok = XmlAttributeValueTok(enc, ptr, end, &next); 58957db96d56Sopenharmony_ci#ifdef XML_DTD 58967db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) { 58977db96d56Sopenharmony_ci accountingOnAbort(parser); 58987db96d56Sopenharmony_ci return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 58997db96d56Sopenharmony_ci } 59007db96d56Sopenharmony_ci#endif 59017db96d56Sopenharmony_ci switch (tok) { 59027db96d56Sopenharmony_ci case XML_TOK_NONE: 59037db96d56Sopenharmony_ci return XML_ERROR_NONE; 59047db96d56Sopenharmony_ci case XML_TOK_INVALID: 59057db96d56Sopenharmony_ci if (enc == parser->m_encoding) 59067db96d56Sopenharmony_ci parser->m_eventPtr = next; 59077db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 59087db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 59097db96d56Sopenharmony_ci if (enc == parser->m_encoding) 59107db96d56Sopenharmony_ci parser->m_eventPtr = ptr; 59117db96d56Sopenharmony_ci return XML_ERROR_INVALID_TOKEN; 59127db96d56Sopenharmony_ci case XML_TOK_CHAR_REF: { 59137db96d56Sopenharmony_ci XML_Char buf[XML_ENCODE_MAX]; 59147db96d56Sopenharmony_ci int i; 59157db96d56Sopenharmony_ci int n = XmlCharRefNumber(enc, ptr); 59167db96d56Sopenharmony_ci if (n < 0) { 59177db96d56Sopenharmony_ci if (enc == parser->m_encoding) 59187db96d56Sopenharmony_ci parser->m_eventPtr = ptr; 59197db96d56Sopenharmony_ci return XML_ERROR_BAD_CHAR_REF; 59207db96d56Sopenharmony_ci } 59217db96d56Sopenharmony_ci if (! isCdata && n == 0x20 /* space */ 59227db96d56Sopenharmony_ci && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 59237db96d56Sopenharmony_ci break; 59247db96d56Sopenharmony_ci n = XmlEncode(n, (ICHAR *)buf); 59257db96d56Sopenharmony_ci /* The XmlEncode() functions can never return 0 here. That 59267db96d56Sopenharmony_ci * error return happens if the code point passed in is either 59277db96d56Sopenharmony_ci * negative or greater than or equal to 0x110000. The 59287db96d56Sopenharmony_ci * XmlCharRefNumber() functions will all return a number 59297db96d56Sopenharmony_ci * strictly less than 0x110000 or a negative value if an error 59307db96d56Sopenharmony_ci * occurred. The negative value is intercepted above, so 59317db96d56Sopenharmony_ci * XmlEncode() is never passed a value it might return an 59327db96d56Sopenharmony_ci * error for. 59337db96d56Sopenharmony_ci */ 59347db96d56Sopenharmony_ci for (i = 0; i < n; i++) { 59357db96d56Sopenharmony_ci if (! poolAppendChar(pool, buf[i])) 59367db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 59377db96d56Sopenharmony_ci } 59387db96d56Sopenharmony_ci } break; 59397db96d56Sopenharmony_ci case XML_TOK_DATA_CHARS: 59407db96d56Sopenharmony_ci if (! poolAppend(pool, enc, ptr, next)) 59417db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 59427db96d56Sopenharmony_ci break; 59437db96d56Sopenharmony_ci case XML_TOK_TRAILING_CR: 59447db96d56Sopenharmony_ci next = ptr + enc->minBytesPerChar; 59457db96d56Sopenharmony_ci /* fall through */ 59467db96d56Sopenharmony_ci case XML_TOK_ATTRIBUTE_VALUE_S: 59477db96d56Sopenharmony_ci case XML_TOK_DATA_NEWLINE: 59487db96d56Sopenharmony_ci if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 59497db96d56Sopenharmony_ci break; 59507db96d56Sopenharmony_ci if (! poolAppendChar(pool, 0x20)) 59517db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 59527db96d56Sopenharmony_ci break; 59537db96d56Sopenharmony_ci case XML_TOK_ENTITY_REF: { 59547db96d56Sopenharmony_ci const XML_Char *name; 59557db96d56Sopenharmony_ci ENTITY *entity; 59567db96d56Sopenharmony_ci char checkEntityDecl; 59577db96d56Sopenharmony_ci XML_Char ch = (XML_Char)XmlPredefinedEntityName( 59587db96d56Sopenharmony_ci enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); 59597db96d56Sopenharmony_ci if (ch) { 59607db96d56Sopenharmony_ci#ifdef XML_DTD 59617db96d56Sopenharmony_ci /* NOTE: We are replacing 4-6 characters original input for 1 character 59627db96d56Sopenharmony_ci * so there is no amplification and hence recording without 59637db96d56Sopenharmony_ci * protection. */ 59647db96d56Sopenharmony_ci accountingDiffTolerated(parser, tok, (char *)&ch, 59657db96d56Sopenharmony_ci ((char *)&ch) + sizeof(XML_Char), __LINE__, 59667db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION); 59677db96d56Sopenharmony_ci#endif /* XML_DTD */ 59687db96d56Sopenharmony_ci if (! poolAppendChar(pool, ch)) 59697db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 59707db96d56Sopenharmony_ci break; 59717db96d56Sopenharmony_ci } 59727db96d56Sopenharmony_ci name = poolStoreString(&parser->m_temp2Pool, enc, 59737db96d56Sopenharmony_ci ptr + enc->minBytesPerChar, 59747db96d56Sopenharmony_ci next - enc->minBytesPerChar); 59757db96d56Sopenharmony_ci if (! name) 59767db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 59777db96d56Sopenharmony_ci entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); 59787db96d56Sopenharmony_ci poolDiscard(&parser->m_temp2Pool); 59797db96d56Sopenharmony_ci /* First, determine if a check for an existing declaration is needed; 59807db96d56Sopenharmony_ci if yes, check that the entity exists, and that it is internal. 59817db96d56Sopenharmony_ci */ 59827db96d56Sopenharmony_ci if (pool == &dtd->pool) /* are we called from prolog? */ 59837db96d56Sopenharmony_ci checkEntityDecl = 59847db96d56Sopenharmony_ci#ifdef XML_DTD 59857db96d56Sopenharmony_ci parser->m_prologState.documentEntity && 59867db96d56Sopenharmony_ci#endif /* XML_DTD */ 59877db96d56Sopenharmony_ci (dtd->standalone ? ! parser->m_openInternalEntities 59887db96d56Sopenharmony_ci : ! dtd->hasParamEntityRefs); 59897db96d56Sopenharmony_ci else /* if (pool == &parser->m_tempPool): we are called from content */ 59907db96d56Sopenharmony_ci checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone; 59917db96d56Sopenharmony_ci if (checkEntityDecl) { 59927db96d56Sopenharmony_ci if (! entity) 59937db96d56Sopenharmony_ci return XML_ERROR_UNDEFINED_ENTITY; 59947db96d56Sopenharmony_ci else if (! entity->is_internal) 59957db96d56Sopenharmony_ci return XML_ERROR_ENTITY_DECLARED_IN_PE; 59967db96d56Sopenharmony_ci } else if (! entity) { 59977db96d56Sopenharmony_ci /* Cannot report skipped entity here - see comments on 59987db96d56Sopenharmony_ci parser->m_skippedEntityHandler. 59997db96d56Sopenharmony_ci if (parser->m_skippedEntityHandler) 60007db96d56Sopenharmony_ci parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); 60017db96d56Sopenharmony_ci */ 60027db96d56Sopenharmony_ci /* Cannot call the default handler because this would be 60037db96d56Sopenharmony_ci out of sync with the call to the startElementHandler. 60047db96d56Sopenharmony_ci if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) 60057db96d56Sopenharmony_ci reportDefault(parser, enc, ptr, next); 60067db96d56Sopenharmony_ci */ 60077db96d56Sopenharmony_ci break; 60087db96d56Sopenharmony_ci } 60097db96d56Sopenharmony_ci if (entity->open) { 60107db96d56Sopenharmony_ci if (enc == parser->m_encoding) { 60117db96d56Sopenharmony_ci /* It does not appear that this line can be executed. 60127db96d56Sopenharmony_ci * 60137db96d56Sopenharmony_ci * The "if (entity->open)" check catches recursive entity 60147db96d56Sopenharmony_ci * definitions. In order to be called with an open 60157db96d56Sopenharmony_ci * entity, it must have gone through this code before and 60167db96d56Sopenharmony_ci * been through the recursive call to 60177db96d56Sopenharmony_ci * appendAttributeValue() some lines below. That call 60187db96d56Sopenharmony_ci * sets the local encoding ("enc") to the parser's 60197db96d56Sopenharmony_ci * internal encoding (internal_utf8 or internal_utf16), 60207db96d56Sopenharmony_ci * which can never be the same as the principle encoding. 60217db96d56Sopenharmony_ci * It doesn't appear there is another code path that gets 60227db96d56Sopenharmony_ci * here with entity->open being TRUE. 60237db96d56Sopenharmony_ci * 60247db96d56Sopenharmony_ci * Since it is not certain that this logic is watertight, 60257db96d56Sopenharmony_ci * we keep the line and merely exclude it from coverage 60267db96d56Sopenharmony_ci * tests. 60277db96d56Sopenharmony_ci */ 60287db96d56Sopenharmony_ci parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ 60297db96d56Sopenharmony_ci } 60307db96d56Sopenharmony_ci return XML_ERROR_RECURSIVE_ENTITY_REF; 60317db96d56Sopenharmony_ci } 60327db96d56Sopenharmony_ci if (entity->notation) { 60337db96d56Sopenharmony_ci if (enc == parser->m_encoding) 60347db96d56Sopenharmony_ci parser->m_eventPtr = ptr; 60357db96d56Sopenharmony_ci return XML_ERROR_BINARY_ENTITY_REF; 60367db96d56Sopenharmony_ci } 60377db96d56Sopenharmony_ci if (! entity->textPtr) { 60387db96d56Sopenharmony_ci if (enc == parser->m_encoding) 60397db96d56Sopenharmony_ci parser->m_eventPtr = ptr; 60407db96d56Sopenharmony_ci return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; 60417db96d56Sopenharmony_ci } else { 60427db96d56Sopenharmony_ci enum XML_Error result; 60437db96d56Sopenharmony_ci const XML_Char *textEnd = entity->textPtr + entity->textLen; 60447db96d56Sopenharmony_ci entity->open = XML_TRUE; 60457db96d56Sopenharmony_ci#ifdef XML_DTD 60467db96d56Sopenharmony_ci entityTrackingOnOpen(parser, entity, __LINE__); 60477db96d56Sopenharmony_ci#endif 60487db96d56Sopenharmony_ci result = appendAttributeValue(parser, parser->m_internalEncoding, 60497db96d56Sopenharmony_ci isCdata, (const char *)entity->textPtr, 60507db96d56Sopenharmony_ci (const char *)textEnd, pool, 60517db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION); 60527db96d56Sopenharmony_ci#ifdef XML_DTD 60537db96d56Sopenharmony_ci entityTrackingOnClose(parser, entity, __LINE__); 60547db96d56Sopenharmony_ci#endif 60557db96d56Sopenharmony_ci entity->open = XML_FALSE; 60567db96d56Sopenharmony_ci if (result) 60577db96d56Sopenharmony_ci return result; 60587db96d56Sopenharmony_ci } 60597db96d56Sopenharmony_ci } break; 60607db96d56Sopenharmony_ci default: 60617db96d56Sopenharmony_ci /* The only token returned by XmlAttributeValueTok() that does 60627db96d56Sopenharmony_ci * not have an explicit case here is XML_TOK_PARTIAL_CHAR. 60637db96d56Sopenharmony_ci * Getting that would require an entity name to contain an 60647db96d56Sopenharmony_ci * incomplete XML character (e.g. \xE2\x82); however previous 60657db96d56Sopenharmony_ci * tokenisers will have already recognised and rejected such 60667db96d56Sopenharmony_ci * names before XmlAttributeValueTok() gets a look-in. This 60677db96d56Sopenharmony_ci * default case should be retained as a safety net, but the code 60687db96d56Sopenharmony_ci * excluded from coverage tests. 60697db96d56Sopenharmony_ci * 60707db96d56Sopenharmony_ci * LCOV_EXCL_START 60717db96d56Sopenharmony_ci */ 60727db96d56Sopenharmony_ci if (enc == parser->m_encoding) 60737db96d56Sopenharmony_ci parser->m_eventPtr = ptr; 60747db96d56Sopenharmony_ci return XML_ERROR_UNEXPECTED_STATE; 60757db96d56Sopenharmony_ci /* LCOV_EXCL_STOP */ 60767db96d56Sopenharmony_ci } 60777db96d56Sopenharmony_ci ptr = next; 60787db96d56Sopenharmony_ci } 60797db96d56Sopenharmony_ci /* not reached */ 60807db96d56Sopenharmony_ci} 60817db96d56Sopenharmony_ci 60827db96d56Sopenharmony_cistatic enum XML_Error 60837db96d56Sopenharmony_cistoreEntityValue(XML_Parser parser, const ENCODING *enc, 60847db96d56Sopenharmony_ci const char *entityTextPtr, const char *entityTextEnd, 60857db96d56Sopenharmony_ci enum XML_Account account) { 60867db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 60877db96d56Sopenharmony_ci STRING_POOL *pool = &(dtd->entityValuePool); 60887db96d56Sopenharmony_ci enum XML_Error result = XML_ERROR_NONE; 60897db96d56Sopenharmony_ci#ifdef XML_DTD 60907db96d56Sopenharmony_ci int oldInEntityValue = parser->m_prologState.inEntityValue; 60917db96d56Sopenharmony_ci parser->m_prologState.inEntityValue = 1; 60927db96d56Sopenharmony_ci#else 60937db96d56Sopenharmony_ci UNUSED_P(account); 60947db96d56Sopenharmony_ci#endif /* XML_DTD */ 60957db96d56Sopenharmony_ci /* never return Null for the value argument in EntityDeclHandler, 60967db96d56Sopenharmony_ci since this would indicate an external entity; therefore we 60977db96d56Sopenharmony_ci have to make sure that entityValuePool.start is not null */ 60987db96d56Sopenharmony_ci if (! pool->blocks) { 60997db96d56Sopenharmony_ci if (! poolGrow(pool)) 61007db96d56Sopenharmony_ci return XML_ERROR_NO_MEMORY; 61017db96d56Sopenharmony_ci } 61027db96d56Sopenharmony_ci 61037db96d56Sopenharmony_ci for (;;) { 61047db96d56Sopenharmony_ci const char *next 61057db96d56Sopenharmony_ci = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */ 61067db96d56Sopenharmony_ci int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); 61077db96d56Sopenharmony_ci 61087db96d56Sopenharmony_ci#ifdef XML_DTD 61097db96d56Sopenharmony_ci if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__, 61107db96d56Sopenharmony_ci account)) { 61117db96d56Sopenharmony_ci accountingOnAbort(parser); 61127db96d56Sopenharmony_ci result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 61137db96d56Sopenharmony_ci goto endEntityValue; 61147db96d56Sopenharmony_ci } 61157db96d56Sopenharmony_ci#endif 61167db96d56Sopenharmony_ci 61177db96d56Sopenharmony_ci switch (tok) { 61187db96d56Sopenharmony_ci case XML_TOK_PARAM_ENTITY_REF: 61197db96d56Sopenharmony_ci#ifdef XML_DTD 61207db96d56Sopenharmony_ci if (parser->m_isParamEntity || enc != parser->m_encoding) { 61217db96d56Sopenharmony_ci const XML_Char *name; 61227db96d56Sopenharmony_ci ENTITY *entity; 61237db96d56Sopenharmony_ci name = poolStoreString(&parser->m_tempPool, enc, 61247db96d56Sopenharmony_ci entityTextPtr + enc->minBytesPerChar, 61257db96d56Sopenharmony_ci next - enc->minBytesPerChar); 61267db96d56Sopenharmony_ci if (! name) { 61277db96d56Sopenharmony_ci result = XML_ERROR_NO_MEMORY; 61287db96d56Sopenharmony_ci goto endEntityValue; 61297db96d56Sopenharmony_ci } 61307db96d56Sopenharmony_ci entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); 61317db96d56Sopenharmony_ci poolDiscard(&parser->m_tempPool); 61327db96d56Sopenharmony_ci if (! entity) { 61337db96d56Sopenharmony_ci /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ 61347db96d56Sopenharmony_ci /* cannot report skipped entity here - see comments on 61357db96d56Sopenharmony_ci parser->m_skippedEntityHandler 61367db96d56Sopenharmony_ci if (parser->m_skippedEntityHandler) 61377db96d56Sopenharmony_ci parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); 61387db96d56Sopenharmony_ci */ 61397db96d56Sopenharmony_ci dtd->keepProcessing = dtd->standalone; 61407db96d56Sopenharmony_ci goto endEntityValue; 61417db96d56Sopenharmony_ci } 61427db96d56Sopenharmony_ci if (entity->open) { 61437db96d56Sopenharmony_ci if (enc == parser->m_encoding) 61447db96d56Sopenharmony_ci parser->m_eventPtr = entityTextPtr; 61457db96d56Sopenharmony_ci result = XML_ERROR_RECURSIVE_ENTITY_REF; 61467db96d56Sopenharmony_ci goto endEntityValue; 61477db96d56Sopenharmony_ci } 61487db96d56Sopenharmony_ci if (entity->systemId) { 61497db96d56Sopenharmony_ci if (parser->m_externalEntityRefHandler) { 61507db96d56Sopenharmony_ci dtd->paramEntityRead = XML_FALSE; 61517db96d56Sopenharmony_ci entity->open = XML_TRUE; 61527db96d56Sopenharmony_ci entityTrackingOnOpen(parser, entity, __LINE__); 61537db96d56Sopenharmony_ci if (! parser->m_externalEntityRefHandler( 61547db96d56Sopenharmony_ci parser->m_externalEntityRefHandlerArg, 0, entity->base, 61557db96d56Sopenharmony_ci entity->systemId, entity->publicId)) { 61567db96d56Sopenharmony_ci entityTrackingOnClose(parser, entity, __LINE__); 61577db96d56Sopenharmony_ci entity->open = XML_FALSE; 61587db96d56Sopenharmony_ci result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; 61597db96d56Sopenharmony_ci goto endEntityValue; 61607db96d56Sopenharmony_ci } 61617db96d56Sopenharmony_ci entityTrackingOnClose(parser, entity, __LINE__); 61627db96d56Sopenharmony_ci entity->open = XML_FALSE; 61637db96d56Sopenharmony_ci if (! dtd->paramEntityRead) 61647db96d56Sopenharmony_ci dtd->keepProcessing = dtd->standalone; 61657db96d56Sopenharmony_ci } else 61667db96d56Sopenharmony_ci dtd->keepProcessing = dtd->standalone; 61677db96d56Sopenharmony_ci } else { 61687db96d56Sopenharmony_ci entity->open = XML_TRUE; 61697db96d56Sopenharmony_ci entityTrackingOnOpen(parser, entity, __LINE__); 61707db96d56Sopenharmony_ci result = storeEntityValue( 61717db96d56Sopenharmony_ci parser, parser->m_internalEncoding, (const char *)entity->textPtr, 61727db96d56Sopenharmony_ci (const char *)(entity->textPtr + entity->textLen), 61737db96d56Sopenharmony_ci XML_ACCOUNT_ENTITY_EXPANSION); 61747db96d56Sopenharmony_ci entityTrackingOnClose(parser, entity, __LINE__); 61757db96d56Sopenharmony_ci entity->open = XML_FALSE; 61767db96d56Sopenharmony_ci if (result) 61777db96d56Sopenharmony_ci goto endEntityValue; 61787db96d56Sopenharmony_ci } 61797db96d56Sopenharmony_ci break; 61807db96d56Sopenharmony_ci } 61817db96d56Sopenharmony_ci#endif /* XML_DTD */ 61827db96d56Sopenharmony_ci /* In the internal subset, PE references are not legal 61837db96d56Sopenharmony_ci within markup declarations, e.g entity values in this case. */ 61847db96d56Sopenharmony_ci parser->m_eventPtr = entityTextPtr; 61857db96d56Sopenharmony_ci result = XML_ERROR_PARAM_ENTITY_REF; 61867db96d56Sopenharmony_ci goto endEntityValue; 61877db96d56Sopenharmony_ci case XML_TOK_NONE: 61887db96d56Sopenharmony_ci result = XML_ERROR_NONE; 61897db96d56Sopenharmony_ci goto endEntityValue; 61907db96d56Sopenharmony_ci case XML_TOK_ENTITY_REF: 61917db96d56Sopenharmony_ci case XML_TOK_DATA_CHARS: 61927db96d56Sopenharmony_ci if (! poolAppend(pool, enc, entityTextPtr, next)) { 61937db96d56Sopenharmony_ci result = XML_ERROR_NO_MEMORY; 61947db96d56Sopenharmony_ci goto endEntityValue; 61957db96d56Sopenharmony_ci } 61967db96d56Sopenharmony_ci break; 61977db96d56Sopenharmony_ci case XML_TOK_TRAILING_CR: 61987db96d56Sopenharmony_ci next = entityTextPtr + enc->minBytesPerChar; 61997db96d56Sopenharmony_ci /* fall through */ 62007db96d56Sopenharmony_ci case XML_TOK_DATA_NEWLINE: 62017db96d56Sopenharmony_ci if (pool->end == pool->ptr && ! poolGrow(pool)) { 62027db96d56Sopenharmony_ci result = XML_ERROR_NO_MEMORY; 62037db96d56Sopenharmony_ci goto endEntityValue; 62047db96d56Sopenharmony_ci } 62057db96d56Sopenharmony_ci *(pool->ptr)++ = 0xA; 62067db96d56Sopenharmony_ci break; 62077db96d56Sopenharmony_ci case XML_TOK_CHAR_REF: { 62087db96d56Sopenharmony_ci XML_Char buf[XML_ENCODE_MAX]; 62097db96d56Sopenharmony_ci int i; 62107db96d56Sopenharmony_ci int n = XmlCharRefNumber(enc, entityTextPtr); 62117db96d56Sopenharmony_ci if (n < 0) { 62127db96d56Sopenharmony_ci if (enc == parser->m_encoding) 62137db96d56Sopenharmony_ci parser->m_eventPtr = entityTextPtr; 62147db96d56Sopenharmony_ci result = XML_ERROR_BAD_CHAR_REF; 62157db96d56Sopenharmony_ci goto endEntityValue; 62167db96d56Sopenharmony_ci } 62177db96d56Sopenharmony_ci n = XmlEncode(n, (ICHAR *)buf); 62187db96d56Sopenharmony_ci /* The XmlEncode() functions can never return 0 here. That 62197db96d56Sopenharmony_ci * error return happens if the code point passed in is either 62207db96d56Sopenharmony_ci * negative or greater than or equal to 0x110000. The 62217db96d56Sopenharmony_ci * XmlCharRefNumber() functions will all return a number 62227db96d56Sopenharmony_ci * strictly less than 0x110000 or a negative value if an error 62237db96d56Sopenharmony_ci * occurred. The negative value is intercepted above, so 62247db96d56Sopenharmony_ci * XmlEncode() is never passed a value it might return an 62257db96d56Sopenharmony_ci * error for. 62267db96d56Sopenharmony_ci */ 62277db96d56Sopenharmony_ci for (i = 0; i < n; i++) { 62287db96d56Sopenharmony_ci if (pool->end == pool->ptr && ! poolGrow(pool)) { 62297db96d56Sopenharmony_ci result = XML_ERROR_NO_MEMORY; 62307db96d56Sopenharmony_ci goto endEntityValue; 62317db96d56Sopenharmony_ci } 62327db96d56Sopenharmony_ci *(pool->ptr)++ = buf[i]; 62337db96d56Sopenharmony_ci } 62347db96d56Sopenharmony_ci } break; 62357db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 62367db96d56Sopenharmony_ci if (enc == parser->m_encoding) 62377db96d56Sopenharmony_ci parser->m_eventPtr = entityTextPtr; 62387db96d56Sopenharmony_ci result = XML_ERROR_INVALID_TOKEN; 62397db96d56Sopenharmony_ci goto endEntityValue; 62407db96d56Sopenharmony_ci case XML_TOK_INVALID: 62417db96d56Sopenharmony_ci if (enc == parser->m_encoding) 62427db96d56Sopenharmony_ci parser->m_eventPtr = next; 62437db96d56Sopenharmony_ci result = XML_ERROR_INVALID_TOKEN; 62447db96d56Sopenharmony_ci goto endEntityValue; 62457db96d56Sopenharmony_ci default: 62467db96d56Sopenharmony_ci /* This default case should be unnecessary -- all the tokens 62477db96d56Sopenharmony_ci * that XmlEntityValueTok() can return have their own explicit 62487db96d56Sopenharmony_ci * cases -- but should be retained for safety. We do however 62497db96d56Sopenharmony_ci * exclude it from the coverage statistics. 62507db96d56Sopenharmony_ci * 62517db96d56Sopenharmony_ci * LCOV_EXCL_START 62527db96d56Sopenharmony_ci */ 62537db96d56Sopenharmony_ci if (enc == parser->m_encoding) 62547db96d56Sopenharmony_ci parser->m_eventPtr = entityTextPtr; 62557db96d56Sopenharmony_ci result = XML_ERROR_UNEXPECTED_STATE; 62567db96d56Sopenharmony_ci goto endEntityValue; 62577db96d56Sopenharmony_ci /* LCOV_EXCL_STOP */ 62587db96d56Sopenharmony_ci } 62597db96d56Sopenharmony_ci entityTextPtr = next; 62607db96d56Sopenharmony_ci } 62617db96d56Sopenharmony_ciendEntityValue: 62627db96d56Sopenharmony_ci#ifdef XML_DTD 62637db96d56Sopenharmony_ci parser->m_prologState.inEntityValue = oldInEntityValue; 62647db96d56Sopenharmony_ci#endif /* XML_DTD */ 62657db96d56Sopenharmony_ci return result; 62667db96d56Sopenharmony_ci} 62677db96d56Sopenharmony_ci 62687db96d56Sopenharmony_cistatic void FASTCALL 62697db96d56Sopenharmony_cinormalizeLines(XML_Char *s) { 62707db96d56Sopenharmony_ci XML_Char *p; 62717db96d56Sopenharmony_ci for (;; s++) { 62727db96d56Sopenharmony_ci if (*s == XML_T('\0')) 62737db96d56Sopenharmony_ci return; 62747db96d56Sopenharmony_ci if (*s == 0xD) 62757db96d56Sopenharmony_ci break; 62767db96d56Sopenharmony_ci } 62777db96d56Sopenharmony_ci p = s; 62787db96d56Sopenharmony_ci do { 62797db96d56Sopenharmony_ci if (*s == 0xD) { 62807db96d56Sopenharmony_ci *p++ = 0xA; 62817db96d56Sopenharmony_ci if (*++s == 0xA) 62827db96d56Sopenharmony_ci s++; 62837db96d56Sopenharmony_ci } else 62847db96d56Sopenharmony_ci *p++ = *s++; 62857db96d56Sopenharmony_ci } while (*s); 62867db96d56Sopenharmony_ci *p = XML_T('\0'); 62877db96d56Sopenharmony_ci} 62887db96d56Sopenharmony_ci 62897db96d56Sopenharmony_cistatic int 62907db96d56Sopenharmony_cireportProcessingInstruction(XML_Parser parser, const ENCODING *enc, 62917db96d56Sopenharmony_ci const char *start, const char *end) { 62927db96d56Sopenharmony_ci const XML_Char *target; 62937db96d56Sopenharmony_ci XML_Char *data; 62947db96d56Sopenharmony_ci const char *tem; 62957db96d56Sopenharmony_ci if (! parser->m_processingInstructionHandler) { 62967db96d56Sopenharmony_ci if (parser->m_defaultHandler) 62977db96d56Sopenharmony_ci reportDefault(parser, enc, start, end); 62987db96d56Sopenharmony_ci return 1; 62997db96d56Sopenharmony_ci } 63007db96d56Sopenharmony_ci start += enc->minBytesPerChar * 2; 63017db96d56Sopenharmony_ci tem = start + XmlNameLength(enc, start); 63027db96d56Sopenharmony_ci target = poolStoreString(&parser->m_tempPool, enc, start, tem); 63037db96d56Sopenharmony_ci if (! target) 63047db96d56Sopenharmony_ci return 0; 63057db96d56Sopenharmony_ci poolFinish(&parser->m_tempPool); 63067db96d56Sopenharmony_ci data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem), 63077db96d56Sopenharmony_ci end - enc->minBytesPerChar * 2); 63087db96d56Sopenharmony_ci if (! data) 63097db96d56Sopenharmony_ci return 0; 63107db96d56Sopenharmony_ci normalizeLines(data); 63117db96d56Sopenharmony_ci parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); 63127db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 63137db96d56Sopenharmony_ci return 1; 63147db96d56Sopenharmony_ci} 63157db96d56Sopenharmony_ci 63167db96d56Sopenharmony_cistatic int 63177db96d56Sopenharmony_cireportComment(XML_Parser parser, const ENCODING *enc, const char *start, 63187db96d56Sopenharmony_ci const char *end) { 63197db96d56Sopenharmony_ci XML_Char *data; 63207db96d56Sopenharmony_ci if (! parser->m_commentHandler) { 63217db96d56Sopenharmony_ci if (parser->m_defaultHandler) 63227db96d56Sopenharmony_ci reportDefault(parser, enc, start, end); 63237db96d56Sopenharmony_ci return 1; 63247db96d56Sopenharmony_ci } 63257db96d56Sopenharmony_ci data = poolStoreString(&parser->m_tempPool, enc, 63267db96d56Sopenharmony_ci start + enc->minBytesPerChar * 4, 63277db96d56Sopenharmony_ci end - enc->minBytesPerChar * 3); 63287db96d56Sopenharmony_ci if (! data) 63297db96d56Sopenharmony_ci return 0; 63307db96d56Sopenharmony_ci normalizeLines(data); 63317db96d56Sopenharmony_ci parser->m_commentHandler(parser->m_handlerArg, data); 63327db96d56Sopenharmony_ci poolClear(&parser->m_tempPool); 63337db96d56Sopenharmony_ci return 1; 63347db96d56Sopenharmony_ci} 63357db96d56Sopenharmony_ci 63367db96d56Sopenharmony_cistatic void 63377db96d56Sopenharmony_cireportDefault(XML_Parser parser, const ENCODING *enc, const char *s, 63387db96d56Sopenharmony_ci const char *end) { 63397db96d56Sopenharmony_ci if (MUST_CONVERT(enc, s)) { 63407db96d56Sopenharmony_ci enum XML_Convert_Result convert_res; 63417db96d56Sopenharmony_ci const char **eventPP; 63427db96d56Sopenharmony_ci const char **eventEndPP; 63437db96d56Sopenharmony_ci if (enc == parser->m_encoding) { 63447db96d56Sopenharmony_ci eventPP = &parser->m_eventPtr; 63457db96d56Sopenharmony_ci eventEndPP = &parser->m_eventEndPtr; 63467db96d56Sopenharmony_ci } else { 63477db96d56Sopenharmony_ci /* To get here, two things must be true; the parser must be 63487db96d56Sopenharmony_ci * using a character encoding that is not the same as the 63497db96d56Sopenharmony_ci * encoding passed in, and the encoding passed in must need 63507db96d56Sopenharmony_ci * conversion to the internal format (UTF-8 unless XML_UNICODE 63517db96d56Sopenharmony_ci * is defined). The only occasions on which the encoding passed 63527db96d56Sopenharmony_ci * in is not the same as the parser's encoding are when it is 63537db96d56Sopenharmony_ci * the internal encoding (e.g. a previously defined parameter 63547db96d56Sopenharmony_ci * entity, already converted to internal format). This by 63557db96d56Sopenharmony_ci * definition doesn't need conversion, so the whole branch never 63567db96d56Sopenharmony_ci * gets executed. 63577db96d56Sopenharmony_ci * 63587db96d56Sopenharmony_ci * For safety's sake we don't delete these lines and merely 63597db96d56Sopenharmony_ci * exclude them from coverage statistics. 63607db96d56Sopenharmony_ci * 63617db96d56Sopenharmony_ci * LCOV_EXCL_START 63627db96d56Sopenharmony_ci */ 63637db96d56Sopenharmony_ci eventPP = &(parser->m_openInternalEntities->internalEventPtr); 63647db96d56Sopenharmony_ci eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 63657db96d56Sopenharmony_ci /* LCOV_EXCL_STOP */ 63667db96d56Sopenharmony_ci } 63677db96d56Sopenharmony_ci do { 63687db96d56Sopenharmony_ci ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; 63697db96d56Sopenharmony_ci convert_res 63707db96d56Sopenharmony_ci = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); 63717db96d56Sopenharmony_ci *eventEndPP = s; 63727db96d56Sopenharmony_ci parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, 63737db96d56Sopenharmony_ci (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); 63747db96d56Sopenharmony_ci *eventPP = s; 63757db96d56Sopenharmony_ci } while ((convert_res != XML_CONVERT_COMPLETED) 63767db96d56Sopenharmony_ci && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); 63777db96d56Sopenharmony_ci } else 63787db96d56Sopenharmony_ci parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, 63797db96d56Sopenharmony_ci (int)((XML_Char *)end - (XML_Char *)s)); 63807db96d56Sopenharmony_ci} 63817db96d56Sopenharmony_ci 63827db96d56Sopenharmony_cistatic int 63837db96d56Sopenharmony_cidefineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, 63847db96d56Sopenharmony_ci XML_Bool isId, const XML_Char *value, XML_Parser parser) { 63857db96d56Sopenharmony_ci DEFAULT_ATTRIBUTE *att; 63867db96d56Sopenharmony_ci if (value || isId) { 63877db96d56Sopenharmony_ci /* The handling of default attributes gets messed up if we have 63887db96d56Sopenharmony_ci a default which duplicates a non-default. */ 63897db96d56Sopenharmony_ci int i; 63907db96d56Sopenharmony_ci for (i = 0; i < type->nDefaultAtts; i++) 63917db96d56Sopenharmony_ci if (attId == type->defaultAtts[i].id) 63927db96d56Sopenharmony_ci return 1; 63937db96d56Sopenharmony_ci if (isId && ! type->idAtt && ! attId->xmlns) 63947db96d56Sopenharmony_ci type->idAtt = attId; 63957db96d56Sopenharmony_ci } 63967db96d56Sopenharmony_ci if (type->nDefaultAtts == type->allocDefaultAtts) { 63977db96d56Sopenharmony_ci if (type->allocDefaultAtts == 0) { 63987db96d56Sopenharmony_ci type->allocDefaultAtts = 8; 63997db96d56Sopenharmony_ci type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC( 64007db96d56Sopenharmony_ci parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); 64017db96d56Sopenharmony_ci if (! type->defaultAtts) { 64027db96d56Sopenharmony_ci type->allocDefaultAtts = 0; 64037db96d56Sopenharmony_ci return 0; 64047db96d56Sopenharmony_ci } 64057db96d56Sopenharmony_ci } else { 64067db96d56Sopenharmony_ci DEFAULT_ATTRIBUTE *temp; 64077db96d56Sopenharmony_ci 64087db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 64097db96d56Sopenharmony_ci if (type->allocDefaultAtts > INT_MAX / 2) { 64107db96d56Sopenharmony_ci return 0; 64117db96d56Sopenharmony_ci } 64127db96d56Sopenharmony_ci 64137db96d56Sopenharmony_ci int count = type->allocDefaultAtts * 2; 64147db96d56Sopenharmony_ci 64157db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 64167db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 64177db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 64187db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 64197db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 64207db96d56Sopenharmony_ci if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) { 64217db96d56Sopenharmony_ci return 0; 64227db96d56Sopenharmony_ci } 64237db96d56Sopenharmony_ci#endif 64247db96d56Sopenharmony_ci 64257db96d56Sopenharmony_ci temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts, 64267db96d56Sopenharmony_ci (count * sizeof(DEFAULT_ATTRIBUTE))); 64277db96d56Sopenharmony_ci if (temp == NULL) 64287db96d56Sopenharmony_ci return 0; 64297db96d56Sopenharmony_ci type->allocDefaultAtts = count; 64307db96d56Sopenharmony_ci type->defaultAtts = temp; 64317db96d56Sopenharmony_ci } 64327db96d56Sopenharmony_ci } 64337db96d56Sopenharmony_ci att = type->defaultAtts + type->nDefaultAtts; 64347db96d56Sopenharmony_ci att->id = attId; 64357db96d56Sopenharmony_ci att->value = value; 64367db96d56Sopenharmony_ci att->isCdata = isCdata; 64377db96d56Sopenharmony_ci if (! isCdata) 64387db96d56Sopenharmony_ci attId->maybeTokenized = XML_TRUE; 64397db96d56Sopenharmony_ci type->nDefaultAtts += 1; 64407db96d56Sopenharmony_ci return 1; 64417db96d56Sopenharmony_ci} 64427db96d56Sopenharmony_ci 64437db96d56Sopenharmony_cistatic int 64447db96d56Sopenharmony_cisetElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { 64457db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 64467db96d56Sopenharmony_ci const XML_Char *name; 64477db96d56Sopenharmony_ci for (name = elementType->name; *name; name++) { 64487db96d56Sopenharmony_ci if (*name == XML_T(ASCII_COLON)) { 64497db96d56Sopenharmony_ci PREFIX *prefix; 64507db96d56Sopenharmony_ci const XML_Char *s; 64517db96d56Sopenharmony_ci for (s = elementType->name; s != name; s++) { 64527db96d56Sopenharmony_ci if (! poolAppendChar(&dtd->pool, *s)) 64537db96d56Sopenharmony_ci return 0; 64547db96d56Sopenharmony_ci } 64557db96d56Sopenharmony_ci if (! poolAppendChar(&dtd->pool, XML_T('\0'))) 64567db96d56Sopenharmony_ci return 0; 64577db96d56Sopenharmony_ci prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), 64587db96d56Sopenharmony_ci sizeof(PREFIX)); 64597db96d56Sopenharmony_ci if (! prefix) 64607db96d56Sopenharmony_ci return 0; 64617db96d56Sopenharmony_ci if (prefix->name == poolStart(&dtd->pool)) 64627db96d56Sopenharmony_ci poolFinish(&dtd->pool); 64637db96d56Sopenharmony_ci else 64647db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 64657db96d56Sopenharmony_ci elementType->prefix = prefix; 64667db96d56Sopenharmony_ci break; 64677db96d56Sopenharmony_ci } 64687db96d56Sopenharmony_ci } 64697db96d56Sopenharmony_ci return 1; 64707db96d56Sopenharmony_ci} 64717db96d56Sopenharmony_ci 64727db96d56Sopenharmony_cistatic ATTRIBUTE_ID * 64737db96d56Sopenharmony_cigetAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, 64747db96d56Sopenharmony_ci const char *end) { 64757db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 64767db96d56Sopenharmony_ci ATTRIBUTE_ID *id; 64777db96d56Sopenharmony_ci const XML_Char *name; 64787db96d56Sopenharmony_ci if (! poolAppendChar(&dtd->pool, XML_T('\0'))) 64797db96d56Sopenharmony_ci return NULL; 64807db96d56Sopenharmony_ci name = poolStoreString(&dtd->pool, enc, start, end); 64817db96d56Sopenharmony_ci if (! name) 64827db96d56Sopenharmony_ci return NULL; 64837db96d56Sopenharmony_ci /* skip quotation mark - its storage will be re-used (like in name[-1]) */ 64847db96d56Sopenharmony_ci ++name; 64857db96d56Sopenharmony_ci id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, 64867db96d56Sopenharmony_ci sizeof(ATTRIBUTE_ID)); 64877db96d56Sopenharmony_ci if (! id) 64887db96d56Sopenharmony_ci return NULL; 64897db96d56Sopenharmony_ci if (id->name != name) 64907db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 64917db96d56Sopenharmony_ci else { 64927db96d56Sopenharmony_ci poolFinish(&dtd->pool); 64937db96d56Sopenharmony_ci if (! parser->m_ns) 64947db96d56Sopenharmony_ci ; 64957db96d56Sopenharmony_ci else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m) 64967db96d56Sopenharmony_ci && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n) 64977db96d56Sopenharmony_ci && name[4] == XML_T(ASCII_s) 64987db96d56Sopenharmony_ci && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { 64997db96d56Sopenharmony_ci if (name[5] == XML_T('\0')) 65007db96d56Sopenharmony_ci id->prefix = &dtd->defaultPrefix; 65017db96d56Sopenharmony_ci else 65027db96d56Sopenharmony_ci id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, 65037db96d56Sopenharmony_ci sizeof(PREFIX)); 65047db96d56Sopenharmony_ci id->xmlns = XML_TRUE; 65057db96d56Sopenharmony_ci } else { 65067db96d56Sopenharmony_ci int i; 65077db96d56Sopenharmony_ci for (i = 0; name[i]; i++) { 65087db96d56Sopenharmony_ci /* attributes without prefix are *not* in the default namespace */ 65097db96d56Sopenharmony_ci if (name[i] == XML_T(ASCII_COLON)) { 65107db96d56Sopenharmony_ci int j; 65117db96d56Sopenharmony_ci for (j = 0; j < i; j++) { 65127db96d56Sopenharmony_ci if (! poolAppendChar(&dtd->pool, name[j])) 65137db96d56Sopenharmony_ci return NULL; 65147db96d56Sopenharmony_ci } 65157db96d56Sopenharmony_ci if (! poolAppendChar(&dtd->pool, XML_T('\0'))) 65167db96d56Sopenharmony_ci return NULL; 65177db96d56Sopenharmony_ci id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, 65187db96d56Sopenharmony_ci poolStart(&dtd->pool), sizeof(PREFIX)); 65197db96d56Sopenharmony_ci if (! id->prefix) 65207db96d56Sopenharmony_ci return NULL; 65217db96d56Sopenharmony_ci if (id->prefix->name == poolStart(&dtd->pool)) 65227db96d56Sopenharmony_ci poolFinish(&dtd->pool); 65237db96d56Sopenharmony_ci else 65247db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 65257db96d56Sopenharmony_ci break; 65267db96d56Sopenharmony_ci } 65277db96d56Sopenharmony_ci } 65287db96d56Sopenharmony_ci } 65297db96d56Sopenharmony_ci } 65307db96d56Sopenharmony_ci return id; 65317db96d56Sopenharmony_ci} 65327db96d56Sopenharmony_ci 65337db96d56Sopenharmony_ci#define CONTEXT_SEP XML_T(ASCII_FF) 65347db96d56Sopenharmony_ci 65357db96d56Sopenharmony_cistatic const XML_Char * 65367db96d56Sopenharmony_cigetContext(XML_Parser parser) { 65377db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 65387db96d56Sopenharmony_ci HASH_TABLE_ITER iter; 65397db96d56Sopenharmony_ci XML_Bool needSep = XML_FALSE; 65407db96d56Sopenharmony_ci 65417db96d56Sopenharmony_ci if (dtd->defaultPrefix.binding) { 65427db96d56Sopenharmony_ci int i; 65437db96d56Sopenharmony_ci int len; 65447db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) 65457db96d56Sopenharmony_ci return NULL; 65467db96d56Sopenharmony_ci len = dtd->defaultPrefix.binding->uriLen; 65477db96d56Sopenharmony_ci if (parser->m_namespaceSeparator) 65487db96d56Sopenharmony_ci len--; 65497db96d56Sopenharmony_ci for (i = 0; i < len; i++) { 65507db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, 65517db96d56Sopenharmony_ci dtd->defaultPrefix.binding->uri[i])) { 65527db96d56Sopenharmony_ci /* Because of memory caching, I don't believe this line can be 65537db96d56Sopenharmony_ci * executed. 65547db96d56Sopenharmony_ci * 65557db96d56Sopenharmony_ci * This is part of a loop copying the default prefix binding 65567db96d56Sopenharmony_ci * URI into the parser's temporary string pool. Previously, 65577db96d56Sopenharmony_ci * that URI was copied into the same string pool, with a 65587db96d56Sopenharmony_ci * terminating NUL character, as part of setContext(). When 65597db96d56Sopenharmony_ci * the pool was cleared, that leaves a block definitely big 65607db96d56Sopenharmony_ci * enough to hold the URI on the free block list of the pool. 65617db96d56Sopenharmony_ci * The URI copy in getContext() therefore cannot run out of 65627db96d56Sopenharmony_ci * memory. 65637db96d56Sopenharmony_ci * 65647db96d56Sopenharmony_ci * If the pool is used between the setContext() and 65657db96d56Sopenharmony_ci * getContext() calls, the worst it can do is leave a bigger 65667db96d56Sopenharmony_ci * block on the front of the free list. Given that this is 65677db96d56Sopenharmony_ci * all somewhat inobvious and program logic can be changed, we 65687db96d56Sopenharmony_ci * don't delete the line but we do exclude it from the test 65697db96d56Sopenharmony_ci * coverage statistics. 65707db96d56Sopenharmony_ci */ 65717db96d56Sopenharmony_ci return NULL; /* LCOV_EXCL_LINE */ 65727db96d56Sopenharmony_ci } 65737db96d56Sopenharmony_ci } 65747db96d56Sopenharmony_ci needSep = XML_TRUE; 65757db96d56Sopenharmony_ci } 65767db96d56Sopenharmony_ci 65777db96d56Sopenharmony_ci hashTableIterInit(&iter, &(dtd->prefixes)); 65787db96d56Sopenharmony_ci for (;;) { 65797db96d56Sopenharmony_ci int i; 65807db96d56Sopenharmony_ci int len; 65817db96d56Sopenharmony_ci const XML_Char *s; 65827db96d56Sopenharmony_ci PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); 65837db96d56Sopenharmony_ci if (! prefix) 65847db96d56Sopenharmony_ci break; 65857db96d56Sopenharmony_ci if (! prefix->binding) { 65867db96d56Sopenharmony_ci /* This test appears to be (justifiable) paranoia. There does 65877db96d56Sopenharmony_ci * not seem to be a way of injecting a prefix without a binding 65887db96d56Sopenharmony_ci * that doesn't get errored long before this function is called. 65897db96d56Sopenharmony_ci * The test should remain for safety's sake, so we instead 65907db96d56Sopenharmony_ci * exclude the following line from the coverage statistics. 65917db96d56Sopenharmony_ci */ 65927db96d56Sopenharmony_ci continue; /* LCOV_EXCL_LINE */ 65937db96d56Sopenharmony_ci } 65947db96d56Sopenharmony_ci if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) 65957db96d56Sopenharmony_ci return NULL; 65967db96d56Sopenharmony_ci for (s = prefix->name; *s; s++) 65977db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, *s)) 65987db96d56Sopenharmony_ci return NULL; 65997db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) 66007db96d56Sopenharmony_ci return NULL; 66017db96d56Sopenharmony_ci len = prefix->binding->uriLen; 66027db96d56Sopenharmony_ci if (parser->m_namespaceSeparator) 66037db96d56Sopenharmony_ci len--; 66047db96d56Sopenharmony_ci for (i = 0; i < len; i++) 66057db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) 66067db96d56Sopenharmony_ci return NULL; 66077db96d56Sopenharmony_ci needSep = XML_TRUE; 66087db96d56Sopenharmony_ci } 66097db96d56Sopenharmony_ci 66107db96d56Sopenharmony_ci hashTableIterInit(&iter, &(dtd->generalEntities)); 66117db96d56Sopenharmony_ci for (;;) { 66127db96d56Sopenharmony_ci const XML_Char *s; 66137db96d56Sopenharmony_ci ENTITY *e = (ENTITY *)hashTableIterNext(&iter); 66147db96d56Sopenharmony_ci if (! e) 66157db96d56Sopenharmony_ci break; 66167db96d56Sopenharmony_ci if (! e->open) 66177db96d56Sopenharmony_ci continue; 66187db96d56Sopenharmony_ci if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) 66197db96d56Sopenharmony_ci return NULL; 66207db96d56Sopenharmony_ci for (s = e->name; *s; s++) 66217db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, *s)) 66227db96d56Sopenharmony_ci return 0; 66237db96d56Sopenharmony_ci needSep = XML_TRUE; 66247db96d56Sopenharmony_ci } 66257db96d56Sopenharmony_ci 66267db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 66277db96d56Sopenharmony_ci return NULL; 66287db96d56Sopenharmony_ci return parser->m_tempPool.start; 66297db96d56Sopenharmony_ci} 66307db96d56Sopenharmony_ci 66317db96d56Sopenharmony_cistatic XML_Bool 66327db96d56Sopenharmony_cisetContext(XML_Parser parser, const XML_Char *context) { 66337db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 66347db96d56Sopenharmony_ci const XML_Char *s = context; 66357db96d56Sopenharmony_ci 66367db96d56Sopenharmony_ci while (*context != XML_T('\0')) { 66377db96d56Sopenharmony_ci if (*s == CONTEXT_SEP || *s == XML_T('\0')) { 66387db96d56Sopenharmony_ci ENTITY *e; 66397db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 66407db96d56Sopenharmony_ci return XML_FALSE; 66417db96d56Sopenharmony_ci e = (ENTITY *)lookup(parser, &dtd->generalEntities, 66427db96d56Sopenharmony_ci poolStart(&parser->m_tempPool), 0); 66437db96d56Sopenharmony_ci if (e) 66447db96d56Sopenharmony_ci e->open = XML_TRUE; 66457db96d56Sopenharmony_ci if (*s != XML_T('\0')) 66467db96d56Sopenharmony_ci s++; 66477db96d56Sopenharmony_ci context = s; 66487db96d56Sopenharmony_ci poolDiscard(&parser->m_tempPool); 66497db96d56Sopenharmony_ci } else if (*s == XML_T(ASCII_EQUALS)) { 66507db96d56Sopenharmony_ci PREFIX *prefix; 66517db96d56Sopenharmony_ci if (poolLength(&parser->m_tempPool) == 0) 66527db96d56Sopenharmony_ci prefix = &dtd->defaultPrefix; 66537db96d56Sopenharmony_ci else { 66547db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 66557db96d56Sopenharmony_ci return XML_FALSE; 66567db96d56Sopenharmony_ci prefix 66577db96d56Sopenharmony_ci = (PREFIX *)lookup(parser, &dtd->prefixes, 66587db96d56Sopenharmony_ci poolStart(&parser->m_tempPool), sizeof(PREFIX)); 66597db96d56Sopenharmony_ci if (! prefix) 66607db96d56Sopenharmony_ci return XML_FALSE; 66617db96d56Sopenharmony_ci if (prefix->name == poolStart(&parser->m_tempPool)) { 66627db96d56Sopenharmony_ci prefix->name = poolCopyString(&dtd->pool, prefix->name); 66637db96d56Sopenharmony_ci if (! prefix->name) 66647db96d56Sopenharmony_ci return XML_FALSE; 66657db96d56Sopenharmony_ci } 66667db96d56Sopenharmony_ci poolDiscard(&parser->m_tempPool); 66677db96d56Sopenharmony_ci } 66687db96d56Sopenharmony_ci for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); 66697db96d56Sopenharmony_ci context++) 66707db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, *context)) 66717db96d56Sopenharmony_ci return XML_FALSE; 66727db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 66737db96d56Sopenharmony_ci return XML_FALSE; 66747db96d56Sopenharmony_ci if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), 66757db96d56Sopenharmony_ci &parser->m_inheritedBindings) 66767db96d56Sopenharmony_ci != XML_ERROR_NONE) 66777db96d56Sopenharmony_ci return XML_FALSE; 66787db96d56Sopenharmony_ci poolDiscard(&parser->m_tempPool); 66797db96d56Sopenharmony_ci if (*context != XML_T('\0')) 66807db96d56Sopenharmony_ci ++context; 66817db96d56Sopenharmony_ci s = context; 66827db96d56Sopenharmony_ci } else { 66837db96d56Sopenharmony_ci if (! poolAppendChar(&parser->m_tempPool, *s)) 66847db96d56Sopenharmony_ci return XML_FALSE; 66857db96d56Sopenharmony_ci s++; 66867db96d56Sopenharmony_ci } 66877db96d56Sopenharmony_ci } 66887db96d56Sopenharmony_ci return XML_TRUE; 66897db96d56Sopenharmony_ci} 66907db96d56Sopenharmony_ci 66917db96d56Sopenharmony_cistatic void FASTCALL 66927db96d56Sopenharmony_cinormalizePublicId(XML_Char *publicId) { 66937db96d56Sopenharmony_ci XML_Char *p = publicId; 66947db96d56Sopenharmony_ci XML_Char *s; 66957db96d56Sopenharmony_ci for (s = publicId; *s; s++) { 66967db96d56Sopenharmony_ci switch (*s) { 66977db96d56Sopenharmony_ci case 0x20: 66987db96d56Sopenharmony_ci case 0xD: 66997db96d56Sopenharmony_ci case 0xA: 67007db96d56Sopenharmony_ci if (p != publicId && p[-1] != 0x20) 67017db96d56Sopenharmony_ci *p++ = 0x20; 67027db96d56Sopenharmony_ci break; 67037db96d56Sopenharmony_ci default: 67047db96d56Sopenharmony_ci *p++ = *s; 67057db96d56Sopenharmony_ci } 67067db96d56Sopenharmony_ci } 67077db96d56Sopenharmony_ci if (p != publicId && p[-1] == 0x20) 67087db96d56Sopenharmony_ci --p; 67097db96d56Sopenharmony_ci *p = XML_T('\0'); 67107db96d56Sopenharmony_ci} 67117db96d56Sopenharmony_ci 67127db96d56Sopenharmony_cistatic DTD * 67137db96d56Sopenharmony_cidtdCreate(const XML_Memory_Handling_Suite *ms) { 67147db96d56Sopenharmony_ci DTD *p = ms->malloc_fcn(sizeof(DTD)); 67157db96d56Sopenharmony_ci if (p == NULL) 67167db96d56Sopenharmony_ci return p; 67177db96d56Sopenharmony_ci poolInit(&(p->pool), ms); 67187db96d56Sopenharmony_ci poolInit(&(p->entityValuePool), ms); 67197db96d56Sopenharmony_ci hashTableInit(&(p->generalEntities), ms); 67207db96d56Sopenharmony_ci hashTableInit(&(p->elementTypes), ms); 67217db96d56Sopenharmony_ci hashTableInit(&(p->attributeIds), ms); 67227db96d56Sopenharmony_ci hashTableInit(&(p->prefixes), ms); 67237db96d56Sopenharmony_ci#ifdef XML_DTD 67247db96d56Sopenharmony_ci p->paramEntityRead = XML_FALSE; 67257db96d56Sopenharmony_ci hashTableInit(&(p->paramEntities), ms); 67267db96d56Sopenharmony_ci#endif /* XML_DTD */ 67277db96d56Sopenharmony_ci p->defaultPrefix.name = NULL; 67287db96d56Sopenharmony_ci p->defaultPrefix.binding = NULL; 67297db96d56Sopenharmony_ci 67307db96d56Sopenharmony_ci p->in_eldecl = XML_FALSE; 67317db96d56Sopenharmony_ci p->scaffIndex = NULL; 67327db96d56Sopenharmony_ci p->scaffold = NULL; 67337db96d56Sopenharmony_ci p->scaffLevel = 0; 67347db96d56Sopenharmony_ci p->scaffSize = 0; 67357db96d56Sopenharmony_ci p->scaffCount = 0; 67367db96d56Sopenharmony_ci p->contentStringLen = 0; 67377db96d56Sopenharmony_ci 67387db96d56Sopenharmony_ci p->keepProcessing = XML_TRUE; 67397db96d56Sopenharmony_ci p->hasParamEntityRefs = XML_FALSE; 67407db96d56Sopenharmony_ci p->standalone = XML_FALSE; 67417db96d56Sopenharmony_ci return p; 67427db96d56Sopenharmony_ci} 67437db96d56Sopenharmony_ci 67447db96d56Sopenharmony_cistatic void 67457db96d56Sopenharmony_cidtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) { 67467db96d56Sopenharmony_ci HASH_TABLE_ITER iter; 67477db96d56Sopenharmony_ci hashTableIterInit(&iter, &(p->elementTypes)); 67487db96d56Sopenharmony_ci for (;;) { 67497db96d56Sopenharmony_ci ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); 67507db96d56Sopenharmony_ci if (! e) 67517db96d56Sopenharmony_ci break; 67527db96d56Sopenharmony_ci if (e->allocDefaultAtts != 0) 67537db96d56Sopenharmony_ci ms->free_fcn(e->defaultAtts); 67547db96d56Sopenharmony_ci } 67557db96d56Sopenharmony_ci hashTableClear(&(p->generalEntities)); 67567db96d56Sopenharmony_ci#ifdef XML_DTD 67577db96d56Sopenharmony_ci p->paramEntityRead = XML_FALSE; 67587db96d56Sopenharmony_ci hashTableClear(&(p->paramEntities)); 67597db96d56Sopenharmony_ci#endif /* XML_DTD */ 67607db96d56Sopenharmony_ci hashTableClear(&(p->elementTypes)); 67617db96d56Sopenharmony_ci hashTableClear(&(p->attributeIds)); 67627db96d56Sopenharmony_ci hashTableClear(&(p->prefixes)); 67637db96d56Sopenharmony_ci poolClear(&(p->pool)); 67647db96d56Sopenharmony_ci poolClear(&(p->entityValuePool)); 67657db96d56Sopenharmony_ci p->defaultPrefix.name = NULL; 67667db96d56Sopenharmony_ci p->defaultPrefix.binding = NULL; 67677db96d56Sopenharmony_ci 67687db96d56Sopenharmony_ci p->in_eldecl = XML_FALSE; 67697db96d56Sopenharmony_ci 67707db96d56Sopenharmony_ci ms->free_fcn(p->scaffIndex); 67717db96d56Sopenharmony_ci p->scaffIndex = NULL; 67727db96d56Sopenharmony_ci ms->free_fcn(p->scaffold); 67737db96d56Sopenharmony_ci p->scaffold = NULL; 67747db96d56Sopenharmony_ci 67757db96d56Sopenharmony_ci p->scaffLevel = 0; 67767db96d56Sopenharmony_ci p->scaffSize = 0; 67777db96d56Sopenharmony_ci p->scaffCount = 0; 67787db96d56Sopenharmony_ci p->contentStringLen = 0; 67797db96d56Sopenharmony_ci 67807db96d56Sopenharmony_ci p->keepProcessing = XML_TRUE; 67817db96d56Sopenharmony_ci p->hasParamEntityRefs = XML_FALSE; 67827db96d56Sopenharmony_ci p->standalone = XML_FALSE; 67837db96d56Sopenharmony_ci} 67847db96d56Sopenharmony_ci 67857db96d56Sopenharmony_cistatic void 67867db96d56Sopenharmony_cidtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) { 67877db96d56Sopenharmony_ci HASH_TABLE_ITER iter; 67887db96d56Sopenharmony_ci hashTableIterInit(&iter, &(p->elementTypes)); 67897db96d56Sopenharmony_ci for (;;) { 67907db96d56Sopenharmony_ci ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); 67917db96d56Sopenharmony_ci if (! e) 67927db96d56Sopenharmony_ci break; 67937db96d56Sopenharmony_ci if (e->allocDefaultAtts != 0) 67947db96d56Sopenharmony_ci ms->free_fcn(e->defaultAtts); 67957db96d56Sopenharmony_ci } 67967db96d56Sopenharmony_ci hashTableDestroy(&(p->generalEntities)); 67977db96d56Sopenharmony_ci#ifdef XML_DTD 67987db96d56Sopenharmony_ci hashTableDestroy(&(p->paramEntities)); 67997db96d56Sopenharmony_ci#endif /* XML_DTD */ 68007db96d56Sopenharmony_ci hashTableDestroy(&(p->elementTypes)); 68017db96d56Sopenharmony_ci hashTableDestroy(&(p->attributeIds)); 68027db96d56Sopenharmony_ci hashTableDestroy(&(p->prefixes)); 68037db96d56Sopenharmony_ci poolDestroy(&(p->pool)); 68047db96d56Sopenharmony_ci poolDestroy(&(p->entityValuePool)); 68057db96d56Sopenharmony_ci if (isDocEntity) { 68067db96d56Sopenharmony_ci ms->free_fcn(p->scaffIndex); 68077db96d56Sopenharmony_ci ms->free_fcn(p->scaffold); 68087db96d56Sopenharmony_ci } 68097db96d56Sopenharmony_ci ms->free_fcn(p); 68107db96d56Sopenharmony_ci} 68117db96d56Sopenharmony_ci 68127db96d56Sopenharmony_ci/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. 68137db96d56Sopenharmony_ci The new DTD has already been initialized. 68147db96d56Sopenharmony_ci*/ 68157db96d56Sopenharmony_cistatic int 68167db96d56Sopenharmony_cidtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, 68177db96d56Sopenharmony_ci const XML_Memory_Handling_Suite *ms) { 68187db96d56Sopenharmony_ci HASH_TABLE_ITER iter; 68197db96d56Sopenharmony_ci 68207db96d56Sopenharmony_ci /* Copy the prefix table. */ 68217db96d56Sopenharmony_ci 68227db96d56Sopenharmony_ci hashTableIterInit(&iter, &(oldDtd->prefixes)); 68237db96d56Sopenharmony_ci for (;;) { 68247db96d56Sopenharmony_ci const XML_Char *name; 68257db96d56Sopenharmony_ci const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); 68267db96d56Sopenharmony_ci if (! oldP) 68277db96d56Sopenharmony_ci break; 68287db96d56Sopenharmony_ci name = poolCopyString(&(newDtd->pool), oldP->name); 68297db96d56Sopenharmony_ci if (! name) 68307db96d56Sopenharmony_ci return 0; 68317db96d56Sopenharmony_ci if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) 68327db96d56Sopenharmony_ci return 0; 68337db96d56Sopenharmony_ci } 68347db96d56Sopenharmony_ci 68357db96d56Sopenharmony_ci hashTableIterInit(&iter, &(oldDtd->attributeIds)); 68367db96d56Sopenharmony_ci 68377db96d56Sopenharmony_ci /* Copy the attribute id table. */ 68387db96d56Sopenharmony_ci 68397db96d56Sopenharmony_ci for (;;) { 68407db96d56Sopenharmony_ci ATTRIBUTE_ID *newA; 68417db96d56Sopenharmony_ci const XML_Char *name; 68427db96d56Sopenharmony_ci const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); 68437db96d56Sopenharmony_ci 68447db96d56Sopenharmony_ci if (! oldA) 68457db96d56Sopenharmony_ci break; 68467db96d56Sopenharmony_ci /* Remember to allocate the scratch byte before the name. */ 68477db96d56Sopenharmony_ci if (! poolAppendChar(&(newDtd->pool), XML_T('\0'))) 68487db96d56Sopenharmony_ci return 0; 68497db96d56Sopenharmony_ci name = poolCopyString(&(newDtd->pool), oldA->name); 68507db96d56Sopenharmony_ci if (! name) 68517db96d56Sopenharmony_ci return 0; 68527db96d56Sopenharmony_ci ++name; 68537db96d56Sopenharmony_ci newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, 68547db96d56Sopenharmony_ci sizeof(ATTRIBUTE_ID)); 68557db96d56Sopenharmony_ci if (! newA) 68567db96d56Sopenharmony_ci return 0; 68577db96d56Sopenharmony_ci newA->maybeTokenized = oldA->maybeTokenized; 68587db96d56Sopenharmony_ci if (oldA->prefix) { 68597db96d56Sopenharmony_ci newA->xmlns = oldA->xmlns; 68607db96d56Sopenharmony_ci if (oldA->prefix == &oldDtd->defaultPrefix) 68617db96d56Sopenharmony_ci newA->prefix = &newDtd->defaultPrefix; 68627db96d56Sopenharmony_ci else 68637db96d56Sopenharmony_ci newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), 68647db96d56Sopenharmony_ci oldA->prefix->name, 0); 68657db96d56Sopenharmony_ci } 68667db96d56Sopenharmony_ci } 68677db96d56Sopenharmony_ci 68687db96d56Sopenharmony_ci /* Copy the element type table. */ 68697db96d56Sopenharmony_ci 68707db96d56Sopenharmony_ci hashTableIterInit(&iter, &(oldDtd->elementTypes)); 68717db96d56Sopenharmony_ci 68727db96d56Sopenharmony_ci for (;;) { 68737db96d56Sopenharmony_ci int i; 68747db96d56Sopenharmony_ci ELEMENT_TYPE *newE; 68757db96d56Sopenharmony_ci const XML_Char *name; 68767db96d56Sopenharmony_ci const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); 68777db96d56Sopenharmony_ci if (! oldE) 68787db96d56Sopenharmony_ci break; 68797db96d56Sopenharmony_ci name = poolCopyString(&(newDtd->pool), oldE->name); 68807db96d56Sopenharmony_ci if (! name) 68817db96d56Sopenharmony_ci return 0; 68827db96d56Sopenharmony_ci newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, 68837db96d56Sopenharmony_ci sizeof(ELEMENT_TYPE)); 68847db96d56Sopenharmony_ci if (! newE) 68857db96d56Sopenharmony_ci return 0; 68867db96d56Sopenharmony_ci if (oldE->nDefaultAtts) { 68877db96d56Sopenharmony_ci newE->defaultAtts 68887db96d56Sopenharmony_ci = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); 68897db96d56Sopenharmony_ci if (! newE->defaultAtts) { 68907db96d56Sopenharmony_ci return 0; 68917db96d56Sopenharmony_ci } 68927db96d56Sopenharmony_ci } 68937db96d56Sopenharmony_ci if (oldE->idAtt) 68947db96d56Sopenharmony_ci newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), 68957db96d56Sopenharmony_ci oldE->idAtt->name, 0); 68967db96d56Sopenharmony_ci newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; 68977db96d56Sopenharmony_ci if (oldE->prefix) 68987db96d56Sopenharmony_ci newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), 68997db96d56Sopenharmony_ci oldE->prefix->name, 0); 69007db96d56Sopenharmony_ci for (i = 0; i < newE->nDefaultAtts; i++) { 69017db96d56Sopenharmony_ci newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup( 69027db96d56Sopenharmony_ci oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); 69037db96d56Sopenharmony_ci newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; 69047db96d56Sopenharmony_ci if (oldE->defaultAtts[i].value) { 69057db96d56Sopenharmony_ci newE->defaultAtts[i].value 69067db96d56Sopenharmony_ci = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); 69077db96d56Sopenharmony_ci if (! newE->defaultAtts[i].value) 69087db96d56Sopenharmony_ci return 0; 69097db96d56Sopenharmony_ci } else 69107db96d56Sopenharmony_ci newE->defaultAtts[i].value = NULL; 69117db96d56Sopenharmony_ci } 69127db96d56Sopenharmony_ci } 69137db96d56Sopenharmony_ci 69147db96d56Sopenharmony_ci /* Copy the entity tables. */ 69157db96d56Sopenharmony_ci if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool), 69167db96d56Sopenharmony_ci &(oldDtd->generalEntities))) 69177db96d56Sopenharmony_ci return 0; 69187db96d56Sopenharmony_ci 69197db96d56Sopenharmony_ci#ifdef XML_DTD 69207db96d56Sopenharmony_ci if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool), 69217db96d56Sopenharmony_ci &(oldDtd->paramEntities))) 69227db96d56Sopenharmony_ci return 0; 69237db96d56Sopenharmony_ci newDtd->paramEntityRead = oldDtd->paramEntityRead; 69247db96d56Sopenharmony_ci#endif /* XML_DTD */ 69257db96d56Sopenharmony_ci 69267db96d56Sopenharmony_ci newDtd->keepProcessing = oldDtd->keepProcessing; 69277db96d56Sopenharmony_ci newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; 69287db96d56Sopenharmony_ci newDtd->standalone = oldDtd->standalone; 69297db96d56Sopenharmony_ci 69307db96d56Sopenharmony_ci /* Don't want deep copying for scaffolding */ 69317db96d56Sopenharmony_ci newDtd->in_eldecl = oldDtd->in_eldecl; 69327db96d56Sopenharmony_ci newDtd->scaffold = oldDtd->scaffold; 69337db96d56Sopenharmony_ci newDtd->contentStringLen = oldDtd->contentStringLen; 69347db96d56Sopenharmony_ci newDtd->scaffSize = oldDtd->scaffSize; 69357db96d56Sopenharmony_ci newDtd->scaffLevel = oldDtd->scaffLevel; 69367db96d56Sopenharmony_ci newDtd->scaffIndex = oldDtd->scaffIndex; 69377db96d56Sopenharmony_ci 69387db96d56Sopenharmony_ci return 1; 69397db96d56Sopenharmony_ci} /* End dtdCopy */ 69407db96d56Sopenharmony_ci 69417db96d56Sopenharmony_cistatic int 69427db96d56Sopenharmony_cicopyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, 69437db96d56Sopenharmony_ci STRING_POOL *newPool, const HASH_TABLE *oldTable) { 69447db96d56Sopenharmony_ci HASH_TABLE_ITER iter; 69457db96d56Sopenharmony_ci const XML_Char *cachedOldBase = NULL; 69467db96d56Sopenharmony_ci const XML_Char *cachedNewBase = NULL; 69477db96d56Sopenharmony_ci 69487db96d56Sopenharmony_ci hashTableIterInit(&iter, oldTable); 69497db96d56Sopenharmony_ci 69507db96d56Sopenharmony_ci for (;;) { 69517db96d56Sopenharmony_ci ENTITY *newE; 69527db96d56Sopenharmony_ci const XML_Char *name; 69537db96d56Sopenharmony_ci const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); 69547db96d56Sopenharmony_ci if (! oldE) 69557db96d56Sopenharmony_ci break; 69567db96d56Sopenharmony_ci name = poolCopyString(newPool, oldE->name); 69577db96d56Sopenharmony_ci if (! name) 69587db96d56Sopenharmony_ci return 0; 69597db96d56Sopenharmony_ci newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); 69607db96d56Sopenharmony_ci if (! newE) 69617db96d56Sopenharmony_ci return 0; 69627db96d56Sopenharmony_ci if (oldE->systemId) { 69637db96d56Sopenharmony_ci const XML_Char *tem = poolCopyString(newPool, oldE->systemId); 69647db96d56Sopenharmony_ci if (! tem) 69657db96d56Sopenharmony_ci return 0; 69667db96d56Sopenharmony_ci newE->systemId = tem; 69677db96d56Sopenharmony_ci if (oldE->base) { 69687db96d56Sopenharmony_ci if (oldE->base == cachedOldBase) 69697db96d56Sopenharmony_ci newE->base = cachedNewBase; 69707db96d56Sopenharmony_ci else { 69717db96d56Sopenharmony_ci cachedOldBase = oldE->base; 69727db96d56Sopenharmony_ci tem = poolCopyString(newPool, cachedOldBase); 69737db96d56Sopenharmony_ci if (! tem) 69747db96d56Sopenharmony_ci return 0; 69757db96d56Sopenharmony_ci cachedNewBase = newE->base = tem; 69767db96d56Sopenharmony_ci } 69777db96d56Sopenharmony_ci } 69787db96d56Sopenharmony_ci if (oldE->publicId) { 69797db96d56Sopenharmony_ci tem = poolCopyString(newPool, oldE->publicId); 69807db96d56Sopenharmony_ci if (! tem) 69817db96d56Sopenharmony_ci return 0; 69827db96d56Sopenharmony_ci newE->publicId = tem; 69837db96d56Sopenharmony_ci } 69847db96d56Sopenharmony_ci } else { 69857db96d56Sopenharmony_ci const XML_Char *tem 69867db96d56Sopenharmony_ci = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); 69877db96d56Sopenharmony_ci if (! tem) 69887db96d56Sopenharmony_ci return 0; 69897db96d56Sopenharmony_ci newE->textPtr = tem; 69907db96d56Sopenharmony_ci newE->textLen = oldE->textLen; 69917db96d56Sopenharmony_ci } 69927db96d56Sopenharmony_ci if (oldE->notation) { 69937db96d56Sopenharmony_ci const XML_Char *tem = poolCopyString(newPool, oldE->notation); 69947db96d56Sopenharmony_ci if (! tem) 69957db96d56Sopenharmony_ci return 0; 69967db96d56Sopenharmony_ci newE->notation = tem; 69977db96d56Sopenharmony_ci } 69987db96d56Sopenharmony_ci newE->is_param = oldE->is_param; 69997db96d56Sopenharmony_ci newE->is_internal = oldE->is_internal; 70007db96d56Sopenharmony_ci } 70017db96d56Sopenharmony_ci return 1; 70027db96d56Sopenharmony_ci} 70037db96d56Sopenharmony_ci 70047db96d56Sopenharmony_ci#define INIT_POWER 6 70057db96d56Sopenharmony_ci 70067db96d56Sopenharmony_cistatic XML_Bool FASTCALL 70077db96d56Sopenharmony_cikeyeq(KEY s1, KEY s2) { 70087db96d56Sopenharmony_ci for (; *s1 == *s2; s1++, s2++) 70097db96d56Sopenharmony_ci if (*s1 == 0) 70107db96d56Sopenharmony_ci return XML_TRUE; 70117db96d56Sopenharmony_ci return XML_FALSE; 70127db96d56Sopenharmony_ci} 70137db96d56Sopenharmony_ci 70147db96d56Sopenharmony_cistatic size_t 70157db96d56Sopenharmony_cikeylen(KEY s) { 70167db96d56Sopenharmony_ci size_t len = 0; 70177db96d56Sopenharmony_ci for (; *s; s++, len++) 70187db96d56Sopenharmony_ci ; 70197db96d56Sopenharmony_ci return len; 70207db96d56Sopenharmony_ci} 70217db96d56Sopenharmony_ci 70227db96d56Sopenharmony_cistatic void 70237db96d56Sopenharmony_cicopy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) { 70247db96d56Sopenharmony_ci key->k[0] = 0; 70257db96d56Sopenharmony_ci key->k[1] = get_hash_secret_salt(parser); 70267db96d56Sopenharmony_ci} 70277db96d56Sopenharmony_ci 70287db96d56Sopenharmony_cistatic unsigned long FASTCALL 70297db96d56Sopenharmony_cihash(XML_Parser parser, KEY s) { 70307db96d56Sopenharmony_ci struct siphash state; 70317db96d56Sopenharmony_ci struct sipkey key; 70327db96d56Sopenharmony_ci (void)sip24_valid; 70337db96d56Sopenharmony_ci copy_salt_to_sipkey(parser, &key); 70347db96d56Sopenharmony_ci sip24_init(&state, &key); 70357db96d56Sopenharmony_ci sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); 70367db96d56Sopenharmony_ci return (unsigned long)sip24_final(&state); 70377db96d56Sopenharmony_ci} 70387db96d56Sopenharmony_ci 70397db96d56Sopenharmony_cistatic NAMED * 70407db96d56Sopenharmony_cilookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { 70417db96d56Sopenharmony_ci size_t i; 70427db96d56Sopenharmony_ci if (table->size == 0) { 70437db96d56Sopenharmony_ci size_t tsize; 70447db96d56Sopenharmony_ci if (! createSize) 70457db96d56Sopenharmony_ci return NULL; 70467db96d56Sopenharmony_ci table->power = INIT_POWER; 70477db96d56Sopenharmony_ci /* table->size is a power of 2 */ 70487db96d56Sopenharmony_ci table->size = (size_t)1 << INIT_POWER; 70497db96d56Sopenharmony_ci tsize = table->size * sizeof(NAMED *); 70507db96d56Sopenharmony_ci table->v = table->mem->malloc_fcn(tsize); 70517db96d56Sopenharmony_ci if (! table->v) { 70527db96d56Sopenharmony_ci table->size = 0; 70537db96d56Sopenharmony_ci return NULL; 70547db96d56Sopenharmony_ci } 70557db96d56Sopenharmony_ci memset(table->v, 0, tsize); 70567db96d56Sopenharmony_ci i = hash(parser, name) & ((unsigned long)table->size - 1); 70577db96d56Sopenharmony_ci } else { 70587db96d56Sopenharmony_ci unsigned long h = hash(parser, name); 70597db96d56Sopenharmony_ci unsigned long mask = (unsigned long)table->size - 1; 70607db96d56Sopenharmony_ci unsigned char step = 0; 70617db96d56Sopenharmony_ci i = h & mask; 70627db96d56Sopenharmony_ci while (table->v[i]) { 70637db96d56Sopenharmony_ci if (keyeq(name, table->v[i]->name)) 70647db96d56Sopenharmony_ci return table->v[i]; 70657db96d56Sopenharmony_ci if (! step) 70667db96d56Sopenharmony_ci step = PROBE_STEP(h, mask, table->power); 70677db96d56Sopenharmony_ci i < step ? (i += table->size - step) : (i -= step); 70687db96d56Sopenharmony_ci } 70697db96d56Sopenharmony_ci if (! createSize) 70707db96d56Sopenharmony_ci return NULL; 70717db96d56Sopenharmony_ci 70727db96d56Sopenharmony_ci /* check for overflow (table is half full) */ 70737db96d56Sopenharmony_ci if (table->used >> (table->power - 1)) { 70747db96d56Sopenharmony_ci unsigned char newPower = table->power + 1; 70757db96d56Sopenharmony_ci 70767db96d56Sopenharmony_ci /* Detect and prevent invalid shift */ 70777db96d56Sopenharmony_ci if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) { 70787db96d56Sopenharmony_ci return NULL; 70797db96d56Sopenharmony_ci } 70807db96d56Sopenharmony_ci 70817db96d56Sopenharmony_ci size_t newSize = (size_t)1 << newPower; 70827db96d56Sopenharmony_ci unsigned long newMask = (unsigned long)newSize - 1; 70837db96d56Sopenharmony_ci 70847db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 70857db96d56Sopenharmony_ci if (newSize > (size_t)(-1) / sizeof(NAMED *)) { 70867db96d56Sopenharmony_ci return NULL; 70877db96d56Sopenharmony_ci } 70887db96d56Sopenharmony_ci 70897db96d56Sopenharmony_ci size_t tsize = newSize * sizeof(NAMED *); 70907db96d56Sopenharmony_ci NAMED **newV = table->mem->malloc_fcn(tsize); 70917db96d56Sopenharmony_ci if (! newV) 70927db96d56Sopenharmony_ci return NULL; 70937db96d56Sopenharmony_ci memset(newV, 0, tsize); 70947db96d56Sopenharmony_ci for (i = 0; i < table->size; i++) 70957db96d56Sopenharmony_ci if (table->v[i]) { 70967db96d56Sopenharmony_ci unsigned long newHash = hash(parser, table->v[i]->name); 70977db96d56Sopenharmony_ci size_t j = newHash & newMask; 70987db96d56Sopenharmony_ci step = 0; 70997db96d56Sopenharmony_ci while (newV[j]) { 71007db96d56Sopenharmony_ci if (! step) 71017db96d56Sopenharmony_ci step = PROBE_STEP(newHash, newMask, newPower); 71027db96d56Sopenharmony_ci j < step ? (j += newSize - step) : (j -= step); 71037db96d56Sopenharmony_ci } 71047db96d56Sopenharmony_ci newV[j] = table->v[i]; 71057db96d56Sopenharmony_ci } 71067db96d56Sopenharmony_ci table->mem->free_fcn(table->v); 71077db96d56Sopenharmony_ci table->v = newV; 71087db96d56Sopenharmony_ci table->power = newPower; 71097db96d56Sopenharmony_ci table->size = newSize; 71107db96d56Sopenharmony_ci i = h & newMask; 71117db96d56Sopenharmony_ci step = 0; 71127db96d56Sopenharmony_ci while (table->v[i]) { 71137db96d56Sopenharmony_ci if (! step) 71147db96d56Sopenharmony_ci step = PROBE_STEP(h, newMask, newPower); 71157db96d56Sopenharmony_ci i < step ? (i += newSize - step) : (i -= step); 71167db96d56Sopenharmony_ci } 71177db96d56Sopenharmony_ci } 71187db96d56Sopenharmony_ci } 71197db96d56Sopenharmony_ci table->v[i] = table->mem->malloc_fcn(createSize); 71207db96d56Sopenharmony_ci if (! table->v[i]) 71217db96d56Sopenharmony_ci return NULL; 71227db96d56Sopenharmony_ci memset(table->v[i], 0, createSize); 71237db96d56Sopenharmony_ci table->v[i]->name = name; 71247db96d56Sopenharmony_ci (table->used)++; 71257db96d56Sopenharmony_ci return table->v[i]; 71267db96d56Sopenharmony_ci} 71277db96d56Sopenharmony_ci 71287db96d56Sopenharmony_cistatic void FASTCALL 71297db96d56Sopenharmony_cihashTableClear(HASH_TABLE *table) { 71307db96d56Sopenharmony_ci size_t i; 71317db96d56Sopenharmony_ci for (i = 0; i < table->size; i++) { 71327db96d56Sopenharmony_ci table->mem->free_fcn(table->v[i]); 71337db96d56Sopenharmony_ci table->v[i] = NULL; 71347db96d56Sopenharmony_ci } 71357db96d56Sopenharmony_ci table->used = 0; 71367db96d56Sopenharmony_ci} 71377db96d56Sopenharmony_ci 71387db96d56Sopenharmony_cistatic void FASTCALL 71397db96d56Sopenharmony_cihashTableDestroy(HASH_TABLE *table) { 71407db96d56Sopenharmony_ci size_t i; 71417db96d56Sopenharmony_ci for (i = 0; i < table->size; i++) 71427db96d56Sopenharmony_ci table->mem->free_fcn(table->v[i]); 71437db96d56Sopenharmony_ci table->mem->free_fcn(table->v); 71447db96d56Sopenharmony_ci} 71457db96d56Sopenharmony_ci 71467db96d56Sopenharmony_cistatic void FASTCALL 71477db96d56Sopenharmony_cihashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) { 71487db96d56Sopenharmony_ci p->power = 0; 71497db96d56Sopenharmony_ci p->size = 0; 71507db96d56Sopenharmony_ci p->used = 0; 71517db96d56Sopenharmony_ci p->v = NULL; 71527db96d56Sopenharmony_ci p->mem = ms; 71537db96d56Sopenharmony_ci} 71547db96d56Sopenharmony_ci 71557db96d56Sopenharmony_cistatic void FASTCALL 71567db96d56Sopenharmony_cihashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) { 71577db96d56Sopenharmony_ci iter->p = table->v; 71587db96d56Sopenharmony_ci iter->end = iter->p ? iter->p + table->size : NULL; 71597db96d56Sopenharmony_ci} 71607db96d56Sopenharmony_ci 71617db96d56Sopenharmony_cistatic NAMED *FASTCALL 71627db96d56Sopenharmony_cihashTableIterNext(HASH_TABLE_ITER *iter) { 71637db96d56Sopenharmony_ci while (iter->p != iter->end) { 71647db96d56Sopenharmony_ci NAMED *tem = *(iter->p)++; 71657db96d56Sopenharmony_ci if (tem) 71667db96d56Sopenharmony_ci return tem; 71677db96d56Sopenharmony_ci } 71687db96d56Sopenharmony_ci return NULL; 71697db96d56Sopenharmony_ci} 71707db96d56Sopenharmony_ci 71717db96d56Sopenharmony_cistatic void FASTCALL 71727db96d56Sopenharmony_cipoolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) { 71737db96d56Sopenharmony_ci pool->blocks = NULL; 71747db96d56Sopenharmony_ci pool->freeBlocks = NULL; 71757db96d56Sopenharmony_ci pool->start = NULL; 71767db96d56Sopenharmony_ci pool->ptr = NULL; 71777db96d56Sopenharmony_ci pool->end = NULL; 71787db96d56Sopenharmony_ci pool->mem = ms; 71797db96d56Sopenharmony_ci} 71807db96d56Sopenharmony_ci 71817db96d56Sopenharmony_cistatic void FASTCALL 71827db96d56Sopenharmony_cipoolClear(STRING_POOL *pool) { 71837db96d56Sopenharmony_ci if (! pool->freeBlocks) 71847db96d56Sopenharmony_ci pool->freeBlocks = pool->blocks; 71857db96d56Sopenharmony_ci else { 71867db96d56Sopenharmony_ci BLOCK *p = pool->blocks; 71877db96d56Sopenharmony_ci while (p) { 71887db96d56Sopenharmony_ci BLOCK *tem = p->next; 71897db96d56Sopenharmony_ci p->next = pool->freeBlocks; 71907db96d56Sopenharmony_ci pool->freeBlocks = p; 71917db96d56Sopenharmony_ci p = tem; 71927db96d56Sopenharmony_ci } 71937db96d56Sopenharmony_ci } 71947db96d56Sopenharmony_ci pool->blocks = NULL; 71957db96d56Sopenharmony_ci pool->start = NULL; 71967db96d56Sopenharmony_ci pool->ptr = NULL; 71977db96d56Sopenharmony_ci pool->end = NULL; 71987db96d56Sopenharmony_ci} 71997db96d56Sopenharmony_ci 72007db96d56Sopenharmony_cistatic void FASTCALL 72017db96d56Sopenharmony_cipoolDestroy(STRING_POOL *pool) { 72027db96d56Sopenharmony_ci BLOCK *p = pool->blocks; 72037db96d56Sopenharmony_ci while (p) { 72047db96d56Sopenharmony_ci BLOCK *tem = p->next; 72057db96d56Sopenharmony_ci pool->mem->free_fcn(p); 72067db96d56Sopenharmony_ci p = tem; 72077db96d56Sopenharmony_ci } 72087db96d56Sopenharmony_ci p = pool->freeBlocks; 72097db96d56Sopenharmony_ci while (p) { 72107db96d56Sopenharmony_ci BLOCK *tem = p->next; 72117db96d56Sopenharmony_ci pool->mem->free_fcn(p); 72127db96d56Sopenharmony_ci p = tem; 72137db96d56Sopenharmony_ci } 72147db96d56Sopenharmony_ci} 72157db96d56Sopenharmony_ci 72167db96d56Sopenharmony_cistatic XML_Char * 72177db96d56Sopenharmony_cipoolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, 72187db96d56Sopenharmony_ci const char *end) { 72197db96d56Sopenharmony_ci if (! pool->ptr && ! poolGrow(pool)) 72207db96d56Sopenharmony_ci return NULL; 72217db96d56Sopenharmony_ci for (;;) { 72227db96d56Sopenharmony_ci const enum XML_Convert_Result convert_res = XmlConvert( 72237db96d56Sopenharmony_ci enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); 72247db96d56Sopenharmony_ci if ((convert_res == XML_CONVERT_COMPLETED) 72257db96d56Sopenharmony_ci || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) 72267db96d56Sopenharmony_ci break; 72277db96d56Sopenharmony_ci if (! poolGrow(pool)) 72287db96d56Sopenharmony_ci return NULL; 72297db96d56Sopenharmony_ci } 72307db96d56Sopenharmony_ci return pool->start; 72317db96d56Sopenharmony_ci} 72327db96d56Sopenharmony_ci 72337db96d56Sopenharmony_cistatic const XML_Char *FASTCALL 72347db96d56Sopenharmony_cipoolCopyString(STRING_POOL *pool, const XML_Char *s) { 72357db96d56Sopenharmony_ci do { 72367db96d56Sopenharmony_ci if (! poolAppendChar(pool, *s)) 72377db96d56Sopenharmony_ci return NULL; 72387db96d56Sopenharmony_ci } while (*s++); 72397db96d56Sopenharmony_ci s = pool->start; 72407db96d56Sopenharmony_ci poolFinish(pool); 72417db96d56Sopenharmony_ci return s; 72427db96d56Sopenharmony_ci} 72437db96d56Sopenharmony_ci 72447db96d56Sopenharmony_cistatic const XML_Char * 72457db96d56Sopenharmony_cipoolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { 72467db96d56Sopenharmony_ci if (! pool->ptr && ! poolGrow(pool)) { 72477db96d56Sopenharmony_ci /* The following line is unreachable given the current usage of 72487db96d56Sopenharmony_ci * poolCopyStringN(). Currently it is called from exactly one 72497db96d56Sopenharmony_ci * place to copy the text of a simple general entity. By that 72507db96d56Sopenharmony_ci * point, the name of the entity is already stored in the pool, so 72517db96d56Sopenharmony_ci * pool->ptr cannot be NULL. 72527db96d56Sopenharmony_ci * 72537db96d56Sopenharmony_ci * If poolCopyStringN() is used elsewhere as it well might be, 72547db96d56Sopenharmony_ci * this line may well become executable again. Regardless, this 72557db96d56Sopenharmony_ci * sort of check shouldn't be removed lightly, so we just exclude 72567db96d56Sopenharmony_ci * it from the coverage statistics. 72577db96d56Sopenharmony_ci */ 72587db96d56Sopenharmony_ci return NULL; /* LCOV_EXCL_LINE */ 72597db96d56Sopenharmony_ci } 72607db96d56Sopenharmony_ci for (; n > 0; --n, s++) { 72617db96d56Sopenharmony_ci if (! poolAppendChar(pool, *s)) 72627db96d56Sopenharmony_ci return NULL; 72637db96d56Sopenharmony_ci } 72647db96d56Sopenharmony_ci s = pool->start; 72657db96d56Sopenharmony_ci poolFinish(pool); 72667db96d56Sopenharmony_ci return s; 72677db96d56Sopenharmony_ci} 72687db96d56Sopenharmony_ci 72697db96d56Sopenharmony_cistatic const XML_Char *FASTCALL 72707db96d56Sopenharmony_cipoolAppendString(STRING_POOL *pool, const XML_Char *s) { 72717db96d56Sopenharmony_ci while (*s) { 72727db96d56Sopenharmony_ci if (! poolAppendChar(pool, *s)) 72737db96d56Sopenharmony_ci return NULL; 72747db96d56Sopenharmony_ci s++; 72757db96d56Sopenharmony_ci } 72767db96d56Sopenharmony_ci return pool->start; 72777db96d56Sopenharmony_ci} 72787db96d56Sopenharmony_ci 72797db96d56Sopenharmony_cistatic XML_Char * 72807db96d56Sopenharmony_cipoolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, 72817db96d56Sopenharmony_ci const char *end) { 72827db96d56Sopenharmony_ci if (! poolAppend(pool, enc, ptr, end)) 72837db96d56Sopenharmony_ci return NULL; 72847db96d56Sopenharmony_ci if (pool->ptr == pool->end && ! poolGrow(pool)) 72857db96d56Sopenharmony_ci return NULL; 72867db96d56Sopenharmony_ci *(pool->ptr)++ = 0; 72877db96d56Sopenharmony_ci return pool->start; 72887db96d56Sopenharmony_ci} 72897db96d56Sopenharmony_ci 72907db96d56Sopenharmony_cistatic size_t 72917db96d56Sopenharmony_cipoolBytesToAllocateFor(int blockSize) { 72927db96d56Sopenharmony_ci /* Unprotected math would be: 72937db96d56Sopenharmony_ci ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); 72947db96d56Sopenharmony_ci ** 72957db96d56Sopenharmony_ci ** Detect overflow, avoiding _signed_ overflow undefined behavior 72967db96d56Sopenharmony_ci ** For a + b * c we check b * c in isolation first, so that addition of a 72977db96d56Sopenharmony_ci ** on top has no chance of making us accept a small non-negative number 72987db96d56Sopenharmony_ci */ 72997db96d56Sopenharmony_ci const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ 73007db96d56Sopenharmony_ci 73017db96d56Sopenharmony_ci if (blockSize <= 0) 73027db96d56Sopenharmony_ci return 0; 73037db96d56Sopenharmony_ci 73047db96d56Sopenharmony_ci if (blockSize > (int)(INT_MAX / stretch)) 73057db96d56Sopenharmony_ci return 0; 73067db96d56Sopenharmony_ci 73077db96d56Sopenharmony_ci { 73087db96d56Sopenharmony_ci const int stretchedBlockSize = blockSize * (int)stretch; 73097db96d56Sopenharmony_ci const int bytesToAllocate 73107db96d56Sopenharmony_ci = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); 73117db96d56Sopenharmony_ci if (bytesToAllocate < 0) 73127db96d56Sopenharmony_ci return 0; 73137db96d56Sopenharmony_ci 73147db96d56Sopenharmony_ci return (size_t)bytesToAllocate; 73157db96d56Sopenharmony_ci } 73167db96d56Sopenharmony_ci} 73177db96d56Sopenharmony_ci 73187db96d56Sopenharmony_cistatic XML_Bool FASTCALL 73197db96d56Sopenharmony_cipoolGrow(STRING_POOL *pool) { 73207db96d56Sopenharmony_ci if (pool->freeBlocks) { 73217db96d56Sopenharmony_ci if (pool->start == 0) { 73227db96d56Sopenharmony_ci pool->blocks = pool->freeBlocks; 73237db96d56Sopenharmony_ci pool->freeBlocks = pool->freeBlocks->next; 73247db96d56Sopenharmony_ci pool->blocks->next = NULL; 73257db96d56Sopenharmony_ci pool->start = pool->blocks->s; 73267db96d56Sopenharmony_ci pool->end = pool->start + pool->blocks->size; 73277db96d56Sopenharmony_ci pool->ptr = pool->start; 73287db96d56Sopenharmony_ci return XML_TRUE; 73297db96d56Sopenharmony_ci } 73307db96d56Sopenharmony_ci if (pool->end - pool->start < pool->freeBlocks->size) { 73317db96d56Sopenharmony_ci BLOCK *tem = pool->freeBlocks->next; 73327db96d56Sopenharmony_ci pool->freeBlocks->next = pool->blocks; 73337db96d56Sopenharmony_ci pool->blocks = pool->freeBlocks; 73347db96d56Sopenharmony_ci pool->freeBlocks = tem; 73357db96d56Sopenharmony_ci memcpy(pool->blocks->s, pool->start, 73367db96d56Sopenharmony_ci (pool->end - pool->start) * sizeof(XML_Char)); 73377db96d56Sopenharmony_ci pool->ptr = pool->blocks->s + (pool->ptr - pool->start); 73387db96d56Sopenharmony_ci pool->start = pool->blocks->s; 73397db96d56Sopenharmony_ci pool->end = pool->start + pool->blocks->size; 73407db96d56Sopenharmony_ci return XML_TRUE; 73417db96d56Sopenharmony_ci } 73427db96d56Sopenharmony_ci } 73437db96d56Sopenharmony_ci if (pool->blocks && pool->start == pool->blocks->s) { 73447db96d56Sopenharmony_ci BLOCK *temp; 73457db96d56Sopenharmony_ci int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U); 73467db96d56Sopenharmony_ci size_t bytesToAllocate; 73477db96d56Sopenharmony_ci 73487db96d56Sopenharmony_ci /* NOTE: Needs to be calculated prior to calling `realloc` 73497db96d56Sopenharmony_ci to avoid dangling pointers: */ 73507db96d56Sopenharmony_ci const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; 73517db96d56Sopenharmony_ci 73527db96d56Sopenharmony_ci if (blockSize < 0) { 73537db96d56Sopenharmony_ci /* This condition traps a situation where either more than 73547db96d56Sopenharmony_ci * INT_MAX/2 bytes have already been allocated. This isn't 73557db96d56Sopenharmony_ci * readily testable, since it is unlikely that an average 73567db96d56Sopenharmony_ci * machine will have that much memory, so we exclude it from the 73577db96d56Sopenharmony_ci * coverage statistics. 73587db96d56Sopenharmony_ci */ 73597db96d56Sopenharmony_ci return XML_FALSE; /* LCOV_EXCL_LINE */ 73607db96d56Sopenharmony_ci } 73617db96d56Sopenharmony_ci 73627db96d56Sopenharmony_ci bytesToAllocate = poolBytesToAllocateFor(blockSize); 73637db96d56Sopenharmony_ci if (bytesToAllocate == 0) 73647db96d56Sopenharmony_ci return XML_FALSE; 73657db96d56Sopenharmony_ci 73667db96d56Sopenharmony_ci temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks, 73677db96d56Sopenharmony_ci (unsigned)bytesToAllocate); 73687db96d56Sopenharmony_ci if (temp == NULL) 73697db96d56Sopenharmony_ci return XML_FALSE; 73707db96d56Sopenharmony_ci pool->blocks = temp; 73717db96d56Sopenharmony_ci pool->blocks->size = blockSize; 73727db96d56Sopenharmony_ci pool->ptr = pool->blocks->s + offsetInsideBlock; 73737db96d56Sopenharmony_ci pool->start = pool->blocks->s; 73747db96d56Sopenharmony_ci pool->end = pool->start + blockSize; 73757db96d56Sopenharmony_ci } else { 73767db96d56Sopenharmony_ci BLOCK *tem; 73777db96d56Sopenharmony_ci int blockSize = (int)(pool->end - pool->start); 73787db96d56Sopenharmony_ci size_t bytesToAllocate; 73797db96d56Sopenharmony_ci 73807db96d56Sopenharmony_ci if (blockSize < 0) { 73817db96d56Sopenharmony_ci /* This condition traps a situation where either more than 73827db96d56Sopenharmony_ci * INT_MAX bytes have already been allocated (which is prevented 73837db96d56Sopenharmony_ci * by various pieces of program logic, not least this one, never 73847db96d56Sopenharmony_ci * mind the unlikelihood of actually having that much memory) or 73857db96d56Sopenharmony_ci * the pool control fields have been corrupted (which could 73867db96d56Sopenharmony_ci * conceivably happen in an extremely buggy user handler 73877db96d56Sopenharmony_ci * function). Either way it isn't readily testable, so we 73887db96d56Sopenharmony_ci * exclude it from the coverage statistics. 73897db96d56Sopenharmony_ci */ 73907db96d56Sopenharmony_ci return XML_FALSE; /* LCOV_EXCL_LINE */ 73917db96d56Sopenharmony_ci } 73927db96d56Sopenharmony_ci 73937db96d56Sopenharmony_ci if (blockSize < INIT_BLOCK_SIZE) 73947db96d56Sopenharmony_ci blockSize = INIT_BLOCK_SIZE; 73957db96d56Sopenharmony_ci else { 73967db96d56Sopenharmony_ci /* Detect overflow, avoiding _signed_ overflow undefined behavior */ 73977db96d56Sopenharmony_ci if ((int)((unsigned)blockSize * 2U) < 0) { 73987db96d56Sopenharmony_ci return XML_FALSE; 73997db96d56Sopenharmony_ci } 74007db96d56Sopenharmony_ci blockSize *= 2; 74017db96d56Sopenharmony_ci } 74027db96d56Sopenharmony_ci 74037db96d56Sopenharmony_ci bytesToAllocate = poolBytesToAllocateFor(blockSize); 74047db96d56Sopenharmony_ci if (bytesToAllocate == 0) 74057db96d56Sopenharmony_ci return XML_FALSE; 74067db96d56Sopenharmony_ci 74077db96d56Sopenharmony_ci tem = pool->mem->malloc_fcn(bytesToAllocate); 74087db96d56Sopenharmony_ci if (! tem) 74097db96d56Sopenharmony_ci return XML_FALSE; 74107db96d56Sopenharmony_ci tem->size = blockSize; 74117db96d56Sopenharmony_ci tem->next = pool->blocks; 74127db96d56Sopenharmony_ci pool->blocks = tem; 74137db96d56Sopenharmony_ci if (pool->ptr != pool->start) 74147db96d56Sopenharmony_ci memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); 74157db96d56Sopenharmony_ci pool->ptr = tem->s + (pool->ptr - pool->start); 74167db96d56Sopenharmony_ci pool->start = tem->s; 74177db96d56Sopenharmony_ci pool->end = tem->s + blockSize; 74187db96d56Sopenharmony_ci } 74197db96d56Sopenharmony_ci return XML_TRUE; 74207db96d56Sopenharmony_ci} 74217db96d56Sopenharmony_ci 74227db96d56Sopenharmony_cistatic int FASTCALL 74237db96d56Sopenharmony_cinextScaffoldPart(XML_Parser parser) { 74247db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 74257db96d56Sopenharmony_ci CONTENT_SCAFFOLD *me; 74267db96d56Sopenharmony_ci int next; 74277db96d56Sopenharmony_ci 74287db96d56Sopenharmony_ci if (! dtd->scaffIndex) { 74297db96d56Sopenharmony_ci dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); 74307db96d56Sopenharmony_ci if (! dtd->scaffIndex) 74317db96d56Sopenharmony_ci return -1; 74327db96d56Sopenharmony_ci dtd->scaffIndex[0] = 0; 74337db96d56Sopenharmony_ci } 74347db96d56Sopenharmony_ci 74357db96d56Sopenharmony_ci if (dtd->scaffCount >= dtd->scaffSize) { 74367db96d56Sopenharmony_ci CONTENT_SCAFFOLD *temp; 74377db96d56Sopenharmony_ci if (dtd->scaffold) { 74387db96d56Sopenharmony_ci /* Detect and prevent integer overflow */ 74397db96d56Sopenharmony_ci if (dtd->scaffSize > UINT_MAX / 2u) { 74407db96d56Sopenharmony_ci return -1; 74417db96d56Sopenharmony_ci } 74427db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 74437db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 74447db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 74457db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 74467db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 74477db96d56Sopenharmony_ci if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) { 74487db96d56Sopenharmony_ci return -1; 74497db96d56Sopenharmony_ci } 74507db96d56Sopenharmony_ci#endif 74517db96d56Sopenharmony_ci 74527db96d56Sopenharmony_ci temp = (CONTENT_SCAFFOLD *)REALLOC( 74537db96d56Sopenharmony_ci parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); 74547db96d56Sopenharmony_ci if (temp == NULL) 74557db96d56Sopenharmony_ci return -1; 74567db96d56Sopenharmony_ci dtd->scaffSize *= 2; 74577db96d56Sopenharmony_ci } else { 74587db96d56Sopenharmony_ci temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS 74597db96d56Sopenharmony_ci * sizeof(CONTENT_SCAFFOLD)); 74607db96d56Sopenharmony_ci if (temp == NULL) 74617db96d56Sopenharmony_ci return -1; 74627db96d56Sopenharmony_ci dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; 74637db96d56Sopenharmony_ci } 74647db96d56Sopenharmony_ci dtd->scaffold = temp; 74657db96d56Sopenharmony_ci } 74667db96d56Sopenharmony_ci next = dtd->scaffCount++; 74677db96d56Sopenharmony_ci me = &dtd->scaffold[next]; 74687db96d56Sopenharmony_ci if (dtd->scaffLevel) { 74697db96d56Sopenharmony_ci CONTENT_SCAFFOLD *parent 74707db96d56Sopenharmony_ci = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]]; 74717db96d56Sopenharmony_ci if (parent->lastchild) { 74727db96d56Sopenharmony_ci dtd->scaffold[parent->lastchild].nextsib = next; 74737db96d56Sopenharmony_ci } 74747db96d56Sopenharmony_ci if (! parent->childcnt) 74757db96d56Sopenharmony_ci parent->firstchild = next; 74767db96d56Sopenharmony_ci parent->lastchild = next; 74777db96d56Sopenharmony_ci parent->childcnt++; 74787db96d56Sopenharmony_ci } 74797db96d56Sopenharmony_ci me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; 74807db96d56Sopenharmony_ci return next; 74817db96d56Sopenharmony_ci} 74827db96d56Sopenharmony_ci 74837db96d56Sopenharmony_cistatic XML_Content * 74847db96d56Sopenharmony_cibuild_model(XML_Parser parser) { 74857db96d56Sopenharmony_ci /* Function build_model transforms the existing parser->m_dtd->scaffold 74867db96d56Sopenharmony_ci * array of CONTENT_SCAFFOLD tree nodes into a new array of 74877db96d56Sopenharmony_ci * XML_Content tree nodes followed by a gapless list of zero-terminated 74887db96d56Sopenharmony_ci * strings. */ 74897db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 74907db96d56Sopenharmony_ci XML_Content *ret; 74917db96d56Sopenharmony_ci XML_Char *str; /* the current string writing location */ 74927db96d56Sopenharmony_ci 74937db96d56Sopenharmony_ci /* Detect and prevent integer overflow. 74947db96d56Sopenharmony_ci * The preprocessor guard addresses the "always false" warning 74957db96d56Sopenharmony_ci * from -Wtype-limits on platforms where 74967db96d56Sopenharmony_ci * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 74977db96d56Sopenharmony_ci#if UINT_MAX >= SIZE_MAX 74987db96d56Sopenharmony_ci if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) { 74997db96d56Sopenharmony_ci return NULL; 75007db96d56Sopenharmony_ci } 75017db96d56Sopenharmony_ci if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) { 75027db96d56Sopenharmony_ci return NULL; 75037db96d56Sopenharmony_ci } 75047db96d56Sopenharmony_ci#endif 75057db96d56Sopenharmony_ci if (dtd->scaffCount * sizeof(XML_Content) 75067db96d56Sopenharmony_ci > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) { 75077db96d56Sopenharmony_ci return NULL; 75087db96d56Sopenharmony_ci } 75097db96d56Sopenharmony_ci 75107db96d56Sopenharmony_ci const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content) 75117db96d56Sopenharmony_ci + (dtd->contentStringLen * sizeof(XML_Char))); 75127db96d56Sopenharmony_ci 75137db96d56Sopenharmony_ci ret = (XML_Content *)MALLOC(parser, allocsize); 75147db96d56Sopenharmony_ci if (! ret) 75157db96d56Sopenharmony_ci return NULL; 75167db96d56Sopenharmony_ci 75177db96d56Sopenharmony_ci /* What follows is an iterative implementation (of what was previously done 75187db96d56Sopenharmony_ci * recursively in a dedicated function called "build_node". The old recursive 75197db96d56Sopenharmony_ci * build_node could be forced into stack exhaustion from input as small as a 75207db96d56Sopenharmony_ci * few megabyte, and so that was a security issue. Hence, a function call 75217db96d56Sopenharmony_ci * stack is avoided now by resolving recursion.) 75227db96d56Sopenharmony_ci * 75237db96d56Sopenharmony_ci * The iterative approach works as follows: 75247db96d56Sopenharmony_ci * 75257db96d56Sopenharmony_ci * - We have two writing pointers, both walking up the result array; one does 75267db96d56Sopenharmony_ci * the work, the other creates "jobs" for its colleague to do, and leads 75277db96d56Sopenharmony_ci * the way: 75287db96d56Sopenharmony_ci * 75297db96d56Sopenharmony_ci * - The faster one, pointer jobDest, always leads and writes "what job 75307db96d56Sopenharmony_ci * to do" by the other, once they reach that place in the 75317db96d56Sopenharmony_ci * array: leader "jobDest" stores the source node array index (relative 75327db96d56Sopenharmony_ci * to array dtd->scaffold) in field "numchildren". 75337db96d56Sopenharmony_ci * 75347db96d56Sopenharmony_ci * - The slower one, pointer dest, looks at the value stored in the 75357db96d56Sopenharmony_ci * "numchildren" field (which actually holds a source node array index 75367db96d56Sopenharmony_ci * at that time) and puts the real data from dtd->scaffold in. 75377db96d56Sopenharmony_ci * 75387db96d56Sopenharmony_ci * - Before the loop starts, jobDest writes source array index 0 75397db96d56Sopenharmony_ci * (where the root node is located) so that dest will have something to do 75407db96d56Sopenharmony_ci * when it starts operation. 75417db96d56Sopenharmony_ci * 75427db96d56Sopenharmony_ci * - Whenever nodes with children are encountered, jobDest appends 75437db96d56Sopenharmony_ci * them as new jobs, in order. As a result, tree node siblings are 75447db96d56Sopenharmony_ci * adjacent in the resulting array, for example: 75457db96d56Sopenharmony_ci * 75467db96d56Sopenharmony_ci * [0] root, has two children 75477db96d56Sopenharmony_ci * [1] first child of 0, has three children 75487db96d56Sopenharmony_ci * [3] first child of 1, does not have children 75497db96d56Sopenharmony_ci * [4] second child of 1, does not have children 75507db96d56Sopenharmony_ci * [5] third child of 1, does not have children 75517db96d56Sopenharmony_ci * [2] second child of 0, does not have children 75527db96d56Sopenharmony_ci * 75537db96d56Sopenharmony_ci * Or (the same data) presented in flat array view: 75547db96d56Sopenharmony_ci * 75557db96d56Sopenharmony_ci * [0] root, has two children 75567db96d56Sopenharmony_ci * 75577db96d56Sopenharmony_ci * [1] first child of 0, has three children 75587db96d56Sopenharmony_ci * [2] second child of 0, does not have children 75597db96d56Sopenharmony_ci * 75607db96d56Sopenharmony_ci * [3] first child of 1, does not have children 75617db96d56Sopenharmony_ci * [4] second child of 1, does not have children 75627db96d56Sopenharmony_ci * [5] third child of 1, does not have children 75637db96d56Sopenharmony_ci * 75647db96d56Sopenharmony_ci * - The algorithm repeats until all target array indices have been processed. 75657db96d56Sopenharmony_ci */ 75667db96d56Sopenharmony_ci XML_Content *dest = ret; /* tree node writing location, moves upwards */ 75677db96d56Sopenharmony_ci XML_Content *const destLimit = &ret[dtd->scaffCount]; 75687db96d56Sopenharmony_ci XML_Content *jobDest = ret; /* next free writing location in target array */ 75697db96d56Sopenharmony_ci str = (XML_Char *)&ret[dtd->scaffCount]; 75707db96d56Sopenharmony_ci 75717db96d56Sopenharmony_ci /* Add the starting job, the root node (index 0) of the source tree */ 75727db96d56Sopenharmony_ci (jobDest++)->numchildren = 0; 75737db96d56Sopenharmony_ci 75747db96d56Sopenharmony_ci for (; dest < destLimit; dest++) { 75757db96d56Sopenharmony_ci /* Retrieve source tree array index from job storage */ 75767db96d56Sopenharmony_ci const int src_node = (int)dest->numchildren; 75777db96d56Sopenharmony_ci 75787db96d56Sopenharmony_ci /* Convert item */ 75797db96d56Sopenharmony_ci dest->type = dtd->scaffold[src_node].type; 75807db96d56Sopenharmony_ci dest->quant = dtd->scaffold[src_node].quant; 75817db96d56Sopenharmony_ci if (dest->type == XML_CTYPE_NAME) { 75827db96d56Sopenharmony_ci const XML_Char *src; 75837db96d56Sopenharmony_ci dest->name = str; 75847db96d56Sopenharmony_ci src = dtd->scaffold[src_node].name; 75857db96d56Sopenharmony_ci for (;;) { 75867db96d56Sopenharmony_ci *str++ = *src; 75877db96d56Sopenharmony_ci if (! *src) 75887db96d56Sopenharmony_ci break; 75897db96d56Sopenharmony_ci src++; 75907db96d56Sopenharmony_ci } 75917db96d56Sopenharmony_ci dest->numchildren = 0; 75927db96d56Sopenharmony_ci dest->children = NULL; 75937db96d56Sopenharmony_ci } else { 75947db96d56Sopenharmony_ci unsigned int i; 75957db96d56Sopenharmony_ci int cn; 75967db96d56Sopenharmony_ci dest->name = NULL; 75977db96d56Sopenharmony_ci dest->numchildren = dtd->scaffold[src_node].childcnt; 75987db96d56Sopenharmony_ci dest->children = jobDest; 75997db96d56Sopenharmony_ci 76007db96d56Sopenharmony_ci /* Append scaffold indices of children to array */ 76017db96d56Sopenharmony_ci for (i = 0, cn = dtd->scaffold[src_node].firstchild; 76027db96d56Sopenharmony_ci i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib) 76037db96d56Sopenharmony_ci (jobDest++)->numchildren = (unsigned int)cn; 76047db96d56Sopenharmony_ci } 76057db96d56Sopenharmony_ci } 76067db96d56Sopenharmony_ci 76077db96d56Sopenharmony_ci return ret; 76087db96d56Sopenharmony_ci} 76097db96d56Sopenharmony_ci 76107db96d56Sopenharmony_cistatic ELEMENT_TYPE * 76117db96d56Sopenharmony_cigetElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, 76127db96d56Sopenharmony_ci const char *end) { 76137db96d56Sopenharmony_ci DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 76147db96d56Sopenharmony_ci const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); 76157db96d56Sopenharmony_ci ELEMENT_TYPE *ret; 76167db96d56Sopenharmony_ci 76177db96d56Sopenharmony_ci if (! name) 76187db96d56Sopenharmony_ci return NULL; 76197db96d56Sopenharmony_ci ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, 76207db96d56Sopenharmony_ci sizeof(ELEMENT_TYPE)); 76217db96d56Sopenharmony_ci if (! ret) 76227db96d56Sopenharmony_ci return NULL; 76237db96d56Sopenharmony_ci if (ret->name != name) 76247db96d56Sopenharmony_ci poolDiscard(&dtd->pool); 76257db96d56Sopenharmony_ci else { 76267db96d56Sopenharmony_ci poolFinish(&dtd->pool); 76277db96d56Sopenharmony_ci if (! setElementTypePrefix(parser, ret)) 76287db96d56Sopenharmony_ci return NULL; 76297db96d56Sopenharmony_ci } 76307db96d56Sopenharmony_ci return ret; 76317db96d56Sopenharmony_ci} 76327db96d56Sopenharmony_ci 76337db96d56Sopenharmony_cistatic XML_Char * 76347db96d56Sopenharmony_cicopyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) { 76357db96d56Sopenharmony_ci size_t charsRequired = 0; 76367db96d56Sopenharmony_ci XML_Char *result; 76377db96d56Sopenharmony_ci 76387db96d56Sopenharmony_ci /* First determine how long the string is */ 76397db96d56Sopenharmony_ci while (s[charsRequired] != 0) { 76407db96d56Sopenharmony_ci charsRequired++; 76417db96d56Sopenharmony_ci } 76427db96d56Sopenharmony_ci /* Include the terminator */ 76437db96d56Sopenharmony_ci charsRequired++; 76447db96d56Sopenharmony_ci 76457db96d56Sopenharmony_ci /* Now allocate space for the copy */ 76467db96d56Sopenharmony_ci result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); 76477db96d56Sopenharmony_ci if (result == NULL) 76487db96d56Sopenharmony_ci return NULL; 76497db96d56Sopenharmony_ci /* Copy the original into place */ 76507db96d56Sopenharmony_ci memcpy(result, s, charsRequired * sizeof(XML_Char)); 76517db96d56Sopenharmony_ci return result; 76527db96d56Sopenharmony_ci} 76537db96d56Sopenharmony_ci 76547db96d56Sopenharmony_ci#ifdef XML_DTD 76557db96d56Sopenharmony_ci 76567db96d56Sopenharmony_cistatic float 76577db96d56Sopenharmony_ciaccountingGetCurrentAmplification(XML_Parser rootParser) { 76587db96d56Sopenharmony_ci const XmlBigCount countBytesOutput 76597db96d56Sopenharmony_ci = rootParser->m_accounting.countBytesDirect 76607db96d56Sopenharmony_ci + rootParser->m_accounting.countBytesIndirect; 76617db96d56Sopenharmony_ci const float amplificationFactor 76627db96d56Sopenharmony_ci = rootParser->m_accounting.countBytesDirect 76637db96d56Sopenharmony_ci ? (countBytesOutput 76647db96d56Sopenharmony_ci / (float)(rootParser->m_accounting.countBytesDirect)) 76657db96d56Sopenharmony_ci : 1.0f; 76667db96d56Sopenharmony_ci assert(! rootParser->m_parentParser); 76677db96d56Sopenharmony_ci return amplificationFactor; 76687db96d56Sopenharmony_ci} 76697db96d56Sopenharmony_ci 76707db96d56Sopenharmony_cistatic void 76717db96d56Sopenharmony_ciaccountingReportStats(XML_Parser originParser, const char *epilog) { 76727db96d56Sopenharmony_ci const XML_Parser rootParser = getRootParserOf(originParser, NULL); 76737db96d56Sopenharmony_ci assert(! rootParser->m_parentParser); 76747db96d56Sopenharmony_ci 76757db96d56Sopenharmony_ci if (rootParser->m_accounting.debugLevel < 1) { 76767db96d56Sopenharmony_ci return; 76777db96d56Sopenharmony_ci } 76787db96d56Sopenharmony_ci 76797db96d56Sopenharmony_ci const float amplificationFactor 76807db96d56Sopenharmony_ci = accountingGetCurrentAmplification(rootParser); 76817db96d56Sopenharmony_ci fprintf(stderr, 76827db96d56Sopenharmony_ci "expat: Accounting(%p): Direct " EXPAT_FMT_ULL( 76837db96d56Sopenharmony_ci "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification %8.2f%s", 76847db96d56Sopenharmony_ci (void *)rootParser, rootParser->m_accounting.countBytesDirect, 76857db96d56Sopenharmony_ci rootParser->m_accounting.countBytesIndirect, 76867db96d56Sopenharmony_ci (double)amplificationFactor, epilog); 76877db96d56Sopenharmony_ci} 76887db96d56Sopenharmony_ci 76897db96d56Sopenharmony_cistatic void 76907db96d56Sopenharmony_ciaccountingOnAbort(XML_Parser originParser) { 76917db96d56Sopenharmony_ci accountingReportStats(originParser, " ABORTING\n"); 76927db96d56Sopenharmony_ci} 76937db96d56Sopenharmony_ci 76947db96d56Sopenharmony_cistatic void 76957db96d56Sopenharmony_ciaccountingReportDiff(XML_Parser rootParser, 76967db96d56Sopenharmony_ci unsigned int levelsAwayFromRootParser, const char *before, 76977db96d56Sopenharmony_ci const char *after, ptrdiff_t bytesMore, int source_line, 76987db96d56Sopenharmony_ci enum XML_Account account) { 76997db96d56Sopenharmony_ci assert(! rootParser->m_parentParser); 77007db96d56Sopenharmony_ci 77017db96d56Sopenharmony_ci fprintf(stderr, 77027db96d56Sopenharmony_ci " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"", 77037db96d56Sopenharmony_ci bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP", 77047db96d56Sopenharmony_ci levelsAwayFromRootParser, source_line, 10, ""); 77057db96d56Sopenharmony_ci 77067db96d56Sopenharmony_ci const char ellipis[] = "[..]"; 77077db96d56Sopenharmony_ci const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1; 77087db96d56Sopenharmony_ci const unsigned int contextLength = 10; 77097db96d56Sopenharmony_ci 77107db96d56Sopenharmony_ci /* Note: Performance is of no concern here */ 77117db96d56Sopenharmony_ci const char *walker = before; 77127db96d56Sopenharmony_ci if ((rootParser->m_accounting.debugLevel >= 3) 77137db96d56Sopenharmony_ci || (after - before) 77147db96d56Sopenharmony_ci <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) { 77157db96d56Sopenharmony_ci for (; walker < after; walker++) { 77167db96d56Sopenharmony_ci fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 77177db96d56Sopenharmony_ci } 77187db96d56Sopenharmony_ci } else { 77197db96d56Sopenharmony_ci for (; walker < before + contextLength; walker++) { 77207db96d56Sopenharmony_ci fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 77217db96d56Sopenharmony_ci } 77227db96d56Sopenharmony_ci fprintf(stderr, ellipis); 77237db96d56Sopenharmony_ci walker = after - contextLength; 77247db96d56Sopenharmony_ci for (; walker < after; walker++) { 77257db96d56Sopenharmony_ci fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 77267db96d56Sopenharmony_ci } 77277db96d56Sopenharmony_ci } 77287db96d56Sopenharmony_ci fprintf(stderr, "\"\n"); 77297db96d56Sopenharmony_ci} 77307db96d56Sopenharmony_ci 77317db96d56Sopenharmony_cistatic XML_Bool 77327db96d56Sopenharmony_ciaccountingDiffTolerated(XML_Parser originParser, int tok, const char *before, 77337db96d56Sopenharmony_ci const char *after, int source_line, 77347db96d56Sopenharmony_ci enum XML_Account account) { 77357db96d56Sopenharmony_ci /* Note: We need to check the token type *first* to be sure that 77367db96d56Sopenharmony_ci * we can even access variable <after>, safely. 77377db96d56Sopenharmony_ci * E.g. for XML_TOK_NONE <after> may hold an invalid pointer. */ 77387db96d56Sopenharmony_ci switch (tok) { 77397db96d56Sopenharmony_ci case XML_TOK_INVALID: 77407db96d56Sopenharmony_ci case XML_TOK_PARTIAL: 77417db96d56Sopenharmony_ci case XML_TOK_PARTIAL_CHAR: 77427db96d56Sopenharmony_ci case XML_TOK_NONE: 77437db96d56Sopenharmony_ci return XML_TRUE; 77447db96d56Sopenharmony_ci } 77457db96d56Sopenharmony_ci 77467db96d56Sopenharmony_ci if (account == XML_ACCOUNT_NONE) 77477db96d56Sopenharmony_ci return XML_TRUE; /* because these bytes have been accounted for, already */ 77487db96d56Sopenharmony_ci 77497db96d56Sopenharmony_ci unsigned int levelsAwayFromRootParser; 77507db96d56Sopenharmony_ci const XML_Parser rootParser 77517db96d56Sopenharmony_ci = getRootParserOf(originParser, &levelsAwayFromRootParser); 77527db96d56Sopenharmony_ci assert(! rootParser->m_parentParser); 77537db96d56Sopenharmony_ci 77547db96d56Sopenharmony_ci const int isDirect 77557db96d56Sopenharmony_ci = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser); 77567db96d56Sopenharmony_ci const ptrdiff_t bytesMore = after - before; 77577db96d56Sopenharmony_ci 77587db96d56Sopenharmony_ci XmlBigCount *const additionTarget 77597db96d56Sopenharmony_ci = isDirect ? &rootParser->m_accounting.countBytesDirect 77607db96d56Sopenharmony_ci : &rootParser->m_accounting.countBytesIndirect; 77617db96d56Sopenharmony_ci 77627db96d56Sopenharmony_ci /* Detect and avoid integer overflow */ 77637db96d56Sopenharmony_ci if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore) 77647db96d56Sopenharmony_ci return XML_FALSE; 77657db96d56Sopenharmony_ci *additionTarget += bytesMore; 77667db96d56Sopenharmony_ci 77677db96d56Sopenharmony_ci const XmlBigCount countBytesOutput 77687db96d56Sopenharmony_ci = rootParser->m_accounting.countBytesDirect 77697db96d56Sopenharmony_ci + rootParser->m_accounting.countBytesIndirect; 77707db96d56Sopenharmony_ci const float amplificationFactor 77717db96d56Sopenharmony_ci = accountingGetCurrentAmplification(rootParser); 77727db96d56Sopenharmony_ci const XML_Bool tolerated 77737db96d56Sopenharmony_ci = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes) 77747db96d56Sopenharmony_ci || (amplificationFactor 77757db96d56Sopenharmony_ci <= rootParser->m_accounting.maximumAmplificationFactor); 77767db96d56Sopenharmony_ci 77777db96d56Sopenharmony_ci if (rootParser->m_accounting.debugLevel >= 2) { 77787db96d56Sopenharmony_ci accountingReportStats(rootParser, ""); 77797db96d56Sopenharmony_ci accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after, 77807db96d56Sopenharmony_ci bytesMore, source_line, account); 77817db96d56Sopenharmony_ci } 77827db96d56Sopenharmony_ci 77837db96d56Sopenharmony_ci return tolerated; 77847db96d56Sopenharmony_ci} 77857db96d56Sopenharmony_ci 77867db96d56Sopenharmony_ciunsigned long long 77877db96d56Sopenharmony_citestingAccountingGetCountBytesDirect(XML_Parser parser) { 77887db96d56Sopenharmony_ci if (! parser) 77897db96d56Sopenharmony_ci return 0; 77907db96d56Sopenharmony_ci return parser->m_accounting.countBytesDirect; 77917db96d56Sopenharmony_ci} 77927db96d56Sopenharmony_ci 77937db96d56Sopenharmony_ciunsigned long long 77947db96d56Sopenharmony_citestingAccountingGetCountBytesIndirect(XML_Parser parser) { 77957db96d56Sopenharmony_ci if (! parser) 77967db96d56Sopenharmony_ci return 0; 77977db96d56Sopenharmony_ci return parser->m_accounting.countBytesIndirect; 77987db96d56Sopenharmony_ci} 77997db96d56Sopenharmony_ci 78007db96d56Sopenharmony_cistatic void 78017db96d56Sopenharmony_cientityTrackingReportStats(XML_Parser rootParser, ENTITY *entity, 78027db96d56Sopenharmony_ci const char *action, int sourceLine) { 78037db96d56Sopenharmony_ci assert(! rootParser->m_parentParser); 78047db96d56Sopenharmony_ci if (rootParser->m_entity_stats.debugLevel < 1) 78057db96d56Sopenharmony_ci return; 78067db96d56Sopenharmony_ci 78077db96d56Sopenharmony_ci# if defined(XML_UNICODE) 78087db96d56Sopenharmony_ci const char *const entityName = "[..]"; 78097db96d56Sopenharmony_ci# else 78107db96d56Sopenharmony_ci const char *const entityName = entity->name; 78117db96d56Sopenharmony_ci# endif 78127db96d56Sopenharmony_ci 78137db96d56Sopenharmony_ci fprintf( 78147db96d56Sopenharmony_ci stderr, 78157db96d56Sopenharmony_ci "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n", 78167db96d56Sopenharmony_ci (void *)rootParser, rootParser->m_entity_stats.countEverOpened, 78177db96d56Sopenharmony_ci rootParser->m_entity_stats.currentDepth, 78187db96d56Sopenharmony_ci rootParser->m_entity_stats.maximumDepthSeen, 78197db96d56Sopenharmony_ci (rootParser->m_entity_stats.currentDepth - 1) * 2, "", 78207db96d56Sopenharmony_ci entity->is_param ? "%" : "&", entityName, action, entity->textLen, 78217db96d56Sopenharmony_ci sourceLine); 78227db96d56Sopenharmony_ci} 78237db96d56Sopenharmony_ci 78247db96d56Sopenharmony_cistatic void 78257db96d56Sopenharmony_cientityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) { 78267db96d56Sopenharmony_ci const XML_Parser rootParser = getRootParserOf(originParser, NULL); 78277db96d56Sopenharmony_ci assert(! rootParser->m_parentParser); 78287db96d56Sopenharmony_ci 78297db96d56Sopenharmony_ci rootParser->m_entity_stats.countEverOpened++; 78307db96d56Sopenharmony_ci rootParser->m_entity_stats.currentDepth++; 78317db96d56Sopenharmony_ci if (rootParser->m_entity_stats.currentDepth 78327db96d56Sopenharmony_ci > rootParser->m_entity_stats.maximumDepthSeen) { 78337db96d56Sopenharmony_ci rootParser->m_entity_stats.maximumDepthSeen++; 78347db96d56Sopenharmony_ci } 78357db96d56Sopenharmony_ci 78367db96d56Sopenharmony_ci entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine); 78377db96d56Sopenharmony_ci} 78387db96d56Sopenharmony_ci 78397db96d56Sopenharmony_cistatic void 78407db96d56Sopenharmony_cientityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) { 78417db96d56Sopenharmony_ci const XML_Parser rootParser = getRootParserOf(originParser, NULL); 78427db96d56Sopenharmony_ci assert(! rootParser->m_parentParser); 78437db96d56Sopenharmony_ci 78447db96d56Sopenharmony_ci entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine); 78457db96d56Sopenharmony_ci rootParser->m_entity_stats.currentDepth--; 78467db96d56Sopenharmony_ci} 78477db96d56Sopenharmony_ci 78487db96d56Sopenharmony_cistatic XML_Parser 78497db96d56Sopenharmony_cigetRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) { 78507db96d56Sopenharmony_ci XML_Parser rootParser = parser; 78517db96d56Sopenharmony_ci unsigned int stepsTakenUpwards = 0; 78527db96d56Sopenharmony_ci while (rootParser->m_parentParser) { 78537db96d56Sopenharmony_ci rootParser = rootParser->m_parentParser; 78547db96d56Sopenharmony_ci stepsTakenUpwards++; 78557db96d56Sopenharmony_ci } 78567db96d56Sopenharmony_ci assert(! rootParser->m_parentParser); 78577db96d56Sopenharmony_ci if (outLevelDiff != NULL) { 78587db96d56Sopenharmony_ci *outLevelDiff = stepsTakenUpwards; 78597db96d56Sopenharmony_ci } 78607db96d56Sopenharmony_ci return rootParser; 78617db96d56Sopenharmony_ci} 78627db96d56Sopenharmony_ci 78637db96d56Sopenharmony_ciconst char * 78647db96d56Sopenharmony_ciunsignedCharToPrintable(unsigned char c) { 78657db96d56Sopenharmony_ci switch (c) { 78667db96d56Sopenharmony_ci case 0: 78677db96d56Sopenharmony_ci return "\\0"; 78687db96d56Sopenharmony_ci case 1: 78697db96d56Sopenharmony_ci return "\\x1"; 78707db96d56Sopenharmony_ci case 2: 78717db96d56Sopenharmony_ci return "\\x2"; 78727db96d56Sopenharmony_ci case 3: 78737db96d56Sopenharmony_ci return "\\x3"; 78747db96d56Sopenharmony_ci case 4: 78757db96d56Sopenharmony_ci return "\\x4"; 78767db96d56Sopenharmony_ci case 5: 78777db96d56Sopenharmony_ci return "\\x5"; 78787db96d56Sopenharmony_ci case 6: 78797db96d56Sopenharmony_ci return "\\x6"; 78807db96d56Sopenharmony_ci case 7: 78817db96d56Sopenharmony_ci return "\\x7"; 78827db96d56Sopenharmony_ci case 8: 78837db96d56Sopenharmony_ci return "\\x8"; 78847db96d56Sopenharmony_ci case 9: 78857db96d56Sopenharmony_ci return "\\t"; 78867db96d56Sopenharmony_ci case 10: 78877db96d56Sopenharmony_ci return "\\n"; 78887db96d56Sopenharmony_ci case 11: 78897db96d56Sopenharmony_ci return "\\xB"; 78907db96d56Sopenharmony_ci case 12: 78917db96d56Sopenharmony_ci return "\\xC"; 78927db96d56Sopenharmony_ci case 13: 78937db96d56Sopenharmony_ci return "\\r"; 78947db96d56Sopenharmony_ci case 14: 78957db96d56Sopenharmony_ci return "\\xE"; 78967db96d56Sopenharmony_ci case 15: 78977db96d56Sopenharmony_ci return "\\xF"; 78987db96d56Sopenharmony_ci case 16: 78997db96d56Sopenharmony_ci return "\\x10"; 79007db96d56Sopenharmony_ci case 17: 79017db96d56Sopenharmony_ci return "\\x11"; 79027db96d56Sopenharmony_ci case 18: 79037db96d56Sopenharmony_ci return "\\x12"; 79047db96d56Sopenharmony_ci case 19: 79057db96d56Sopenharmony_ci return "\\x13"; 79067db96d56Sopenharmony_ci case 20: 79077db96d56Sopenharmony_ci return "\\x14"; 79087db96d56Sopenharmony_ci case 21: 79097db96d56Sopenharmony_ci return "\\x15"; 79107db96d56Sopenharmony_ci case 22: 79117db96d56Sopenharmony_ci return "\\x16"; 79127db96d56Sopenharmony_ci case 23: 79137db96d56Sopenharmony_ci return "\\x17"; 79147db96d56Sopenharmony_ci case 24: 79157db96d56Sopenharmony_ci return "\\x18"; 79167db96d56Sopenharmony_ci case 25: 79177db96d56Sopenharmony_ci return "\\x19"; 79187db96d56Sopenharmony_ci case 26: 79197db96d56Sopenharmony_ci return "\\x1A"; 79207db96d56Sopenharmony_ci case 27: 79217db96d56Sopenharmony_ci return "\\x1B"; 79227db96d56Sopenharmony_ci case 28: 79237db96d56Sopenharmony_ci return "\\x1C"; 79247db96d56Sopenharmony_ci case 29: 79257db96d56Sopenharmony_ci return "\\x1D"; 79267db96d56Sopenharmony_ci case 30: 79277db96d56Sopenharmony_ci return "\\x1E"; 79287db96d56Sopenharmony_ci case 31: 79297db96d56Sopenharmony_ci return "\\x1F"; 79307db96d56Sopenharmony_ci case 32: 79317db96d56Sopenharmony_ci return " "; 79327db96d56Sopenharmony_ci case 33: 79337db96d56Sopenharmony_ci return "!"; 79347db96d56Sopenharmony_ci case 34: 79357db96d56Sopenharmony_ci return "\\\""; 79367db96d56Sopenharmony_ci case 35: 79377db96d56Sopenharmony_ci return "#"; 79387db96d56Sopenharmony_ci case 36: 79397db96d56Sopenharmony_ci return "$"; 79407db96d56Sopenharmony_ci case 37: 79417db96d56Sopenharmony_ci return "%"; 79427db96d56Sopenharmony_ci case 38: 79437db96d56Sopenharmony_ci return "&"; 79447db96d56Sopenharmony_ci case 39: 79457db96d56Sopenharmony_ci return "'"; 79467db96d56Sopenharmony_ci case 40: 79477db96d56Sopenharmony_ci return "("; 79487db96d56Sopenharmony_ci case 41: 79497db96d56Sopenharmony_ci return ")"; 79507db96d56Sopenharmony_ci case 42: 79517db96d56Sopenharmony_ci return "*"; 79527db96d56Sopenharmony_ci case 43: 79537db96d56Sopenharmony_ci return "+"; 79547db96d56Sopenharmony_ci case 44: 79557db96d56Sopenharmony_ci return ","; 79567db96d56Sopenharmony_ci case 45: 79577db96d56Sopenharmony_ci return "-"; 79587db96d56Sopenharmony_ci case 46: 79597db96d56Sopenharmony_ci return "."; 79607db96d56Sopenharmony_ci case 47: 79617db96d56Sopenharmony_ci return "/"; 79627db96d56Sopenharmony_ci case 48: 79637db96d56Sopenharmony_ci return "0"; 79647db96d56Sopenharmony_ci case 49: 79657db96d56Sopenharmony_ci return "1"; 79667db96d56Sopenharmony_ci case 50: 79677db96d56Sopenharmony_ci return "2"; 79687db96d56Sopenharmony_ci case 51: 79697db96d56Sopenharmony_ci return "3"; 79707db96d56Sopenharmony_ci case 52: 79717db96d56Sopenharmony_ci return "4"; 79727db96d56Sopenharmony_ci case 53: 79737db96d56Sopenharmony_ci return "5"; 79747db96d56Sopenharmony_ci case 54: 79757db96d56Sopenharmony_ci return "6"; 79767db96d56Sopenharmony_ci case 55: 79777db96d56Sopenharmony_ci return "7"; 79787db96d56Sopenharmony_ci case 56: 79797db96d56Sopenharmony_ci return "8"; 79807db96d56Sopenharmony_ci case 57: 79817db96d56Sopenharmony_ci return "9"; 79827db96d56Sopenharmony_ci case 58: 79837db96d56Sopenharmony_ci return ":"; 79847db96d56Sopenharmony_ci case 59: 79857db96d56Sopenharmony_ci return ";"; 79867db96d56Sopenharmony_ci case 60: 79877db96d56Sopenharmony_ci return "<"; 79887db96d56Sopenharmony_ci case 61: 79897db96d56Sopenharmony_ci return "="; 79907db96d56Sopenharmony_ci case 62: 79917db96d56Sopenharmony_ci return ">"; 79927db96d56Sopenharmony_ci case 63: 79937db96d56Sopenharmony_ci return "?"; 79947db96d56Sopenharmony_ci case 64: 79957db96d56Sopenharmony_ci return "@"; 79967db96d56Sopenharmony_ci case 65: 79977db96d56Sopenharmony_ci return "A"; 79987db96d56Sopenharmony_ci case 66: 79997db96d56Sopenharmony_ci return "B"; 80007db96d56Sopenharmony_ci case 67: 80017db96d56Sopenharmony_ci return "C"; 80027db96d56Sopenharmony_ci case 68: 80037db96d56Sopenharmony_ci return "D"; 80047db96d56Sopenharmony_ci case 69: 80057db96d56Sopenharmony_ci return "E"; 80067db96d56Sopenharmony_ci case 70: 80077db96d56Sopenharmony_ci return "F"; 80087db96d56Sopenharmony_ci case 71: 80097db96d56Sopenharmony_ci return "G"; 80107db96d56Sopenharmony_ci case 72: 80117db96d56Sopenharmony_ci return "H"; 80127db96d56Sopenharmony_ci case 73: 80137db96d56Sopenharmony_ci return "I"; 80147db96d56Sopenharmony_ci case 74: 80157db96d56Sopenharmony_ci return "J"; 80167db96d56Sopenharmony_ci case 75: 80177db96d56Sopenharmony_ci return "K"; 80187db96d56Sopenharmony_ci case 76: 80197db96d56Sopenharmony_ci return "L"; 80207db96d56Sopenharmony_ci case 77: 80217db96d56Sopenharmony_ci return "M"; 80227db96d56Sopenharmony_ci case 78: 80237db96d56Sopenharmony_ci return "N"; 80247db96d56Sopenharmony_ci case 79: 80257db96d56Sopenharmony_ci return "O"; 80267db96d56Sopenharmony_ci case 80: 80277db96d56Sopenharmony_ci return "P"; 80287db96d56Sopenharmony_ci case 81: 80297db96d56Sopenharmony_ci return "Q"; 80307db96d56Sopenharmony_ci case 82: 80317db96d56Sopenharmony_ci return "R"; 80327db96d56Sopenharmony_ci case 83: 80337db96d56Sopenharmony_ci return "S"; 80347db96d56Sopenharmony_ci case 84: 80357db96d56Sopenharmony_ci return "T"; 80367db96d56Sopenharmony_ci case 85: 80377db96d56Sopenharmony_ci return "U"; 80387db96d56Sopenharmony_ci case 86: 80397db96d56Sopenharmony_ci return "V"; 80407db96d56Sopenharmony_ci case 87: 80417db96d56Sopenharmony_ci return "W"; 80427db96d56Sopenharmony_ci case 88: 80437db96d56Sopenharmony_ci return "X"; 80447db96d56Sopenharmony_ci case 89: 80457db96d56Sopenharmony_ci return "Y"; 80467db96d56Sopenharmony_ci case 90: 80477db96d56Sopenharmony_ci return "Z"; 80487db96d56Sopenharmony_ci case 91: 80497db96d56Sopenharmony_ci return "["; 80507db96d56Sopenharmony_ci case 92: 80517db96d56Sopenharmony_ci return "\\\\"; 80527db96d56Sopenharmony_ci case 93: 80537db96d56Sopenharmony_ci return "]"; 80547db96d56Sopenharmony_ci case 94: 80557db96d56Sopenharmony_ci return "^"; 80567db96d56Sopenharmony_ci case 95: 80577db96d56Sopenharmony_ci return "_"; 80587db96d56Sopenharmony_ci case 96: 80597db96d56Sopenharmony_ci return "`"; 80607db96d56Sopenharmony_ci case 97: 80617db96d56Sopenharmony_ci return "a"; 80627db96d56Sopenharmony_ci case 98: 80637db96d56Sopenharmony_ci return "b"; 80647db96d56Sopenharmony_ci case 99: 80657db96d56Sopenharmony_ci return "c"; 80667db96d56Sopenharmony_ci case 100: 80677db96d56Sopenharmony_ci return "d"; 80687db96d56Sopenharmony_ci case 101: 80697db96d56Sopenharmony_ci return "e"; 80707db96d56Sopenharmony_ci case 102: 80717db96d56Sopenharmony_ci return "f"; 80727db96d56Sopenharmony_ci case 103: 80737db96d56Sopenharmony_ci return "g"; 80747db96d56Sopenharmony_ci case 104: 80757db96d56Sopenharmony_ci return "h"; 80767db96d56Sopenharmony_ci case 105: 80777db96d56Sopenharmony_ci return "i"; 80787db96d56Sopenharmony_ci case 106: 80797db96d56Sopenharmony_ci return "j"; 80807db96d56Sopenharmony_ci case 107: 80817db96d56Sopenharmony_ci return "k"; 80827db96d56Sopenharmony_ci case 108: 80837db96d56Sopenharmony_ci return "l"; 80847db96d56Sopenharmony_ci case 109: 80857db96d56Sopenharmony_ci return "m"; 80867db96d56Sopenharmony_ci case 110: 80877db96d56Sopenharmony_ci return "n"; 80887db96d56Sopenharmony_ci case 111: 80897db96d56Sopenharmony_ci return "o"; 80907db96d56Sopenharmony_ci case 112: 80917db96d56Sopenharmony_ci return "p"; 80927db96d56Sopenharmony_ci case 113: 80937db96d56Sopenharmony_ci return "q"; 80947db96d56Sopenharmony_ci case 114: 80957db96d56Sopenharmony_ci return "r"; 80967db96d56Sopenharmony_ci case 115: 80977db96d56Sopenharmony_ci return "s"; 80987db96d56Sopenharmony_ci case 116: 80997db96d56Sopenharmony_ci return "t"; 81007db96d56Sopenharmony_ci case 117: 81017db96d56Sopenharmony_ci return "u"; 81027db96d56Sopenharmony_ci case 118: 81037db96d56Sopenharmony_ci return "v"; 81047db96d56Sopenharmony_ci case 119: 81057db96d56Sopenharmony_ci return "w"; 81067db96d56Sopenharmony_ci case 120: 81077db96d56Sopenharmony_ci return "x"; 81087db96d56Sopenharmony_ci case 121: 81097db96d56Sopenharmony_ci return "y"; 81107db96d56Sopenharmony_ci case 122: 81117db96d56Sopenharmony_ci return "z"; 81127db96d56Sopenharmony_ci case 123: 81137db96d56Sopenharmony_ci return "{"; 81147db96d56Sopenharmony_ci case 124: 81157db96d56Sopenharmony_ci return "|"; 81167db96d56Sopenharmony_ci case 125: 81177db96d56Sopenharmony_ci return "}"; 81187db96d56Sopenharmony_ci case 126: 81197db96d56Sopenharmony_ci return "~"; 81207db96d56Sopenharmony_ci case 127: 81217db96d56Sopenharmony_ci return "\\x7F"; 81227db96d56Sopenharmony_ci case 128: 81237db96d56Sopenharmony_ci return "\\x80"; 81247db96d56Sopenharmony_ci case 129: 81257db96d56Sopenharmony_ci return "\\x81"; 81267db96d56Sopenharmony_ci case 130: 81277db96d56Sopenharmony_ci return "\\x82"; 81287db96d56Sopenharmony_ci case 131: 81297db96d56Sopenharmony_ci return "\\x83"; 81307db96d56Sopenharmony_ci case 132: 81317db96d56Sopenharmony_ci return "\\x84"; 81327db96d56Sopenharmony_ci case 133: 81337db96d56Sopenharmony_ci return "\\x85"; 81347db96d56Sopenharmony_ci case 134: 81357db96d56Sopenharmony_ci return "\\x86"; 81367db96d56Sopenharmony_ci case 135: 81377db96d56Sopenharmony_ci return "\\x87"; 81387db96d56Sopenharmony_ci case 136: 81397db96d56Sopenharmony_ci return "\\x88"; 81407db96d56Sopenharmony_ci case 137: 81417db96d56Sopenharmony_ci return "\\x89"; 81427db96d56Sopenharmony_ci case 138: 81437db96d56Sopenharmony_ci return "\\x8A"; 81447db96d56Sopenharmony_ci case 139: 81457db96d56Sopenharmony_ci return "\\x8B"; 81467db96d56Sopenharmony_ci case 140: 81477db96d56Sopenharmony_ci return "\\x8C"; 81487db96d56Sopenharmony_ci case 141: 81497db96d56Sopenharmony_ci return "\\x8D"; 81507db96d56Sopenharmony_ci case 142: 81517db96d56Sopenharmony_ci return "\\x8E"; 81527db96d56Sopenharmony_ci case 143: 81537db96d56Sopenharmony_ci return "\\x8F"; 81547db96d56Sopenharmony_ci case 144: 81557db96d56Sopenharmony_ci return "\\x90"; 81567db96d56Sopenharmony_ci case 145: 81577db96d56Sopenharmony_ci return "\\x91"; 81587db96d56Sopenharmony_ci case 146: 81597db96d56Sopenharmony_ci return "\\x92"; 81607db96d56Sopenharmony_ci case 147: 81617db96d56Sopenharmony_ci return "\\x93"; 81627db96d56Sopenharmony_ci case 148: 81637db96d56Sopenharmony_ci return "\\x94"; 81647db96d56Sopenharmony_ci case 149: 81657db96d56Sopenharmony_ci return "\\x95"; 81667db96d56Sopenharmony_ci case 150: 81677db96d56Sopenharmony_ci return "\\x96"; 81687db96d56Sopenharmony_ci case 151: 81697db96d56Sopenharmony_ci return "\\x97"; 81707db96d56Sopenharmony_ci case 152: 81717db96d56Sopenharmony_ci return "\\x98"; 81727db96d56Sopenharmony_ci case 153: 81737db96d56Sopenharmony_ci return "\\x99"; 81747db96d56Sopenharmony_ci case 154: 81757db96d56Sopenharmony_ci return "\\x9A"; 81767db96d56Sopenharmony_ci case 155: 81777db96d56Sopenharmony_ci return "\\x9B"; 81787db96d56Sopenharmony_ci case 156: 81797db96d56Sopenharmony_ci return "\\x9C"; 81807db96d56Sopenharmony_ci case 157: 81817db96d56Sopenharmony_ci return "\\x9D"; 81827db96d56Sopenharmony_ci case 158: 81837db96d56Sopenharmony_ci return "\\x9E"; 81847db96d56Sopenharmony_ci case 159: 81857db96d56Sopenharmony_ci return "\\x9F"; 81867db96d56Sopenharmony_ci case 160: 81877db96d56Sopenharmony_ci return "\\xA0"; 81887db96d56Sopenharmony_ci case 161: 81897db96d56Sopenharmony_ci return "\\xA1"; 81907db96d56Sopenharmony_ci case 162: 81917db96d56Sopenharmony_ci return "\\xA2"; 81927db96d56Sopenharmony_ci case 163: 81937db96d56Sopenharmony_ci return "\\xA3"; 81947db96d56Sopenharmony_ci case 164: 81957db96d56Sopenharmony_ci return "\\xA4"; 81967db96d56Sopenharmony_ci case 165: 81977db96d56Sopenharmony_ci return "\\xA5"; 81987db96d56Sopenharmony_ci case 166: 81997db96d56Sopenharmony_ci return "\\xA6"; 82007db96d56Sopenharmony_ci case 167: 82017db96d56Sopenharmony_ci return "\\xA7"; 82027db96d56Sopenharmony_ci case 168: 82037db96d56Sopenharmony_ci return "\\xA8"; 82047db96d56Sopenharmony_ci case 169: 82057db96d56Sopenharmony_ci return "\\xA9"; 82067db96d56Sopenharmony_ci case 170: 82077db96d56Sopenharmony_ci return "\\xAA"; 82087db96d56Sopenharmony_ci case 171: 82097db96d56Sopenharmony_ci return "\\xAB"; 82107db96d56Sopenharmony_ci case 172: 82117db96d56Sopenharmony_ci return "\\xAC"; 82127db96d56Sopenharmony_ci case 173: 82137db96d56Sopenharmony_ci return "\\xAD"; 82147db96d56Sopenharmony_ci case 174: 82157db96d56Sopenharmony_ci return "\\xAE"; 82167db96d56Sopenharmony_ci case 175: 82177db96d56Sopenharmony_ci return "\\xAF"; 82187db96d56Sopenharmony_ci case 176: 82197db96d56Sopenharmony_ci return "\\xB0"; 82207db96d56Sopenharmony_ci case 177: 82217db96d56Sopenharmony_ci return "\\xB1"; 82227db96d56Sopenharmony_ci case 178: 82237db96d56Sopenharmony_ci return "\\xB2"; 82247db96d56Sopenharmony_ci case 179: 82257db96d56Sopenharmony_ci return "\\xB3"; 82267db96d56Sopenharmony_ci case 180: 82277db96d56Sopenharmony_ci return "\\xB4"; 82287db96d56Sopenharmony_ci case 181: 82297db96d56Sopenharmony_ci return "\\xB5"; 82307db96d56Sopenharmony_ci case 182: 82317db96d56Sopenharmony_ci return "\\xB6"; 82327db96d56Sopenharmony_ci case 183: 82337db96d56Sopenharmony_ci return "\\xB7"; 82347db96d56Sopenharmony_ci case 184: 82357db96d56Sopenharmony_ci return "\\xB8"; 82367db96d56Sopenharmony_ci case 185: 82377db96d56Sopenharmony_ci return "\\xB9"; 82387db96d56Sopenharmony_ci case 186: 82397db96d56Sopenharmony_ci return "\\xBA"; 82407db96d56Sopenharmony_ci case 187: 82417db96d56Sopenharmony_ci return "\\xBB"; 82427db96d56Sopenharmony_ci case 188: 82437db96d56Sopenharmony_ci return "\\xBC"; 82447db96d56Sopenharmony_ci case 189: 82457db96d56Sopenharmony_ci return "\\xBD"; 82467db96d56Sopenharmony_ci case 190: 82477db96d56Sopenharmony_ci return "\\xBE"; 82487db96d56Sopenharmony_ci case 191: 82497db96d56Sopenharmony_ci return "\\xBF"; 82507db96d56Sopenharmony_ci case 192: 82517db96d56Sopenharmony_ci return "\\xC0"; 82527db96d56Sopenharmony_ci case 193: 82537db96d56Sopenharmony_ci return "\\xC1"; 82547db96d56Sopenharmony_ci case 194: 82557db96d56Sopenharmony_ci return "\\xC2"; 82567db96d56Sopenharmony_ci case 195: 82577db96d56Sopenharmony_ci return "\\xC3"; 82587db96d56Sopenharmony_ci case 196: 82597db96d56Sopenharmony_ci return "\\xC4"; 82607db96d56Sopenharmony_ci case 197: 82617db96d56Sopenharmony_ci return "\\xC5"; 82627db96d56Sopenharmony_ci case 198: 82637db96d56Sopenharmony_ci return "\\xC6"; 82647db96d56Sopenharmony_ci case 199: 82657db96d56Sopenharmony_ci return "\\xC7"; 82667db96d56Sopenharmony_ci case 200: 82677db96d56Sopenharmony_ci return "\\xC8"; 82687db96d56Sopenharmony_ci case 201: 82697db96d56Sopenharmony_ci return "\\xC9"; 82707db96d56Sopenharmony_ci case 202: 82717db96d56Sopenharmony_ci return "\\xCA"; 82727db96d56Sopenharmony_ci case 203: 82737db96d56Sopenharmony_ci return "\\xCB"; 82747db96d56Sopenharmony_ci case 204: 82757db96d56Sopenharmony_ci return "\\xCC"; 82767db96d56Sopenharmony_ci case 205: 82777db96d56Sopenharmony_ci return "\\xCD"; 82787db96d56Sopenharmony_ci case 206: 82797db96d56Sopenharmony_ci return "\\xCE"; 82807db96d56Sopenharmony_ci case 207: 82817db96d56Sopenharmony_ci return "\\xCF"; 82827db96d56Sopenharmony_ci case 208: 82837db96d56Sopenharmony_ci return "\\xD0"; 82847db96d56Sopenharmony_ci case 209: 82857db96d56Sopenharmony_ci return "\\xD1"; 82867db96d56Sopenharmony_ci case 210: 82877db96d56Sopenharmony_ci return "\\xD2"; 82887db96d56Sopenharmony_ci case 211: 82897db96d56Sopenharmony_ci return "\\xD3"; 82907db96d56Sopenharmony_ci case 212: 82917db96d56Sopenharmony_ci return "\\xD4"; 82927db96d56Sopenharmony_ci case 213: 82937db96d56Sopenharmony_ci return "\\xD5"; 82947db96d56Sopenharmony_ci case 214: 82957db96d56Sopenharmony_ci return "\\xD6"; 82967db96d56Sopenharmony_ci case 215: 82977db96d56Sopenharmony_ci return "\\xD7"; 82987db96d56Sopenharmony_ci case 216: 82997db96d56Sopenharmony_ci return "\\xD8"; 83007db96d56Sopenharmony_ci case 217: 83017db96d56Sopenharmony_ci return "\\xD9"; 83027db96d56Sopenharmony_ci case 218: 83037db96d56Sopenharmony_ci return "\\xDA"; 83047db96d56Sopenharmony_ci case 219: 83057db96d56Sopenharmony_ci return "\\xDB"; 83067db96d56Sopenharmony_ci case 220: 83077db96d56Sopenharmony_ci return "\\xDC"; 83087db96d56Sopenharmony_ci case 221: 83097db96d56Sopenharmony_ci return "\\xDD"; 83107db96d56Sopenharmony_ci case 222: 83117db96d56Sopenharmony_ci return "\\xDE"; 83127db96d56Sopenharmony_ci case 223: 83137db96d56Sopenharmony_ci return "\\xDF"; 83147db96d56Sopenharmony_ci case 224: 83157db96d56Sopenharmony_ci return "\\xE0"; 83167db96d56Sopenharmony_ci case 225: 83177db96d56Sopenharmony_ci return "\\xE1"; 83187db96d56Sopenharmony_ci case 226: 83197db96d56Sopenharmony_ci return "\\xE2"; 83207db96d56Sopenharmony_ci case 227: 83217db96d56Sopenharmony_ci return "\\xE3"; 83227db96d56Sopenharmony_ci case 228: 83237db96d56Sopenharmony_ci return "\\xE4"; 83247db96d56Sopenharmony_ci case 229: 83257db96d56Sopenharmony_ci return "\\xE5"; 83267db96d56Sopenharmony_ci case 230: 83277db96d56Sopenharmony_ci return "\\xE6"; 83287db96d56Sopenharmony_ci case 231: 83297db96d56Sopenharmony_ci return "\\xE7"; 83307db96d56Sopenharmony_ci case 232: 83317db96d56Sopenharmony_ci return "\\xE8"; 83327db96d56Sopenharmony_ci case 233: 83337db96d56Sopenharmony_ci return "\\xE9"; 83347db96d56Sopenharmony_ci case 234: 83357db96d56Sopenharmony_ci return "\\xEA"; 83367db96d56Sopenharmony_ci case 235: 83377db96d56Sopenharmony_ci return "\\xEB"; 83387db96d56Sopenharmony_ci case 236: 83397db96d56Sopenharmony_ci return "\\xEC"; 83407db96d56Sopenharmony_ci case 237: 83417db96d56Sopenharmony_ci return "\\xED"; 83427db96d56Sopenharmony_ci case 238: 83437db96d56Sopenharmony_ci return "\\xEE"; 83447db96d56Sopenharmony_ci case 239: 83457db96d56Sopenharmony_ci return "\\xEF"; 83467db96d56Sopenharmony_ci case 240: 83477db96d56Sopenharmony_ci return "\\xF0"; 83487db96d56Sopenharmony_ci case 241: 83497db96d56Sopenharmony_ci return "\\xF1"; 83507db96d56Sopenharmony_ci case 242: 83517db96d56Sopenharmony_ci return "\\xF2"; 83527db96d56Sopenharmony_ci case 243: 83537db96d56Sopenharmony_ci return "\\xF3"; 83547db96d56Sopenharmony_ci case 244: 83557db96d56Sopenharmony_ci return "\\xF4"; 83567db96d56Sopenharmony_ci case 245: 83577db96d56Sopenharmony_ci return "\\xF5"; 83587db96d56Sopenharmony_ci case 246: 83597db96d56Sopenharmony_ci return "\\xF6"; 83607db96d56Sopenharmony_ci case 247: 83617db96d56Sopenharmony_ci return "\\xF7"; 83627db96d56Sopenharmony_ci case 248: 83637db96d56Sopenharmony_ci return "\\xF8"; 83647db96d56Sopenharmony_ci case 249: 83657db96d56Sopenharmony_ci return "\\xF9"; 83667db96d56Sopenharmony_ci case 250: 83677db96d56Sopenharmony_ci return "\\xFA"; 83687db96d56Sopenharmony_ci case 251: 83697db96d56Sopenharmony_ci return "\\xFB"; 83707db96d56Sopenharmony_ci case 252: 83717db96d56Sopenharmony_ci return "\\xFC"; 83727db96d56Sopenharmony_ci case 253: 83737db96d56Sopenharmony_ci return "\\xFD"; 83747db96d56Sopenharmony_ci case 254: 83757db96d56Sopenharmony_ci return "\\xFE"; 83767db96d56Sopenharmony_ci case 255: 83777db96d56Sopenharmony_ci return "\\xFF"; 83787db96d56Sopenharmony_ci default: 83797db96d56Sopenharmony_ci assert(0); /* never gets here */ 83807db96d56Sopenharmony_ci return "dead code"; 83817db96d56Sopenharmony_ci } 83827db96d56Sopenharmony_ci assert(0); /* never gets here */ 83837db96d56Sopenharmony_ci} 83847db96d56Sopenharmony_ci 83857db96d56Sopenharmony_ci#endif /* XML_DTD */ 83867db96d56Sopenharmony_ci 83877db96d56Sopenharmony_cistatic unsigned long 83887db96d56Sopenharmony_cigetDebugLevel(const char *variableName, unsigned long defaultDebugLevel) { 83897db96d56Sopenharmony_ci const char *const valueOrNull = getenv(variableName); 83907db96d56Sopenharmony_ci if (valueOrNull == NULL) { 83917db96d56Sopenharmony_ci return defaultDebugLevel; 83927db96d56Sopenharmony_ci } 83937db96d56Sopenharmony_ci const char *const value = valueOrNull; 83947db96d56Sopenharmony_ci 83957db96d56Sopenharmony_ci errno = 0; 83967db96d56Sopenharmony_ci char *afterValue = (char *)value; 83977db96d56Sopenharmony_ci unsigned long debugLevel = strtoul(value, &afterValue, 10); 83987db96d56Sopenharmony_ci if ((errno != 0) || (afterValue[0] != '\0')) { 83997db96d56Sopenharmony_ci errno = 0; 84007db96d56Sopenharmony_ci return defaultDebugLevel; 84017db96d56Sopenharmony_ci } 84027db96d56Sopenharmony_ci 84037db96d56Sopenharmony_ci return debugLevel; 84047db96d56Sopenharmony_ci} 8405