Geant4 Cross Reference |
1 /* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065 1 /* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065e42784e001db4f23de324 (2.4.9+) 2 __ __ 2 __ __ _ 3 ___\ \/ /_ __ __ _| 3 ___\ \/ /_ __ __ _| |_ 4 / _ \\ /| '_ \ / _` | 4 / _ \\ /| '_ \ / _` | __| 5 | __// \| |_) | (_| | 5 | __// \| |_) | (_| | |_ 6 \___/_/\_\ .__/ \__,_| 6 \___/_/\_\ .__/ \__,_|\__| 7 |_| XML parse 7 |_| XML parser 8 8 9 Copyright (c) 1997-2000 Thai Open Source So 9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 Copyright (c) 2000 Clark Cooper <coope 10 Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net> 11 Copyright (c) 2000-2006 Fred L. Drake, Jr. 11 Copyright (c) 2000-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net> 12 Copyright (c) 2001-2002 Greg Stein <gstein@ 12 Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net> 13 Copyright (c) 2002-2016 Karl Waclawek <karl 13 Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net> 14 Copyright (c) 2005-2009 Steven Solie <steve 14 Copyright (c) 2005-2009 Steven Solie <steven@solie.ca> 15 Copyright (c) 2016 Eric Rahm <erahm@mo 15 Copyright (c) 2016 Eric Rahm <erahm@mozilla.com> 16 Copyright (c) 2016-2022 Sebastian Pipping < 16 Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org> 17 Copyright (c) 2016 Gaurav <g.gupta@sam 17 Copyright (c) 2016 Gaurav <g.gupta@samsung.com> 18 Copyright (c) 2016 Thomas Beutlich <tc 18 Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de> 19 Copyright (c) 2016 Gustavo Grieco <gus 19 Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr> 20 Copyright (c) 2016 Pascal Cuoq <cuoq@t 20 Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com> 21 Copyright (c) 2016 Ed Schouten <ed@nux 21 Copyright (c) 2016 Ed Schouten <ed@nuxi.nl> 22 Copyright (c) 2017-2022 Rhodri James <rhodr 22 Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk> 23 Copyright (c) 2017 Václav Slavík <va 23 Copyright (c) 2017 Václav Slavík <vaclav@slavik.io> 24 Copyright (c) 2017 Viktor Szakats <com 24 Copyright (c) 2017 Viktor Szakats <commit@vsz.me> 25 Copyright (c) 2017 Chanho Park <chanho 25 Copyright (c) 2017 Chanho Park <chanho61.park@samsung.com> 26 Copyright (c) 2017 Rolf Eike Beer <eik 26 Copyright (c) 2017 Rolf Eike Beer <eike@sf-mail.de> 27 Copyright (c) 2017 Hans Wennborg <hans 27 Copyright (c) 2017 Hans Wennborg <hans@chromium.org> 28 Copyright (c) 2018 Anton Maklakov <ant 28 Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com> 29 Copyright (c) 2018 Benjamin Peterson < 29 Copyright (c) 2018 Benjamin Peterson <benjamin@python.org> 30 Copyright (c) 2018 Marco Maggi <marco. 30 Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it> 31 Copyright (c) 2018 Mariusz Zaborski <o 31 Copyright (c) 2018 Mariusz Zaborski <oshogbo@vexillium.org> 32 Copyright (c) 2019 David Loffredo <lof 32 Copyright (c) 2019 David Loffredo <loffredo@steptools.com> 33 Copyright (c) 2019-2020 Ben Wagner <bungema 33 Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org> 34 Copyright (c) 2019 Vadim Zeitlin <vadi 34 Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org> 35 Copyright (c) 2021 Dong-hee Na <donghe 35 Copyright (c) 2021 Dong-hee Na <donghee.na@python.org> 36 Copyright (c) 2022 Samanta Navarro <fe 36 Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net> 37 Copyright (c) 2022 Jeffrey Walton <nol 37 Copyright (c) 2022 Jeffrey Walton <noloader@gmail.com> 38 Licensed under the MIT license: 38 Licensed under the MIT license: 39 39 40 Permission is hereby granted, free of cha 40 Permission is hereby granted, free of charge, to any person obtaining 41 a copy of this software and associat 41 a copy of this software and associated documentation files (the 42 "Software"), to deal in the Software w 42 "Software"), to deal in the Software without restriction, including 43 without limitation the rights to use, c 43 without limitation the rights to use, copy, modify, merge, publish, 44 distribute, sublicense, and/or sell copies 44 distribute, sublicense, and/or sell copies of the Software, and to permit 45 persons to whom the Software is furnish 45 persons to whom the Software is furnished to do so, subject to the 46 following conditions: 46 following conditions: 47 47 48 The above copyright notice and this permis 48 The above copyright notice and this permission notice shall be included 49 in all copies or substantial portions of th 49 in all copies or substantial portions of the Software. 50 50 51 THE SOFTWARE IS PROVIDED "AS IS", WIT 51 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 52 EXPRESS OR IMPLIED, INCLUDING BUT NOT L 52 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 53 MERCHANTABILITY, FITNESS FOR A PARTICULAR P 53 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 54 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HO 54 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 55 DAMAGES OR OTHER LIABILITY, WHETHER IN AN 55 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 56 OTHERWISE, ARISING FROM, OUT OF OR IN CONNE 56 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 57 USE OR OTHER DEALINGS IN THE SOFTWARE. 57 USE OR OTHER DEALINGS IN THE SOFTWARE. 58 */ 58 */ 59 59 60 #define XML_BUILDING_EXPAT 1 60 #define XML_BUILDING_EXPAT 1 61 61 62 #include <expat_config.h> 62 #include <expat_config.h> 63 63 64 #if ! defined(_GNU_SOURCE) 64 #if ! defined(_GNU_SOURCE) 65 # define _GNU_SOURCE 1 /* syscall prototype * 65 # define _GNU_SOURCE 1 /* syscall prototype */ 66 #endif 66 #endif 67 67 68 #ifdef _WIN32 68 #ifdef _WIN32 69 /* force stdlib to define rand_s() */ 69 /* force stdlib to define rand_s() */ 70 # if ! defined(_CRT_RAND_S) 70 # if ! defined(_CRT_RAND_S) 71 # define _CRT_RAND_S 71 # define _CRT_RAND_S 72 # endif 72 # endif 73 #endif 73 #endif 74 74 75 #include <stddef.h> 75 #include <stddef.h> 76 #include <string.h> /* memset(), memcpy() */ 76 #include <string.h> /* memset(), memcpy() */ 77 #include <assert.h> 77 #include <assert.h> 78 #include <limits.h> /* UINT_MAX */ 78 #include <limits.h> /* UINT_MAX */ 79 #include <stdio.h> /* fprintf */ 79 #include <stdio.h> /* fprintf */ 80 #include <stdlib.h> /* getenv, rand_s */ 80 #include <stdlib.h> /* getenv, rand_s */ 81 #include <stdint.h> /* uintptr_t */ 81 #include <stdint.h> /* uintptr_t */ 82 #include <math.h> /* isnan */ 82 #include <math.h> /* isnan */ 83 83 84 #ifdef _WIN32 84 #ifdef _WIN32 85 # define getpid GetCurrentProcessId 85 # define getpid GetCurrentProcessId 86 #else 86 #else 87 # include <sys/time.h> /* gettimeofday() */ 87 # include <sys/time.h> /* gettimeofday() */ 88 # include <sys/types.h> /* getpid() */ 88 # include <sys/types.h> /* getpid() */ 89 # include <unistd.h> /* getpid() */ 89 # include <unistd.h> /* getpid() */ 90 # include <fcntl.h> /* O_RDONLY */ 90 # include <fcntl.h> /* O_RDONLY */ 91 # include <errno.h> 91 # include <errno.h> 92 #endif 92 #endif 93 93 94 #ifdef _WIN32 94 #ifdef _WIN32 95 # include "winconfig.h" 95 # include "winconfig.h" 96 #endif 96 #endif 97 97 98 #include "ascii.h" 98 #include "ascii.h" 99 #include "expat.h" 99 #include "expat.h" 100 #include "siphash.h" 100 #include "siphash.h" 101 101 102 #if defined(HAVE_GETRANDOM) || defined(HAVE_SY 102 #if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 103 # if defined(HAVE_GETRANDOM) 103 # if defined(HAVE_GETRANDOM) 104 # include <sys/random.h> /* getrandom */ 104 # include <sys/random.h> /* getrandom */ 105 # else 105 # else 106 # include <unistd.h> /* syscall */ 106 # include <unistd.h> /* syscall */ 107 # include <sys/syscall.h> /* SYS_getrandom 107 # include <sys/syscall.h> /* SYS_getrandom */ 108 # endif 108 # endif 109 # if ! defined(GRND_NONBLOCK) 109 # if ! defined(GRND_NONBLOCK) 110 # define GRND_NONBLOCK 0x0001 110 # define GRND_NONBLOCK 0x0001 111 # endif /* defined(GRND_NONBLOCK) */ 111 # endif /* defined(GRND_NONBLOCK) */ 112 #endif /* defined(HAVE_GETRANDOM) || defined 112 #endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ 113 113 114 #if defined(HAVE_LIBBSD) 114 #if defined(HAVE_LIBBSD) \ 115 && (defined(HAVE_ARC4RANDOM_BUF) || define 115 && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM)) 116 # include <bsd/stdlib.h> 116 # include <bsd/stdlib.h> 117 #endif 117 #endif 118 118 119 #if defined(_WIN32) && ! defined(LOAD_LIBRARY_ 119 #if defined(_WIN32) && ! defined(LOAD_LIBRARY_SEARCH_SYSTEM32) 120 # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000 120 # define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 121 #endif 121 #endif 122 122 123 #if ! defined(HAVE_GETRANDOM) && ! defined(HAV 123 #if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \ 124 && ! defined(HAVE_ARC4RANDOM_BUF) && ! def 124 && ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) \ 125 && ! defined(XML_DEV_URANDOM) && ! defined 125 && ! defined(XML_DEV_URANDOM) && ! defined(_WIN32) \ 126 && ! defined(XML_POOR_ENTROPY) 126 && ! defined(XML_POOR_ENTROPY) 127 # error You do not have support for any sourc 127 # error You do not have support for any sources of high quality entropy \ 128 enabled. For end user security, that is p 128 enabled. For end user security, that is probably not what you want. \ 129 \ 129 \ 130 Your options include: \ 130 Your options include: \ 131 * Linux >=3.17 + glibc >=2.25 (getrandom 131 * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \ 132 * Linux >=3.17 + glibc (including <2.25) 132 * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \ 133 * BSD / macOS >=10.7 (arc4random_buf): H 133 * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \ 134 * BSD / macOS (including <10.7) (arc4ran 134 * BSD / macOS (including <10.7) (arc4random): HAVE_ARC4RANDOM, \ 135 * libbsd (arc4random_buf): HAVE_ARC4RAND 135 * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \ 136 * libbsd (arc4random): HAVE_ARC4RANDOM + 136 * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \ 137 * Linux (including <3.17) / BSD / macOS 137 * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \ 138 * Windows >=Vista (rand_s): _WIN32. \ 138 * Windows >=Vista (rand_s): _WIN32. \ 139 \ 139 \ 140 If insist on not using any of these, bypas 140 If insist on not using any of these, bypass this error by defining \ 141 XML_POOR_ENTROPY; you have been warned. \ 141 XML_POOR_ENTROPY; you have been warned. \ 142 \ 142 \ 143 If you have reasons to patch this detectio 143 If you have reasons to patch this detection code away or need changes \ 144 to the build system, please open a bug. T 144 to the build system, please open a bug. Thank you! 145 #endif 145 #endif 146 146 147 #ifdef XML_UNICODE 147 #ifdef XML_UNICODE 148 # define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX 148 # define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX 149 # define XmlConvert XmlUtf16Convert 149 # define XmlConvert XmlUtf16Convert 150 # define XmlGetInternalEncoding XmlGetUtf16In 150 # define XmlGetInternalEncoding XmlGetUtf16InternalEncoding 151 # define XmlGetInternalEncodingNS XmlGetUtf16 151 # define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS 152 # define XmlEncode XmlUtf16Encode 152 # define XmlEncode XmlUtf16Encode 153 # define MUST_CONVERT(enc, s) (! (enc)->isUtf 153 # define MUST_CONVERT(enc, s) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1)) 154 typedef unsigned short ICHAR; 154 typedef unsigned short ICHAR; 155 #else 155 #else 156 # define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX 156 # define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX 157 # define XmlConvert XmlUtf8Convert 157 # define XmlConvert XmlUtf8Convert 158 # define XmlGetInternalEncoding XmlGetUtf8Int 158 # define XmlGetInternalEncoding XmlGetUtf8InternalEncoding 159 # define XmlGetInternalEncodingNS XmlGetUtf8I 159 # define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS 160 # define XmlEncode XmlUtf8Encode 160 # define XmlEncode XmlUtf8Encode 161 # define MUST_CONVERT(enc, s) (! (enc)->isUtf 161 # define MUST_CONVERT(enc, s) (! (enc)->isUtf8) 162 typedef char ICHAR; 162 typedef char ICHAR; 163 #endif 163 #endif 164 164 165 #ifndef XML_NS 165 #ifndef XML_NS 166 166 167 # define XmlInitEncodingNS XmlInitEncoding 167 # define XmlInitEncodingNS XmlInitEncoding 168 # define XmlInitUnknownEncodingNS XmlInitUnkn 168 # define XmlInitUnknownEncodingNS XmlInitUnknownEncoding 169 # undef XmlGetInternalEncodingNS 169 # undef XmlGetInternalEncodingNS 170 # define XmlGetInternalEncodingNS XmlGetInter 170 # define XmlGetInternalEncodingNS XmlGetInternalEncoding 171 # define XmlParseXmlDeclNS XmlParseXmlDecl 171 # define XmlParseXmlDeclNS XmlParseXmlDecl 172 172 173 #endif 173 #endif 174 174 175 #ifdef XML_UNICODE 175 #ifdef XML_UNICODE 176 176 177 # ifdef XML_UNICODE_WCHAR_T 177 # ifdef XML_UNICODE_WCHAR_T 178 # define XML_T(x) (const wchar_t) x 178 # define XML_T(x) (const wchar_t) x 179 # define XML_L(x) L##x 179 # define XML_L(x) L##x 180 # else 180 # else 181 # define XML_T(x) (const unsigned short)x 181 # define XML_T(x) (const unsigned short)x 182 # define XML_L(x) x 182 # define XML_L(x) x 183 # endif 183 # endif 184 184 185 #else 185 #else 186 186 187 # define XML_T(x) x 187 # define XML_T(x) x 188 # define XML_L(x) x 188 # define XML_L(x) x 189 189 190 #endif 190 #endif 191 191 192 /* Round up n to be a multiple of sz, where sz 192 /* Round up n to be a multiple of sz, where sz is a power of 2. */ 193 #define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~( 193 #define ROUND_UP(n, sz) (((n) + ((sz)-1)) & ~((sz)-1)) 194 194 195 /* Do safe (NULL-aware) pointer arithmetic */ 195 /* Do safe (NULL-aware) pointer arithmetic */ 196 #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q) 196 #define EXPAT_SAFE_PTR_DIFF(p, q) (((p) && (q)) ? ((p) - (q)) : 0) 197 197 198 #include "internal.h" 198 #include "internal.h" 199 #include "xmltok.h" 199 #include "xmltok.h" 200 #include "xmlrole.h" 200 #include "xmlrole.h" 201 201 202 typedef const XML_Char *KEY; 202 typedef const XML_Char *KEY; 203 203 204 typedef struct { 204 typedef struct { 205 KEY name; 205 KEY name; 206 } NAMED; 206 } NAMED; 207 207 208 typedef struct { 208 typedef struct { 209 NAMED **v; 209 NAMED **v; 210 unsigned char power; 210 unsigned char power; 211 size_t size; 211 size_t size; 212 size_t used; 212 size_t used; 213 const XML_Memory_Handling_Suite *mem; 213 const XML_Memory_Handling_Suite *mem; 214 } HASH_TABLE; 214 } HASH_TABLE; 215 215 216 static size_t keylen(KEY s); 216 static size_t keylen(KEY s); 217 217 218 static void copy_salt_to_sipkey(XML_Parser par 218 static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key); 219 219 220 /* For probing (after a collision) we need a s 220 /* For probing (after a collision) we need a step size relative prime 221 to the hash table size, which is a power of 221 to the hash table size, which is a power of 2. We use double-hashing, 222 since we can calculate a second hash value 222 since we can calculate a second hash value cheaply by taking those bits 223 of the first hash value that were discarded 223 of the first hash value that were discarded (masked out) when the table 224 index was calculated: index = hash & mask, 224 index was calculated: index = hash & mask, where mask = table->size - 1. 225 We limit the maximum step size to table->si 225 We limit the maximum step size to table->size / 4 (mask >> 2) and make 226 it odd, since odd numbers are always relati 226 it odd, since odd numbers are always relative prime to a power of 2. 227 */ 227 */ 228 #define SECOND_HASH(hash, mask, power) 228 #define SECOND_HASH(hash, mask, power) \ 229 ((((hash) & ~(mask)) >> ((power)-1)) & ((mas 229 ((((hash) & ~(mask)) >> ((power)-1)) & ((mask) >> 2)) 230 #define PROBE_STEP(hash, mask, power) 230 #define PROBE_STEP(hash, mask, power) \ 231 ((unsigned char)((SECOND_HASH(hash, mask, po 231 ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) 232 232 233 typedef struct { 233 typedef struct { 234 NAMED **p; 234 NAMED **p; 235 NAMED **end; 235 NAMED **end; 236 } HASH_TABLE_ITER; 236 } HASH_TABLE_ITER; 237 237 238 #define INIT_TAG_BUF_SIZE 32 /* must be a mult 238 #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ 239 #define INIT_DATA_BUF_SIZE 1024 239 #define INIT_DATA_BUF_SIZE 1024 240 #define INIT_ATTS_SIZE 16 240 #define INIT_ATTS_SIZE 16 241 #define INIT_ATTS_VERSION 0xFFFFFFFF 241 #define INIT_ATTS_VERSION 0xFFFFFFFF 242 #define INIT_BLOCK_SIZE 1024 242 #define INIT_BLOCK_SIZE 1024 243 #define INIT_BUFFER_SIZE 1024 243 #define INIT_BUFFER_SIZE 1024 244 244 245 #define EXPAND_SPARE 24 245 #define EXPAND_SPARE 24 246 246 247 typedef struct binding { 247 typedef struct binding { 248 struct prefix *prefix; 248 struct prefix *prefix; 249 struct binding *nextTagBinding; 249 struct binding *nextTagBinding; 250 struct binding *prevPrefixBinding; 250 struct binding *prevPrefixBinding; 251 const struct attribute_id *attId; 251 const struct attribute_id *attId; 252 XML_Char *uri; 252 XML_Char *uri; 253 int uriLen; 253 int uriLen; 254 int uriAlloc; 254 int uriAlloc; 255 } BINDING; 255 } BINDING; 256 256 257 typedef struct prefix { 257 typedef struct prefix { 258 const XML_Char *name; 258 const XML_Char *name; 259 BINDING *binding; 259 BINDING *binding; 260 } PREFIX; 260 } PREFIX; 261 261 262 typedef struct { 262 typedef struct { 263 const XML_Char *str; 263 const XML_Char *str; 264 const XML_Char *localPart; 264 const XML_Char *localPart; 265 const XML_Char *prefix; 265 const XML_Char *prefix; 266 int strLen; 266 int strLen; 267 int uriLen; 267 int uriLen; 268 int prefixLen; 268 int prefixLen; 269 } TAG_NAME; 269 } TAG_NAME; 270 270 271 /* TAG represents an open element. 271 /* TAG represents an open element. 272 The name of the element is stored in both t 272 The name of the element is stored in both the document and API 273 encodings. The memory buffer 'buf' is a se 273 encodings. The memory buffer 'buf' is a separately-allocated 274 memory area which stores the name. During 274 memory area which stores the name. During the XML_Parse()/ 275 XMLParseBuffer() when the element is open, 275 XMLParseBuffer() when the element is open, the memory for the 'raw' 276 version of the name (in the document encodi 276 version of the name (in the document encoding) is shared with the 277 document buffer. If the element is open ac 277 document buffer. If the element is open across calls to 278 XML_Parse()/XML_ParseBuffer(), the buffer i 278 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to 279 contain the 'raw' name as well. 279 contain the 'raw' name as well. 280 280 281 A parser re-uses these structures, maintain 281 A parser re-uses these structures, maintaining a list of allocated 282 TAG objects in a free list. 282 TAG objects in a free list. 283 */ 283 */ 284 typedef struct tag { 284 typedef struct tag { 285 struct tag *parent; /* parent of this eleme 285 struct tag *parent; /* parent of this element */ 286 const char *rawName; /* tagName in the origi 286 const char *rawName; /* tagName in the original encoding */ 287 int rawNameLength; 287 int rawNameLength; 288 TAG_NAME name; /* tagName in the API encodin 288 TAG_NAME name; /* tagName in the API encoding */ 289 char *buf; /* buffer for name components 289 char *buf; /* buffer for name components */ 290 char *bufEnd; /* end of the buffer */ 290 char *bufEnd; /* end of the buffer */ 291 BINDING *bindings; 291 BINDING *bindings; 292 } TAG; 292 } TAG; 293 293 294 typedef struct { 294 typedef struct { 295 const XML_Char *name; 295 const XML_Char *name; 296 const XML_Char *textPtr; 296 const XML_Char *textPtr; 297 int textLen; /* length in XML_Chars */ 297 int textLen; /* length in XML_Chars */ 298 int processed; /* # of processed bytes - whe 298 int processed; /* # of processed bytes - when suspended */ 299 const XML_Char *systemId; 299 const XML_Char *systemId; 300 const XML_Char *base; 300 const XML_Char *base; 301 const XML_Char *publicId; 301 const XML_Char *publicId; 302 const XML_Char *notation; 302 const XML_Char *notation; 303 XML_Bool open; 303 XML_Bool open; 304 XML_Bool is_param; 304 XML_Bool is_param; 305 XML_Bool is_internal; /* true if declared in 305 XML_Bool is_internal; /* true if declared in internal subset outside PE */ 306 } ENTITY; 306 } ENTITY; 307 307 308 typedef struct { 308 typedef struct { 309 enum XML_Content_Type type; 309 enum XML_Content_Type type; 310 enum XML_Content_Quant quant; 310 enum XML_Content_Quant quant; 311 const XML_Char *name; 311 const XML_Char *name; 312 int firstchild; 312 int firstchild; 313 int lastchild; 313 int lastchild; 314 int childcnt; 314 int childcnt; 315 int nextsib; 315 int nextsib; 316 } CONTENT_SCAFFOLD; 316 } CONTENT_SCAFFOLD; 317 317 318 #define INIT_SCAFFOLD_ELEMENTS 32 318 #define INIT_SCAFFOLD_ELEMENTS 32 319 319 320 typedef struct block { 320 typedef struct block { 321 struct block *next; 321 struct block *next; 322 int size; 322 int size; 323 XML_Char s[1]; 323 XML_Char s[1]; 324 } BLOCK; 324 } BLOCK; 325 325 326 typedef struct { 326 typedef struct { 327 BLOCK *blocks; 327 BLOCK *blocks; 328 BLOCK *freeBlocks; 328 BLOCK *freeBlocks; 329 const XML_Char *end; 329 const XML_Char *end; 330 XML_Char *ptr; 330 XML_Char *ptr; 331 XML_Char *start; 331 XML_Char *start; 332 const XML_Memory_Handling_Suite *mem; 332 const XML_Memory_Handling_Suite *mem; 333 } STRING_POOL; 333 } STRING_POOL; 334 334 335 /* The XML_Char before the name is used to det 335 /* The XML_Char before the name is used to determine whether 336 an attribute has been specified. */ 336 an attribute has been specified. */ 337 typedef struct attribute_id { 337 typedef struct attribute_id { 338 XML_Char *name; 338 XML_Char *name; 339 PREFIX *prefix; 339 PREFIX *prefix; 340 XML_Bool maybeTokenized; 340 XML_Bool maybeTokenized; 341 XML_Bool xmlns; 341 XML_Bool xmlns; 342 } ATTRIBUTE_ID; 342 } ATTRIBUTE_ID; 343 343 344 typedef struct { 344 typedef struct { 345 const ATTRIBUTE_ID *id; 345 const ATTRIBUTE_ID *id; 346 XML_Bool isCdata; 346 XML_Bool isCdata; 347 const XML_Char *value; 347 const XML_Char *value; 348 } DEFAULT_ATTRIBUTE; 348 } DEFAULT_ATTRIBUTE; 349 349 350 typedef struct { 350 typedef struct { 351 unsigned long version; 351 unsigned long version; 352 unsigned long hash; 352 unsigned long hash; 353 const XML_Char *uriName; 353 const XML_Char *uriName; 354 } NS_ATT; 354 } NS_ATT; 355 355 356 typedef struct { 356 typedef struct { 357 const XML_Char *name; 357 const XML_Char *name; 358 PREFIX *prefix; 358 PREFIX *prefix; 359 const ATTRIBUTE_ID *idAtt; 359 const ATTRIBUTE_ID *idAtt; 360 int nDefaultAtts; 360 int nDefaultAtts; 361 int allocDefaultAtts; 361 int allocDefaultAtts; 362 DEFAULT_ATTRIBUTE *defaultAtts; 362 DEFAULT_ATTRIBUTE *defaultAtts; 363 } ELEMENT_TYPE; 363 } ELEMENT_TYPE; 364 364 365 typedef struct { 365 typedef struct { 366 HASH_TABLE generalEntities; 366 HASH_TABLE generalEntities; 367 HASH_TABLE elementTypes; 367 HASH_TABLE elementTypes; 368 HASH_TABLE attributeIds; 368 HASH_TABLE attributeIds; 369 HASH_TABLE prefixes; 369 HASH_TABLE prefixes; 370 STRING_POOL pool; 370 STRING_POOL pool; 371 STRING_POOL entityValuePool; 371 STRING_POOL entityValuePool; 372 /* false once a parameter entity reference h 372 /* false once a parameter entity reference has been skipped */ 373 XML_Bool keepProcessing; 373 XML_Bool keepProcessing; 374 /* true once an internal or external PE refe 374 /* true once an internal or external PE reference has been encountered; 375 this includes the reference to an externa 375 this includes the reference to an external subset */ 376 XML_Bool hasParamEntityRefs; 376 XML_Bool hasParamEntityRefs; 377 XML_Bool standalone; 377 XML_Bool standalone; 378 #ifdef XML_DTD 378 #ifdef XML_DTD 379 /* indicates if external PE has been read */ 379 /* indicates if external PE has been read */ 380 XML_Bool paramEntityRead; 380 XML_Bool paramEntityRead; 381 HASH_TABLE paramEntities; 381 HASH_TABLE paramEntities; 382 #endif /* XML_DTD */ 382 #endif /* XML_DTD */ 383 PREFIX defaultPrefix; 383 PREFIX defaultPrefix; 384 /* === scaffolding for building content mode 384 /* === scaffolding for building content model === */ 385 XML_Bool in_eldecl; 385 XML_Bool in_eldecl; 386 CONTENT_SCAFFOLD *scaffold; 386 CONTENT_SCAFFOLD *scaffold; 387 unsigned contentStringLen; 387 unsigned contentStringLen; 388 unsigned scaffSize; 388 unsigned scaffSize; 389 unsigned scaffCount; 389 unsigned scaffCount; 390 int scaffLevel; 390 int scaffLevel; 391 int *scaffIndex; 391 int *scaffIndex; 392 } DTD; 392 } DTD; 393 393 394 typedef struct open_internal_entity { 394 typedef struct open_internal_entity { 395 const char *internalEventPtr; 395 const char *internalEventPtr; 396 const char *internalEventEndPtr; 396 const char *internalEventEndPtr; 397 struct open_internal_entity *next; 397 struct open_internal_entity *next; 398 ENTITY *entity; 398 ENTITY *entity; 399 int startTagLevel; 399 int startTagLevel; 400 XML_Bool betweenDecl; /* WFC: PE Between Dec 400 XML_Bool betweenDecl; /* WFC: PE Between Declarations */ 401 } OPEN_INTERNAL_ENTITY; 401 } OPEN_INTERNAL_ENTITY; 402 402 403 enum XML_Account { 403 enum XML_Account { 404 XML_ACCOUNT_DIRECT, /* bytes direc 404 XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser */ 405 XML_ACCOUNT_ENTITY_EXPANSION, /* intermediat 405 XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity 406 expansion * 406 expansion */ 407 XML_ACCOUNT_NONE /* i.e. do not 407 XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */ 408 }; 408 }; 409 409 410 #ifdef XML_DTD 410 #ifdef XML_DTD 411 typedef unsigned long long XmlBigCount; 411 typedef unsigned long long XmlBigCount; 412 typedef struct accounting { 412 typedef struct accounting { 413 XmlBigCount countBytesDirect; 413 XmlBigCount countBytesDirect; 414 XmlBigCount countBytesIndirect; 414 XmlBigCount countBytesIndirect; 415 int debugLevel; 415 int debugLevel; 416 float maximumAmplificationFactor; // >=1.0 416 float maximumAmplificationFactor; // >=1.0 417 unsigned long long activationThresholdBytes; 417 unsigned long long activationThresholdBytes; 418 } ACCOUNTING; 418 } ACCOUNTING; 419 419 420 typedef struct entity_stats { 420 typedef struct entity_stats { 421 unsigned int countEverOpened; 421 unsigned int countEverOpened; 422 unsigned int currentDepth; 422 unsigned int currentDepth; 423 unsigned int maximumDepthSeen; 423 unsigned int maximumDepthSeen; 424 int debugLevel; 424 int debugLevel; 425 } ENTITY_STATS; 425 } ENTITY_STATS; 426 #endif /* XML_DTD */ 426 #endif /* XML_DTD */ 427 427 428 typedef enum XML_Error PTRCALL Processor(XML_P 428 typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start, 429 const 429 const char *end, const char **endPtr); 430 430 431 static Processor prologProcessor; 431 static Processor prologProcessor; 432 static Processor prologInitProcessor; 432 static Processor prologInitProcessor; 433 static Processor contentProcessor; 433 static Processor contentProcessor; 434 static Processor cdataSectionProcessor; 434 static Processor cdataSectionProcessor; 435 #ifdef XML_DTD 435 #ifdef XML_DTD 436 static Processor ignoreSectionProcessor; 436 static Processor ignoreSectionProcessor; 437 static Processor externalParEntProcessor; 437 static Processor externalParEntProcessor; 438 static Processor externalParEntInitProcessor; 438 static Processor externalParEntInitProcessor; 439 static Processor entityValueProcessor; 439 static Processor entityValueProcessor; 440 static Processor entityValueInitProcessor; 440 static Processor entityValueInitProcessor; 441 #endif /* XML_DTD */ 441 #endif /* XML_DTD */ 442 static Processor epilogProcessor; 442 static Processor epilogProcessor; 443 static Processor errorProcessor; 443 static Processor errorProcessor; 444 static Processor externalEntityInitProcessor; 444 static Processor externalEntityInitProcessor; 445 static Processor externalEntityInitProcessor2; 445 static Processor externalEntityInitProcessor2; 446 static Processor externalEntityInitProcessor3; 446 static Processor externalEntityInitProcessor3; 447 static Processor externalEntityContentProcesso 447 static Processor externalEntityContentProcessor; 448 static Processor internalEntityProcessor; 448 static Processor internalEntityProcessor; 449 449 450 static enum XML_Error handleUnknownEncoding(XM 450 static enum XML_Error handleUnknownEncoding(XML_Parser parser, 451 co 451 const XML_Char *encodingName); 452 static enum XML_Error processXmlDecl(XML_Parse 452 static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, 453 const cha 453 const char *s, const char *next); 454 static enum XML_Error initializeEncoding(XML_P 454 static enum XML_Error initializeEncoding(XML_Parser parser); 455 static enum XML_Error doProlog(XML_Parser pars 455 static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc, 456 const char *s, 456 const char *s, const char *end, int tok, 457 const char *nex 457 const char *next, const char **nextPtr, 458 XML_Bool haveMo 458 XML_Bool haveMore, XML_Bool allowClosingDoctype, 459 enum XML_Accoun 459 enum XML_Account account); 460 static enum XML_Error processInternalEntity(XM 460 static enum XML_Error processInternalEntity(XML_Parser parser, ENTITY *entity, 461 XM 461 XML_Bool betweenDecl); 462 static enum XML_Error doContent(XML_Parser par 462 static enum XML_Error doContent(XML_Parser parser, int startTagLevel, 463 const ENCODING 463 const ENCODING *enc, const char *start, 464 const char *en 464 const char *end, const char **endPtr, 465 XML_Bool haveM 465 XML_Bool haveMore, enum XML_Account account); 466 static enum XML_Error doCdataSection(XML_Parse 466 static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, 467 const cha 467 const char **startPtr, const char *end, 468 const cha 468 const char **nextPtr, XML_Bool haveMore, 469 enum XML_ 469 enum XML_Account account); 470 #ifdef XML_DTD 470 #ifdef XML_DTD 471 static enum XML_Error doIgnoreSection(XML_Pars 471 static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *, 472 const ch 472 const char **startPtr, const char *end, 473 const ch 473 const char **nextPtr, XML_Bool haveMore); 474 #endif /* XML_DTD */ 474 #endif /* XML_DTD */ 475 475 476 static void freeBindings(XML_Parser parser, BI 476 static void freeBindings(XML_Parser parser, BINDING *bindings); 477 static enum XML_Error storeAtts(XML_Parser par 477 static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, 478 const char *s, 478 const char *s, TAG_NAME *tagNamePtr, 479 BINDING **bind 479 BINDING **bindingsPtr, 480 enum XML_Accou 480 enum XML_Account account); 481 static enum XML_Error addBinding(XML_Parser pa 481 static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix, 482 const ATTRIBU 482 const ATTRIBUTE_ID *attId, const XML_Char *uri, 483 BINDING **bin 483 BINDING **bindingsPtr); 484 static int defineAttribute(ELEMENT_TYPE *type, 484 static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 485 XML_Bool isId, cons 485 XML_Bool isId, const XML_Char *dfltValue, 486 XML_Parser parser); 486 XML_Parser parser); 487 static enum XML_Error storeAttributeValue(XML_ 487 static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *, 488 XML_ 488 XML_Bool isCdata, const char *, 489 cons 489 const char *, STRING_POOL *, 490 enum 490 enum XML_Account account); 491 static enum XML_Error appendAttributeValue(XML 491 static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *, 492 XML 492 XML_Bool isCdata, const char *, 493 con 493 const char *, STRING_POOL *, 494 enu 494 enum XML_Account account); 495 static ATTRIBUTE_ID *getAttributeId(XML_Parser 495 static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, 496 const char 496 const char *start, const char *end); 497 static int setElementTypePrefix(XML_Parser par 497 static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); 498 static enum XML_Error storeEntityValue(XML_Par 498 static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc, 499 const c 499 const char *start, const char *end, 500 enum XM 500 enum XML_Account account); 501 static int reportProcessingInstruction(XML_Par 501 static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, 502 const c 502 const char *start, const char *end); 503 static int reportComment(XML_Parser parser, co 503 static int reportComment(XML_Parser parser, const ENCODING *enc, 504 const char *start, co 504 const char *start, const char *end); 505 static void reportDefault(XML_Parser parser, c 505 static void reportDefault(XML_Parser parser, const ENCODING *enc, 506 const char *start, c 506 const char *start, const char *end); 507 507 508 static const XML_Char *getContext(XML_Parser p 508 static const XML_Char *getContext(XML_Parser parser); 509 static XML_Bool setContext(XML_Parser parser, 509 static XML_Bool setContext(XML_Parser parser, const XML_Char *context); 510 510 511 static void FASTCALL normalizePublicId(XML_Cha 511 static void FASTCALL normalizePublicId(XML_Char *s); 512 512 513 static DTD *dtdCreate(const XML_Memory_Handlin 513 static DTD *dtdCreate(const XML_Memory_Handling_Suite *ms); 514 /* do not call if m_parentParser != NULL */ 514 /* do not call if m_parentParser != NULL */ 515 static void dtdReset(DTD *p, const XML_Memory_ 515 static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); 516 static void dtdDestroy(DTD *p, XML_Bool isDocE 516 static void dtdDestroy(DTD *p, XML_Bool isDocEntity, 517 const XML_Memory_Handli 517 const XML_Memory_Handling_Suite *ms); 518 static int dtdCopy(XML_Parser oldParser, DTD * 518 static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, 519 const XML_Memory_Handling_S 519 const XML_Memory_Handling_Suite *ms); 520 static int copyEntityTable(XML_Parser oldParse 520 static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *, STRING_POOL *, 521 const HASH_TABLE *) 521 const HASH_TABLE *); 522 static NAMED *lookup(XML_Parser parser, HASH_T 522 static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name, 523 size_t createSize); 523 size_t createSize); 524 static void FASTCALL hashTableInit(HASH_TABLE 524 static void FASTCALL hashTableInit(HASH_TABLE *, 525 const XML_M 525 const XML_Memory_Handling_Suite *ms); 526 static void FASTCALL hashTableClear(HASH_TABLE 526 static void FASTCALL hashTableClear(HASH_TABLE *); 527 static void FASTCALL hashTableDestroy(HASH_TAB 527 static void FASTCALL hashTableDestroy(HASH_TABLE *); 528 static void FASTCALL hashTableIterInit(HASH_TA 528 static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); 529 static NAMED *FASTCALL hashTableIterNext(HASH_ 529 static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *); 530 530 531 static void FASTCALL poolInit(STRING_POOL *, 531 static void FASTCALL poolInit(STRING_POOL *, 532 const XML_Memory 532 const XML_Memory_Handling_Suite *ms); 533 static void FASTCALL poolClear(STRING_POOL *); 533 static void FASTCALL poolClear(STRING_POOL *); 534 static void FASTCALL poolDestroy(STRING_POOL * 534 static void FASTCALL poolDestroy(STRING_POOL *); 535 static XML_Char *poolAppend(STRING_POOL *pool, 535 static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, 536 const char *ptr, c 536 const char *ptr, const char *end); 537 static XML_Char *poolStoreString(STRING_POOL * 537 static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, 538 const char *p 538 const char *ptr, const char *end); 539 static XML_Bool FASTCALL poolGrow(STRING_POOL 539 static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); 540 static const XML_Char *FASTCALL poolCopyString 540 static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, 541 541 const XML_Char *s); 542 static const XML_Char *poolCopyStringN(STRING_ 542 static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, 543 int n); 543 int n); 544 static const XML_Char *FASTCALL poolAppendStri 544 static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, 545 545 const XML_Char *s); 546 546 547 static int FASTCALL nextScaffoldPart(XML_Parse 547 static int FASTCALL nextScaffoldPart(XML_Parser parser); 548 static XML_Content *build_model(XML_Parser par 548 static XML_Content *build_model(XML_Parser parser); 549 static ELEMENT_TYPE *getElementType(XML_Parser 549 static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc, 550 const char 550 const char *ptr, const char *end); 551 551 552 static XML_Char *copyString(const XML_Char *s, 552 static XML_Char *copyString(const XML_Char *s, 553 const XML_Memory_H 553 const XML_Memory_Handling_Suite *memsuite); 554 554 555 static unsigned long generate_hash_secret_salt 555 static unsigned long generate_hash_secret_salt(XML_Parser parser); 556 static XML_Bool startParsing(XML_Parser parser 556 static XML_Bool startParsing(XML_Parser parser); 557 557 558 static XML_Parser parserCreate(const XML_Char 558 static XML_Parser parserCreate(const XML_Char *encodingName, 559 const XML_Memor 559 const XML_Memory_Handling_Suite *memsuite, 560 const XML_Char 560 const XML_Char *nameSep, DTD *dtd); 561 561 562 static void parserInit(XML_Parser parser, cons 562 static void parserInit(XML_Parser parser, const XML_Char *encodingName); 563 563 564 #ifdef XML_DTD 564 #ifdef XML_DTD 565 static float accountingGetCurrentAmplification 565 static float accountingGetCurrentAmplification(XML_Parser rootParser); 566 static void accountingReportStats(XML_Parser o 566 static void accountingReportStats(XML_Parser originParser, const char *epilog); 567 static void accountingOnAbort(XML_Parser origi 567 static void accountingOnAbort(XML_Parser originParser); 568 static void accountingReportDiff(XML_Parser ro 568 static void accountingReportDiff(XML_Parser rootParser, 569 unsigned int 569 unsigned int levelsAwayFromRootParser, 570 const char *b 570 const char *before, const char *after, 571 ptrdiff_t byt 571 ptrdiff_t bytesMore, int source_line, 572 enum XML_Acco 572 enum XML_Account account); 573 static XML_Bool accountingDiffTolerated(XML_Pa 573 static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok, 574 const 574 const char *before, const char *after, 575 int so 575 int source_line, 576 enum X 576 enum XML_Account account); 577 577 578 static void entityTrackingReportStats(XML_Pars 578 static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity, 579 const ch 579 const char *action, int sourceLine); 580 static void entityTrackingOnOpen(XML_Parser pa 580 static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity, 581 int sourceLin 581 int sourceLine); 582 static void entityTrackingOnClose(XML_Parser p 582 static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity, 583 int sourceLi 583 int sourceLine); 584 584 585 static XML_Parser getRootParserOf(XML_Parser p 585 static XML_Parser getRootParserOf(XML_Parser parser, 586 unsigned int 586 unsigned int *outLevelDiff); 587 #endif /* XML_DTD */ 587 #endif /* XML_DTD */ 588 588 589 static unsigned long getDebugLevel(const char 589 static unsigned long getDebugLevel(const char *variableName, 590 unsigned lo 590 unsigned long defaultDebugLevel); 591 591 592 #define poolStart(pool) ((pool)->start) 592 #define poolStart(pool) ((pool)->start) 593 #define poolEnd(pool) ((pool)->ptr) 593 #define poolEnd(pool) ((pool)->ptr) 594 #define poolLength(pool) ((pool)->ptr - (pool) 594 #define poolLength(pool) ((pool)->ptr - (pool)->start) 595 #define poolChop(pool) ((void)--(pool->ptr)) 595 #define poolChop(pool) ((void)--(pool->ptr)) 596 #define poolLastChar(pool) (((pool)->ptr)[-1]) 596 #define poolLastChar(pool) (((pool)->ptr)[-1]) 597 #define poolDiscard(pool) ((pool)->ptr = (pool 597 #define poolDiscard(pool) ((pool)->ptr = (pool)->start) 598 #define poolFinish(pool) ((pool)->start = (poo 598 #define poolFinish(pool) ((pool)->start = (pool)->ptr) 599 #define poolAppendChar(pool, c) 599 #define poolAppendChar(pool, c) \ 600 (((pool)->ptr == (pool)->end && ! poolGrow(p 600 (((pool)->ptr == (pool)->end && ! poolGrow(pool)) \ 601 ? 0 601 ? 0 \ 602 : ((*((pool)->ptr)++ = c), 1)) 602 : ((*((pool)->ptr)++ = c), 1)) 603 603 604 struct XML_ParserStruct { 604 struct XML_ParserStruct { 605 /* The first member must be m_userData so th 605 /* The first member must be m_userData so that the XML_GetUserData 606 macro works. */ 606 macro works. */ 607 void *m_userData; 607 void *m_userData; 608 void *m_handlerArg; 608 void *m_handlerArg; 609 char *m_buffer; 609 char *m_buffer; 610 const XML_Memory_Handling_Suite m_mem; 610 const XML_Memory_Handling_Suite m_mem; 611 /* first character to be parsed */ 611 /* first character to be parsed */ 612 const char *m_bufferPtr; 612 const char *m_bufferPtr; 613 /* past last character to be parsed */ 613 /* past last character to be parsed */ 614 char *m_bufferEnd; 614 char *m_bufferEnd; 615 /* allocated end of m_buffer */ 615 /* allocated end of m_buffer */ 616 const char *m_bufferLim; 616 const char *m_bufferLim; 617 XML_Index m_parseEndByteIndex; 617 XML_Index m_parseEndByteIndex; 618 const char *m_parseEndPtr; 618 const char *m_parseEndPtr; 619 XML_Char *m_dataBuf; 619 XML_Char *m_dataBuf; 620 XML_Char *m_dataBufEnd; 620 XML_Char *m_dataBufEnd; 621 XML_StartElementHandler m_startElementHandle 621 XML_StartElementHandler m_startElementHandler; 622 XML_EndElementHandler m_endElementHandler; 622 XML_EndElementHandler m_endElementHandler; 623 XML_CharacterDataHandler m_characterDataHand 623 XML_CharacterDataHandler m_characterDataHandler; 624 XML_ProcessingInstructionHandler m_processin 624 XML_ProcessingInstructionHandler m_processingInstructionHandler; 625 XML_CommentHandler m_commentHandler; 625 XML_CommentHandler m_commentHandler; 626 XML_StartCdataSectionHandler m_startCdataSec 626 XML_StartCdataSectionHandler m_startCdataSectionHandler; 627 XML_EndCdataSectionHandler m_endCdataSection 627 XML_EndCdataSectionHandler m_endCdataSectionHandler; 628 XML_DefaultHandler m_defaultHandler; 628 XML_DefaultHandler m_defaultHandler; 629 XML_StartDoctypeDeclHandler m_startDoctypeDe 629 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; 630 XML_EndDoctypeDeclHandler m_endDoctypeDeclHa 630 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; 631 XML_UnparsedEntityDeclHandler m_unparsedEnti 631 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; 632 XML_NotationDeclHandler m_notationDeclHandle 632 XML_NotationDeclHandler m_notationDeclHandler; 633 XML_StartNamespaceDeclHandler m_startNamespa 633 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; 634 XML_EndNamespaceDeclHandler m_endNamespaceDe 634 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; 635 XML_NotStandaloneHandler m_notStandaloneHand 635 XML_NotStandaloneHandler m_notStandaloneHandler; 636 XML_ExternalEntityRefHandler m_externalEntit 636 XML_ExternalEntityRefHandler m_externalEntityRefHandler; 637 XML_Parser m_externalEntityRefHandlerArg; 637 XML_Parser m_externalEntityRefHandlerArg; 638 XML_SkippedEntityHandler m_skippedEntityHand 638 XML_SkippedEntityHandler m_skippedEntityHandler; 639 XML_UnknownEncodingHandler m_unknownEncoding 639 XML_UnknownEncodingHandler m_unknownEncodingHandler; 640 XML_ElementDeclHandler m_elementDeclHandler; 640 XML_ElementDeclHandler m_elementDeclHandler; 641 XML_AttlistDeclHandler m_attlistDeclHandler; 641 XML_AttlistDeclHandler m_attlistDeclHandler; 642 XML_EntityDeclHandler m_entityDeclHandler; 642 XML_EntityDeclHandler m_entityDeclHandler; 643 XML_XmlDeclHandler m_xmlDeclHandler; 643 XML_XmlDeclHandler m_xmlDeclHandler; 644 const ENCODING *m_encoding; 644 const ENCODING *m_encoding; 645 INIT_ENCODING m_initEncoding; 645 INIT_ENCODING m_initEncoding; 646 const ENCODING *m_internalEncoding; 646 const ENCODING *m_internalEncoding; 647 const XML_Char *m_protocolEncodingName; 647 const XML_Char *m_protocolEncodingName; 648 XML_Bool m_ns; 648 XML_Bool m_ns; 649 XML_Bool m_ns_triplets; 649 XML_Bool m_ns_triplets; 650 void *m_unknownEncodingMem; 650 void *m_unknownEncodingMem; 651 void *m_unknownEncodingData; 651 void *m_unknownEncodingData; 652 void *m_unknownEncodingHandlerData; 652 void *m_unknownEncodingHandlerData; 653 void(XMLCALL *m_unknownEncodingRelease)(void 653 void(XMLCALL *m_unknownEncodingRelease)(void *); 654 PROLOG_STATE m_prologState; 654 PROLOG_STATE m_prologState; 655 Processor *m_processor; 655 Processor *m_processor; 656 enum XML_Error m_errorCode; 656 enum XML_Error m_errorCode; 657 const char *m_eventPtr; 657 const char *m_eventPtr; 658 const char *m_eventEndPtr; 658 const char *m_eventEndPtr; 659 const char *m_positionPtr; 659 const char *m_positionPtr; 660 OPEN_INTERNAL_ENTITY *m_openInternalEntities 660 OPEN_INTERNAL_ENTITY *m_openInternalEntities; 661 OPEN_INTERNAL_ENTITY *m_freeInternalEntities 661 OPEN_INTERNAL_ENTITY *m_freeInternalEntities; 662 XML_Bool m_defaultExpandInternalEntities; 662 XML_Bool m_defaultExpandInternalEntities; 663 int m_tagLevel; 663 int m_tagLevel; 664 ENTITY *m_declEntity; 664 ENTITY *m_declEntity; 665 const XML_Char *m_doctypeName; 665 const XML_Char *m_doctypeName; 666 const XML_Char *m_doctypeSysid; 666 const XML_Char *m_doctypeSysid; 667 const XML_Char *m_doctypePubid; 667 const XML_Char *m_doctypePubid; 668 const XML_Char *m_declAttributeType; 668 const XML_Char *m_declAttributeType; 669 const XML_Char *m_declNotationName; 669 const XML_Char *m_declNotationName; 670 const XML_Char *m_declNotationPublicId; 670 const XML_Char *m_declNotationPublicId; 671 ELEMENT_TYPE *m_declElementType; 671 ELEMENT_TYPE *m_declElementType; 672 ATTRIBUTE_ID *m_declAttributeId; 672 ATTRIBUTE_ID *m_declAttributeId; 673 XML_Bool m_declAttributeIsCdata; 673 XML_Bool m_declAttributeIsCdata; 674 XML_Bool m_declAttributeIsId; 674 XML_Bool m_declAttributeIsId; 675 DTD *m_dtd; 675 DTD *m_dtd; 676 const XML_Char *m_curBase; 676 const XML_Char *m_curBase; 677 TAG *m_tagStack; 677 TAG *m_tagStack; 678 TAG *m_freeTagList; 678 TAG *m_freeTagList; 679 BINDING *m_inheritedBindings; 679 BINDING *m_inheritedBindings; 680 BINDING *m_freeBindingList; 680 BINDING *m_freeBindingList; 681 int m_attsSize; 681 int m_attsSize; 682 int m_nSpecifiedAtts; 682 int m_nSpecifiedAtts; 683 int m_idAttIndex; 683 int m_idAttIndex; 684 ATTRIBUTE *m_atts; 684 ATTRIBUTE *m_atts; 685 NS_ATT *m_nsAtts; 685 NS_ATT *m_nsAtts; 686 unsigned long m_nsAttsVersion; 686 unsigned long m_nsAttsVersion; 687 unsigned char m_nsAttsPower; 687 unsigned char m_nsAttsPower; 688 #ifdef XML_ATTR_INFO 688 #ifdef XML_ATTR_INFO 689 XML_AttrInfo *m_attInfo; 689 XML_AttrInfo *m_attInfo; 690 #endif 690 #endif 691 POSITION m_position; 691 POSITION m_position; 692 STRING_POOL m_tempPool; 692 STRING_POOL m_tempPool; 693 STRING_POOL m_temp2Pool; 693 STRING_POOL m_temp2Pool; 694 char *m_groupConnector; 694 char *m_groupConnector; 695 unsigned int m_groupSize; 695 unsigned int m_groupSize; 696 XML_Char m_namespaceSeparator; 696 XML_Char m_namespaceSeparator; 697 XML_Parser m_parentParser; 697 XML_Parser m_parentParser; 698 XML_ParsingStatus m_parsingStatus; 698 XML_ParsingStatus m_parsingStatus; 699 #ifdef XML_DTD 699 #ifdef XML_DTD 700 XML_Bool m_isParamEntity; 700 XML_Bool m_isParamEntity; 701 XML_Bool m_useForeignDTD; 701 XML_Bool m_useForeignDTD; 702 enum XML_ParamEntityParsing m_paramEntityPar 702 enum XML_ParamEntityParsing m_paramEntityParsing; 703 #endif 703 #endif 704 unsigned long m_hash_secret_salt; 704 unsigned long m_hash_secret_salt; 705 #ifdef XML_DTD 705 #ifdef XML_DTD 706 ACCOUNTING m_accounting; 706 ACCOUNTING m_accounting; 707 ENTITY_STATS m_entity_stats; 707 ENTITY_STATS m_entity_stats; 708 #endif 708 #endif 709 }; 709 }; 710 710 711 #define MALLOC(parser, s) (parser->m_mem.mallo 711 #define MALLOC(parser, s) (parser->m_mem.malloc_fcn((s))) 712 #define REALLOC(parser, p, s) (parser->m_mem.r 712 #define REALLOC(parser, p, s) (parser->m_mem.realloc_fcn((p), (s))) 713 #define FREE(parser, p) (parser->m_mem.free_fc 713 #define FREE(parser, p) (parser->m_mem.free_fcn((p))) 714 714 715 XML_Parser XMLCALL 715 XML_Parser XMLCALL 716 XML_ParserCreate(const XML_Char *encodingName) 716 XML_ParserCreate(const XML_Char *encodingName) { 717 return XML_ParserCreate_MM(encodingName, NUL 717 return XML_ParserCreate_MM(encodingName, NULL, NULL); 718 } 718 } 719 719 720 XML_Parser XMLCALL 720 XML_Parser XMLCALL 721 XML_ParserCreateNS(const XML_Char *encodingNam 721 XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { 722 XML_Char tmp[2] = {nsSep, 0}; 722 XML_Char tmp[2] = {nsSep, 0}; 723 return XML_ParserCreate_MM(encodingName, NUL 723 return XML_ParserCreate_MM(encodingName, NULL, tmp); 724 } 724 } 725 725 726 // "xml=http://www.w3.org/XML/1998/namespace" 726 // "xml=http://www.w3.org/XML/1998/namespace" 727 static const XML_Char implicitContext[] 727 static const XML_Char implicitContext[] 728 = {ASCII_x, ASCII_m, ASCII_l, 728 = {ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, 729 ASCII_t, ASCII_t, ASCII_p, 729 ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, 730 ASCII_SLASH, ASCII_w, ASCII_w, 730 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, 731 ASCII_w, ASCII_3, ASCII_PERIOD, 731 ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, 732 ASCII_g, ASCII_SLASH, ASCII_X, 732 ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, 733 ASCII_SLASH, ASCII_1, ASCII_9, 733 ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, 734 ASCII_SLASH, ASCII_n, ASCII_a, 734 ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, 735 ASCII_s, ASCII_p, ASCII_a, 735 ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, 736 '\0'}; 736 '\0'}; 737 737 738 /* To avoid warnings about unused functions: * 738 /* To avoid warnings about unused functions: */ 739 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! define 739 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) 740 740 741 # if defined(HAVE_GETRANDOM) || defined(HAVE_ 741 # if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 742 742 743 /* Obtain entropy on Linux 3.17+ */ 743 /* Obtain entropy on Linux 3.17+ */ 744 static int 744 static int 745 writeRandomBytes_getrandom_nonblock(void *targ 745 writeRandomBytes_getrandom_nonblock(void *target, size_t count) { 746 int success = 0; /* full count bytes written 746 int success = 0; /* full count bytes written? */ 747 size_t bytesWrittenTotal = 0; 747 size_t bytesWrittenTotal = 0; 748 const unsigned int getrandomFlags = GRND_NON 748 const unsigned int getrandomFlags = GRND_NONBLOCK; 749 749 750 do { 750 do { 751 void *const currentTarget = (void *)((char 751 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); 752 const size_t bytesToWrite = count - bytesW 752 const size_t bytesToWrite = count - bytesWrittenTotal; 753 753 754 const int bytesWrittenMore = 754 const int bytesWrittenMore = 755 # if defined(HAVE_GETRANDOM) 755 # if defined(HAVE_GETRANDOM) 756 getrandom(currentTarget, bytesToWrite, 756 getrandom(currentTarget, bytesToWrite, getrandomFlags); 757 # else 757 # else 758 syscall(SYS_getrandom, currentTarget, 758 syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); 759 # endif 759 # endif 760 760 761 if (bytesWrittenMore > 0) { 761 if (bytesWrittenMore > 0) { 762 bytesWrittenTotal += bytesWrittenMore; 762 bytesWrittenTotal += bytesWrittenMore; 763 if (bytesWrittenTotal >= count) 763 if (bytesWrittenTotal >= count) 764 success = 1; 764 success = 1; 765 } 765 } 766 } while (! success && (errno == EINTR)); 766 } while (! success && (errno == EINTR)); 767 767 768 return success; 768 return success; 769 } 769 } 770 770 771 # endif /* defined(HAVE_GETRANDOM) || defined 771 # endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ 772 772 773 # if ! defined(_WIN32) && defined(XML_DEV_URA 773 # if ! defined(_WIN32) && defined(XML_DEV_URANDOM) 774 774 775 /* Extract entropy from /dev/urandom */ 775 /* Extract entropy from /dev/urandom */ 776 static int 776 static int 777 writeRandomBytes_dev_urandom(void *target, siz 777 writeRandomBytes_dev_urandom(void *target, size_t count) { 778 int success = 0; /* full count bytes written 778 int success = 0; /* full count bytes written? */ 779 size_t bytesWrittenTotal = 0; 779 size_t bytesWrittenTotal = 0; 780 780 781 const int fd = open("/dev/urandom", O_RDONLY 781 const int fd = open("/dev/urandom", O_RDONLY); 782 if (fd < 0) { 782 if (fd < 0) { 783 return 0; 783 return 0; 784 } 784 } 785 785 786 do { 786 do { 787 void *const currentTarget = (void *)((char 787 void *const currentTarget = (void *)((char *)target + bytesWrittenTotal); 788 const size_t bytesToWrite = count - bytesW 788 const size_t bytesToWrite = count - bytesWrittenTotal; 789 789 790 const ssize_t bytesWrittenMore = read(fd, 790 const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite); 791 791 792 if (bytesWrittenMore > 0) { 792 if (bytesWrittenMore > 0) { 793 bytesWrittenTotal += bytesWrittenMore; 793 bytesWrittenTotal += bytesWrittenMore; 794 if (bytesWrittenTotal >= count) 794 if (bytesWrittenTotal >= count) 795 success = 1; 795 success = 1; 796 } 796 } 797 } while (! success && (errno == EINTR)); 797 } while (! success && (errno == EINTR)); 798 798 799 close(fd); 799 close(fd); 800 return success; 800 return success; 801 } 801 } 802 802 803 # endif /* ! defined(_WIN32) && defined(XML_D 803 # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ 804 804 805 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! 805 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ 806 806 807 #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE 807 #if defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) 808 808 809 static void 809 static void 810 writeRandomBytes_arc4random(void *target, size 810 writeRandomBytes_arc4random(void *target, size_t count) { 811 size_t bytesWrittenTotal = 0; 811 size_t bytesWrittenTotal = 0; 812 812 813 while (bytesWrittenTotal < count) { 813 while (bytesWrittenTotal < count) { 814 const uint32_t random32 = arc4random(); 814 const uint32_t random32 = arc4random(); 815 size_t i = 0; 815 size_t i = 0; 816 816 817 for (; (i < sizeof(random32)) && (bytesWri 817 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); 818 i++, bytesWrittenTotal++) { 818 i++, bytesWrittenTotal++) { 819 const uint8_t random8 = (uint8_t)(random 819 const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); 820 ((uint8_t *)target)[bytesWrittenTotal] = 820 ((uint8_t *)target)[bytesWrittenTotal] = random8; 821 } 821 } 822 } 822 } 823 } 823 } 824 824 825 #endif /* defined(HAVE_ARC4RANDOM) && ! define 825 #endif /* defined(HAVE_ARC4RANDOM) && ! defined(HAVE_ARC4RANDOM_BUF) */ 826 826 827 #ifdef _WIN32 827 #ifdef _WIN32 828 828 829 /* Provide declaration of rand_s() for MinGW-3 829 /* Provide declaration of rand_s() for MinGW-32 (not 64, which has it), 830 as it didn't declare it in its header prior 830 as it didn't declare it in its header prior to version 5.3.0 of its 831 runtime package (mingwrt, containing stdlib 831 runtime package (mingwrt, containing stdlib.h). The upstream fix 832 was introduced at https://osdn.net/projects 832 was introduced at https://osdn.net/projects/mingw/ticket/39658 . */ 833 # if defined(__MINGW32__) && defined(__MINGW3 833 # if defined(__MINGW32__) && defined(__MINGW32_VERSION) \ 834 && __MINGW32_VERSION < 5003000L && ! def 834 && __MINGW32_VERSION < 5003000L && ! defined(__MINGW64_VERSION_MAJOR) 835 __declspec(dllimport) int rand_s(unsigned int 835 __declspec(dllimport) int rand_s(unsigned int *); 836 # endif 836 # endif 837 837 838 /* Obtain entropy on Windows using the rand_s( 838 /* Obtain entropy on Windows using the rand_s() function which 839 * generates cryptographically secure random n 839 * generates cryptographically secure random numbers. Internally it 840 * uses RtlGenRandom API which is present in W 840 * uses RtlGenRandom API which is present in Windows XP and later. 841 */ 841 */ 842 static int 842 static int 843 writeRandomBytes_rand_s(void *target, size_t c 843 writeRandomBytes_rand_s(void *target, size_t count) { 844 size_t bytesWrittenTotal = 0; 844 size_t bytesWrittenTotal = 0; 845 845 846 while (bytesWrittenTotal < count) { 846 while (bytesWrittenTotal < count) { 847 unsigned int random32 = 0; 847 unsigned int random32 = 0; 848 size_t i = 0; 848 size_t i = 0; 849 849 850 if (rand_s(&random32)) 850 if (rand_s(&random32)) 851 return 0; /* failure */ 851 return 0; /* failure */ 852 852 853 for (; (i < sizeof(random32)) && (bytesWri 853 for (; (i < sizeof(random32)) && (bytesWrittenTotal < count); 854 i++, bytesWrittenTotal++) { 854 i++, bytesWrittenTotal++) { 855 const uint8_t random8 = (uint8_t)(random 855 const uint8_t random8 = (uint8_t)(random32 >> (i * 8)); 856 ((uint8_t *)target)[bytesWrittenTotal] = 856 ((uint8_t *)target)[bytesWrittenTotal] = random8; 857 } 857 } 858 } 858 } 859 return 1; /* success */ 859 return 1; /* success */ 860 } 860 } 861 861 862 #endif /* _WIN32 */ 862 #endif /* _WIN32 */ 863 863 864 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! define 864 #if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) 865 865 866 static unsigned long 866 static unsigned long 867 gather_time_entropy(void) { 867 gather_time_entropy(void) { 868 # ifdef _WIN32 868 # ifdef _WIN32 869 FILETIME ft; 869 FILETIME ft; 870 GetSystemTimeAsFileTime(&ft); /* never fails 870 GetSystemTimeAsFileTime(&ft); /* never fails */ 871 return ft.dwHighDateTime ^ ft.dwLowDateTime; 871 return ft.dwHighDateTime ^ ft.dwLowDateTime; 872 # else 872 # else 873 struct timeval tv; 873 struct timeval tv; 874 int gettimeofday_res; 874 int gettimeofday_res; 875 875 876 gettimeofday_res = gettimeofday(&tv, NULL); 876 gettimeofday_res = gettimeofday(&tv, NULL); 877 877 878 # if defined(NDEBUG) 878 # if defined(NDEBUG) 879 (void)gettimeofday_res; 879 (void)gettimeofday_res; 880 # else 880 # else 881 assert(gettimeofday_res == 0); 881 assert(gettimeofday_res == 0); 882 # endif /* defined(NDEBUG) */ 882 # endif /* defined(NDEBUG) */ 883 883 884 /* Microseconds time is <20 bits entropy */ 884 /* Microseconds time is <20 bits entropy */ 885 return tv.tv_usec; 885 return tv.tv_usec; 886 # endif 886 # endif 887 } 887 } 888 888 889 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! 889 #endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */ 890 890 891 static unsigned long 891 static unsigned long 892 ENTROPY_DEBUG(const char *label, unsigned long 892 ENTROPY_DEBUG(const char *label, unsigned long entropy) { 893 if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) 893 if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) { 894 fprintf(stderr, "expat: Entropy: %s --> 0x 894 fprintf(stderr, "expat: Entropy: %s --> 0x%0*lx (%lu bytes)\n", label, 895 (int)sizeof(entropy) * 2, entropy, 895 (int)sizeof(entropy) * 2, entropy, (unsigned long)sizeof(entropy)); 896 } 896 } 897 return entropy; 897 return entropy; 898 } 898 } 899 899 900 static unsigned long 900 static unsigned long 901 generate_hash_secret_salt(XML_Parser parser) { 901 generate_hash_secret_salt(XML_Parser parser) { 902 unsigned long entropy; 902 unsigned long entropy; 903 (void)parser; 903 (void)parser; 904 904 905 /* "Failproof" high quality providers: */ 905 /* "Failproof" high quality providers: */ 906 #if defined(HAVE_ARC4RANDOM_BUF) 906 #if defined(HAVE_ARC4RANDOM_BUF) 907 arc4random_buf(&entropy, sizeof(entropy)); 907 arc4random_buf(&entropy, sizeof(entropy)); 908 return ENTROPY_DEBUG("arc4random_buf", entro 908 return ENTROPY_DEBUG("arc4random_buf", entropy); 909 #elif defined(HAVE_ARC4RANDOM) 909 #elif defined(HAVE_ARC4RANDOM) 910 writeRandomBytes_arc4random((void *)&entropy 910 writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy)); 911 return ENTROPY_DEBUG("arc4random", entropy); 911 return ENTROPY_DEBUG("arc4random", entropy); 912 #else 912 #else 913 /* Try high quality providers first .. */ 913 /* Try high quality providers first .. */ 914 # ifdef _WIN32 914 # ifdef _WIN32 915 if (writeRandomBytes_rand_s((void *)&entropy 915 if (writeRandomBytes_rand_s((void *)&entropy, sizeof(entropy))) { 916 return ENTROPY_DEBUG("rand_s", entropy); 916 return ENTROPY_DEBUG("rand_s", entropy); 917 } 917 } 918 # elif defined(HAVE_GETRANDOM) || defined(HAV 918 # elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) 919 if (writeRandomBytes_getrandom_nonblock((voi 919 if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) { 920 return ENTROPY_DEBUG("getrandom", entropy) 920 return ENTROPY_DEBUG("getrandom", entropy); 921 } 921 } 922 # endif 922 # endif 923 # if ! defined(_WIN32) && defined(XML_DEV_URA 923 # if ! defined(_WIN32) && defined(XML_DEV_URANDOM) 924 if (writeRandomBytes_dev_urandom((void *)&en 924 if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) { 925 return ENTROPY_DEBUG("/dev/urandom", entro 925 return ENTROPY_DEBUG("/dev/urandom", entropy); 926 } 926 } 927 # endif /* ! defined(_WIN32) && defined(XML_D 927 # endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */ 928 /* .. and self-made low quality for backup: 928 /* .. and self-made low quality for backup: */ 929 929 930 /* Process ID is 0 bits entropy if attacker 930 /* Process ID is 0 bits entropy if attacker has local access */ 931 entropy = gather_time_entropy() ^ getpid(); 931 entropy = gather_time_entropy() ^ getpid(); 932 932 933 /* Factors are 2^31-1 and 2^61-1 (Mersenne p 933 /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ 934 if (sizeof(unsigned long) == 4) { 934 if (sizeof(unsigned long) == 4) { 935 return ENTROPY_DEBUG("fallback(4)", entrop 935 return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); 936 } else { 936 } else { 937 return ENTROPY_DEBUG("fallback(8)", 937 return ENTROPY_DEBUG("fallback(8)", 938 entropy * (unsigned l 938 entropy * (unsigned long)2305843009213693951ULL); 939 } 939 } 940 #endif 940 #endif 941 } 941 } 942 942 943 static unsigned long 943 static unsigned long 944 get_hash_secret_salt(XML_Parser parser) { 944 get_hash_secret_salt(XML_Parser parser) { 945 if (parser->m_parentParser != NULL) 945 if (parser->m_parentParser != NULL) 946 return get_hash_secret_salt(parser->m_pare 946 return get_hash_secret_salt(parser->m_parentParser); 947 return parser->m_hash_secret_salt; 947 return parser->m_hash_secret_salt; 948 } 948 } 949 949 950 static XML_Bool /* only valid for root parser 950 static XML_Bool /* only valid for root parser */ 951 startParsing(XML_Parser parser) { 951 startParsing(XML_Parser parser) { 952 /* hash functions must be initialized before 952 /* hash functions must be initialized before setContext() is called */ 953 if (parser->m_hash_secret_salt == 0) 953 if (parser->m_hash_secret_salt == 0) 954 parser->m_hash_secret_salt = generate_hash 954 parser->m_hash_secret_salt = generate_hash_secret_salt(parser); 955 if (parser->m_ns) { 955 if (parser->m_ns) { 956 /* implicit context only set for root pars 956 /* implicit context only set for root parser, since child 957 parsers (i.e. external entity parsers) 957 parsers (i.e. external entity parsers) will inherit it 958 */ 958 */ 959 return setContext(parser, implicitContext) 959 return setContext(parser, implicitContext); 960 } 960 } 961 return XML_TRUE; 961 return XML_TRUE; 962 } 962 } 963 963 964 XML_Parser XMLCALL 964 XML_Parser XMLCALL 965 XML_ParserCreate_MM(const XML_Char *encodingNa 965 XML_ParserCreate_MM(const XML_Char *encodingName, 966 const XML_Memory_Handling_ 966 const XML_Memory_Handling_Suite *memsuite, 967 const XML_Char *nameSep) { 967 const XML_Char *nameSep) { 968 return parserCreate(encodingName, memsuite, 968 return parserCreate(encodingName, memsuite, nameSep, NULL); 969 } 969 } 970 970 971 static XML_Parser 971 static XML_Parser 972 parserCreate(const XML_Char *encodingName, 972 parserCreate(const XML_Char *encodingName, 973 const XML_Memory_Handling_Suite * 973 const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep, 974 DTD *dtd) { 974 DTD *dtd) { 975 XML_Parser parser; 975 XML_Parser parser; 976 976 977 if (memsuite) { 977 if (memsuite) { 978 XML_Memory_Handling_Suite *mtemp; 978 XML_Memory_Handling_Suite *mtemp; 979 parser = memsuite->malloc_fcn(sizeof(struc 979 parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); 980 if (parser != NULL) { 980 if (parser != NULL) { 981 mtemp = (XML_Memory_Handling_Suite *)&(p 981 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); 982 mtemp->malloc_fcn = memsuite->malloc_fcn 982 mtemp->malloc_fcn = memsuite->malloc_fcn; 983 mtemp->realloc_fcn = memsuite->realloc_f 983 mtemp->realloc_fcn = memsuite->realloc_fcn; 984 mtemp->free_fcn = memsuite->free_fcn; 984 mtemp->free_fcn = memsuite->free_fcn; 985 } 985 } 986 } else { 986 } else { 987 XML_Memory_Handling_Suite *mtemp; 987 XML_Memory_Handling_Suite *mtemp; 988 parser = (XML_Parser)malloc(sizeof(struct 988 parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); 989 if (parser != NULL) { 989 if (parser != NULL) { 990 mtemp = (XML_Memory_Handling_Suite *)&(p 990 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); 991 mtemp->malloc_fcn = malloc; 991 mtemp->malloc_fcn = malloc; 992 mtemp->realloc_fcn = realloc; 992 mtemp->realloc_fcn = realloc; 993 mtemp->free_fcn = free; 993 mtemp->free_fcn = free; 994 } 994 } 995 } 995 } 996 996 997 if (! parser) 997 if (! parser) 998 return parser; 998 return parser; 999 999 1000 parser->m_buffer = NULL; 1000 parser->m_buffer = NULL; 1001 parser->m_bufferLim = NULL; 1001 parser->m_bufferLim = NULL; 1002 1002 1003 parser->m_attsSize = INIT_ATTS_SIZE; 1003 parser->m_attsSize = INIT_ATTS_SIZE; 1004 parser->m_atts 1004 parser->m_atts 1005 = (ATTRIBUTE *)MALLOC(parser, parser->m 1005 = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE)); 1006 if (parser->m_atts == NULL) { 1006 if (parser->m_atts == NULL) { 1007 FREE(parser, parser); 1007 FREE(parser, parser); 1008 return NULL; 1008 return NULL; 1009 } 1009 } 1010 #ifdef XML_ATTR_INFO 1010 #ifdef XML_ATTR_INFO 1011 parser->m_attInfo = (XML_AttrInfo *)MALLOC( 1011 parser->m_attInfo = (XML_AttrInfo *)MALLOC( 1012 parser, parser->m_attsSize * sizeof(XML 1012 parser, parser->m_attsSize * sizeof(XML_AttrInfo)); 1013 if (parser->m_attInfo == NULL) { 1013 if (parser->m_attInfo == NULL) { 1014 FREE(parser, parser->m_atts); 1014 FREE(parser, parser->m_atts); 1015 FREE(parser, parser); 1015 FREE(parser, parser); 1016 return NULL; 1016 return NULL; 1017 } 1017 } 1018 #endif 1018 #endif 1019 parser->m_dataBuf 1019 parser->m_dataBuf 1020 = (XML_Char *)MALLOC(parser, INIT_DATA_ 1020 = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char)); 1021 if (parser->m_dataBuf == NULL) { 1021 if (parser->m_dataBuf == NULL) { 1022 FREE(parser, parser->m_atts); 1022 FREE(parser, parser->m_atts); 1023 #ifdef XML_ATTR_INFO 1023 #ifdef XML_ATTR_INFO 1024 FREE(parser, parser->m_attInfo); 1024 FREE(parser, parser->m_attInfo); 1025 #endif 1025 #endif 1026 FREE(parser, parser); 1026 FREE(parser, parser); 1027 return NULL; 1027 return NULL; 1028 } 1028 } 1029 parser->m_dataBufEnd = parser->m_dataBuf + 1029 parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE; 1030 1030 1031 if (dtd) 1031 if (dtd) 1032 parser->m_dtd = dtd; 1032 parser->m_dtd = dtd; 1033 else { 1033 else { 1034 parser->m_dtd = dtdCreate(&parser->m_mem) 1034 parser->m_dtd = dtdCreate(&parser->m_mem); 1035 if (parser->m_dtd == NULL) { 1035 if (parser->m_dtd == NULL) { 1036 FREE(parser, parser->m_dataBuf); 1036 FREE(parser, parser->m_dataBuf); 1037 FREE(parser, parser->m_atts); 1037 FREE(parser, parser->m_atts); 1038 #ifdef XML_ATTR_INFO 1038 #ifdef XML_ATTR_INFO 1039 FREE(parser, parser->m_attInfo); 1039 FREE(parser, parser->m_attInfo); 1040 #endif 1040 #endif 1041 FREE(parser, parser); 1041 FREE(parser, parser); 1042 return NULL; 1042 return NULL; 1043 } 1043 } 1044 } 1044 } 1045 1045 1046 parser->m_freeBindingList = NULL; 1046 parser->m_freeBindingList = NULL; 1047 parser->m_freeTagList = NULL; 1047 parser->m_freeTagList = NULL; 1048 parser->m_freeInternalEntities = NULL; 1048 parser->m_freeInternalEntities = NULL; 1049 1049 1050 parser->m_groupSize = 0; 1050 parser->m_groupSize = 0; 1051 parser->m_groupConnector = NULL; 1051 parser->m_groupConnector = NULL; 1052 1052 1053 parser->m_unknownEncodingHandler = NULL; 1053 parser->m_unknownEncodingHandler = NULL; 1054 parser->m_unknownEncodingHandlerData = NULL 1054 parser->m_unknownEncodingHandlerData = NULL; 1055 1055 1056 parser->m_namespaceSeparator = ASCII_EXCL; 1056 parser->m_namespaceSeparator = ASCII_EXCL; 1057 parser->m_ns = XML_FALSE; 1057 parser->m_ns = XML_FALSE; 1058 parser->m_ns_triplets = XML_FALSE; 1058 parser->m_ns_triplets = XML_FALSE; 1059 1059 1060 parser->m_nsAtts = NULL; 1060 parser->m_nsAtts = NULL; 1061 parser->m_nsAttsVersion = 0; 1061 parser->m_nsAttsVersion = 0; 1062 parser->m_nsAttsPower = 0; 1062 parser->m_nsAttsPower = 0; 1063 1063 1064 parser->m_protocolEncodingName = NULL; 1064 parser->m_protocolEncodingName = NULL; 1065 1065 1066 poolInit(&parser->m_tempPool, &(parser->m_m 1066 poolInit(&parser->m_tempPool, &(parser->m_mem)); 1067 poolInit(&parser->m_temp2Pool, &(parser->m_ 1067 poolInit(&parser->m_temp2Pool, &(parser->m_mem)); 1068 parserInit(parser, encodingName); 1068 parserInit(parser, encodingName); 1069 1069 1070 if (encodingName && ! parser->m_protocolEnc 1070 if (encodingName && ! parser->m_protocolEncodingName) { 1071 XML_ParserFree(parser); 1071 XML_ParserFree(parser); 1072 return NULL; 1072 return NULL; 1073 } 1073 } 1074 1074 1075 if (nameSep) { 1075 if (nameSep) { 1076 parser->m_ns = XML_TRUE; 1076 parser->m_ns = XML_TRUE; 1077 parser->m_internalEncoding = XmlGetIntern 1077 parser->m_internalEncoding = XmlGetInternalEncodingNS(); 1078 parser->m_namespaceSeparator = *nameSep; 1078 parser->m_namespaceSeparator = *nameSep; 1079 } else { 1079 } else { 1080 parser->m_internalEncoding = XmlGetIntern 1080 parser->m_internalEncoding = XmlGetInternalEncoding(); 1081 } 1081 } 1082 1082 1083 return parser; 1083 return parser; 1084 } 1084 } 1085 1085 1086 static void 1086 static void 1087 parserInit(XML_Parser parser, const XML_Char 1087 parserInit(XML_Parser parser, const XML_Char *encodingName) { 1088 parser->m_processor = prologInitProcessor; 1088 parser->m_processor = prologInitProcessor; 1089 XmlPrologStateInit(&parser->m_prologState); 1089 XmlPrologStateInit(&parser->m_prologState); 1090 if (encodingName != NULL) { 1090 if (encodingName != NULL) { 1091 parser->m_protocolEncodingName = copyStri 1091 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); 1092 } 1092 } 1093 parser->m_curBase = NULL; 1093 parser->m_curBase = NULL; 1094 XmlInitEncoding(&parser->m_initEncoding, &p 1094 XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0); 1095 parser->m_userData = NULL; 1095 parser->m_userData = NULL; 1096 parser->m_handlerArg = NULL; 1096 parser->m_handlerArg = NULL; 1097 parser->m_startElementHandler = NULL; 1097 parser->m_startElementHandler = NULL; 1098 parser->m_endElementHandler = NULL; 1098 parser->m_endElementHandler = NULL; 1099 parser->m_characterDataHandler = NULL; 1099 parser->m_characterDataHandler = NULL; 1100 parser->m_processingInstructionHandler = NU 1100 parser->m_processingInstructionHandler = NULL; 1101 parser->m_commentHandler = NULL; 1101 parser->m_commentHandler = NULL; 1102 parser->m_startCdataSectionHandler = NULL; 1102 parser->m_startCdataSectionHandler = NULL; 1103 parser->m_endCdataSectionHandler = NULL; 1103 parser->m_endCdataSectionHandler = NULL; 1104 parser->m_defaultHandler = NULL; 1104 parser->m_defaultHandler = NULL; 1105 parser->m_startDoctypeDeclHandler = NULL; 1105 parser->m_startDoctypeDeclHandler = NULL; 1106 parser->m_endDoctypeDeclHandler = NULL; 1106 parser->m_endDoctypeDeclHandler = NULL; 1107 parser->m_unparsedEntityDeclHandler = NULL; 1107 parser->m_unparsedEntityDeclHandler = NULL; 1108 parser->m_notationDeclHandler = NULL; 1108 parser->m_notationDeclHandler = NULL; 1109 parser->m_startNamespaceDeclHandler = NULL; 1109 parser->m_startNamespaceDeclHandler = NULL; 1110 parser->m_endNamespaceDeclHandler = NULL; 1110 parser->m_endNamespaceDeclHandler = NULL; 1111 parser->m_notStandaloneHandler = NULL; 1111 parser->m_notStandaloneHandler = NULL; 1112 parser->m_externalEntityRefHandler = NULL; 1112 parser->m_externalEntityRefHandler = NULL; 1113 parser->m_externalEntityRefHandlerArg = par 1113 parser->m_externalEntityRefHandlerArg = parser; 1114 parser->m_skippedEntityHandler = NULL; 1114 parser->m_skippedEntityHandler = NULL; 1115 parser->m_elementDeclHandler = NULL; 1115 parser->m_elementDeclHandler = NULL; 1116 parser->m_attlistDeclHandler = NULL; 1116 parser->m_attlistDeclHandler = NULL; 1117 parser->m_entityDeclHandler = NULL; 1117 parser->m_entityDeclHandler = NULL; 1118 parser->m_xmlDeclHandler = NULL; 1118 parser->m_xmlDeclHandler = NULL; 1119 parser->m_bufferPtr = parser->m_buffer; 1119 parser->m_bufferPtr = parser->m_buffer; 1120 parser->m_bufferEnd = parser->m_buffer; 1120 parser->m_bufferEnd = parser->m_buffer; 1121 parser->m_parseEndByteIndex = 0; 1121 parser->m_parseEndByteIndex = 0; 1122 parser->m_parseEndPtr = NULL; 1122 parser->m_parseEndPtr = NULL; 1123 parser->m_declElementType = NULL; 1123 parser->m_declElementType = NULL; 1124 parser->m_declAttributeId = NULL; 1124 parser->m_declAttributeId = NULL; 1125 parser->m_declEntity = NULL; 1125 parser->m_declEntity = NULL; 1126 parser->m_doctypeName = NULL; 1126 parser->m_doctypeName = NULL; 1127 parser->m_doctypeSysid = NULL; 1127 parser->m_doctypeSysid = NULL; 1128 parser->m_doctypePubid = NULL; 1128 parser->m_doctypePubid = NULL; 1129 parser->m_declAttributeType = NULL; 1129 parser->m_declAttributeType = NULL; 1130 parser->m_declNotationName = NULL; 1130 parser->m_declNotationName = NULL; 1131 parser->m_declNotationPublicId = NULL; 1131 parser->m_declNotationPublicId = NULL; 1132 parser->m_declAttributeIsCdata = XML_FALSE; 1132 parser->m_declAttributeIsCdata = XML_FALSE; 1133 parser->m_declAttributeIsId = XML_FALSE; 1133 parser->m_declAttributeIsId = XML_FALSE; 1134 memset(&parser->m_position, 0, sizeof(POSIT 1134 memset(&parser->m_position, 0, sizeof(POSITION)); 1135 parser->m_errorCode = XML_ERROR_NONE; 1135 parser->m_errorCode = XML_ERROR_NONE; 1136 parser->m_eventPtr = NULL; 1136 parser->m_eventPtr = NULL; 1137 parser->m_eventEndPtr = NULL; 1137 parser->m_eventEndPtr = NULL; 1138 parser->m_positionPtr = NULL; 1138 parser->m_positionPtr = NULL; 1139 parser->m_openInternalEntities = NULL; 1139 parser->m_openInternalEntities = NULL; 1140 parser->m_defaultExpandInternalEntities = X 1140 parser->m_defaultExpandInternalEntities = XML_TRUE; 1141 parser->m_tagLevel = 0; 1141 parser->m_tagLevel = 0; 1142 parser->m_tagStack = NULL; 1142 parser->m_tagStack = NULL; 1143 parser->m_inheritedBindings = NULL; 1143 parser->m_inheritedBindings = NULL; 1144 parser->m_nSpecifiedAtts = 0; 1144 parser->m_nSpecifiedAtts = 0; 1145 parser->m_unknownEncodingMem = NULL; 1145 parser->m_unknownEncodingMem = NULL; 1146 parser->m_unknownEncodingRelease = NULL; 1146 parser->m_unknownEncodingRelease = NULL; 1147 parser->m_unknownEncodingData = NULL; 1147 parser->m_unknownEncodingData = NULL; 1148 parser->m_parentParser = NULL; 1148 parser->m_parentParser = NULL; 1149 parser->m_parsingStatus.parsing = XML_INITI 1149 parser->m_parsingStatus.parsing = XML_INITIALIZED; 1150 #ifdef XML_DTD 1150 #ifdef XML_DTD 1151 parser->m_isParamEntity = XML_FALSE; 1151 parser->m_isParamEntity = XML_FALSE; 1152 parser->m_useForeignDTD = XML_FALSE; 1152 parser->m_useForeignDTD = XML_FALSE; 1153 parser->m_paramEntityParsing = XML_PARAM_EN 1153 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 1154 #endif 1154 #endif 1155 parser->m_hash_secret_salt = 0; 1155 parser->m_hash_secret_salt = 0; 1156 1156 1157 #ifdef XML_DTD 1157 #ifdef XML_DTD 1158 memset(&parser->m_accounting, 0, sizeof(ACC 1158 memset(&parser->m_accounting, 0, sizeof(ACCOUNTING)); 1159 parser->m_accounting.debugLevel = getDebugL 1159 parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u); 1160 parser->m_accounting.maximumAmplificationFa 1160 parser->m_accounting.maximumAmplificationFactor 1161 = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTIO 1161 = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT; 1162 parser->m_accounting.activationThresholdByt 1162 parser->m_accounting.activationThresholdBytes 1163 = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTIO 1163 = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT; 1164 1164 1165 memset(&parser->m_entity_stats, 0, sizeof(E 1165 memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS)); 1166 parser->m_entity_stats.debugLevel = getDebu 1166 parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u); 1167 #endif 1167 #endif 1168 } 1168 } 1169 1169 1170 /* moves list of bindings to m_freeBindingLis 1170 /* moves list of bindings to m_freeBindingList */ 1171 static void FASTCALL 1171 static void FASTCALL 1172 moveToFreeBindingList(XML_Parser parser, BIND 1172 moveToFreeBindingList(XML_Parser parser, BINDING *bindings) { 1173 while (bindings) { 1173 while (bindings) { 1174 BINDING *b = bindings; 1174 BINDING *b = bindings; 1175 bindings = bindings->nextTagBinding; 1175 bindings = bindings->nextTagBinding; 1176 b->nextTagBinding = parser->m_freeBinding 1176 b->nextTagBinding = parser->m_freeBindingList; 1177 parser->m_freeBindingList = b; 1177 parser->m_freeBindingList = b; 1178 } 1178 } 1179 } 1179 } 1180 1180 1181 XML_Bool XMLCALL 1181 XML_Bool XMLCALL 1182 XML_ParserReset(XML_Parser parser, const XML_ 1182 XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { 1183 TAG *tStk; 1183 TAG *tStk; 1184 OPEN_INTERNAL_ENTITY *openEntityList; 1184 OPEN_INTERNAL_ENTITY *openEntityList; 1185 1185 1186 if (parser == NULL) 1186 if (parser == NULL) 1187 return XML_FALSE; 1187 return XML_FALSE; 1188 1188 1189 if (parser->m_parentParser) 1189 if (parser->m_parentParser) 1190 return XML_FALSE; 1190 return XML_FALSE; 1191 /* move m_tagStack to m_freeTagList */ 1191 /* move m_tagStack to m_freeTagList */ 1192 tStk = parser->m_tagStack; 1192 tStk = parser->m_tagStack; 1193 while (tStk) { 1193 while (tStk) { 1194 TAG *tag = tStk; 1194 TAG *tag = tStk; 1195 tStk = tStk->parent; 1195 tStk = tStk->parent; 1196 tag->parent = parser->m_freeTagList; 1196 tag->parent = parser->m_freeTagList; 1197 moveToFreeBindingList(parser, tag->bindin 1197 moveToFreeBindingList(parser, tag->bindings); 1198 tag->bindings = NULL; 1198 tag->bindings = NULL; 1199 parser->m_freeTagList = tag; 1199 parser->m_freeTagList = tag; 1200 } 1200 } 1201 /* move m_openInternalEntities to m_freeInt 1201 /* move m_openInternalEntities to m_freeInternalEntities */ 1202 openEntityList = parser->m_openInternalEnti 1202 openEntityList = parser->m_openInternalEntities; 1203 while (openEntityList) { 1203 while (openEntityList) { 1204 OPEN_INTERNAL_ENTITY *openEntity = openEn 1204 OPEN_INTERNAL_ENTITY *openEntity = openEntityList; 1205 openEntityList = openEntity->next; 1205 openEntityList = openEntity->next; 1206 openEntity->next = parser->m_freeInternal 1206 openEntity->next = parser->m_freeInternalEntities; 1207 parser->m_freeInternalEntities = openEnti 1207 parser->m_freeInternalEntities = openEntity; 1208 } 1208 } 1209 moveToFreeBindingList(parser, parser->m_inh 1209 moveToFreeBindingList(parser, parser->m_inheritedBindings); 1210 FREE(parser, parser->m_unknownEncodingMem); 1210 FREE(parser, parser->m_unknownEncodingMem); 1211 if (parser->m_unknownEncodingRelease) 1211 if (parser->m_unknownEncodingRelease) 1212 parser->m_unknownEncodingRelease(parser-> 1212 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); 1213 poolClear(&parser->m_tempPool); 1213 poolClear(&parser->m_tempPool); 1214 poolClear(&parser->m_temp2Pool); 1214 poolClear(&parser->m_temp2Pool); 1215 FREE(parser, (void *)parser->m_protocolEnco 1215 FREE(parser, (void *)parser->m_protocolEncodingName); 1216 parser->m_protocolEncodingName = NULL; 1216 parser->m_protocolEncodingName = NULL; 1217 parserInit(parser, encodingName); 1217 parserInit(parser, encodingName); 1218 dtdReset(parser->m_dtd, &parser->m_mem); 1218 dtdReset(parser->m_dtd, &parser->m_mem); 1219 return XML_TRUE; 1219 return XML_TRUE; 1220 } 1220 } 1221 1221 1222 enum XML_Status XMLCALL 1222 enum XML_Status XMLCALL 1223 XML_SetEncoding(XML_Parser parser, const XML_ 1223 XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { 1224 if (parser == NULL) 1224 if (parser == NULL) 1225 return XML_STATUS_ERROR; 1225 return XML_STATUS_ERROR; 1226 /* Block after XML_Parse()/XML_ParseBuffer( 1226 /* Block after XML_Parse()/XML_ParseBuffer() has been called. 1227 XXX There's no way for the caller to det 1227 XXX There's no way for the caller to determine which of the 1228 XXX possible error cases caused the XML_ 1228 XXX possible error cases caused the XML_STATUS_ERROR return. 1229 */ 1229 */ 1230 if (parser->m_parsingStatus.parsing == XML_ 1230 if (parser->m_parsingStatus.parsing == XML_PARSING 1231 || parser->m_parsingStatus.parsing == X 1231 || parser->m_parsingStatus.parsing == XML_SUSPENDED) 1232 return XML_STATUS_ERROR; 1232 return XML_STATUS_ERROR; 1233 1233 1234 /* Get rid of any previous encoding name */ 1234 /* Get rid of any previous encoding name */ 1235 FREE(parser, (void *)parser->m_protocolEnco 1235 FREE(parser, (void *)parser->m_protocolEncodingName); 1236 1236 1237 if (encodingName == NULL) 1237 if (encodingName == NULL) 1238 /* No new encoding name */ 1238 /* No new encoding name */ 1239 parser->m_protocolEncodingName = NULL; 1239 parser->m_protocolEncodingName = NULL; 1240 else { 1240 else { 1241 /* Copy the new encoding name into alloca 1241 /* Copy the new encoding name into allocated memory */ 1242 parser->m_protocolEncodingName = copyStri 1242 parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem)); 1243 if (! parser->m_protocolEncodingName) 1243 if (! parser->m_protocolEncodingName) 1244 return XML_STATUS_ERROR; 1244 return XML_STATUS_ERROR; 1245 } 1245 } 1246 return XML_STATUS_OK; 1246 return XML_STATUS_OK; 1247 } 1247 } 1248 1248 1249 XML_Parser XMLCALL 1249 XML_Parser XMLCALL 1250 XML_ExternalEntityParserCreate(XML_Parser old 1250 XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, 1251 const XML_Char 1251 const XML_Char *encodingName) { 1252 XML_Parser parser = oldParser; 1252 XML_Parser parser = oldParser; 1253 DTD *newDtd = NULL; 1253 DTD *newDtd = NULL; 1254 DTD *oldDtd; 1254 DTD *oldDtd; 1255 XML_StartElementHandler oldStartElementHand 1255 XML_StartElementHandler oldStartElementHandler; 1256 XML_EndElementHandler oldEndElementHandler; 1256 XML_EndElementHandler oldEndElementHandler; 1257 XML_CharacterDataHandler oldCharacterDataHa 1257 XML_CharacterDataHandler oldCharacterDataHandler; 1258 XML_ProcessingInstructionHandler oldProcess 1258 XML_ProcessingInstructionHandler oldProcessingInstructionHandler; 1259 XML_CommentHandler oldCommentHandler; 1259 XML_CommentHandler oldCommentHandler; 1260 XML_StartCdataSectionHandler oldStartCdataS 1260 XML_StartCdataSectionHandler oldStartCdataSectionHandler; 1261 XML_EndCdataSectionHandler oldEndCdataSecti 1261 XML_EndCdataSectionHandler oldEndCdataSectionHandler; 1262 XML_DefaultHandler oldDefaultHandler; 1262 XML_DefaultHandler oldDefaultHandler; 1263 XML_UnparsedEntityDeclHandler oldUnparsedEn 1263 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; 1264 XML_NotationDeclHandler oldNotationDeclHand 1264 XML_NotationDeclHandler oldNotationDeclHandler; 1265 XML_StartNamespaceDeclHandler oldStartNames 1265 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; 1266 XML_EndNamespaceDeclHandler oldEndNamespace 1266 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; 1267 XML_NotStandaloneHandler oldNotStandaloneHa 1267 XML_NotStandaloneHandler oldNotStandaloneHandler; 1268 XML_ExternalEntityRefHandler oldExternalEnt 1268 XML_ExternalEntityRefHandler oldExternalEntityRefHandler; 1269 XML_SkippedEntityHandler oldSkippedEntityHa 1269 XML_SkippedEntityHandler oldSkippedEntityHandler; 1270 XML_UnknownEncodingHandler oldUnknownEncodi 1270 XML_UnknownEncodingHandler oldUnknownEncodingHandler; 1271 XML_ElementDeclHandler oldElementDeclHandle 1271 XML_ElementDeclHandler oldElementDeclHandler; 1272 XML_AttlistDeclHandler oldAttlistDeclHandle 1272 XML_AttlistDeclHandler oldAttlistDeclHandler; 1273 XML_EntityDeclHandler oldEntityDeclHandler; 1273 XML_EntityDeclHandler oldEntityDeclHandler; 1274 XML_XmlDeclHandler oldXmlDeclHandler; 1274 XML_XmlDeclHandler oldXmlDeclHandler; 1275 ELEMENT_TYPE *oldDeclElementType; 1275 ELEMENT_TYPE *oldDeclElementType; 1276 1276 1277 void *oldUserData; 1277 void *oldUserData; 1278 void *oldHandlerArg; 1278 void *oldHandlerArg; 1279 XML_Bool oldDefaultExpandInternalEntities; 1279 XML_Bool oldDefaultExpandInternalEntities; 1280 XML_Parser oldExternalEntityRefHandlerArg; 1280 XML_Parser oldExternalEntityRefHandlerArg; 1281 #ifdef XML_DTD 1281 #ifdef XML_DTD 1282 enum XML_ParamEntityParsing oldParamEntityP 1282 enum XML_ParamEntityParsing oldParamEntityParsing; 1283 int oldInEntityValue; 1283 int oldInEntityValue; 1284 #endif 1284 #endif 1285 XML_Bool oldns_triplets; 1285 XML_Bool oldns_triplets; 1286 /* Note that the new parser shares the same 1286 /* Note that the new parser shares the same hash secret as the old 1287 parser, so that dtdCopy and copyEntityTa 1287 parser, so that dtdCopy and copyEntityTable can lookup values 1288 from hash tables associated with either 1288 from hash tables associated with either parser without us having 1289 to worry which hash secrets each table h 1289 to worry which hash secrets each table has. 1290 */ 1290 */ 1291 unsigned long oldhash_secret_salt; 1291 unsigned long oldhash_secret_salt; 1292 1292 1293 /* Validate the oldParser parameter before 1293 /* Validate the oldParser parameter before we pull everything out of it */ 1294 if (oldParser == NULL) 1294 if (oldParser == NULL) 1295 return NULL; 1295 return NULL; 1296 1296 1297 /* Stash the original parser contents on th 1297 /* Stash the original parser contents on the stack */ 1298 oldDtd = parser->m_dtd; 1298 oldDtd = parser->m_dtd; 1299 oldStartElementHandler = parser->m_startEle 1299 oldStartElementHandler = parser->m_startElementHandler; 1300 oldEndElementHandler = parser->m_endElement 1300 oldEndElementHandler = parser->m_endElementHandler; 1301 oldCharacterDataHandler = parser->m_charact 1301 oldCharacterDataHandler = parser->m_characterDataHandler; 1302 oldProcessingInstructionHandler = parser->m 1302 oldProcessingInstructionHandler = parser->m_processingInstructionHandler; 1303 oldCommentHandler = parser->m_commentHandle 1303 oldCommentHandler = parser->m_commentHandler; 1304 oldStartCdataSectionHandler = parser->m_sta 1304 oldStartCdataSectionHandler = parser->m_startCdataSectionHandler; 1305 oldEndCdataSectionHandler = parser->m_endCd 1305 oldEndCdataSectionHandler = parser->m_endCdataSectionHandler; 1306 oldDefaultHandler = parser->m_defaultHandle 1306 oldDefaultHandler = parser->m_defaultHandler; 1307 oldUnparsedEntityDeclHandler = parser->m_un 1307 oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler; 1308 oldNotationDeclHandler = parser->m_notation 1308 oldNotationDeclHandler = parser->m_notationDeclHandler; 1309 oldStartNamespaceDeclHandler = parser->m_st 1309 oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler; 1310 oldEndNamespaceDeclHandler = parser->m_endN 1310 oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler; 1311 oldNotStandaloneHandler = parser->m_notStan 1311 oldNotStandaloneHandler = parser->m_notStandaloneHandler; 1312 oldExternalEntityRefHandler = parser->m_ext 1312 oldExternalEntityRefHandler = parser->m_externalEntityRefHandler; 1313 oldSkippedEntityHandler = parser->m_skipped 1313 oldSkippedEntityHandler = parser->m_skippedEntityHandler; 1314 oldUnknownEncodingHandler = parser->m_unkno 1314 oldUnknownEncodingHandler = parser->m_unknownEncodingHandler; 1315 oldElementDeclHandler = parser->m_elementDe 1315 oldElementDeclHandler = parser->m_elementDeclHandler; 1316 oldAttlistDeclHandler = parser->m_attlistDe 1316 oldAttlistDeclHandler = parser->m_attlistDeclHandler; 1317 oldEntityDeclHandler = parser->m_entityDecl 1317 oldEntityDeclHandler = parser->m_entityDeclHandler; 1318 oldXmlDeclHandler = parser->m_xmlDeclHandle 1318 oldXmlDeclHandler = parser->m_xmlDeclHandler; 1319 oldDeclElementType = parser->m_declElementT 1319 oldDeclElementType = parser->m_declElementType; 1320 1320 1321 oldUserData = parser->m_userData; 1321 oldUserData = parser->m_userData; 1322 oldHandlerArg = parser->m_handlerArg; 1322 oldHandlerArg = parser->m_handlerArg; 1323 oldDefaultExpandInternalEntities = parser-> 1323 oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities; 1324 oldExternalEntityRefHandlerArg = parser->m_ 1324 oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg; 1325 #ifdef XML_DTD 1325 #ifdef XML_DTD 1326 oldParamEntityParsing = parser->m_paramEnti 1326 oldParamEntityParsing = parser->m_paramEntityParsing; 1327 oldInEntityValue = parser->m_prologState.in 1327 oldInEntityValue = parser->m_prologState.inEntityValue; 1328 #endif 1328 #endif 1329 oldns_triplets = parser->m_ns_triplets; 1329 oldns_triplets = parser->m_ns_triplets; 1330 /* Note that the new parser shares the same 1330 /* Note that the new parser shares the same hash secret as the old 1331 parser, so that dtdCopy and copyEntityTa 1331 parser, so that dtdCopy and copyEntityTable can lookup values 1332 from hash tables associated with either 1332 from hash tables associated with either parser without us having 1333 to worry which hash secrets each table h 1333 to worry which hash secrets each table has. 1334 */ 1334 */ 1335 oldhash_secret_salt = parser->m_hash_secret 1335 oldhash_secret_salt = parser->m_hash_secret_salt; 1336 1336 1337 #ifdef XML_DTD 1337 #ifdef XML_DTD 1338 if (! context) 1338 if (! context) 1339 newDtd = oldDtd; 1339 newDtd = oldDtd; 1340 #endif /* XML_DTD */ 1340 #endif /* XML_DTD */ 1341 1341 1342 /* Note that the magical uses of the pre-pr 1342 /* Note that the magical uses of the pre-processor to make field 1343 access look more like C++ require that ` 1343 access look more like C++ require that `parser' be overwritten 1344 here. This makes this function more pai 1344 here. This makes this function more painful to follow than it 1345 would be otherwise. 1345 would be otherwise. 1346 */ 1346 */ 1347 if (parser->m_ns) { 1347 if (parser->m_ns) { 1348 XML_Char tmp[2] = {parser->m_namespaceSep 1348 XML_Char tmp[2] = {parser->m_namespaceSeparator, 0}; 1349 parser = parserCreate(encodingName, &pars 1349 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); 1350 } else { 1350 } else { 1351 parser = parserCreate(encodingName, &pars 1351 parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); 1352 } 1352 } 1353 1353 1354 if (! parser) 1354 if (! parser) 1355 return NULL; 1355 return NULL; 1356 1356 1357 parser->m_startElementHandler = oldStartEle 1357 parser->m_startElementHandler = oldStartElementHandler; 1358 parser->m_endElementHandler = oldEndElement 1358 parser->m_endElementHandler = oldEndElementHandler; 1359 parser->m_characterDataHandler = oldCharact 1359 parser->m_characterDataHandler = oldCharacterDataHandler; 1360 parser->m_processingInstructionHandler = ol 1360 parser->m_processingInstructionHandler = oldProcessingInstructionHandler; 1361 parser->m_commentHandler = oldCommentHandle 1361 parser->m_commentHandler = oldCommentHandler; 1362 parser->m_startCdataSectionHandler = oldSta 1362 parser->m_startCdataSectionHandler = oldStartCdataSectionHandler; 1363 parser->m_endCdataSectionHandler = oldEndCd 1363 parser->m_endCdataSectionHandler = oldEndCdataSectionHandler; 1364 parser->m_defaultHandler = oldDefaultHandle 1364 parser->m_defaultHandler = oldDefaultHandler; 1365 parser->m_unparsedEntityDeclHandler = oldUn 1365 parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; 1366 parser->m_notationDeclHandler = oldNotation 1366 parser->m_notationDeclHandler = oldNotationDeclHandler; 1367 parser->m_startNamespaceDeclHandler = oldSt 1367 parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler; 1368 parser->m_endNamespaceDeclHandler = oldEndN 1368 parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler; 1369 parser->m_notStandaloneHandler = oldNotStan 1369 parser->m_notStandaloneHandler = oldNotStandaloneHandler; 1370 parser->m_externalEntityRefHandler = oldExt 1370 parser->m_externalEntityRefHandler = oldExternalEntityRefHandler; 1371 parser->m_skippedEntityHandler = oldSkipped 1371 parser->m_skippedEntityHandler = oldSkippedEntityHandler; 1372 parser->m_unknownEncodingHandler = oldUnkno 1372 parser->m_unknownEncodingHandler = oldUnknownEncodingHandler; 1373 parser->m_elementDeclHandler = oldElementDe 1373 parser->m_elementDeclHandler = oldElementDeclHandler; 1374 parser->m_attlistDeclHandler = oldAttlistDe 1374 parser->m_attlistDeclHandler = oldAttlistDeclHandler; 1375 parser->m_entityDeclHandler = oldEntityDecl 1375 parser->m_entityDeclHandler = oldEntityDeclHandler; 1376 parser->m_xmlDeclHandler = oldXmlDeclHandle 1376 parser->m_xmlDeclHandler = oldXmlDeclHandler; 1377 parser->m_declElementType = oldDeclElementT 1377 parser->m_declElementType = oldDeclElementType; 1378 parser->m_userData = oldUserData; 1378 parser->m_userData = oldUserData; 1379 if (oldUserData == oldHandlerArg) 1379 if (oldUserData == oldHandlerArg) 1380 parser->m_handlerArg = parser->m_userData 1380 parser->m_handlerArg = parser->m_userData; 1381 else 1381 else 1382 parser->m_handlerArg = parser; 1382 parser->m_handlerArg = parser; 1383 if (oldExternalEntityRefHandlerArg != oldPa 1383 if (oldExternalEntityRefHandlerArg != oldParser) 1384 parser->m_externalEntityRefHandlerArg = o 1384 parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; 1385 parser->m_defaultExpandInternalEntities = o 1385 parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities; 1386 parser->m_ns_triplets = oldns_triplets; 1386 parser->m_ns_triplets = oldns_triplets; 1387 parser->m_hash_secret_salt = oldhash_secret 1387 parser->m_hash_secret_salt = oldhash_secret_salt; 1388 parser->m_parentParser = oldParser; 1388 parser->m_parentParser = oldParser; 1389 #ifdef XML_DTD 1389 #ifdef XML_DTD 1390 parser->m_paramEntityParsing = oldParamEnti 1390 parser->m_paramEntityParsing = oldParamEntityParsing; 1391 parser->m_prologState.inEntityValue = oldIn 1391 parser->m_prologState.inEntityValue = oldInEntityValue; 1392 if (context) { 1392 if (context) { 1393 #endif /* XML_DTD */ 1393 #endif /* XML_DTD */ 1394 if (! dtdCopy(oldParser, parser->m_dtd, o 1394 if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem) 1395 || ! setContext(parser, context)) { 1395 || ! setContext(parser, context)) { 1396 XML_ParserFree(parser); 1396 XML_ParserFree(parser); 1397 return NULL; 1397 return NULL; 1398 } 1398 } 1399 parser->m_processor = externalEntityInitP 1399 parser->m_processor = externalEntityInitProcessor; 1400 #ifdef XML_DTD 1400 #ifdef XML_DTD 1401 } else { 1401 } else { 1402 /* The DTD instance referenced by parser- 1402 /* The DTD instance referenced by parser->m_dtd is shared between the 1403 document's root parser and external PE 1403 document's root parser and external PE parsers, therefore one does not 1404 need to call setContext. In addition, 1404 need to call setContext. In addition, one also *must* not call 1405 setContext, because this would overwri 1405 setContext, because this would overwrite existing prefix->binding 1406 pointers in parser->m_dtd with ones th 1406 pointers in parser->m_dtd with ones that get destroyed with the external 1407 PE parser. This would leave those pref 1407 PE parser. This would leave those prefixes with dangling pointers. 1408 */ 1408 */ 1409 parser->m_isParamEntity = XML_TRUE; 1409 parser->m_isParamEntity = XML_TRUE; 1410 XmlPrologStateInitExternalEntity(&parser- 1410 XmlPrologStateInitExternalEntity(&parser->m_prologState); 1411 parser->m_processor = externalParEntInitP 1411 parser->m_processor = externalParEntInitProcessor; 1412 } 1412 } 1413 #endif /* XML_DTD */ 1413 #endif /* XML_DTD */ 1414 return parser; 1414 return parser; 1415 } 1415 } 1416 1416 1417 static void FASTCALL 1417 static void FASTCALL 1418 destroyBindings(BINDING *bindings, XML_Parser 1418 destroyBindings(BINDING *bindings, XML_Parser parser) { 1419 for (;;) { 1419 for (;;) { 1420 BINDING *b = bindings; 1420 BINDING *b = bindings; 1421 if (! b) 1421 if (! b) 1422 break; 1422 break; 1423 bindings = b->nextTagBinding; 1423 bindings = b->nextTagBinding; 1424 FREE(parser, b->uri); 1424 FREE(parser, b->uri); 1425 FREE(parser, b); 1425 FREE(parser, b); 1426 } 1426 } 1427 } 1427 } 1428 1428 1429 void XMLCALL 1429 void XMLCALL 1430 XML_ParserFree(XML_Parser parser) { 1430 XML_ParserFree(XML_Parser parser) { 1431 TAG *tagList; 1431 TAG *tagList; 1432 OPEN_INTERNAL_ENTITY *entityList; 1432 OPEN_INTERNAL_ENTITY *entityList; 1433 if (parser == NULL) 1433 if (parser == NULL) 1434 return; 1434 return; 1435 /* free m_tagStack and m_freeTagList */ 1435 /* free m_tagStack and m_freeTagList */ 1436 tagList = parser->m_tagStack; 1436 tagList = parser->m_tagStack; 1437 for (;;) { 1437 for (;;) { 1438 TAG *p; 1438 TAG *p; 1439 if (tagList == NULL) { 1439 if (tagList == NULL) { 1440 if (parser->m_freeTagList == NULL) 1440 if (parser->m_freeTagList == NULL) 1441 break; 1441 break; 1442 tagList = parser->m_freeTagList; 1442 tagList = parser->m_freeTagList; 1443 parser->m_freeTagList = NULL; 1443 parser->m_freeTagList = NULL; 1444 } 1444 } 1445 p = tagList; 1445 p = tagList; 1446 tagList = tagList->parent; 1446 tagList = tagList->parent; 1447 FREE(parser, p->buf); 1447 FREE(parser, p->buf); 1448 destroyBindings(p->bindings, parser); 1448 destroyBindings(p->bindings, parser); 1449 FREE(parser, p); 1449 FREE(parser, p); 1450 } 1450 } 1451 /* free m_openInternalEntities and m_freeIn 1451 /* free m_openInternalEntities and m_freeInternalEntities */ 1452 entityList = parser->m_openInternalEntities 1452 entityList = parser->m_openInternalEntities; 1453 for (;;) { 1453 for (;;) { 1454 OPEN_INTERNAL_ENTITY *openEntity; 1454 OPEN_INTERNAL_ENTITY *openEntity; 1455 if (entityList == NULL) { 1455 if (entityList == NULL) { 1456 if (parser->m_freeInternalEntities == N 1456 if (parser->m_freeInternalEntities == NULL) 1457 break; 1457 break; 1458 entityList = parser->m_freeInternalEnti 1458 entityList = parser->m_freeInternalEntities; 1459 parser->m_freeInternalEntities = NULL; 1459 parser->m_freeInternalEntities = NULL; 1460 } 1460 } 1461 openEntity = entityList; 1461 openEntity = entityList; 1462 entityList = entityList->next; 1462 entityList = entityList->next; 1463 FREE(parser, openEntity); 1463 FREE(parser, openEntity); 1464 } 1464 } 1465 1465 1466 destroyBindings(parser->m_freeBindingList, 1466 destroyBindings(parser->m_freeBindingList, parser); 1467 destroyBindings(parser->m_inheritedBindings 1467 destroyBindings(parser->m_inheritedBindings, parser); 1468 poolDestroy(&parser->m_tempPool); 1468 poolDestroy(&parser->m_tempPool); 1469 poolDestroy(&parser->m_temp2Pool); 1469 poolDestroy(&parser->m_temp2Pool); 1470 FREE(parser, (void *)parser->m_protocolEnco 1470 FREE(parser, (void *)parser->m_protocolEncodingName); 1471 #ifdef XML_DTD 1471 #ifdef XML_DTD 1472 /* external parameter entity parsers share 1472 /* external parameter entity parsers share the DTD structure 1473 parser->m_dtd with the root parser, so w 1473 parser->m_dtd with the root parser, so we must not destroy it 1474 */ 1474 */ 1475 if (! parser->m_isParamEntity && parser->m_ 1475 if (! parser->m_isParamEntity && parser->m_dtd) 1476 #else 1476 #else 1477 if (parser->m_dtd) 1477 if (parser->m_dtd) 1478 #endif /* XML_DTD */ 1478 #endif /* XML_DTD */ 1479 dtdDestroy(parser->m_dtd, (XML_Bool)! par 1479 dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, 1480 &parser->m_mem); 1480 &parser->m_mem); 1481 FREE(parser, (void *)parser->m_atts); 1481 FREE(parser, (void *)parser->m_atts); 1482 #ifdef XML_ATTR_INFO 1482 #ifdef XML_ATTR_INFO 1483 FREE(parser, (void *)parser->m_attInfo); 1483 FREE(parser, (void *)parser->m_attInfo); 1484 #endif 1484 #endif 1485 FREE(parser, parser->m_groupConnector); 1485 FREE(parser, parser->m_groupConnector); 1486 FREE(parser, parser->m_buffer); 1486 FREE(parser, parser->m_buffer); 1487 FREE(parser, parser->m_dataBuf); 1487 FREE(parser, parser->m_dataBuf); 1488 FREE(parser, parser->m_nsAtts); 1488 FREE(parser, parser->m_nsAtts); 1489 FREE(parser, parser->m_unknownEncodingMem); 1489 FREE(parser, parser->m_unknownEncodingMem); 1490 if (parser->m_unknownEncodingRelease) 1490 if (parser->m_unknownEncodingRelease) 1491 parser->m_unknownEncodingRelease(parser-> 1491 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData); 1492 FREE(parser, parser); 1492 FREE(parser, parser); 1493 } 1493 } 1494 1494 1495 void XMLCALL 1495 void XMLCALL 1496 XML_UseParserAsHandlerArg(XML_Parser parser) 1496 XML_UseParserAsHandlerArg(XML_Parser parser) { 1497 if (parser != NULL) 1497 if (parser != NULL) 1498 parser->m_handlerArg = parser; 1498 parser->m_handlerArg = parser; 1499 } 1499 } 1500 1500 1501 enum XML_Error XMLCALL 1501 enum XML_Error XMLCALL 1502 XML_UseForeignDTD(XML_Parser parser, XML_Bool 1502 XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { 1503 if (parser == NULL) 1503 if (parser == NULL) 1504 return XML_ERROR_INVALID_ARGUMENT; 1504 return XML_ERROR_INVALID_ARGUMENT; 1505 #ifdef XML_DTD 1505 #ifdef XML_DTD 1506 /* block after XML_Parse()/XML_ParseBuffer( 1506 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 1507 if (parser->m_parsingStatus.parsing == XML_ 1507 if (parser->m_parsingStatus.parsing == XML_PARSING 1508 || parser->m_parsingStatus.parsing == X 1508 || parser->m_parsingStatus.parsing == XML_SUSPENDED) 1509 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE 1509 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; 1510 parser->m_useForeignDTD = useDTD; 1510 parser->m_useForeignDTD = useDTD; 1511 return XML_ERROR_NONE; 1511 return XML_ERROR_NONE; 1512 #else 1512 #else 1513 UNUSED_P(useDTD); 1513 UNUSED_P(useDTD); 1514 return XML_ERROR_FEATURE_REQUIRES_XML_DTD; 1514 return XML_ERROR_FEATURE_REQUIRES_XML_DTD; 1515 #endif 1515 #endif 1516 } 1516 } 1517 1517 1518 void XMLCALL 1518 void XMLCALL 1519 XML_SetReturnNSTriplet(XML_Parser parser, int 1519 XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { 1520 if (parser == NULL) 1520 if (parser == NULL) 1521 return; 1521 return; 1522 /* block after XML_Parse()/XML_ParseBuffer( 1522 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 1523 if (parser->m_parsingStatus.parsing == XML_ 1523 if (parser->m_parsingStatus.parsing == XML_PARSING 1524 || parser->m_parsingStatus.parsing == X 1524 || parser->m_parsingStatus.parsing == XML_SUSPENDED) 1525 return; 1525 return; 1526 parser->m_ns_triplets = do_nst ? XML_TRUE : 1526 parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE; 1527 } 1527 } 1528 1528 1529 void XMLCALL 1529 void XMLCALL 1530 XML_SetUserData(XML_Parser parser, void *p) { 1530 XML_SetUserData(XML_Parser parser, void *p) { 1531 if (parser == NULL) 1531 if (parser == NULL) 1532 return; 1532 return; 1533 if (parser->m_handlerArg == parser->m_userD 1533 if (parser->m_handlerArg == parser->m_userData) 1534 parser->m_handlerArg = parser->m_userData 1534 parser->m_handlerArg = parser->m_userData = p; 1535 else 1535 else 1536 parser->m_userData = p; 1536 parser->m_userData = p; 1537 } 1537 } 1538 1538 1539 enum XML_Status XMLCALL 1539 enum XML_Status XMLCALL 1540 XML_SetBase(XML_Parser parser, const XML_Char 1540 XML_SetBase(XML_Parser parser, const XML_Char *p) { 1541 if (parser == NULL) 1541 if (parser == NULL) 1542 return XML_STATUS_ERROR; 1542 return XML_STATUS_ERROR; 1543 if (p) { 1543 if (p) { 1544 p = poolCopyString(&parser->m_dtd->pool, 1544 p = poolCopyString(&parser->m_dtd->pool, p); 1545 if (! p) 1545 if (! p) 1546 return XML_STATUS_ERROR; 1546 return XML_STATUS_ERROR; 1547 parser->m_curBase = p; 1547 parser->m_curBase = p; 1548 } else 1548 } else 1549 parser->m_curBase = NULL; 1549 parser->m_curBase = NULL; 1550 return XML_STATUS_OK; 1550 return XML_STATUS_OK; 1551 } 1551 } 1552 1552 1553 const XML_Char *XMLCALL 1553 const XML_Char *XMLCALL 1554 XML_GetBase(XML_Parser parser) { 1554 XML_GetBase(XML_Parser parser) { 1555 if (parser == NULL) 1555 if (parser == NULL) 1556 return NULL; 1556 return NULL; 1557 return parser->m_curBase; 1557 return parser->m_curBase; 1558 } 1558 } 1559 1559 1560 int XMLCALL 1560 int XMLCALL 1561 XML_GetSpecifiedAttributeCount(XML_Parser par 1561 XML_GetSpecifiedAttributeCount(XML_Parser parser) { 1562 if (parser == NULL) 1562 if (parser == NULL) 1563 return -1; 1563 return -1; 1564 return parser->m_nSpecifiedAtts; 1564 return parser->m_nSpecifiedAtts; 1565 } 1565 } 1566 1566 1567 int XMLCALL 1567 int XMLCALL 1568 XML_GetIdAttributeIndex(XML_Parser parser) { 1568 XML_GetIdAttributeIndex(XML_Parser parser) { 1569 if (parser == NULL) 1569 if (parser == NULL) 1570 return -1; 1570 return -1; 1571 return parser->m_idAttIndex; 1571 return parser->m_idAttIndex; 1572 } 1572 } 1573 1573 1574 #ifdef XML_ATTR_INFO 1574 #ifdef XML_ATTR_INFO 1575 const XML_AttrInfo *XMLCALL 1575 const XML_AttrInfo *XMLCALL 1576 XML_GetAttributeInfo(XML_Parser parser) { 1576 XML_GetAttributeInfo(XML_Parser parser) { 1577 if (parser == NULL) 1577 if (parser == NULL) 1578 return NULL; 1578 return NULL; 1579 return parser->m_attInfo; 1579 return parser->m_attInfo; 1580 } 1580 } 1581 #endif 1581 #endif 1582 1582 1583 void XMLCALL 1583 void XMLCALL 1584 XML_SetElementHandler(XML_Parser parser, XML_ 1584 XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, 1585 XML_EndElementHandler e 1585 XML_EndElementHandler end) { 1586 if (parser == NULL) 1586 if (parser == NULL) 1587 return; 1587 return; 1588 parser->m_startElementHandler = start; 1588 parser->m_startElementHandler = start; 1589 parser->m_endElementHandler = end; 1589 parser->m_endElementHandler = end; 1590 } 1590 } 1591 1591 1592 void XMLCALL 1592 void XMLCALL 1593 XML_SetStartElementHandler(XML_Parser parser, 1593 XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { 1594 if (parser != NULL) 1594 if (parser != NULL) 1595 parser->m_startElementHandler = start; 1595 parser->m_startElementHandler = start; 1596 } 1596 } 1597 1597 1598 void XMLCALL 1598 void XMLCALL 1599 XML_SetEndElementHandler(XML_Parser parser, X 1599 XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { 1600 if (parser != NULL) 1600 if (parser != NULL) 1601 parser->m_endElementHandler = end; 1601 parser->m_endElementHandler = end; 1602 } 1602 } 1603 1603 1604 void XMLCALL 1604 void XMLCALL 1605 XML_SetCharacterDataHandler(XML_Parser parser 1605 XML_SetCharacterDataHandler(XML_Parser parser, 1606 XML_CharacterData 1606 XML_CharacterDataHandler handler) { 1607 if (parser != NULL) 1607 if (parser != NULL) 1608 parser->m_characterDataHandler = handler; 1608 parser->m_characterDataHandler = handler; 1609 } 1609 } 1610 1610 1611 void XMLCALL 1611 void XMLCALL 1612 XML_SetProcessingInstructionHandler(XML_Parse 1612 XML_SetProcessingInstructionHandler(XML_Parser parser, 1613 XML_Proce 1613 XML_ProcessingInstructionHandler handler) { 1614 if (parser != NULL) 1614 if (parser != NULL) 1615 parser->m_processingInstructionHandler = 1615 parser->m_processingInstructionHandler = handler; 1616 } 1616 } 1617 1617 1618 void XMLCALL 1618 void XMLCALL 1619 XML_SetCommentHandler(XML_Parser parser, XML_ 1619 XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { 1620 if (parser != NULL) 1620 if (parser != NULL) 1621 parser->m_commentHandler = handler; 1621 parser->m_commentHandler = handler; 1622 } 1622 } 1623 1623 1624 void XMLCALL 1624 void XMLCALL 1625 XML_SetCdataSectionHandler(XML_Parser parser, 1625 XML_SetCdataSectionHandler(XML_Parser parser, 1626 XML_StartCdataSect 1626 XML_StartCdataSectionHandler start, 1627 XML_EndCdataSectio 1627 XML_EndCdataSectionHandler end) { 1628 if (parser == NULL) 1628 if (parser == NULL) 1629 return; 1629 return; 1630 parser->m_startCdataSectionHandler = start; 1630 parser->m_startCdataSectionHandler = start; 1631 parser->m_endCdataSectionHandler = end; 1631 parser->m_endCdataSectionHandler = end; 1632 } 1632 } 1633 1633 1634 void XMLCALL 1634 void XMLCALL 1635 XML_SetStartCdataSectionHandler(XML_Parser pa 1635 XML_SetStartCdataSectionHandler(XML_Parser parser, 1636 XML_StartCdat 1636 XML_StartCdataSectionHandler start) { 1637 if (parser != NULL) 1637 if (parser != NULL) 1638 parser->m_startCdataSectionHandler = star 1638 parser->m_startCdataSectionHandler = start; 1639 } 1639 } 1640 1640 1641 void XMLCALL 1641 void XMLCALL 1642 XML_SetEndCdataSectionHandler(XML_Parser pars 1642 XML_SetEndCdataSectionHandler(XML_Parser parser, 1643 XML_EndCdataSec 1643 XML_EndCdataSectionHandler end) { 1644 if (parser != NULL) 1644 if (parser != NULL) 1645 parser->m_endCdataSectionHandler = end; 1645 parser->m_endCdataSectionHandler = end; 1646 } 1646 } 1647 1647 1648 void XMLCALL 1648 void XMLCALL 1649 XML_SetDefaultHandler(XML_Parser parser, XML_ 1649 XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { 1650 if (parser == NULL) 1650 if (parser == NULL) 1651 return; 1651 return; 1652 parser->m_defaultHandler = handler; 1652 parser->m_defaultHandler = handler; 1653 parser->m_defaultExpandInternalEntities = X 1653 parser->m_defaultExpandInternalEntities = XML_FALSE; 1654 } 1654 } 1655 1655 1656 void XMLCALL 1656 void XMLCALL 1657 XML_SetDefaultHandlerExpand(XML_Parser parser 1657 XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { 1658 if (parser == NULL) 1658 if (parser == NULL) 1659 return; 1659 return; 1660 parser->m_defaultHandler = handler; 1660 parser->m_defaultHandler = handler; 1661 parser->m_defaultExpandInternalEntities = X 1661 parser->m_defaultExpandInternalEntities = XML_TRUE; 1662 } 1662 } 1663 1663 1664 void XMLCALL 1664 void XMLCALL 1665 XML_SetDoctypeDeclHandler(XML_Parser parser, 1665 XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, 1666 XML_EndDoctypeDeclH 1666 XML_EndDoctypeDeclHandler end) { 1667 if (parser == NULL) 1667 if (parser == NULL) 1668 return; 1668 return; 1669 parser->m_startDoctypeDeclHandler = start; 1669 parser->m_startDoctypeDeclHandler = start; 1670 parser->m_endDoctypeDeclHandler = end; 1670 parser->m_endDoctypeDeclHandler = end; 1671 } 1671 } 1672 1672 1673 void XMLCALL 1673 void XMLCALL 1674 XML_SetStartDoctypeDeclHandler(XML_Parser par 1674 XML_SetStartDoctypeDeclHandler(XML_Parser parser, 1675 XML_StartDocty 1675 XML_StartDoctypeDeclHandler start) { 1676 if (parser != NULL) 1676 if (parser != NULL) 1677 parser->m_startDoctypeDeclHandler = start 1677 parser->m_startDoctypeDeclHandler = start; 1678 } 1678 } 1679 1679 1680 void XMLCALL 1680 void XMLCALL 1681 XML_SetEndDoctypeDeclHandler(XML_Parser parse 1681 XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { 1682 if (parser != NULL) 1682 if (parser != NULL) 1683 parser->m_endDoctypeDeclHandler = end; 1683 parser->m_endDoctypeDeclHandler = end; 1684 } 1684 } 1685 1685 1686 void XMLCALL 1686 void XMLCALL 1687 XML_SetUnparsedEntityDeclHandler(XML_Parser p 1687 XML_SetUnparsedEntityDeclHandler(XML_Parser parser, 1688 XML_Unparsed 1688 XML_UnparsedEntityDeclHandler handler) { 1689 if (parser != NULL) 1689 if (parser != NULL) 1690 parser->m_unparsedEntityDeclHandler = han 1690 parser->m_unparsedEntityDeclHandler = handler; 1691 } 1691 } 1692 1692 1693 void XMLCALL 1693 void XMLCALL 1694 XML_SetNotationDeclHandler(XML_Parser parser, 1694 XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { 1695 if (parser != NULL) 1695 if (parser != NULL) 1696 parser->m_notationDeclHandler = handler; 1696 parser->m_notationDeclHandler = handler; 1697 } 1697 } 1698 1698 1699 void XMLCALL 1699 void XMLCALL 1700 XML_SetNamespaceDeclHandler(XML_Parser parser 1700 XML_SetNamespaceDeclHandler(XML_Parser parser, 1701 XML_StartNamespac 1701 XML_StartNamespaceDeclHandler start, 1702 XML_EndNamespaceD 1702 XML_EndNamespaceDeclHandler end) { 1703 if (parser == NULL) 1703 if (parser == NULL) 1704 return; 1704 return; 1705 parser->m_startNamespaceDeclHandler = start 1705 parser->m_startNamespaceDeclHandler = start; 1706 parser->m_endNamespaceDeclHandler = end; 1706 parser->m_endNamespaceDeclHandler = end; 1707 } 1707 } 1708 1708 1709 void XMLCALL 1709 void XMLCALL 1710 XML_SetStartNamespaceDeclHandler(XML_Parser p 1710 XML_SetStartNamespaceDeclHandler(XML_Parser parser, 1711 XML_StartNam 1711 XML_StartNamespaceDeclHandler start) { 1712 if (parser != NULL) 1712 if (parser != NULL) 1713 parser->m_startNamespaceDeclHandler = sta 1713 parser->m_startNamespaceDeclHandler = start; 1714 } 1714 } 1715 1715 1716 void XMLCALL 1716 void XMLCALL 1717 XML_SetEndNamespaceDeclHandler(XML_Parser par 1717 XML_SetEndNamespaceDeclHandler(XML_Parser parser, 1718 XML_EndNamespa 1718 XML_EndNamespaceDeclHandler end) { 1719 if (parser != NULL) 1719 if (parser != NULL) 1720 parser->m_endNamespaceDeclHandler = end; 1720 parser->m_endNamespaceDeclHandler = end; 1721 } 1721 } 1722 1722 1723 void XMLCALL 1723 void XMLCALL 1724 XML_SetNotStandaloneHandler(XML_Parser parser 1724 XML_SetNotStandaloneHandler(XML_Parser parser, 1725 XML_NotStandalone 1725 XML_NotStandaloneHandler handler) { 1726 if (parser != NULL) 1726 if (parser != NULL) 1727 parser->m_notStandaloneHandler = handler; 1727 parser->m_notStandaloneHandler = handler; 1728 } 1728 } 1729 1729 1730 void XMLCALL 1730 void XMLCALL 1731 XML_SetExternalEntityRefHandler(XML_Parser pa 1731 XML_SetExternalEntityRefHandler(XML_Parser parser, 1732 XML_ExternalE 1732 XML_ExternalEntityRefHandler handler) { 1733 if (parser != NULL) 1733 if (parser != NULL) 1734 parser->m_externalEntityRefHandler = hand 1734 parser->m_externalEntityRefHandler = handler; 1735 } 1735 } 1736 1736 1737 void XMLCALL 1737 void XMLCALL 1738 XML_SetExternalEntityRefHandlerArg(XML_Parser 1738 XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { 1739 if (parser == NULL) 1739 if (parser == NULL) 1740 return; 1740 return; 1741 if (arg) 1741 if (arg) 1742 parser->m_externalEntityRefHandlerArg = ( 1742 parser->m_externalEntityRefHandlerArg = (XML_Parser)arg; 1743 else 1743 else 1744 parser->m_externalEntityRefHandlerArg = p 1744 parser->m_externalEntityRefHandlerArg = parser; 1745 } 1745 } 1746 1746 1747 void XMLCALL 1747 void XMLCALL 1748 XML_SetSkippedEntityHandler(XML_Parser parser 1748 XML_SetSkippedEntityHandler(XML_Parser parser, 1749 XML_SkippedEntity 1749 XML_SkippedEntityHandler handler) { 1750 if (parser != NULL) 1750 if (parser != NULL) 1751 parser->m_skippedEntityHandler = handler; 1751 parser->m_skippedEntityHandler = handler; 1752 } 1752 } 1753 1753 1754 void XMLCALL 1754 void XMLCALL 1755 XML_SetUnknownEncodingHandler(XML_Parser pars 1755 XML_SetUnknownEncodingHandler(XML_Parser parser, 1756 XML_UnknownEnco 1756 XML_UnknownEncodingHandler handler, void *data) { 1757 if (parser == NULL) 1757 if (parser == NULL) 1758 return; 1758 return; 1759 parser->m_unknownEncodingHandler = handler; 1759 parser->m_unknownEncodingHandler = handler; 1760 parser->m_unknownEncodingHandlerData = data 1760 parser->m_unknownEncodingHandlerData = data; 1761 } 1761 } 1762 1762 1763 void XMLCALL 1763 void XMLCALL 1764 XML_SetElementDeclHandler(XML_Parser parser, 1764 XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { 1765 if (parser != NULL) 1765 if (parser != NULL) 1766 parser->m_elementDeclHandler = eldecl; 1766 parser->m_elementDeclHandler = eldecl; 1767 } 1767 } 1768 1768 1769 void XMLCALL 1769 void XMLCALL 1770 XML_SetAttlistDeclHandler(XML_Parser parser, 1770 XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { 1771 if (parser != NULL) 1771 if (parser != NULL) 1772 parser->m_attlistDeclHandler = attdecl; 1772 parser->m_attlistDeclHandler = attdecl; 1773 } 1773 } 1774 1774 1775 void XMLCALL 1775 void XMLCALL 1776 XML_SetEntityDeclHandler(XML_Parser parser, X 1776 XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { 1777 if (parser != NULL) 1777 if (parser != NULL) 1778 parser->m_entityDeclHandler = handler; 1778 parser->m_entityDeclHandler = handler; 1779 } 1779 } 1780 1780 1781 void XMLCALL 1781 void XMLCALL 1782 XML_SetXmlDeclHandler(XML_Parser parser, XML_ 1782 XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { 1783 if (parser != NULL) 1783 if (parser != NULL) 1784 parser->m_xmlDeclHandler = handler; 1784 parser->m_xmlDeclHandler = handler; 1785 } 1785 } 1786 1786 1787 int XMLCALL 1787 int XMLCALL 1788 XML_SetParamEntityParsing(XML_Parser parser, 1788 XML_SetParamEntityParsing(XML_Parser parser, 1789 enum XML_ParamEntit 1789 enum XML_ParamEntityParsing peParsing) { 1790 if (parser == NULL) 1790 if (parser == NULL) 1791 return 0; 1791 return 0; 1792 /* block after XML_Parse()/XML_ParseBuffer( 1792 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 1793 if (parser->m_parsingStatus.parsing == XML_ 1793 if (parser->m_parsingStatus.parsing == XML_PARSING 1794 || parser->m_parsingStatus.parsing == X 1794 || parser->m_parsingStatus.parsing == XML_SUSPENDED) 1795 return 0; 1795 return 0; 1796 #ifdef XML_DTD 1796 #ifdef XML_DTD 1797 parser->m_paramEntityParsing = peParsing; 1797 parser->m_paramEntityParsing = peParsing; 1798 return 1; 1798 return 1; 1799 #else 1799 #else 1800 return peParsing == XML_PARAM_ENTITY_PARSIN 1800 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; 1801 #endif 1801 #endif 1802 } 1802 } 1803 1803 1804 int XMLCALL 1804 int XMLCALL 1805 XML_SetHashSalt(XML_Parser parser, unsigned l 1805 XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { 1806 if (parser == NULL) 1806 if (parser == NULL) 1807 return 0; 1807 return 0; 1808 if (parser->m_parentParser) 1808 if (parser->m_parentParser) 1809 return XML_SetHashSalt(parser->m_parentPa 1809 return XML_SetHashSalt(parser->m_parentParser, hash_salt); 1810 /* block after XML_Parse()/XML_ParseBuffer( 1810 /* block after XML_Parse()/XML_ParseBuffer() has been called */ 1811 if (parser->m_parsingStatus.parsing == XML_ 1811 if (parser->m_parsingStatus.parsing == XML_PARSING 1812 || parser->m_parsingStatus.parsing == X 1812 || parser->m_parsingStatus.parsing == XML_SUSPENDED) 1813 return 0; 1813 return 0; 1814 parser->m_hash_secret_salt = hash_salt; 1814 parser->m_hash_secret_salt = hash_salt; 1815 return 1; 1815 return 1; 1816 } 1816 } 1817 1817 1818 enum XML_Status XMLCALL 1818 enum XML_Status XMLCALL 1819 XML_Parse(XML_Parser parser, const char *s, i 1819 XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { 1820 if ((parser == NULL) || (len < 0) || ((s == 1820 if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { 1821 if (parser != NULL) 1821 if (parser != NULL) 1822 parser->m_errorCode = XML_ERROR_INVALID 1822 parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT; 1823 return XML_STATUS_ERROR; 1823 return XML_STATUS_ERROR; 1824 } 1824 } 1825 switch (parser->m_parsingStatus.parsing) { 1825 switch (parser->m_parsingStatus.parsing) { 1826 case XML_SUSPENDED: 1826 case XML_SUSPENDED: 1827 parser->m_errorCode = XML_ERROR_SUSPENDED 1827 parser->m_errorCode = XML_ERROR_SUSPENDED; 1828 return XML_STATUS_ERROR; 1828 return XML_STATUS_ERROR; 1829 case XML_FINISHED: 1829 case XML_FINISHED: 1830 parser->m_errorCode = XML_ERROR_FINISHED; 1830 parser->m_errorCode = XML_ERROR_FINISHED; 1831 return XML_STATUS_ERROR; 1831 return XML_STATUS_ERROR; 1832 case XML_INITIALIZED: 1832 case XML_INITIALIZED: 1833 if (parser->m_parentParser == NULL && ! s 1833 if (parser->m_parentParser == NULL && ! startParsing(parser)) { 1834 parser->m_errorCode = XML_ERROR_NO_MEMO 1834 parser->m_errorCode = XML_ERROR_NO_MEMORY; 1835 return XML_STATUS_ERROR; 1835 return XML_STATUS_ERROR; 1836 } 1836 } 1837 /* fall through */ 1837 /* fall through */ 1838 default: 1838 default: 1839 parser->m_parsingStatus.parsing = XML_PAR 1839 parser->m_parsingStatus.parsing = XML_PARSING; 1840 } 1840 } 1841 1841 1842 if (len == 0) { 1842 if (len == 0) { 1843 parser->m_parsingStatus.finalBuffer = (XM 1843 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; 1844 if (! isFinal) 1844 if (! isFinal) 1845 return XML_STATUS_OK; 1845 return XML_STATUS_OK; 1846 parser->m_positionPtr = parser->m_bufferP 1846 parser->m_positionPtr = parser->m_bufferPtr; 1847 parser->m_parseEndPtr = parser->m_bufferE 1847 parser->m_parseEndPtr = parser->m_bufferEnd; 1848 1848 1849 /* If data are left over from last buffer 1849 /* If data are left over from last buffer, and we now know that these 1850 data are the final chunk of input, the 1850 data are the final chunk of input, then we have to check them again 1851 to detect errors based on that fact. 1851 to detect errors based on that fact. 1852 */ 1852 */ 1853 parser->m_errorCode 1853 parser->m_errorCode 1854 = parser->m_processor(parser, parser- 1854 = parser->m_processor(parser, parser->m_bufferPtr, 1855 parser->m_parse 1855 parser->m_parseEndPtr, &parser->m_bufferPtr); 1856 1856 1857 if (parser->m_errorCode == XML_ERROR_NONE 1857 if (parser->m_errorCode == XML_ERROR_NONE) { 1858 switch (parser->m_parsingStatus.parsing 1858 switch (parser->m_parsingStatus.parsing) { 1859 case XML_SUSPENDED: 1859 case XML_SUSPENDED: 1860 /* It is hard to be certain, but it s 1860 /* It is hard to be certain, but it seems that this case 1861 * cannot occur. This code is cleani 1861 * cannot occur. This code is cleaning up a previous parse 1862 * with no new data (since len == 0). 1862 * with no new data (since len == 0). Changing the parsing 1863 * state requires getting to execute 1863 * state requires getting to execute a handler function, and 1864 * there doesn't seem to be an opport 1864 * there doesn't seem to be an opportunity for that while in 1865 * this circumstance. 1865 * this circumstance. 1866 * 1866 * 1867 * Given the uncertainty, we retain t 1867 * Given the uncertainty, we retain the code but exclude it 1868 * from coverage tests. 1868 * from coverage tests. 1869 * 1869 * 1870 * LCOV_EXCL_START 1870 * LCOV_EXCL_START 1871 */ 1871 */ 1872 XmlUpdatePosition(parser->m_encoding, 1872 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 1873 parser->m_bufferPtr 1873 parser->m_bufferPtr, &parser->m_position); 1874 parser->m_positionPtr = parser->m_buf 1874 parser->m_positionPtr = parser->m_bufferPtr; 1875 return XML_STATUS_SUSPENDED; 1875 return XML_STATUS_SUSPENDED; 1876 /* LCOV_EXCL_STOP */ 1876 /* LCOV_EXCL_STOP */ 1877 case XML_INITIALIZED: 1877 case XML_INITIALIZED: 1878 case XML_PARSING: 1878 case XML_PARSING: 1879 parser->m_parsingStatus.parsing = XML 1879 parser->m_parsingStatus.parsing = XML_FINISHED; 1880 /* fall through */ 1880 /* fall through */ 1881 default: 1881 default: 1882 return XML_STATUS_OK; 1882 return XML_STATUS_OK; 1883 } 1883 } 1884 } 1884 } 1885 parser->m_eventEndPtr = parser->m_eventPt 1885 parser->m_eventEndPtr = parser->m_eventPtr; 1886 parser->m_processor = errorProcessor; 1886 parser->m_processor = errorProcessor; 1887 return XML_STATUS_ERROR; 1887 return XML_STATUS_ERROR; 1888 } 1888 } 1889 #ifndef XML_CONTEXT_BYTES 1889 #ifndef XML_CONTEXT_BYTES 1890 else if (parser->m_bufferPtr == parser->m_b 1890 else if (parser->m_bufferPtr == parser->m_bufferEnd) { 1891 const char *end; 1891 const char *end; 1892 int nLeftOver; 1892 int nLeftOver; 1893 enum XML_Status result; 1893 enum XML_Status result; 1894 /* Detect overflow (a+b > MAX <==> b > MA 1894 /* Detect overflow (a+b > MAX <==> b > MAX-a) */ 1895 if ((XML_Size)len > ((XML_Size)-1) / 2 - 1895 if ((XML_Size)len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) { 1896 parser->m_errorCode = XML_ERROR_NO_MEMO 1896 parser->m_errorCode = XML_ERROR_NO_MEMORY; 1897 parser->m_eventPtr = parser->m_eventEnd 1897 parser->m_eventPtr = parser->m_eventEndPtr = NULL; 1898 parser->m_processor = errorProcessor; 1898 parser->m_processor = errorProcessor; 1899 return XML_STATUS_ERROR; 1899 return XML_STATUS_ERROR; 1900 } 1900 } 1901 parser->m_parseEndByteIndex += len; 1901 parser->m_parseEndByteIndex += len; 1902 parser->m_positionPtr = s; 1902 parser->m_positionPtr = s; 1903 parser->m_parsingStatus.finalBuffer = (XM 1903 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; 1904 1904 1905 parser->m_errorCode 1905 parser->m_errorCode 1906 = parser->m_processor(parser, s, pars 1906 = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end); 1907 1907 1908 if (parser->m_errorCode != XML_ERROR_NONE 1908 if (parser->m_errorCode != XML_ERROR_NONE) { 1909 parser->m_eventEndPtr = parser->m_event 1909 parser->m_eventEndPtr = parser->m_eventPtr; 1910 parser->m_processor = errorProcessor; 1910 parser->m_processor = errorProcessor; 1911 return XML_STATUS_ERROR; 1911 return XML_STATUS_ERROR; 1912 } else { 1912 } else { 1913 switch (parser->m_parsingStatus.parsing 1913 switch (parser->m_parsingStatus.parsing) { 1914 case XML_SUSPENDED: 1914 case XML_SUSPENDED: 1915 result = XML_STATUS_SUSPENDED; 1915 result = XML_STATUS_SUSPENDED; 1916 break; 1916 break; 1917 case XML_INITIALIZED: 1917 case XML_INITIALIZED: 1918 case XML_PARSING: 1918 case XML_PARSING: 1919 if (isFinal) { 1919 if (isFinal) { 1920 parser->m_parsingStatus.parsing = X 1920 parser->m_parsingStatus.parsing = XML_FINISHED; 1921 return XML_STATUS_OK; 1921 return XML_STATUS_OK; 1922 } 1922 } 1923 /* fall through */ 1923 /* fall through */ 1924 default: 1924 default: 1925 result = XML_STATUS_OK; 1925 result = XML_STATUS_OK; 1926 } 1926 } 1927 } 1927 } 1928 1928 1929 XmlUpdatePosition(parser->m_encoding, par 1929 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, 1930 &parser->m_position); 1930 &parser->m_position); 1931 nLeftOver = s + len - end; 1931 nLeftOver = s + len - end; 1932 if (nLeftOver) { 1932 if (nLeftOver) { 1933 if (parser->m_buffer == NULL 1933 if (parser->m_buffer == NULL 1934 || nLeftOver > parser->m_bufferLim 1934 || nLeftOver > parser->m_bufferLim - parser->m_buffer) { 1935 /* avoid _signed_ integer overflow */ 1935 /* avoid _signed_ integer overflow */ 1936 char *temp = NULL; 1936 char *temp = NULL; 1937 const int bytesToAllocate = (int)((un 1937 const int bytesToAllocate = (int)((unsigned)len * 2U); 1938 if (bytesToAllocate > 0) { 1938 if (bytesToAllocate > 0) { 1939 temp = (char *)REALLOC(parser, pars 1939 temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate); 1940 } 1940 } 1941 if (temp == NULL) { 1941 if (temp == NULL) { 1942 parser->m_errorCode = XML_ERROR_NO_ 1942 parser->m_errorCode = XML_ERROR_NO_MEMORY; 1943 parser->m_eventPtr = parser->m_even 1943 parser->m_eventPtr = parser->m_eventEndPtr = NULL; 1944 parser->m_processor = errorProcesso 1944 parser->m_processor = errorProcessor; 1945 return XML_STATUS_ERROR; 1945 return XML_STATUS_ERROR; 1946 } 1946 } 1947 parser->m_buffer = temp; 1947 parser->m_buffer = temp; 1948 parser->m_bufferLim = parser->m_buffe 1948 parser->m_bufferLim = parser->m_buffer + bytesToAllocate; 1949 } 1949 } 1950 memcpy(parser->m_buffer, end, nLeftOver 1950 memcpy(parser->m_buffer, end, nLeftOver); 1951 } 1951 } 1952 parser->m_bufferPtr = parser->m_buffer; 1952 parser->m_bufferPtr = parser->m_buffer; 1953 parser->m_bufferEnd = parser->m_buffer + 1953 parser->m_bufferEnd = parser->m_buffer + nLeftOver; 1954 parser->m_positionPtr = parser->m_bufferP 1954 parser->m_positionPtr = parser->m_bufferPtr; 1955 parser->m_parseEndPtr = parser->m_bufferE 1955 parser->m_parseEndPtr = parser->m_bufferEnd; 1956 parser->m_eventPtr = parser->m_bufferPtr; 1956 parser->m_eventPtr = parser->m_bufferPtr; 1957 parser->m_eventEndPtr = parser->m_bufferP 1957 parser->m_eventEndPtr = parser->m_bufferPtr; 1958 return result; 1958 return result; 1959 } 1959 } 1960 #endif /* not defined XML_CONTEXT_BYTES */ 1960 #endif /* not defined XML_CONTEXT_BYTES */ 1961 else { 1961 else { 1962 void *buff = XML_GetBuffer(parser, len); 1962 void *buff = XML_GetBuffer(parser, len); 1963 if (buff == NULL) 1963 if (buff == NULL) 1964 return XML_STATUS_ERROR; 1964 return XML_STATUS_ERROR; 1965 else { 1965 else { 1966 memcpy(buff, s, len); 1966 memcpy(buff, s, len); 1967 return XML_ParseBuffer(parser, len, isF 1967 return XML_ParseBuffer(parser, len, isFinal); 1968 } 1968 } 1969 } 1969 } 1970 } 1970 } 1971 1971 1972 enum XML_Status XMLCALL 1972 enum XML_Status XMLCALL 1973 XML_ParseBuffer(XML_Parser parser, int len, i 1973 XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { 1974 const char *start; 1974 const char *start; 1975 enum XML_Status result = XML_STATUS_OK; 1975 enum XML_Status result = XML_STATUS_OK; 1976 1976 1977 if (parser == NULL) 1977 if (parser == NULL) 1978 return XML_STATUS_ERROR; 1978 return XML_STATUS_ERROR; 1979 switch (parser->m_parsingStatus.parsing) { 1979 switch (parser->m_parsingStatus.parsing) { 1980 case XML_SUSPENDED: 1980 case XML_SUSPENDED: 1981 parser->m_errorCode = XML_ERROR_SUSPENDED 1981 parser->m_errorCode = XML_ERROR_SUSPENDED; 1982 return XML_STATUS_ERROR; 1982 return XML_STATUS_ERROR; 1983 case XML_FINISHED: 1983 case XML_FINISHED: 1984 parser->m_errorCode = XML_ERROR_FINISHED; 1984 parser->m_errorCode = XML_ERROR_FINISHED; 1985 return XML_STATUS_ERROR; 1985 return XML_STATUS_ERROR; 1986 case XML_INITIALIZED: 1986 case XML_INITIALIZED: 1987 /* Has someone called XML_GetBuffer succe 1987 /* Has someone called XML_GetBuffer successfully before? */ 1988 if (! parser->m_bufferPtr) { 1988 if (! parser->m_bufferPtr) { 1989 parser->m_errorCode = XML_ERROR_NO_BUFF 1989 parser->m_errorCode = XML_ERROR_NO_BUFFER; 1990 return XML_STATUS_ERROR; 1990 return XML_STATUS_ERROR; 1991 } 1991 } 1992 1992 1993 if (parser->m_parentParser == NULL && ! s 1993 if (parser->m_parentParser == NULL && ! startParsing(parser)) { 1994 parser->m_errorCode = XML_ERROR_NO_MEMO 1994 parser->m_errorCode = XML_ERROR_NO_MEMORY; 1995 return XML_STATUS_ERROR; 1995 return XML_STATUS_ERROR; 1996 } 1996 } 1997 /* fall through */ 1997 /* fall through */ 1998 default: 1998 default: 1999 parser->m_parsingStatus.parsing = XML_PAR 1999 parser->m_parsingStatus.parsing = XML_PARSING; 2000 } 2000 } 2001 2001 2002 start = parser->m_bufferPtr; 2002 start = parser->m_bufferPtr; 2003 parser->m_positionPtr = start; 2003 parser->m_positionPtr = start; 2004 parser->m_bufferEnd += len; 2004 parser->m_bufferEnd += len; 2005 parser->m_parseEndPtr = parser->m_bufferEnd 2005 parser->m_parseEndPtr = parser->m_bufferEnd; 2006 parser->m_parseEndByteIndex += len; 2006 parser->m_parseEndByteIndex += len; 2007 parser->m_parsingStatus.finalBuffer = (XML_ 2007 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal; 2008 2008 2009 parser->m_errorCode = parser->m_processor( 2009 parser->m_errorCode = parser->m_processor( 2010 parser, start, parser->m_parseEndPtr, & 2010 parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr); 2011 2011 2012 if (parser->m_errorCode != XML_ERROR_NONE) 2012 if (parser->m_errorCode != XML_ERROR_NONE) { 2013 parser->m_eventEndPtr = parser->m_eventPt 2013 parser->m_eventEndPtr = parser->m_eventPtr; 2014 parser->m_processor = errorProcessor; 2014 parser->m_processor = errorProcessor; 2015 return XML_STATUS_ERROR; 2015 return XML_STATUS_ERROR; 2016 } else { 2016 } else { 2017 switch (parser->m_parsingStatus.parsing) 2017 switch (parser->m_parsingStatus.parsing) { 2018 case XML_SUSPENDED: 2018 case XML_SUSPENDED: 2019 result = XML_STATUS_SUSPENDED; 2019 result = XML_STATUS_SUSPENDED; 2020 break; 2020 break; 2021 case XML_INITIALIZED: 2021 case XML_INITIALIZED: 2022 case XML_PARSING: 2022 case XML_PARSING: 2023 if (isFinal) { 2023 if (isFinal) { 2024 parser->m_parsingStatus.parsing = XML 2024 parser->m_parsingStatus.parsing = XML_FINISHED; 2025 return result; 2025 return result; 2026 } 2026 } 2027 default:; /* should not happen */ 2027 default:; /* should not happen */ 2028 } 2028 } 2029 } 2029 } 2030 2030 2031 XmlUpdatePosition(parser->m_encoding, parse 2031 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 2032 parser->m_bufferPtr, &par 2032 parser->m_bufferPtr, &parser->m_position); 2033 parser->m_positionPtr = parser->m_bufferPtr 2033 parser->m_positionPtr = parser->m_bufferPtr; 2034 return result; 2034 return result; 2035 } 2035 } 2036 2036 2037 void *XMLCALL 2037 void *XMLCALL 2038 XML_GetBuffer(XML_Parser parser, int len) { 2038 XML_GetBuffer(XML_Parser parser, int len) { 2039 if (parser == NULL) 2039 if (parser == NULL) 2040 return NULL; 2040 return NULL; 2041 if (len < 0) { 2041 if (len < 0) { 2042 parser->m_errorCode = XML_ERROR_NO_MEMORY 2042 parser->m_errorCode = XML_ERROR_NO_MEMORY; 2043 return NULL; 2043 return NULL; 2044 } 2044 } 2045 switch (parser->m_parsingStatus.parsing) { 2045 switch (parser->m_parsingStatus.parsing) { 2046 case XML_SUSPENDED: 2046 case XML_SUSPENDED: 2047 parser->m_errorCode = XML_ERROR_SUSPENDED 2047 parser->m_errorCode = XML_ERROR_SUSPENDED; 2048 return NULL; 2048 return NULL; 2049 case XML_FINISHED: 2049 case XML_FINISHED: 2050 parser->m_errorCode = XML_ERROR_FINISHED; 2050 parser->m_errorCode = XML_ERROR_FINISHED; 2051 return NULL; 2051 return NULL; 2052 default:; 2052 default:; 2053 } 2053 } 2054 2054 2055 if (len > EXPAT_SAFE_PTR_DIFF(parser->m_buf 2055 if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)) { 2056 #ifdef XML_CONTEXT_BYTES 2056 #ifdef XML_CONTEXT_BYTES 2057 int keep; 2057 int keep; 2058 #endif /* defined XML_CONTEXT_BYTES */ 2058 #endif /* defined XML_CONTEXT_BYTES */ 2059 /* Do not invoke signed arithmetic overfl 2059 /* Do not invoke signed arithmetic overflow: */ 2060 int neededSize = (int)((unsigned)len 2060 int neededSize = (int)((unsigned)len 2061 + (unsigned)EXPAT_ 2061 + (unsigned)EXPAT_SAFE_PTR_DIFF( 2062 parser->m_buff 2062 parser->m_bufferEnd, parser->m_bufferPtr)); 2063 if (neededSize < 0) { 2063 if (neededSize < 0) { 2064 parser->m_errorCode = XML_ERROR_NO_MEMO 2064 parser->m_errorCode = XML_ERROR_NO_MEMORY; 2065 return NULL; 2065 return NULL; 2066 } 2066 } 2067 #ifdef XML_CONTEXT_BYTES 2067 #ifdef XML_CONTEXT_BYTES 2068 keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m 2068 keep = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer); 2069 if (keep > XML_CONTEXT_BYTES) 2069 if (keep > XML_CONTEXT_BYTES) 2070 keep = XML_CONTEXT_BYTES; 2070 keep = XML_CONTEXT_BYTES; 2071 /* Detect and prevent integer overflow */ 2071 /* Detect and prevent integer overflow */ 2072 if (keep > INT_MAX - neededSize) { 2072 if (keep > INT_MAX - neededSize) { 2073 parser->m_errorCode = XML_ERROR_NO_MEMO 2073 parser->m_errorCode = XML_ERROR_NO_MEMORY; 2074 return NULL; 2074 return NULL; 2075 } 2075 } 2076 neededSize += keep; 2076 neededSize += keep; 2077 #endif /* defined XML_CONTEXT_BYTES */ 2077 #endif /* defined XML_CONTEXT_BYTES */ 2078 if (neededSize 2078 if (neededSize 2079 <= EXPAT_SAFE_PTR_DIFF(parser->m_buff 2079 <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)) { 2080 #ifdef XML_CONTEXT_BYTES 2080 #ifdef XML_CONTEXT_BYTES 2081 if (keep < EXPAT_SAFE_PTR_DIFF(parser-> 2081 if (keep < EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)) { 2082 int offset 2082 int offset 2083 = (int)EXPAT_SAFE_PTR_DIFF(parser 2083 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer) 2084 - keep; 2084 - keep; 2085 /* The buffer pointers cannot be NULL 2085 /* The buffer pointers cannot be NULL here; we have at least some bytes 2086 * in the buffer */ 2086 * in the buffer */ 2087 memmove(parser->m_buffer, &parser->m_ 2087 memmove(parser->m_buffer, &parser->m_buffer[offset], 2088 parser->m_bufferEnd - parser- 2088 parser->m_bufferEnd - parser->m_bufferPtr + keep); 2089 parser->m_bufferEnd -= offset; 2089 parser->m_bufferEnd -= offset; 2090 parser->m_bufferPtr -= offset; 2090 parser->m_bufferPtr -= offset; 2091 } 2091 } 2092 #else 2092 #else 2093 if (parser->m_buffer && parser->m_buffe 2093 if (parser->m_buffer && parser->m_bufferPtr) { 2094 memmove(parser->m_buffer, parser->m_b 2094 memmove(parser->m_buffer, parser->m_bufferPtr, 2095 EXPAT_SAFE_PTR_DIFF(parser->m 2095 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); 2096 parser->m_bufferEnd 2096 parser->m_bufferEnd 2097 = parser->m_buffer 2097 = parser->m_buffer 2098 + EXPAT_SAFE_PTR_DIFF(parser->m 2098 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); 2099 parser->m_bufferPtr = parser->m_buffe 2099 parser->m_bufferPtr = parser->m_buffer; 2100 } 2100 } 2101 #endif /* not defined XML_CONTEXT_BYTES */ 2101 #endif /* not defined XML_CONTEXT_BYTES */ 2102 } else { 2102 } else { 2103 char *newBuf; 2103 char *newBuf; 2104 int bufferSize 2104 int bufferSize 2105 = (int)EXPAT_SAFE_PTR_DIFF(parser-> 2105 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferPtr); 2106 if (bufferSize == 0) 2106 if (bufferSize == 0) 2107 bufferSize = INIT_BUFFER_SIZE; 2107 bufferSize = INIT_BUFFER_SIZE; 2108 do { 2108 do { 2109 /* Do not invoke signed arithmetic ov 2109 /* Do not invoke signed arithmetic overflow: */ 2110 bufferSize = (int)(2U * (unsigned)buf 2110 bufferSize = (int)(2U * (unsigned)bufferSize); 2111 } while (bufferSize < neededSize && buf 2111 } while (bufferSize < neededSize && bufferSize > 0); 2112 if (bufferSize <= 0) { 2112 if (bufferSize <= 0) { 2113 parser->m_errorCode = XML_ERROR_NO_ME 2113 parser->m_errorCode = XML_ERROR_NO_MEMORY; 2114 return NULL; 2114 return NULL; 2115 } 2115 } 2116 newBuf = (char *)MALLOC(parser, bufferS 2116 newBuf = (char *)MALLOC(parser, bufferSize); 2117 if (newBuf == 0) { 2117 if (newBuf == 0) { 2118 parser->m_errorCode = XML_ERROR_NO_ME 2118 parser->m_errorCode = XML_ERROR_NO_MEMORY; 2119 return NULL; 2119 return NULL; 2120 } 2120 } 2121 parser->m_bufferLim = newBuf + bufferSi 2121 parser->m_bufferLim = newBuf + bufferSize; 2122 #ifdef XML_CONTEXT_BYTES 2122 #ifdef XML_CONTEXT_BYTES 2123 if (parser->m_bufferPtr) { 2123 if (parser->m_bufferPtr) { 2124 memcpy(newBuf, &parser->m_bufferPtr[- 2124 memcpy(newBuf, &parser->m_bufferPtr[-keep], 2125 EXPAT_SAFE_PTR_DIFF(parser->m_ 2125 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) 2126 + keep); 2126 + keep); 2127 FREE(parser, parser->m_buffer); 2127 FREE(parser, parser->m_buffer); 2128 parser->m_buffer = newBuf; 2128 parser->m_buffer = newBuf; 2129 parser->m_bufferEnd 2129 parser->m_bufferEnd 2130 = parser->m_buffer 2130 = parser->m_buffer 2131 + EXPAT_SAFE_PTR_DIFF(parser->m 2131 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr) 2132 + keep; 2132 + keep; 2133 parser->m_bufferPtr = parser->m_buffe 2133 parser->m_bufferPtr = parser->m_buffer + keep; 2134 } else { 2134 } else { 2135 /* This must be a brand new buffer wi 2135 /* This must be a brand new buffer with no data in it yet */ 2136 parser->m_bufferEnd = newBuf; 2136 parser->m_bufferEnd = newBuf; 2137 parser->m_bufferPtr = parser->m_buffe 2137 parser->m_bufferPtr = parser->m_buffer = newBuf; 2138 } 2138 } 2139 #else 2139 #else 2140 if (parser->m_bufferPtr) { 2140 if (parser->m_bufferPtr) { 2141 memcpy(newBuf, parser->m_bufferPtr, 2141 memcpy(newBuf, parser->m_bufferPtr, 2142 EXPAT_SAFE_PTR_DIFF(parser->m_ 2142 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)); 2143 FREE(parser, parser->m_buffer); 2143 FREE(parser, parser->m_buffer); 2144 parser->m_bufferEnd 2144 parser->m_bufferEnd 2145 = newBuf 2145 = newBuf 2146 + EXPAT_SAFE_PTR_DIFF(parser->m 2146 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr); 2147 } else { 2147 } else { 2148 /* This must be a brand new buffer wi 2148 /* This must be a brand new buffer with no data in it yet */ 2149 parser->m_bufferEnd = newBuf; 2149 parser->m_bufferEnd = newBuf; 2150 } 2150 } 2151 parser->m_bufferPtr = parser->m_buffer 2151 parser->m_bufferPtr = parser->m_buffer = newBuf; 2152 #endif /* not defined XML_CONTEXT_BYTES */ 2152 #endif /* not defined XML_CONTEXT_BYTES */ 2153 } 2153 } 2154 parser->m_eventPtr = parser->m_eventEndPt 2154 parser->m_eventPtr = parser->m_eventEndPtr = NULL; 2155 parser->m_positionPtr = NULL; 2155 parser->m_positionPtr = NULL; 2156 } 2156 } 2157 return parser->m_bufferEnd; 2157 return parser->m_bufferEnd; 2158 } 2158 } 2159 2159 2160 enum XML_Status XMLCALL 2160 enum XML_Status XMLCALL 2161 XML_StopParser(XML_Parser parser, XML_Bool re 2161 XML_StopParser(XML_Parser parser, XML_Bool resumable) { 2162 if (parser == NULL) 2162 if (parser == NULL) 2163 return XML_STATUS_ERROR; 2163 return XML_STATUS_ERROR; 2164 switch (parser->m_parsingStatus.parsing) { 2164 switch (parser->m_parsingStatus.parsing) { 2165 case XML_SUSPENDED: 2165 case XML_SUSPENDED: 2166 if (resumable) { 2166 if (resumable) { 2167 parser->m_errorCode = XML_ERROR_SUSPEND 2167 parser->m_errorCode = XML_ERROR_SUSPENDED; 2168 return XML_STATUS_ERROR; 2168 return XML_STATUS_ERROR; 2169 } 2169 } 2170 parser->m_parsingStatus.parsing = XML_FIN 2170 parser->m_parsingStatus.parsing = XML_FINISHED; 2171 break; 2171 break; 2172 case XML_FINISHED: 2172 case XML_FINISHED: 2173 parser->m_errorCode = XML_ERROR_FINISHED; 2173 parser->m_errorCode = XML_ERROR_FINISHED; 2174 return XML_STATUS_ERROR; 2174 return XML_STATUS_ERROR; 2175 default: 2175 default: 2176 if (resumable) { 2176 if (resumable) { 2177 #ifdef XML_DTD 2177 #ifdef XML_DTD 2178 if (parser->m_isParamEntity) { 2178 if (parser->m_isParamEntity) { 2179 parser->m_errorCode = XML_ERROR_SUSPE 2179 parser->m_errorCode = XML_ERROR_SUSPEND_PE; 2180 return XML_STATUS_ERROR; 2180 return XML_STATUS_ERROR; 2181 } 2181 } 2182 #endif 2182 #endif 2183 parser->m_parsingStatus.parsing = XML_S 2183 parser->m_parsingStatus.parsing = XML_SUSPENDED; 2184 } else 2184 } else 2185 parser->m_parsingStatus.parsing = XML_F 2185 parser->m_parsingStatus.parsing = XML_FINISHED; 2186 } 2186 } 2187 return XML_STATUS_OK; 2187 return XML_STATUS_OK; 2188 } 2188 } 2189 2189 2190 enum XML_Status XMLCALL 2190 enum XML_Status XMLCALL 2191 XML_ResumeParser(XML_Parser parser) { 2191 XML_ResumeParser(XML_Parser parser) { 2192 enum XML_Status result = XML_STATUS_OK; 2192 enum XML_Status result = XML_STATUS_OK; 2193 2193 2194 if (parser == NULL) 2194 if (parser == NULL) 2195 return XML_STATUS_ERROR; 2195 return XML_STATUS_ERROR; 2196 if (parser->m_parsingStatus.parsing != XML_ 2196 if (parser->m_parsingStatus.parsing != XML_SUSPENDED) { 2197 parser->m_errorCode = XML_ERROR_NOT_SUSPE 2197 parser->m_errorCode = XML_ERROR_NOT_SUSPENDED; 2198 return XML_STATUS_ERROR; 2198 return XML_STATUS_ERROR; 2199 } 2199 } 2200 parser->m_parsingStatus.parsing = XML_PARSI 2200 parser->m_parsingStatus.parsing = XML_PARSING; 2201 2201 2202 parser->m_errorCode = parser->m_processor( 2202 parser->m_errorCode = parser->m_processor( 2203 parser, parser->m_bufferPtr, parser->m_ 2203 parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr); 2204 2204 2205 if (parser->m_errorCode != XML_ERROR_NONE) 2205 if (parser->m_errorCode != XML_ERROR_NONE) { 2206 parser->m_eventEndPtr = parser->m_eventPt 2206 parser->m_eventEndPtr = parser->m_eventPtr; 2207 parser->m_processor = errorProcessor; 2207 parser->m_processor = errorProcessor; 2208 return XML_STATUS_ERROR; 2208 return XML_STATUS_ERROR; 2209 } else { 2209 } else { 2210 switch (parser->m_parsingStatus.parsing) 2210 switch (parser->m_parsingStatus.parsing) { 2211 case XML_SUSPENDED: 2211 case XML_SUSPENDED: 2212 result = XML_STATUS_SUSPENDED; 2212 result = XML_STATUS_SUSPENDED; 2213 break; 2213 break; 2214 case XML_INITIALIZED: 2214 case XML_INITIALIZED: 2215 case XML_PARSING: 2215 case XML_PARSING: 2216 if (parser->m_parsingStatus.finalBuffer 2216 if (parser->m_parsingStatus.finalBuffer) { 2217 parser->m_parsingStatus.parsing = XML 2217 parser->m_parsingStatus.parsing = XML_FINISHED; 2218 return result; 2218 return result; 2219 } 2219 } 2220 default:; 2220 default:; 2221 } 2221 } 2222 } 2222 } 2223 2223 2224 XmlUpdatePosition(parser->m_encoding, parse 2224 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 2225 parser->m_bufferPtr, &par 2225 parser->m_bufferPtr, &parser->m_position); 2226 parser->m_positionPtr = parser->m_bufferPtr 2226 parser->m_positionPtr = parser->m_bufferPtr; 2227 return result; 2227 return result; 2228 } 2228 } 2229 2229 2230 void XMLCALL 2230 void XMLCALL 2231 XML_GetParsingStatus(XML_Parser parser, XML_P 2231 XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { 2232 if (parser == NULL) 2232 if (parser == NULL) 2233 return; 2233 return; 2234 assert(status != NULL); 2234 assert(status != NULL); 2235 *status = parser->m_parsingStatus; 2235 *status = parser->m_parsingStatus; 2236 } 2236 } 2237 2237 2238 enum XML_Error XMLCALL 2238 enum XML_Error XMLCALL 2239 XML_GetErrorCode(XML_Parser parser) { 2239 XML_GetErrorCode(XML_Parser parser) { 2240 if (parser == NULL) 2240 if (parser == NULL) 2241 return XML_ERROR_INVALID_ARGUMENT; 2241 return XML_ERROR_INVALID_ARGUMENT; 2242 return parser->m_errorCode; 2242 return parser->m_errorCode; 2243 } 2243 } 2244 2244 2245 XML_Index XMLCALL 2245 XML_Index XMLCALL 2246 XML_GetCurrentByteIndex(XML_Parser parser) { 2246 XML_GetCurrentByteIndex(XML_Parser parser) { 2247 if (parser == NULL) 2247 if (parser == NULL) 2248 return -1; 2248 return -1; 2249 if (parser->m_eventPtr) 2249 if (parser->m_eventPtr) 2250 return (XML_Index)(parser->m_parseEndByte 2250 return (XML_Index)(parser->m_parseEndByteIndex 2251 - (parser->m_parseEndP 2251 - (parser->m_parseEndPtr - parser->m_eventPtr)); 2252 return -1; 2252 return -1; 2253 } 2253 } 2254 2254 2255 int XMLCALL 2255 int XMLCALL 2256 XML_GetCurrentByteCount(XML_Parser parser) { 2256 XML_GetCurrentByteCount(XML_Parser parser) { 2257 if (parser == NULL) 2257 if (parser == NULL) 2258 return 0; 2258 return 0; 2259 if (parser->m_eventEndPtr && parser->m_even 2259 if (parser->m_eventEndPtr && parser->m_eventPtr) 2260 return (int)(parser->m_eventEndPtr - pars 2260 return (int)(parser->m_eventEndPtr - parser->m_eventPtr); 2261 return 0; 2261 return 0; 2262 } 2262 } 2263 2263 2264 const char *XMLCALL 2264 const char *XMLCALL 2265 XML_GetInputContext(XML_Parser parser, int *o 2265 XML_GetInputContext(XML_Parser parser, int *offset, int *size) { 2266 #ifdef XML_CONTEXT_BYTES 2266 #ifdef XML_CONTEXT_BYTES 2267 if (parser == NULL) 2267 if (parser == NULL) 2268 return NULL; 2268 return NULL; 2269 if (parser->m_eventPtr && parser->m_buffer) 2269 if (parser->m_eventPtr && parser->m_buffer) { 2270 if (offset != NULL) 2270 if (offset != NULL) 2271 *offset = (int)(parser->m_eventPtr - pa 2271 *offset = (int)(parser->m_eventPtr - parser->m_buffer); 2272 if (size != NULL) 2272 if (size != NULL) 2273 *size = (int)(parser->m_bufferEnd - par 2273 *size = (int)(parser->m_bufferEnd - parser->m_buffer); 2274 return parser->m_buffer; 2274 return parser->m_buffer; 2275 } 2275 } 2276 #else 2276 #else 2277 (void)parser; 2277 (void)parser; 2278 (void)offset; 2278 (void)offset; 2279 (void)size; 2279 (void)size; 2280 #endif /* defined XML_CONTEXT_BYTES */ 2280 #endif /* defined XML_CONTEXT_BYTES */ 2281 return (const char *)0; 2281 return (const char *)0; 2282 } 2282 } 2283 2283 2284 XML_Size XMLCALL 2284 XML_Size XMLCALL 2285 XML_GetCurrentLineNumber(XML_Parser parser) { 2285 XML_GetCurrentLineNumber(XML_Parser parser) { 2286 if (parser == NULL) 2286 if (parser == NULL) 2287 return 0; 2287 return 0; 2288 if (parser->m_eventPtr && parser->m_eventPt 2288 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { 2289 XmlUpdatePosition(parser->m_encoding, par 2289 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 2290 parser->m_eventPtr, &pa 2290 parser->m_eventPtr, &parser->m_position); 2291 parser->m_positionPtr = parser->m_eventPt 2291 parser->m_positionPtr = parser->m_eventPtr; 2292 } 2292 } 2293 return parser->m_position.lineNumber + 1; 2293 return parser->m_position.lineNumber + 1; 2294 } 2294 } 2295 2295 2296 XML_Size XMLCALL 2296 XML_Size XMLCALL 2297 XML_GetCurrentColumnNumber(XML_Parser parser) 2297 XML_GetCurrentColumnNumber(XML_Parser parser) { 2298 if (parser == NULL) 2298 if (parser == NULL) 2299 return 0; 2299 return 0; 2300 if (parser->m_eventPtr && parser->m_eventPt 2300 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) { 2301 XmlUpdatePosition(parser->m_encoding, par 2301 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, 2302 parser->m_eventPtr, &pa 2302 parser->m_eventPtr, &parser->m_position); 2303 parser->m_positionPtr = parser->m_eventPt 2303 parser->m_positionPtr = parser->m_eventPtr; 2304 } 2304 } 2305 return parser->m_position.columnNumber; 2305 return parser->m_position.columnNumber; 2306 } 2306 } 2307 2307 2308 void XMLCALL 2308 void XMLCALL 2309 XML_FreeContentModel(XML_Parser parser, XML_C 2309 XML_FreeContentModel(XML_Parser parser, XML_Content *model) { 2310 if (parser != NULL) 2310 if (parser != NULL) 2311 FREE(parser, model); 2311 FREE(parser, model); 2312 } 2312 } 2313 2313 2314 void *XMLCALL 2314 void *XMLCALL 2315 XML_MemMalloc(XML_Parser parser, size_t size) 2315 XML_MemMalloc(XML_Parser parser, size_t size) { 2316 if (parser == NULL) 2316 if (parser == NULL) 2317 return NULL; 2317 return NULL; 2318 return MALLOC(parser, size); 2318 return MALLOC(parser, size); 2319 } 2319 } 2320 2320 2321 void *XMLCALL 2321 void *XMLCALL 2322 XML_MemRealloc(XML_Parser parser, void *ptr, 2322 XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { 2323 if (parser == NULL) 2323 if (parser == NULL) 2324 return NULL; 2324 return NULL; 2325 return REALLOC(parser, ptr, size); 2325 return REALLOC(parser, ptr, size); 2326 } 2326 } 2327 2327 2328 void XMLCALL 2328 void XMLCALL 2329 XML_MemFree(XML_Parser parser, void *ptr) { 2329 XML_MemFree(XML_Parser parser, void *ptr) { 2330 if (parser != NULL) 2330 if (parser != NULL) 2331 FREE(parser, ptr); 2331 FREE(parser, ptr); 2332 } 2332 } 2333 2333 2334 void XMLCALL 2334 void XMLCALL 2335 XML_DefaultCurrent(XML_Parser parser) { 2335 XML_DefaultCurrent(XML_Parser parser) { 2336 if (parser == NULL) 2336 if (parser == NULL) 2337 return; 2337 return; 2338 if (parser->m_defaultHandler) { 2338 if (parser->m_defaultHandler) { 2339 if (parser->m_openInternalEntities) 2339 if (parser->m_openInternalEntities) 2340 reportDefault(parser, parser->m_interna 2340 reportDefault(parser, parser->m_internalEncoding, 2341 parser->m_openInternalEnt 2341 parser->m_openInternalEntities->internalEventPtr, 2342 parser->m_openInternalEnt 2342 parser->m_openInternalEntities->internalEventEndPtr); 2343 else 2343 else 2344 reportDefault(parser, parser->m_encodin 2344 reportDefault(parser, parser->m_encoding, parser->m_eventPtr, 2345 parser->m_eventEndPtr); 2345 parser->m_eventEndPtr); 2346 } 2346 } 2347 } 2347 } 2348 2348 2349 const XML_LChar *XMLCALL 2349 const XML_LChar *XMLCALL 2350 XML_ErrorString(enum XML_Error code) { 2350 XML_ErrorString(enum XML_Error code) { 2351 switch (code) { 2351 switch (code) { 2352 case XML_ERROR_NONE: 2352 case XML_ERROR_NONE: 2353 return NULL; 2353 return NULL; 2354 case XML_ERROR_NO_MEMORY: 2354 case XML_ERROR_NO_MEMORY: 2355 return XML_L("out of memory"); 2355 return XML_L("out of memory"); 2356 case XML_ERROR_SYNTAX: 2356 case XML_ERROR_SYNTAX: 2357 return XML_L("syntax error"); 2357 return XML_L("syntax error"); 2358 case XML_ERROR_NO_ELEMENTS: 2358 case XML_ERROR_NO_ELEMENTS: 2359 return XML_L("no element found"); 2359 return XML_L("no element found"); 2360 case XML_ERROR_INVALID_TOKEN: 2360 case XML_ERROR_INVALID_TOKEN: 2361 return XML_L("not well-formed (invalid to 2361 return XML_L("not well-formed (invalid token)"); 2362 case XML_ERROR_UNCLOSED_TOKEN: 2362 case XML_ERROR_UNCLOSED_TOKEN: 2363 return XML_L("unclosed token"); 2363 return XML_L("unclosed token"); 2364 case XML_ERROR_PARTIAL_CHAR: 2364 case XML_ERROR_PARTIAL_CHAR: 2365 return XML_L("partial character"); 2365 return XML_L("partial character"); 2366 case XML_ERROR_TAG_MISMATCH: 2366 case XML_ERROR_TAG_MISMATCH: 2367 return XML_L("mismatched tag"); 2367 return XML_L("mismatched tag"); 2368 case XML_ERROR_DUPLICATE_ATTRIBUTE: 2368 case XML_ERROR_DUPLICATE_ATTRIBUTE: 2369 return XML_L("duplicate attribute"); 2369 return XML_L("duplicate attribute"); 2370 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: 2370 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: 2371 return XML_L("junk after document element 2371 return XML_L("junk after document element"); 2372 case XML_ERROR_PARAM_ENTITY_REF: 2372 case XML_ERROR_PARAM_ENTITY_REF: 2373 return XML_L("illegal parameter entity re 2373 return XML_L("illegal parameter entity reference"); 2374 case XML_ERROR_UNDEFINED_ENTITY: 2374 case XML_ERROR_UNDEFINED_ENTITY: 2375 return XML_L("undefined entity"); 2375 return XML_L("undefined entity"); 2376 case XML_ERROR_RECURSIVE_ENTITY_REF: 2376 case XML_ERROR_RECURSIVE_ENTITY_REF: 2377 return XML_L("recursive entity reference" 2377 return XML_L("recursive entity reference"); 2378 case XML_ERROR_ASYNC_ENTITY: 2378 case XML_ERROR_ASYNC_ENTITY: 2379 return XML_L("asynchronous entity"); 2379 return XML_L("asynchronous entity"); 2380 case XML_ERROR_BAD_CHAR_REF: 2380 case XML_ERROR_BAD_CHAR_REF: 2381 return XML_L("reference to invalid charac 2381 return XML_L("reference to invalid character number"); 2382 case XML_ERROR_BINARY_ENTITY_REF: 2382 case XML_ERROR_BINARY_ENTITY_REF: 2383 return XML_L("reference to binary entity" 2383 return XML_L("reference to binary entity"); 2384 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_RE 2384 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: 2385 return XML_L("reference to external entit 2385 return XML_L("reference to external entity in attribute"); 2386 case XML_ERROR_MISPLACED_XML_PI: 2386 case XML_ERROR_MISPLACED_XML_PI: 2387 return XML_L("XML or text declaration not 2387 return XML_L("XML or text declaration not at start of entity"); 2388 case XML_ERROR_UNKNOWN_ENCODING: 2388 case XML_ERROR_UNKNOWN_ENCODING: 2389 return XML_L("unknown encoding"); 2389 return XML_L("unknown encoding"); 2390 case XML_ERROR_INCORRECT_ENCODING: 2390 case XML_ERROR_INCORRECT_ENCODING: 2391 return XML_L("encoding specified in XML d 2391 return XML_L("encoding specified in XML declaration is incorrect"); 2392 case XML_ERROR_UNCLOSED_CDATA_SECTION: 2392 case XML_ERROR_UNCLOSED_CDATA_SECTION: 2393 return XML_L("unclosed CDATA section"); 2393 return XML_L("unclosed CDATA section"); 2394 case XML_ERROR_EXTERNAL_ENTITY_HANDLING: 2394 case XML_ERROR_EXTERNAL_ENTITY_HANDLING: 2395 return XML_L("error in processing externa 2395 return XML_L("error in processing external entity reference"); 2396 case XML_ERROR_NOT_STANDALONE: 2396 case XML_ERROR_NOT_STANDALONE: 2397 return XML_L("document is not standalone" 2397 return XML_L("document is not standalone"); 2398 case XML_ERROR_UNEXPECTED_STATE: 2398 case XML_ERROR_UNEXPECTED_STATE: 2399 return XML_L("unexpected parser state - p 2399 return XML_L("unexpected parser state - please send a bug report"); 2400 case XML_ERROR_ENTITY_DECLARED_IN_PE: 2400 case XML_ERROR_ENTITY_DECLARED_IN_PE: 2401 return XML_L("entity declared in paramete 2401 return XML_L("entity declared in parameter entity"); 2402 case XML_ERROR_FEATURE_REQUIRES_XML_DTD: 2402 case XML_ERROR_FEATURE_REQUIRES_XML_DTD: 2403 return XML_L("requested feature requires 2403 return XML_L("requested feature requires XML_DTD support in Expat"); 2404 case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PAR 2404 case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: 2405 return XML_L("cannot change setting once 2405 return XML_L("cannot change setting once parsing has begun"); 2406 /* Added in 1.95.7. */ 2406 /* Added in 1.95.7. */ 2407 case XML_ERROR_UNBOUND_PREFIX: 2407 case XML_ERROR_UNBOUND_PREFIX: 2408 return XML_L("unbound prefix"); 2408 return XML_L("unbound prefix"); 2409 /* Added in 1.95.8. */ 2409 /* Added in 1.95.8. */ 2410 case XML_ERROR_UNDECLARING_PREFIX: 2410 case XML_ERROR_UNDECLARING_PREFIX: 2411 return XML_L("must not undeclare prefix") 2411 return XML_L("must not undeclare prefix"); 2412 case XML_ERROR_INCOMPLETE_PE: 2412 case XML_ERROR_INCOMPLETE_PE: 2413 return XML_L("incomplete markup in parame 2413 return XML_L("incomplete markup in parameter entity"); 2414 case XML_ERROR_XML_DECL: 2414 case XML_ERROR_XML_DECL: 2415 return XML_L("XML declaration not well-fo 2415 return XML_L("XML declaration not well-formed"); 2416 case XML_ERROR_TEXT_DECL: 2416 case XML_ERROR_TEXT_DECL: 2417 return XML_L("text declaration not well-f 2417 return XML_L("text declaration not well-formed"); 2418 case XML_ERROR_PUBLICID: 2418 case XML_ERROR_PUBLICID: 2419 return XML_L("illegal character(s) in pub 2419 return XML_L("illegal character(s) in public id"); 2420 case XML_ERROR_SUSPENDED: 2420 case XML_ERROR_SUSPENDED: 2421 return XML_L("parser suspended"); 2421 return XML_L("parser suspended"); 2422 case XML_ERROR_NOT_SUSPENDED: 2422 case XML_ERROR_NOT_SUSPENDED: 2423 return XML_L("parser not suspended"); 2423 return XML_L("parser not suspended"); 2424 case XML_ERROR_ABORTED: 2424 case XML_ERROR_ABORTED: 2425 return XML_L("parsing aborted"); 2425 return XML_L("parsing aborted"); 2426 case XML_ERROR_FINISHED: 2426 case XML_ERROR_FINISHED: 2427 return XML_L("parsing finished"); 2427 return XML_L("parsing finished"); 2428 case XML_ERROR_SUSPEND_PE: 2428 case XML_ERROR_SUSPEND_PE: 2429 return XML_L("cannot suspend in external 2429 return XML_L("cannot suspend in external parameter entity"); 2430 /* Added in 2.0.0. */ 2430 /* Added in 2.0.0. */ 2431 case XML_ERROR_RESERVED_PREFIX_XML: 2431 case XML_ERROR_RESERVED_PREFIX_XML: 2432 return XML_L( 2432 return XML_L( 2433 "reserved prefix (xml) must not be un 2433 "reserved prefix (xml) must not be undeclared or bound to another namespace name"); 2434 case XML_ERROR_RESERVED_PREFIX_XMLNS: 2434 case XML_ERROR_RESERVED_PREFIX_XMLNS: 2435 return XML_L("reserved prefix (xmlns) mus 2435 return XML_L("reserved prefix (xmlns) must not be declared or undeclared"); 2436 case XML_ERROR_RESERVED_NAMESPACE_URI: 2436 case XML_ERROR_RESERVED_NAMESPACE_URI: 2437 return XML_L( 2437 return XML_L( 2438 "prefix must not be bound to one of t 2438 "prefix must not be bound to one of the reserved namespace names"); 2439 /* Added in 2.2.5. */ 2439 /* Added in 2.2.5. */ 2440 case XML_ERROR_INVALID_ARGUMENT: /* Constan 2440 case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */ 2441 return XML_L("invalid argument"); 2441 return XML_L("invalid argument"); 2442 /* Added in 2.3.0. */ 2442 /* Added in 2.3.0. */ 2443 case XML_ERROR_NO_BUFFER: 2443 case XML_ERROR_NO_BUFFER: 2444 return XML_L( 2444 return XML_L( 2445 "a successful prior call to function 2445 "a successful prior call to function XML_GetBuffer is required"); 2446 /* Added in 2.4.0. */ 2446 /* Added in 2.4.0. */ 2447 case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: 2447 case XML_ERROR_AMPLIFICATION_LIMIT_BREACH: 2448 return XML_L( 2448 return XML_L( 2449 "limit on input amplification factor 2449 "limit on input amplification factor (from DTD and entities) breached"); 2450 } 2450 } 2451 return NULL; 2451 return NULL; 2452 } 2452 } 2453 2453 2454 const XML_LChar *XMLCALL 2454 const XML_LChar *XMLCALL 2455 XML_ExpatVersion(void) { 2455 XML_ExpatVersion(void) { 2456 /* V1 is used to string-ize the version num 2456 /* V1 is used to string-ize the version number. However, it would 2457 string-ize the actual version macro *nam 2457 string-ize the actual version macro *names* unless we get them 2458 substituted before being passed to V1. C 2458 substituted before being passed to V1. CPP is defined to expand 2459 a macro, then rescan for more expansions 2459 a macro, then rescan for more expansions. Thus, we use V2 to expand 2460 the version macros, then CPP will expand 2460 the version macros, then CPP will expand the resulting V1() macro 2461 with the correct numerals. */ 2461 with the correct numerals. */ 2462 /* ### I'm assuming cpp is portable in this 2462 /* ### I'm assuming cpp is portable in this respect... */ 2463 2463 2464 #define V1(a, b, c) XML_L(#a) XML_L(".") XML_ 2464 #define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c) 2465 #define V2(a, b, c) XML_L("expat_") V1(a, b, 2465 #define V2(a, b, c) XML_L("expat_") V1(a, b, c) 2466 2466 2467 return V2(XML_MAJOR_VERSION, XML_MINOR_VERS 2467 return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); 2468 2468 2469 #undef V1 2469 #undef V1 2470 #undef V2 2470 #undef V2 2471 } 2471 } 2472 2472 2473 XML_Expat_Version XMLCALL 2473 XML_Expat_Version XMLCALL 2474 XML_ExpatVersionInfo(void) { 2474 XML_ExpatVersionInfo(void) { 2475 XML_Expat_Version version; 2475 XML_Expat_Version version; 2476 2476 2477 version.major = XML_MAJOR_VERSION; 2477 version.major = XML_MAJOR_VERSION; 2478 version.minor = XML_MINOR_VERSION; 2478 version.minor = XML_MINOR_VERSION; 2479 version.micro = XML_MICRO_VERSION; 2479 version.micro = XML_MICRO_VERSION; 2480 2480 2481 return version; 2481 return version; 2482 } 2482 } 2483 2483 2484 const XML_Feature *XMLCALL 2484 const XML_Feature *XMLCALL 2485 XML_GetFeatureList(void) { 2485 XML_GetFeatureList(void) { 2486 static const XML_Feature features[] = { 2486 static const XML_Feature features[] = { 2487 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("si 2487 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"), 2488 sizeof(XML_Char)}, 2488 sizeof(XML_Char)}, 2489 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("s 2489 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), 2490 sizeof(XML_LChar)}, 2490 sizeof(XML_LChar)}, 2491 #ifdef XML_UNICODE 2491 #ifdef XML_UNICODE 2492 {XML_FEATURE_UNICODE, XML_L("XML_UNICOD 2492 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0}, 2493 #endif 2493 #endif 2494 #ifdef XML_UNICODE_WCHAR_T 2494 #ifdef XML_UNICODE_WCHAR_T 2495 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XM 2495 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0}, 2496 #endif 2496 #endif 2497 #ifdef XML_DTD 2497 #ifdef XML_DTD 2498 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, 2498 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0}, 2499 #endif 2499 #endif 2500 #ifdef XML_CONTEXT_BYTES 2500 #ifdef XML_CONTEXT_BYTES 2501 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_ 2501 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"), 2502 XML_CONTEXT_BYTES}, 2502 XML_CONTEXT_BYTES}, 2503 #endif 2503 #endif 2504 #ifdef XML_MIN_SIZE 2504 #ifdef XML_MIN_SIZE 2505 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_S 2505 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0}, 2506 #endif 2506 #endif 2507 #ifdef XML_NS 2507 #ifdef XML_NS 2508 {XML_FEATURE_NS, XML_L("XML_NS"), 0}, 2508 {XML_FEATURE_NS, XML_L("XML_NS"), 0}, 2509 #endif 2509 #endif 2510 #ifdef XML_LARGE_SIZE 2510 #ifdef XML_LARGE_SIZE 2511 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LAR 2511 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0}, 2512 #endif 2512 #endif 2513 #ifdef XML_ATTR_INFO 2513 #ifdef XML_ATTR_INFO 2514 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR 2514 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0}, 2515 #endif 2515 #endif 2516 #ifdef XML_DTD 2516 #ifdef XML_DTD 2517 /* Added in Expat 2.4.0. */ 2517 /* Added in Expat 2.4.0. */ 2518 {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROT 2518 {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT, 2519 XML_L("XML_BLAP_MAX_AMP"), 2519 XML_L("XML_BLAP_MAX_AMP"), 2520 (long int) 2520 (long int) 2521 EXPAT_BILLION_LAUGHS_ATTACK_PROTEC 2521 EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT}, 2522 {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROT 2522 {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT, 2523 XML_L("XML_BLAP_ACT_THRES"), 2523 XML_L("XML_BLAP_ACT_THRES"), 2524 EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION 2524 EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT}, 2525 #endif 2525 #endif 2526 {XML_FEATURE_END, NULL, 0}}; 2526 {XML_FEATURE_END, NULL, 0}}; 2527 2527 2528 return features; 2528 return features; 2529 } 2529 } 2530 2530 2531 #ifdef XML_DTD 2531 #ifdef XML_DTD 2532 XML_Bool XMLCALL 2532 XML_Bool XMLCALL 2533 XML_SetBillionLaughsAttackProtectionMaximumAm 2533 XML_SetBillionLaughsAttackProtectionMaximumAmplification( 2534 XML_Parser parser, float maximumAmplifica 2534 XML_Parser parser, float maximumAmplificationFactor) { 2535 if ((parser == NULL) || (parser->m_parentPa 2535 if ((parser == NULL) || (parser->m_parentParser != NULL) 2536 || isnan(maximumAmplificationFactor) 2536 || isnan(maximumAmplificationFactor) 2537 || (maximumAmplificationFactor < 1.0f)) 2537 || (maximumAmplificationFactor < 1.0f)) { 2538 return XML_FALSE; 2538 return XML_FALSE; 2539 } 2539 } 2540 parser->m_accounting.maximumAmplificationFa 2540 parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor; 2541 return XML_TRUE; 2541 return XML_TRUE; 2542 } 2542 } 2543 2543 2544 XML_Bool XMLCALL 2544 XML_Bool XMLCALL 2545 XML_SetBillionLaughsAttackProtectionActivatio 2545 XML_SetBillionLaughsAttackProtectionActivationThreshold( 2546 XML_Parser parser, unsigned long long act 2546 XML_Parser parser, unsigned long long activationThresholdBytes) { 2547 if ((parser == NULL) || (parser->m_parentPa 2547 if ((parser == NULL) || (parser->m_parentParser != NULL)) { 2548 return XML_FALSE; 2548 return XML_FALSE; 2549 } 2549 } 2550 parser->m_accounting.activationThresholdByt 2550 parser->m_accounting.activationThresholdBytes = activationThresholdBytes; 2551 return XML_TRUE; 2551 return XML_TRUE; 2552 } 2552 } 2553 #endif /* XML_DTD */ 2553 #endif /* XML_DTD */ 2554 2554 2555 /* Initially tag->rawName always points into 2555 /* Initially tag->rawName always points into the parse buffer; 2556 for those TAG instances opened while the c 2556 for those TAG instances opened while the current parse buffer was 2557 processed, and not yet closed, we need to 2557 processed, and not yet closed, we need to store tag->rawName in a more 2558 permanent location, since the parse buffer 2558 permanent location, since the parse buffer is about to be discarded. 2559 */ 2559 */ 2560 static XML_Bool 2560 static XML_Bool 2561 storeRawNames(XML_Parser parser) { 2561 storeRawNames(XML_Parser parser) { 2562 TAG *tag = parser->m_tagStack; 2562 TAG *tag = parser->m_tagStack; 2563 while (tag) { 2563 while (tag) { 2564 int bufSize; 2564 int bufSize; 2565 int nameLen = sizeof(XML_Char) * (tag->na 2565 int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); 2566 size_t rawNameLen; 2566 size_t rawNameLen; 2567 char *rawNameBuf = tag->buf + nameLen; 2567 char *rawNameBuf = tag->buf + nameLen; 2568 /* Stop if already stored. Since m_tagSt 2568 /* Stop if already stored. Since m_tagStack is a stack, we can stop 2569 at the first entry that has already be 2569 at the first entry that has already been copied; everything 2570 below it in the stack is already been 2570 below it in the stack is already been accounted for in a 2571 previous call to this function. 2571 previous call to this function. 2572 */ 2572 */ 2573 if (tag->rawName == rawNameBuf) 2573 if (tag->rawName == rawNameBuf) 2574 break; 2574 break; 2575 /* For re-use purposes we need to ensure 2575 /* For re-use purposes we need to ensure that the 2576 size of tag->buf is a multiple of size 2576 size of tag->buf is a multiple of sizeof(XML_Char). 2577 */ 2577 */ 2578 rawNameLen = ROUND_UP(tag->rawNameLength, 2578 rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); 2579 /* Detect and prevent integer overflow. * 2579 /* Detect and prevent integer overflow. */ 2580 if (rawNameLen > (size_t)INT_MAX - nameLe 2580 if (rawNameLen > (size_t)INT_MAX - nameLen) 2581 return XML_FALSE; 2581 return XML_FALSE; 2582 bufSize = nameLen + (int)rawNameLen; 2582 bufSize = nameLen + (int)rawNameLen; 2583 if (bufSize > tag->bufEnd - tag->buf) { 2583 if (bufSize > tag->bufEnd - tag->buf) { 2584 char *temp = (char *)REALLOC(parser, ta 2584 char *temp = (char *)REALLOC(parser, tag->buf, bufSize); 2585 if (temp == NULL) 2585 if (temp == NULL) 2586 return XML_FALSE; 2586 return XML_FALSE; 2587 /* if tag->name.str points to tag->buf 2587 /* if tag->name.str points to tag->buf (only when namespace 2588 processing is off) then we have to u 2588 processing is off) then we have to update it 2589 */ 2589 */ 2590 if (tag->name.str == (XML_Char *)tag->b 2590 if (tag->name.str == (XML_Char *)tag->buf) 2591 tag->name.str = (XML_Char *)temp; 2591 tag->name.str = (XML_Char *)temp; 2592 /* if tag->name.localPart is set (when 2592 /* if tag->name.localPart is set (when namespace processing is on) 2593 then update it as well, since it wil 2593 then update it as well, since it will always point into tag->buf 2594 */ 2594 */ 2595 if (tag->name.localPart) 2595 if (tag->name.localPart) 2596 tag->name.localPart 2596 tag->name.localPart 2597 = (XML_Char *)temp + (tag->name.l 2597 = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf); 2598 tag->buf = temp; 2598 tag->buf = temp; 2599 tag->bufEnd = temp + bufSize; 2599 tag->bufEnd = temp + bufSize; 2600 rawNameBuf = temp + nameLen; 2600 rawNameBuf = temp + nameLen; 2601 } 2601 } 2602 memcpy(rawNameBuf, tag->rawName, tag->raw 2602 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); 2603 tag->rawName = rawNameBuf; 2603 tag->rawName = rawNameBuf; 2604 tag = tag->parent; 2604 tag = tag->parent; 2605 } 2605 } 2606 return XML_TRUE; 2606 return XML_TRUE; 2607 } 2607 } 2608 2608 2609 static enum XML_Error PTRCALL 2609 static enum XML_Error PTRCALL 2610 contentProcessor(XML_Parser parser, const cha 2610 contentProcessor(XML_Parser parser, const char *start, const char *end, 2611 const char **endPtr) { 2611 const char **endPtr) { 2612 enum XML_Error result = doContent( 2612 enum XML_Error result = doContent( 2613 parser, 0, parser->m_encoding, start, e 2613 parser, 0, parser->m_encoding, start, end, endPtr, 2614 (XML_Bool)! parser->m_parsingStatus.fin 2614 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); 2615 if (result == XML_ERROR_NONE) { 2615 if (result == XML_ERROR_NONE) { 2616 if (! storeRawNames(parser)) 2616 if (! storeRawNames(parser)) 2617 return XML_ERROR_NO_MEMORY; 2617 return XML_ERROR_NO_MEMORY; 2618 } 2618 } 2619 return result; 2619 return result; 2620 } 2620 } 2621 2621 2622 static enum XML_Error PTRCALL 2622 static enum XML_Error PTRCALL 2623 externalEntityInitProcessor(XML_Parser parser 2623 externalEntityInitProcessor(XML_Parser parser, const char *start, 2624 const char *end, 2624 const char *end, const char **endPtr) { 2625 enum XML_Error result = initializeEncoding( 2625 enum XML_Error result = initializeEncoding(parser); 2626 if (result != XML_ERROR_NONE) 2626 if (result != XML_ERROR_NONE) 2627 return result; 2627 return result; 2628 parser->m_processor = externalEntityInitPro 2628 parser->m_processor = externalEntityInitProcessor2; 2629 return externalEntityInitProcessor2(parser, 2629 return externalEntityInitProcessor2(parser, start, end, endPtr); 2630 } 2630 } 2631 2631 2632 static enum XML_Error PTRCALL 2632 static enum XML_Error PTRCALL 2633 externalEntityInitProcessor2(XML_Parser parse 2633 externalEntityInitProcessor2(XML_Parser parser, const char *start, 2634 const char *end, 2634 const char *end, const char **endPtr) { 2635 const char *next = start; /* XmlContentTok 2635 const char *next = start; /* XmlContentTok doesn't always set the last arg */ 2636 int tok = XmlContentTok(parser->m_encoding, 2636 int tok = XmlContentTok(parser->m_encoding, start, end, &next); 2637 switch (tok) { 2637 switch (tok) { 2638 case XML_TOK_BOM: 2638 case XML_TOK_BOM: 2639 #ifdef XML_DTD 2639 #ifdef XML_DTD 2640 if (! accountingDiffTolerated(parser, tok 2640 if (! accountingDiffTolerated(parser, tok, start, next, __LINE__, 2641 XML_ACCOUNT 2641 XML_ACCOUNT_DIRECT)) { 2642 accountingOnAbort(parser); 2642 accountingOnAbort(parser); 2643 return XML_ERROR_AMPLIFICATION_LIMIT_BR 2643 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 2644 } 2644 } 2645 #endif /* XML_DTD */ 2645 #endif /* XML_DTD */ 2646 2646 2647 /* If we are at the end of the buffer, th 2647 /* If we are at the end of the buffer, this would cause the next stage, 2648 i.e. externalEntityInitProcessor3, to 2648 i.e. externalEntityInitProcessor3, to pass control directly to 2649 doContent (by detecting XML_TOK_NONE) 2649 doContent (by detecting XML_TOK_NONE) without processing any xml text 2650 declaration - causing the error XML_ER 2650 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. 2651 */ 2651 */ 2652 if (next == end && ! parser->m_parsingSta 2652 if (next == end && ! parser->m_parsingStatus.finalBuffer) { 2653 *endPtr = next; 2653 *endPtr = next; 2654 return XML_ERROR_NONE; 2654 return XML_ERROR_NONE; 2655 } 2655 } 2656 start = next; 2656 start = next; 2657 break; 2657 break; 2658 case XML_TOK_PARTIAL: 2658 case XML_TOK_PARTIAL: 2659 if (! parser->m_parsingStatus.finalBuffer 2659 if (! parser->m_parsingStatus.finalBuffer) { 2660 *endPtr = start; 2660 *endPtr = start; 2661 return XML_ERROR_NONE; 2661 return XML_ERROR_NONE; 2662 } 2662 } 2663 parser->m_eventPtr = start; 2663 parser->m_eventPtr = start; 2664 return XML_ERROR_UNCLOSED_TOKEN; 2664 return XML_ERROR_UNCLOSED_TOKEN; 2665 case XML_TOK_PARTIAL_CHAR: 2665 case XML_TOK_PARTIAL_CHAR: 2666 if (! parser->m_parsingStatus.finalBuffer 2666 if (! parser->m_parsingStatus.finalBuffer) { 2667 *endPtr = start; 2667 *endPtr = start; 2668 return XML_ERROR_NONE; 2668 return XML_ERROR_NONE; 2669 } 2669 } 2670 parser->m_eventPtr = start; 2670 parser->m_eventPtr = start; 2671 return XML_ERROR_PARTIAL_CHAR; 2671 return XML_ERROR_PARTIAL_CHAR; 2672 } 2672 } 2673 parser->m_processor = externalEntityInitPro 2673 parser->m_processor = externalEntityInitProcessor3; 2674 return externalEntityInitProcessor3(parser, 2674 return externalEntityInitProcessor3(parser, start, end, endPtr); 2675 } 2675 } 2676 2676 2677 static enum XML_Error PTRCALL 2677 static enum XML_Error PTRCALL 2678 externalEntityInitProcessor3(XML_Parser parse 2678 externalEntityInitProcessor3(XML_Parser parser, const char *start, 2679 const char *end, 2679 const char *end, const char **endPtr) { 2680 int tok; 2680 int tok; 2681 const char *next = start; /* XmlContentTok 2681 const char *next = start; /* XmlContentTok doesn't always set the last arg */ 2682 parser->m_eventPtr = start; 2682 parser->m_eventPtr = start; 2683 tok = XmlContentTok(parser->m_encoding, sta 2683 tok = XmlContentTok(parser->m_encoding, start, end, &next); 2684 /* Note: These bytes are accounted later in 2684 /* Note: These bytes are accounted later in: 2685 - processXmlDecl 2685 - processXmlDecl 2686 - externalEntityContentProcessor 2686 - externalEntityContentProcessor 2687 */ 2687 */ 2688 parser->m_eventEndPtr = next; 2688 parser->m_eventEndPtr = next; 2689 2689 2690 switch (tok) { 2690 switch (tok) { 2691 case XML_TOK_XML_DECL: { 2691 case XML_TOK_XML_DECL: { 2692 enum XML_Error result; 2692 enum XML_Error result; 2693 result = processXmlDecl(parser, 1, start, 2693 result = processXmlDecl(parser, 1, start, next); 2694 if (result != XML_ERROR_NONE) 2694 if (result != XML_ERROR_NONE) 2695 return result; 2695 return result; 2696 switch (parser->m_parsingStatus.parsing) 2696 switch (parser->m_parsingStatus.parsing) { 2697 case XML_SUSPENDED: 2697 case XML_SUSPENDED: 2698 *endPtr = next; 2698 *endPtr = next; 2699 return XML_ERROR_NONE; 2699 return XML_ERROR_NONE; 2700 case XML_FINISHED: 2700 case XML_FINISHED: 2701 return XML_ERROR_ABORTED; 2701 return XML_ERROR_ABORTED; 2702 default: 2702 default: 2703 start = next; 2703 start = next; 2704 } 2704 } 2705 } break; 2705 } break; 2706 case XML_TOK_PARTIAL: 2706 case XML_TOK_PARTIAL: 2707 if (! parser->m_parsingStatus.finalBuffer 2707 if (! parser->m_parsingStatus.finalBuffer) { 2708 *endPtr = start; 2708 *endPtr = start; 2709 return XML_ERROR_NONE; 2709 return XML_ERROR_NONE; 2710 } 2710 } 2711 return XML_ERROR_UNCLOSED_TOKEN; 2711 return XML_ERROR_UNCLOSED_TOKEN; 2712 case XML_TOK_PARTIAL_CHAR: 2712 case XML_TOK_PARTIAL_CHAR: 2713 if (! parser->m_parsingStatus.finalBuffer 2713 if (! parser->m_parsingStatus.finalBuffer) { 2714 *endPtr = start; 2714 *endPtr = start; 2715 return XML_ERROR_NONE; 2715 return XML_ERROR_NONE; 2716 } 2716 } 2717 return XML_ERROR_PARTIAL_CHAR; 2717 return XML_ERROR_PARTIAL_CHAR; 2718 } 2718 } 2719 parser->m_processor = externalEntityContent 2719 parser->m_processor = externalEntityContentProcessor; 2720 parser->m_tagLevel = 1; 2720 parser->m_tagLevel = 1; 2721 return externalEntityContentProcessor(parse 2721 return externalEntityContentProcessor(parser, start, end, endPtr); 2722 } 2722 } 2723 2723 2724 static enum XML_Error PTRCALL 2724 static enum XML_Error PTRCALL 2725 externalEntityContentProcessor(XML_Parser par 2725 externalEntityContentProcessor(XML_Parser parser, const char *start, 2726 const char *en 2726 const char *end, const char **endPtr) { 2727 enum XML_Error result 2727 enum XML_Error result 2728 = doContent(parser, 1, parser->m_encodi 2728 = doContent(parser, 1, parser->m_encoding, start, end, endPtr, 2729 (XML_Bool)! parser->m_parsi 2729 (XML_Bool)! parser->m_parsingStatus.finalBuffer, 2730 XML_ACCOUNT_ENTITY_EXPANSIO 2730 XML_ACCOUNT_ENTITY_EXPANSION); 2731 if (result == XML_ERROR_NONE) { 2731 if (result == XML_ERROR_NONE) { 2732 if (! storeRawNames(parser)) 2732 if (! storeRawNames(parser)) 2733 return XML_ERROR_NO_MEMORY; 2733 return XML_ERROR_NO_MEMORY; 2734 } 2734 } 2735 return result; 2735 return result; 2736 } 2736 } 2737 2737 2738 static enum XML_Error 2738 static enum XML_Error 2739 doContent(XML_Parser parser, int startTagLeve 2739 doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, 2740 const char *s, const char *end, con 2740 const char *s, const char *end, const char **nextPtr, 2741 XML_Bool haveMore, enum XML_Account 2741 XML_Bool haveMore, enum XML_Account account) { 2742 /* save one level of indirection */ 2742 /* save one level of indirection */ 2743 DTD *const dtd = parser->m_dtd; 2743 DTD *const dtd = parser->m_dtd; 2744 2744 2745 const char **eventPP; 2745 const char **eventPP; 2746 const char **eventEndPP; 2746 const char **eventEndPP; 2747 if (enc == parser->m_encoding) { 2747 if (enc == parser->m_encoding) { 2748 eventPP = &parser->m_eventPtr; 2748 eventPP = &parser->m_eventPtr; 2749 eventEndPP = &parser->m_eventEndPtr; 2749 eventEndPP = &parser->m_eventEndPtr; 2750 } else { 2750 } else { 2751 eventPP = &(parser->m_openInternalEntitie 2751 eventPP = &(parser->m_openInternalEntities->internalEventPtr); 2752 eventEndPP = &(parser->m_openInternalEnti 2752 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 2753 } 2753 } 2754 *eventPP = s; 2754 *eventPP = s; 2755 2755 2756 for (;;) { 2756 for (;;) { 2757 const char *next = s; /* XmlContentTok do 2757 const char *next = s; /* XmlContentTok doesn't always set the last arg */ 2758 int tok = XmlContentTok(enc, s, end, &nex 2758 int tok = XmlContentTok(enc, s, end, &next); 2759 #ifdef XML_DTD 2759 #ifdef XML_DTD 2760 const char *accountAfter 2760 const char *accountAfter 2761 = ((tok == XML_TOK_TRAILING_RSQB) || 2761 = ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR)) 2762 ? (haveMore ? s /* i.e. 0 bytes 2762 ? (haveMore ? s /* i.e. 0 bytes */ : end) 2763 : next; 2763 : next; 2764 if (! accountingDiffTolerated(parser, tok 2764 if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__, 2765 account)) { 2765 account)) { 2766 accountingOnAbort(parser); 2766 accountingOnAbort(parser); 2767 return XML_ERROR_AMPLIFICATION_LIMIT_BR 2767 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 2768 } 2768 } 2769 #endif 2769 #endif 2770 *eventEndPP = next; 2770 *eventEndPP = next; 2771 switch (tok) { 2771 switch (tok) { 2772 case XML_TOK_TRAILING_CR: 2772 case XML_TOK_TRAILING_CR: 2773 if (haveMore) { 2773 if (haveMore) { 2774 *nextPtr = s; 2774 *nextPtr = s; 2775 return XML_ERROR_NONE; 2775 return XML_ERROR_NONE; 2776 } 2776 } 2777 *eventEndPP = end; 2777 *eventEndPP = end; 2778 if (parser->m_characterDataHandler) { 2778 if (parser->m_characterDataHandler) { 2779 XML_Char c = 0xA; 2779 XML_Char c = 0xA; 2780 parser->m_characterDataHandler(parser 2780 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); 2781 } else if (parser->m_defaultHandler) 2781 } else if (parser->m_defaultHandler) 2782 reportDefault(parser, enc, s, end); 2782 reportDefault(parser, enc, s, end); 2783 /* We are at the end of the final buffe 2783 /* We are at the end of the final buffer, should we check for 2784 XML_SUSPENDED, XML_FINISHED? 2784 XML_SUSPENDED, XML_FINISHED? 2785 */ 2785 */ 2786 if (startTagLevel == 0) 2786 if (startTagLevel == 0) 2787 return XML_ERROR_NO_ELEMENTS; 2787 return XML_ERROR_NO_ELEMENTS; 2788 if (parser->m_tagLevel != startTagLevel 2788 if (parser->m_tagLevel != startTagLevel) 2789 return XML_ERROR_ASYNC_ENTITY; 2789 return XML_ERROR_ASYNC_ENTITY; 2790 *nextPtr = end; 2790 *nextPtr = end; 2791 return XML_ERROR_NONE; 2791 return XML_ERROR_NONE; 2792 case XML_TOK_NONE: 2792 case XML_TOK_NONE: 2793 if (haveMore) { 2793 if (haveMore) { 2794 *nextPtr = s; 2794 *nextPtr = s; 2795 return XML_ERROR_NONE; 2795 return XML_ERROR_NONE; 2796 } 2796 } 2797 if (startTagLevel > 0) { 2797 if (startTagLevel > 0) { 2798 if (parser->m_tagLevel != startTagLev 2798 if (parser->m_tagLevel != startTagLevel) 2799 return XML_ERROR_ASYNC_ENTITY; 2799 return XML_ERROR_ASYNC_ENTITY; 2800 *nextPtr = s; 2800 *nextPtr = s; 2801 return XML_ERROR_NONE; 2801 return XML_ERROR_NONE; 2802 } 2802 } 2803 return XML_ERROR_NO_ELEMENTS; 2803 return XML_ERROR_NO_ELEMENTS; 2804 case XML_TOK_INVALID: 2804 case XML_TOK_INVALID: 2805 *eventPP = next; 2805 *eventPP = next; 2806 return XML_ERROR_INVALID_TOKEN; 2806 return XML_ERROR_INVALID_TOKEN; 2807 case XML_TOK_PARTIAL: 2807 case XML_TOK_PARTIAL: 2808 if (haveMore) { 2808 if (haveMore) { 2809 *nextPtr = s; 2809 *nextPtr = s; 2810 return XML_ERROR_NONE; 2810 return XML_ERROR_NONE; 2811 } 2811 } 2812 return XML_ERROR_UNCLOSED_TOKEN; 2812 return XML_ERROR_UNCLOSED_TOKEN; 2813 case XML_TOK_PARTIAL_CHAR: 2813 case XML_TOK_PARTIAL_CHAR: 2814 if (haveMore) { 2814 if (haveMore) { 2815 *nextPtr = s; 2815 *nextPtr = s; 2816 return XML_ERROR_NONE; 2816 return XML_ERROR_NONE; 2817 } 2817 } 2818 return XML_ERROR_PARTIAL_CHAR; 2818 return XML_ERROR_PARTIAL_CHAR; 2819 case XML_TOK_ENTITY_REF: { 2819 case XML_TOK_ENTITY_REF: { 2820 const XML_Char *name; 2820 const XML_Char *name; 2821 ENTITY *entity; 2821 ENTITY *entity; 2822 XML_Char ch = (XML_Char)XmlPredefinedEn 2822 XML_Char ch = (XML_Char)XmlPredefinedEntityName( 2823 enc, s + enc->minBytesPerChar, next 2823 enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); 2824 if (ch) { 2824 if (ch) { 2825 #ifdef XML_DTD 2825 #ifdef XML_DTD 2826 /* NOTE: We are replacing 4-6 charact 2826 /* NOTE: We are replacing 4-6 characters original input for 1 character 2827 * so there is no amplification 2827 * so there is no amplification and hence recording without 2828 * protection. */ 2828 * protection. */ 2829 accountingDiffTolerated(parser, tok, 2829 accountingDiffTolerated(parser, tok, (char *)&ch, 2830 ((char *)&ch) 2830 ((char *)&ch) + sizeof(XML_Char), __LINE__, 2831 XML_ACCOUNT_E 2831 XML_ACCOUNT_ENTITY_EXPANSION); 2832 #endif /* XML_DTD */ 2832 #endif /* XML_DTD */ 2833 if (parser->m_characterDataHandler) 2833 if (parser->m_characterDataHandler) 2834 parser->m_characterDataHandler(pars 2834 parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1); 2835 else if (parser->m_defaultHandler) 2835 else if (parser->m_defaultHandler) 2836 reportDefault(parser, enc, s, next) 2836 reportDefault(parser, enc, s, next); 2837 break; 2837 break; 2838 } 2838 } 2839 name = poolStoreString(&dtd->pool, enc, 2839 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, 2840 next - enc->minB 2840 next - enc->minBytesPerChar); 2841 if (! name) 2841 if (! name) 2842 return XML_ERROR_NO_MEMORY; 2842 return XML_ERROR_NO_MEMORY; 2843 entity = (ENTITY *)lookup(parser, &dtd- 2843 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); 2844 poolDiscard(&dtd->pool); 2844 poolDiscard(&dtd->pool); 2845 /* First, determine if a check for an e 2845 /* First, determine if a check for an existing declaration is needed; 2846 if yes, check that the entity exists 2846 if yes, check that the entity exists, and that it is internal, 2847 otherwise call the skipped entity or 2847 otherwise call the skipped entity or default handler. 2848 */ 2848 */ 2849 if (! dtd->hasParamEntityRefs || dtd->s 2849 if (! dtd->hasParamEntityRefs || dtd->standalone) { 2850 if (! entity) 2850 if (! entity) 2851 return XML_ERROR_UNDEFINED_ENTITY; 2851 return XML_ERROR_UNDEFINED_ENTITY; 2852 else if (! entity->is_internal) 2852 else if (! entity->is_internal) 2853 return XML_ERROR_ENTITY_DECLARED_IN 2853 return XML_ERROR_ENTITY_DECLARED_IN_PE; 2854 } else if (! entity) { 2854 } else if (! entity) { 2855 if (parser->m_skippedEntityHandler) 2855 if (parser->m_skippedEntityHandler) 2856 parser->m_skippedEntityHandler(pars 2856 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); 2857 else if (parser->m_defaultHandler) 2857 else if (parser->m_defaultHandler) 2858 reportDefault(parser, enc, s, next) 2858 reportDefault(parser, enc, s, next); 2859 break; 2859 break; 2860 } 2860 } 2861 if (entity->open) 2861 if (entity->open) 2862 return XML_ERROR_RECURSIVE_ENTITY_REF 2862 return XML_ERROR_RECURSIVE_ENTITY_REF; 2863 if (entity->notation) 2863 if (entity->notation) 2864 return XML_ERROR_BINARY_ENTITY_REF; 2864 return XML_ERROR_BINARY_ENTITY_REF; 2865 if (entity->textPtr) { 2865 if (entity->textPtr) { 2866 enum XML_Error result; 2866 enum XML_Error result; 2867 if (! parser->m_defaultExpandInternal 2867 if (! parser->m_defaultExpandInternalEntities) { 2868 if (parser->m_skippedEntityHandler) 2868 if (parser->m_skippedEntityHandler) 2869 parser->m_skippedEntityHandler(pa 2869 parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 2870 0) 2870 0); 2871 else if (parser->m_defaultHandler) 2871 else if (parser->m_defaultHandler) 2872 reportDefault(parser, enc, s, nex 2872 reportDefault(parser, enc, s, next); 2873 break; 2873 break; 2874 } 2874 } 2875 result = processInternalEntity(parser 2875 result = processInternalEntity(parser, entity, XML_FALSE); 2876 if (result != XML_ERROR_NONE) 2876 if (result != XML_ERROR_NONE) 2877 return result; 2877 return result; 2878 } else if (parser->m_externalEntityRefH 2878 } else if (parser->m_externalEntityRefHandler) { 2879 const XML_Char *context; 2879 const XML_Char *context; 2880 entity->open = XML_TRUE; 2880 entity->open = XML_TRUE; 2881 context = getContext(parser); 2881 context = getContext(parser); 2882 entity->open = XML_FALSE; 2882 entity->open = XML_FALSE; 2883 if (! context) 2883 if (! context) 2884 return XML_ERROR_NO_MEMORY; 2884 return XML_ERROR_NO_MEMORY; 2885 if (! parser->m_externalEntityRefHand 2885 if (! parser->m_externalEntityRefHandler( 2886 parser->m_externalEntityRefHa 2886 parser->m_externalEntityRefHandlerArg, context, entity->base, 2887 entity->systemId, entity->pub 2887 entity->systemId, entity->publicId)) 2888 return XML_ERROR_EXTERNAL_ENTITY_HA 2888 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 2889 poolDiscard(&parser->m_tempPool); 2889 poolDiscard(&parser->m_tempPool); 2890 } else if (parser->m_defaultHandler) 2890 } else if (parser->m_defaultHandler) 2891 reportDefault(parser, enc, s, next); 2891 reportDefault(parser, enc, s, next); 2892 break; 2892 break; 2893 } 2893 } 2894 case XML_TOK_START_TAG_NO_ATTS: 2894 case XML_TOK_START_TAG_NO_ATTS: 2895 /* fall through */ 2895 /* fall through */ 2896 case XML_TOK_START_TAG_WITH_ATTS: { 2896 case XML_TOK_START_TAG_WITH_ATTS: { 2897 TAG *tag; 2897 TAG *tag; 2898 enum XML_Error result; 2898 enum XML_Error result; 2899 XML_Char *toPtr; 2899 XML_Char *toPtr; 2900 if (parser->m_freeTagList) { 2900 if (parser->m_freeTagList) { 2901 tag = parser->m_freeTagList; 2901 tag = parser->m_freeTagList; 2902 parser->m_freeTagList = parser->m_fre 2902 parser->m_freeTagList = parser->m_freeTagList->parent; 2903 } else { 2903 } else { 2904 tag = (TAG *)MALLOC(parser, sizeof(TA 2904 tag = (TAG *)MALLOC(parser, sizeof(TAG)); 2905 if (! tag) 2905 if (! tag) 2906 return XML_ERROR_NO_MEMORY; 2906 return XML_ERROR_NO_MEMORY; 2907 tag->buf = (char *)MALLOC(parser, INI 2907 tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE); 2908 if (! tag->buf) { 2908 if (! tag->buf) { 2909 FREE(parser, tag); 2909 FREE(parser, tag); 2910 return XML_ERROR_NO_MEMORY; 2910 return XML_ERROR_NO_MEMORY; 2911 } 2911 } 2912 tag->bufEnd = tag->buf + INIT_TAG_BUF 2912 tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; 2913 } 2913 } 2914 tag->bindings = NULL; 2914 tag->bindings = NULL; 2915 tag->parent = parser->m_tagStack; 2915 tag->parent = parser->m_tagStack; 2916 parser->m_tagStack = tag; 2916 parser->m_tagStack = tag; 2917 tag->name.localPart = NULL; 2917 tag->name.localPart = NULL; 2918 tag->name.prefix = NULL; 2918 tag->name.prefix = NULL; 2919 tag->rawName = s + enc->minBytesPerChar 2919 tag->rawName = s + enc->minBytesPerChar; 2920 tag->rawNameLength = XmlNameLength(enc, 2920 tag->rawNameLength = XmlNameLength(enc, tag->rawName); 2921 ++parser->m_tagLevel; 2921 ++parser->m_tagLevel; 2922 { 2922 { 2923 const char *rawNameEnd = tag->rawName 2923 const char *rawNameEnd = tag->rawName + tag->rawNameLength; 2924 const char *fromPtr = tag->rawName; 2924 const char *fromPtr = tag->rawName; 2925 toPtr = (XML_Char *)tag->buf; 2925 toPtr = (XML_Char *)tag->buf; 2926 for (;;) { 2926 for (;;) { 2927 int bufSize; 2927 int bufSize; 2928 int convLen; 2928 int convLen; 2929 const enum XML_Convert_Result conve 2929 const enum XML_Convert_Result convert_res 2930 = XmlConvert(enc, &fromPtr, raw 2930 = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, 2931 (ICHAR *)tag->bufE 2931 (ICHAR *)tag->bufEnd - 1); 2932 convLen = (int)(toPtr - (XML_Char * 2932 convLen = (int)(toPtr - (XML_Char *)tag->buf); 2933 if ((fromPtr >= rawNameEnd) 2933 if ((fromPtr >= rawNameEnd) 2934 || (convert_res == XML_CONVERT_ 2934 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { 2935 tag->name.strLen = convLen; 2935 tag->name.strLen = convLen; 2936 break; 2936 break; 2937 } 2937 } 2938 bufSize = (int)(tag->bufEnd - tag-> 2938 bufSize = (int)(tag->bufEnd - tag->buf) << 1; 2939 { 2939 { 2940 char *temp = (char *)REALLOC(pars 2940 char *temp = (char *)REALLOC(parser, tag->buf, bufSize); 2941 if (temp == NULL) 2941 if (temp == NULL) 2942 return XML_ERROR_NO_MEMORY; 2942 return XML_ERROR_NO_MEMORY; 2943 tag->buf = temp; 2943 tag->buf = temp; 2944 tag->bufEnd = temp + bufSize; 2944 tag->bufEnd = temp + bufSize; 2945 toPtr = (XML_Char *)temp + convLe 2945 toPtr = (XML_Char *)temp + convLen; 2946 } 2946 } 2947 } 2947 } 2948 } 2948 } 2949 tag->name.str = (XML_Char *)tag->buf; 2949 tag->name.str = (XML_Char *)tag->buf; 2950 *toPtr = XML_T('\0'); 2950 *toPtr = XML_T('\0'); 2951 result 2951 result 2952 = storeAtts(parser, enc, s, &(tag-> 2952 = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account); 2953 if (result) 2953 if (result) 2954 return result; 2954 return result; 2955 if (parser->m_startElementHandler) 2955 if (parser->m_startElementHandler) 2956 parser->m_startElementHandler(parser- 2956 parser->m_startElementHandler(parser->m_handlerArg, tag->name.str, 2957 (const 2957 (const XML_Char **)parser->m_atts); 2958 else if (parser->m_defaultHandler) 2958 else if (parser->m_defaultHandler) 2959 reportDefault(parser, enc, s, next); 2959 reportDefault(parser, enc, s, next); 2960 poolClear(&parser->m_tempPool); 2960 poolClear(&parser->m_tempPool); 2961 break; 2961 break; 2962 } 2962 } 2963 case XML_TOK_EMPTY_ELEMENT_NO_ATTS: 2963 case XML_TOK_EMPTY_ELEMENT_NO_ATTS: 2964 /* fall through */ 2964 /* fall through */ 2965 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: { 2965 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: { 2966 const char *rawName = s + enc->minBytes 2966 const char *rawName = s + enc->minBytesPerChar; 2967 enum XML_Error result; 2967 enum XML_Error result; 2968 BINDING *bindings = NULL; 2968 BINDING *bindings = NULL; 2969 XML_Bool noElmHandlers = XML_TRUE; 2969 XML_Bool noElmHandlers = XML_TRUE; 2970 TAG_NAME name; 2970 TAG_NAME name; 2971 name.str = poolStoreString(&parser->m_t 2971 name.str = poolStoreString(&parser->m_tempPool, enc, rawName, 2972 rawName + Xm 2972 rawName + XmlNameLength(enc, rawName)); 2973 if (! name.str) 2973 if (! name.str) 2974 return XML_ERROR_NO_MEMORY; 2974 return XML_ERROR_NO_MEMORY; 2975 poolFinish(&parser->m_tempPool); 2975 poolFinish(&parser->m_tempPool); 2976 result = storeAtts(parser, enc, s, &nam 2976 result = storeAtts(parser, enc, s, &name, &bindings, 2977 XML_ACCOUNT_NONE /* 2977 XML_ACCOUNT_NONE /* token spans whole start tag */); 2978 if (result != XML_ERROR_NONE) { 2978 if (result != XML_ERROR_NONE) { 2979 freeBindings(parser, bindings); 2979 freeBindings(parser, bindings); 2980 return result; 2980 return result; 2981 } 2981 } 2982 poolFinish(&parser->m_tempPool); 2982 poolFinish(&parser->m_tempPool); 2983 if (parser->m_startElementHandler) { 2983 if (parser->m_startElementHandler) { 2984 parser->m_startElementHandler(parser- 2984 parser->m_startElementHandler(parser->m_handlerArg, name.str, 2985 (const 2985 (const XML_Char **)parser->m_atts); 2986 noElmHandlers = XML_FALSE; 2986 noElmHandlers = XML_FALSE; 2987 } 2987 } 2988 if (parser->m_endElementHandler) { 2988 if (parser->m_endElementHandler) { 2989 if (parser->m_startElementHandler) 2989 if (parser->m_startElementHandler) 2990 *eventPP = *eventEndPP; 2990 *eventPP = *eventEndPP; 2991 parser->m_endElementHandler(parser->m 2991 parser->m_endElementHandler(parser->m_handlerArg, name.str); 2992 noElmHandlers = XML_FALSE; 2992 noElmHandlers = XML_FALSE; 2993 } 2993 } 2994 if (noElmHandlers && parser->m_defaultH 2994 if (noElmHandlers && parser->m_defaultHandler) 2995 reportDefault(parser, enc, s, next); 2995 reportDefault(parser, enc, s, next); 2996 poolClear(&parser->m_tempPool); 2996 poolClear(&parser->m_tempPool); 2997 freeBindings(parser, bindings); 2997 freeBindings(parser, bindings); 2998 } 2998 } 2999 if ((parser->m_tagLevel == 0) 2999 if ((parser->m_tagLevel == 0) 3000 && (parser->m_parsingStatus.parsing 3000 && (parser->m_parsingStatus.parsing != XML_FINISHED)) { 3001 if (parser->m_parsingStatus.parsing = 3001 if (parser->m_parsingStatus.parsing == XML_SUSPENDED) 3002 parser->m_processor = epilogProcess 3002 parser->m_processor = epilogProcessor; 3003 else 3003 else 3004 return epilogProcessor(parser, next 3004 return epilogProcessor(parser, next, end, nextPtr); 3005 } 3005 } 3006 break; 3006 break; 3007 case XML_TOK_END_TAG: 3007 case XML_TOK_END_TAG: 3008 if (parser->m_tagLevel == startTagLevel 3008 if (parser->m_tagLevel == startTagLevel) 3009 return XML_ERROR_ASYNC_ENTITY; 3009 return XML_ERROR_ASYNC_ENTITY; 3010 else { 3010 else { 3011 int len; 3011 int len; 3012 const char *rawName; 3012 const char *rawName; 3013 TAG *tag = parser->m_tagStack; 3013 TAG *tag = parser->m_tagStack; 3014 parser->m_tagStack = tag->parent; 3014 parser->m_tagStack = tag->parent; 3015 tag->parent = parser->m_freeTagList; 3015 tag->parent = parser->m_freeTagList; 3016 parser->m_freeTagList = tag; 3016 parser->m_freeTagList = tag; 3017 rawName = s + enc->minBytesPerChar * 3017 rawName = s + enc->minBytesPerChar * 2; 3018 len = XmlNameLength(enc, rawName); 3018 len = XmlNameLength(enc, rawName); 3019 if (len != tag->rawNameLength 3019 if (len != tag->rawNameLength 3020 || memcmp(tag->rawName, rawName, 3020 || memcmp(tag->rawName, rawName, len) != 0) { 3021 *eventPP = rawName; 3021 *eventPP = rawName; 3022 return XML_ERROR_TAG_MISMATCH; 3022 return XML_ERROR_TAG_MISMATCH; 3023 } 3023 } 3024 --parser->m_tagLevel; 3024 --parser->m_tagLevel; 3025 if (parser->m_endElementHandler) { 3025 if (parser->m_endElementHandler) { 3026 const XML_Char *localPart; 3026 const XML_Char *localPart; 3027 const XML_Char *prefix; 3027 const XML_Char *prefix; 3028 XML_Char *uri; 3028 XML_Char *uri; 3029 localPart = tag->name.localPart; 3029 localPart = tag->name.localPart; 3030 if (parser->m_ns && localPart) { 3030 if (parser->m_ns && localPart) { 3031 /* localPart and prefix may have 3031 /* localPart and prefix may have been overwritten in 3032 tag->name.str, since this poin 3032 tag->name.str, since this points to the binding->uri 3033 buffer which gets re-used; so 3033 buffer which gets re-used; so we have to add them again 3034 */ 3034 */ 3035 uri = (XML_Char *)tag->name.str + 3035 uri = (XML_Char *)tag->name.str + tag->name.uriLen; 3036 /* don't need to check for space 3036 /* don't need to check for space - already done in storeAtts() */ 3037 while (*localPart) 3037 while (*localPart) 3038 *uri++ = *localPart++; 3038 *uri++ = *localPart++; 3039 prefix = (XML_Char *)tag->name.pr 3039 prefix = (XML_Char *)tag->name.prefix; 3040 if (parser->m_ns_triplets && pref 3040 if (parser->m_ns_triplets && prefix) { 3041 *uri++ = parser->m_namespaceSep 3041 *uri++ = parser->m_namespaceSeparator; 3042 while (*prefix) 3042 while (*prefix) 3043 *uri++ = *prefix++; 3043 *uri++ = *prefix++; 3044 } 3044 } 3045 *uri = XML_T('\0'); 3045 *uri = XML_T('\0'); 3046 } 3046 } 3047 parser->m_endElementHandler(parser- 3047 parser->m_endElementHandler(parser->m_handlerArg, tag->name.str); 3048 } else if (parser->m_defaultHandler) 3048 } else if (parser->m_defaultHandler) 3049 reportDefault(parser, enc, s, next) 3049 reportDefault(parser, enc, s, next); 3050 while (tag->bindings) { 3050 while (tag->bindings) { 3051 BINDING *b = tag->bindings; 3051 BINDING *b = tag->bindings; 3052 if (parser->m_endNamespaceDeclHandl 3052 if (parser->m_endNamespaceDeclHandler) 3053 parser->m_endNamespaceDeclHandler 3053 parser->m_endNamespaceDeclHandler(parser->m_handlerArg, 3054 3054 b->prefix->name); 3055 tag->bindings = tag->bindings->next 3055 tag->bindings = tag->bindings->nextTagBinding; 3056 b->nextTagBinding = parser->m_freeB 3056 b->nextTagBinding = parser->m_freeBindingList; 3057 parser->m_freeBindingList = b; 3057 parser->m_freeBindingList = b; 3058 b->prefix->binding = b->prevPrefixB 3058 b->prefix->binding = b->prevPrefixBinding; 3059 } 3059 } 3060 if ((parser->m_tagLevel == 0) 3060 if ((parser->m_tagLevel == 0) 3061 && (parser->m_parsingStatus.parsi 3061 && (parser->m_parsingStatus.parsing != XML_FINISHED)) { 3062 if (parser->m_parsingStatus.parsing 3062 if (parser->m_parsingStatus.parsing == XML_SUSPENDED) 3063 parser->m_processor = epilogProce 3063 parser->m_processor = epilogProcessor; 3064 else 3064 else 3065 return epilogProcessor(parser, ne 3065 return epilogProcessor(parser, next, end, nextPtr); 3066 } 3066 } 3067 } 3067 } 3068 break; 3068 break; 3069 case XML_TOK_CHAR_REF: { 3069 case XML_TOK_CHAR_REF: { 3070 int n = XmlCharRefNumber(enc, s); 3070 int n = XmlCharRefNumber(enc, s); 3071 if (n < 0) 3071 if (n < 0) 3072 return XML_ERROR_BAD_CHAR_REF; 3072 return XML_ERROR_BAD_CHAR_REF; 3073 if (parser->m_characterDataHandler) { 3073 if (parser->m_characterDataHandler) { 3074 XML_Char buf[XML_ENCODE_MAX]; 3074 XML_Char buf[XML_ENCODE_MAX]; 3075 parser->m_characterDataHandler(parser 3075 parser->m_characterDataHandler(parser->m_handlerArg, buf, 3076 XmlEnc 3076 XmlEncode(n, (ICHAR *)buf)); 3077 } else if (parser->m_defaultHandler) 3077 } else if (parser->m_defaultHandler) 3078 reportDefault(parser, enc, s, next); 3078 reportDefault(parser, enc, s, next); 3079 } break; 3079 } break; 3080 case XML_TOK_XML_DECL: 3080 case XML_TOK_XML_DECL: 3081 return XML_ERROR_MISPLACED_XML_PI; 3081 return XML_ERROR_MISPLACED_XML_PI; 3082 case XML_TOK_DATA_NEWLINE: 3082 case XML_TOK_DATA_NEWLINE: 3083 if (parser->m_characterDataHandler) { 3083 if (parser->m_characterDataHandler) { 3084 XML_Char c = 0xA; 3084 XML_Char c = 0xA; 3085 parser->m_characterDataHandler(parser 3085 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); 3086 } else if (parser->m_defaultHandler) 3086 } else if (parser->m_defaultHandler) 3087 reportDefault(parser, enc, s, next); 3087 reportDefault(parser, enc, s, next); 3088 break; 3088 break; 3089 case XML_TOK_CDATA_SECT_OPEN: { 3089 case XML_TOK_CDATA_SECT_OPEN: { 3090 enum XML_Error result; 3090 enum XML_Error result; 3091 if (parser->m_startCdataSectionHandler) 3091 if (parser->m_startCdataSectionHandler) 3092 parser->m_startCdataSectionHandler(pa 3092 parser->m_startCdataSectionHandler(parser->m_handlerArg); 3093 /* BEGIN disabled code */ 3093 /* BEGIN disabled code */ 3094 /* Suppose you doing a transformation o 3094 /* Suppose you doing a transformation on a document that involves 3095 changing only the character data. Y 3095 changing only the character data. You set up a defaultHandler 3096 and a characterDataHandler. The def 3096 and a characterDataHandler. The defaultHandler simply copies 3097 characters through. The characterDa 3097 characters through. The characterDataHandler does the 3098 transformation and writes the charac 3098 transformation and writes the characters out escaping them as 3099 necessary. This case will fail to w 3099 necessary. This case will fail to work if we leave out the 3100 following two lines (because & and < 3100 following two lines (because & and < inside CDATA sections will 3101 be incorrectly escaped). 3101 be incorrectly escaped). 3102 3102 3103 However, now we have a start/endCdat 3103 However, now we have a start/endCdataSectionHandler, so it seems 3104 easier to let the user deal with thi 3104 easier to let the user deal with this. 3105 */ 3105 */ 3106 else if (0 && parser->m_characterDataHa 3106 else if (0 && parser->m_characterDataHandler) 3107 parser->m_characterDataHandler(parser 3107 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 3108 0); 3108 0); 3109 /* END disabled code */ 3109 /* END disabled code */ 3110 else if (parser->m_defaultHandler) 3110 else if (parser->m_defaultHandler) 3111 reportDefault(parser, enc, s, next); 3111 reportDefault(parser, enc, s, next); 3112 result 3112 result 3113 = doCdataSection(parser, enc, &next 3113 = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account); 3114 if (result != XML_ERROR_NONE) 3114 if (result != XML_ERROR_NONE) 3115 return result; 3115 return result; 3116 else if (! next) { 3116 else if (! next) { 3117 parser->m_processor = cdataSectionPro 3117 parser->m_processor = cdataSectionProcessor; 3118 return result; 3118 return result; 3119 } 3119 } 3120 } break; 3120 } break; 3121 case XML_TOK_TRAILING_RSQB: 3121 case XML_TOK_TRAILING_RSQB: 3122 if (haveMore) { 3122 if (haveMore) { 3123 *nextPtr = s; 3123 *nextPtr = s; 3124 return XML_ERROR_NONE; 3124 return XML_ERROR_NONE; 3125 } 3125 } 3126 if (parser->m_characterDataHandler) { 3126 if (parser->m_characterDataHandler) { 3127 if (MUST_CONVERT(enc, s)) { 3127 if (MUST_CONVERT(enc, s)) { 3128 ICHAR *dataPtr = (ICHAR *)parser->m 3128 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; 3129 XmlConvert(enc, &s, end, &dataPtr, 3129 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); 3130 parser->m_characterDataHandler( 3130 parser->m_characterDataHandler( 3131 parser->m_handlerArg, parser->m 3131 parser->m_handlerArg, parser->m_dataBuf, 3132 (int)(dataPtr - (ICHAR *)parser 3132 (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); 3133 } else 3133 } else 3134 parser->m_characterDataHandler( 3134 parser->m_characterDataHandler( 3135 parser->m_handlerArg, (XML_Char 3135 parser->m_handlerArg, (XML_Char *)s, 3136 (int)((XML_Char *)end - (XML_Ch 3136 (int)((XML_Char *)end - (XML_Char *)s)); 3137 } else if (parser->m_defaultHandler) 3137 } else if (parser->m_defaultHandler) 3138 reportDefault(parser, enc, s, end); 3138 reportDefault(parser, enc, s, end); 3139 /* We are at the end of the final buffe 3139 /* We are at the end of the final buffer, should we check for 3140 XML_SUSPENDED, XML_FINISHED? 3140 XML_SUSPENDED, XML_FINISHED? 3141 */ 3141 */ 3142 if (startTagLevel == 0) { 3142 if (startTagLevel == 0) { 3143 *eventPP = end; 3143 *eventPP = end; 3144 return XML_ERROR_NO_ELEMENTS; 3144 return XML_ERROR_NO_ELEMENTS; 3145 } 3145 } 3146 if (parser->m_tagLevel != startTagLevel 3146 if (parser->m_tagLevel != startTagLevel) { 3147 *eventPP = end; 3147 *eventPP = end; 3148 return XML_ERROR_ASYNC_ENTITY; 3148 return XML_ERROR_ASYNC_ENTITY; 3149 } 3149 } 3150 *nextPtr = end; 3150 *nextPtr = end; 3151 return XML_ERROR_NONE; 3151 return XML_ERROR_NONE; 3152 case XML_TOK_DATA_CHARS: { 3152 case XML_TOK_DATA_CHARS: { 3153 XML_CharacterDataHandler charDataHandle 3153 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; 3154 if (charDataHandler) { 3154 if (charDataHandler) { 3155 if (MUST_CONVERT(enc, s)) { 3155 if (MUST_CONVERT(enc, s)) { 3156 for (;;) { 3156 for (;;) { 3157 ICHAR *dataPtr = (ICHAR *)parser- 3157 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; 3158 const enum XML_Convert_Result con 3158 const enum XML_Convert_Result convert_res = XmlConvert( 3159 enc, &s, next, &dataPtr, (ICH 3159 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); 3160 *eventEndPP = s; 3160 *eventEndPP = s; 3161 charDataHandler(parser->m_handler 3161 charDataHandler(parser->m_handlerArg, parser->m_dataBuf, 3162 (int)(dataPtr - ( 3162 (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); 3163 if ((convert_res == XML_CONVERT_C 3163 if ((convert_res == XML_CONVERT_COMPLETED) 3164 || (convert_res == XML_CONVER 3164 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) 3165 break; 3165 break; 3166 *eventPP = s; 3166 *eventPP = s; 3167 } 3167 } 3168 } else 3168 } else 3169 charDataHandler(parser->m_handlerAr 3169 charDataHandler(parser->m_handlerArg, (XML_Char *)s, 3170 (int)((XML_Char *)n 3170 (int)((XML_Char *)next - (XML_Char *)s)); 3171 } else if (parser->m_defaultHandler) 3171 } else if (parser->m_defaultHandler) 3172 reportDefault(parser, enc, s, next); 3172 reportDefault(parser, enc, s, next); 3173 } break; 3173 } break; 3174 case XML_TOK_PI: 3174 case XML_TOK_PI: 3175 if (! reportProcessingInstruction(parse 3175 if (! reportProcessingInstruction(parser, enc, s, next)) 3176 return XML_ERROR_NO_MEMORY; 3176 return XML_ERROR_NO_MEMORY; 3177 break; 3177 break; 3178 case XML_TOK_COMMENT: 3178 case XML_TOK_COMMENT: 3179 if (! reportComment(parser, enc, s, nex 3179 if (! reportComment(parser, enc, s, next)) 3180 return XML_ERROR_NO_MEMORY; 3180 return XML_ERROR_NO_MEMORY; 3181 break; 3181 break; 3182 default: 3182 default: 3183 /* All of the tokens produced by XmlCon 3183 /* All of the tokens produced by XmlContentTok() have their own 3184 * explicit cases, so this default is n 3184 * explicit cases, so this default is not strictly necessary. 3185 * However it is a useful safety net, s 3185 * However it is a useful safety net, so we retain the code and 3186 * simply exclude it from the coverage 3186 * simply exclude it from the coverage tests. 3187 * 3187 * 3188 * LCOV_EXCL_START 3188 * LCOV_EXCL_START 3189 */ 3189 */ 3190 if (parser->m_defaultHandler) 3190 if (parser->m_defaultHandler) 3191 reportDefault(parser, enc, s, next); 3191 reportDefault(parser, enc, s, next); 3192 break; 3192 break; 3193 /* LCOV_EXCL_STOP */ 3193 /* LCOV_EXCL_STOP */ 3194 } 3194 } 3195 *eventPP = s = next; 3195 *eventPP = s = next; 3196 switch (parser->m_parsingStatus.parsing) 3196 switch (parser->m_parsingStatus.parsing) { 3197 case XML_SUSPENDED: 3197 case XML_SUSPENDED: 3198 *nextPtr = next; 3198 *nextPtr = next; 3199 return XML_ERROR_NONE; 3199 return XML_ERROR_NONE; 3200 case XML_FINISHED: 3200 case XML_FINISHED: 3201 return XML_ERROR_ABORTED; 3201 return XML_ERROR_ABORTED; 3202 default:; 3202 default:; 3203 } 3203 } 3204 } 3204 } 3205 /* not reached */ 3205 /* not reached */ 3206 } 3206 } 3207 3207 3208 /* This function does not call free() on the 3208 /* This function does not call free() on the allocated memory, merely 3209 * moving it to the parser's m_freeBindingLis 3209 * moving it to the parser's m_freeBindingList where it can be freed or 3210 * reused as appropriate. 3210 * reused as appropriate. 3211 */ 3211 */ 3212 static void 3212 static void 3213 freeBindings(XML_Parser parser, BINDING *bind 3213 freeBindings(XML_Parser parser, BINDING *bindings) { 3214 while (bindings) { 3214 while (bindings) { 3215 BINDING *b = bindings; 3215 BINDING *b = bindings; 3216 3216 3217 /* m_startNamespaceDeclHandler will have 3217 /* m_startNamespaceDeclHandler will have been called for this 3218 * binding in addBindings(), so call the 3218 * binding in addBindings(), so call the end handler now. 3219 */ 3219 */ 3220 if (parser->m_endNamespaceDeclHandler) 3220 if (parser->m_endNamespaceDeclHandler) 3221 parser->m_endNamespaceDeclHandler(parse 3221 parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name); 3222 3222 3223 bindings = bindings->nextTagBinding; 3223 bindings = bindings->nextTagBinding; 3224 b->nextTagBinding = parser->m_freeBinding 3224 b->nextTagBinding = parser->m_freeBindingList; 3225 parser->m_freeBindingList = b; 3225 parser->m_freeBindingList = b; 3226 b->prefix->binding = b->prevPrefixBinding 3226 b->prefix->binding = b->prevPrefixBinding; 3227 } 3227 } 3228 } 3228 } 3229 3229 3230 /* Precondition: all arguments must be non-NU 3230 /* Precondition: all arguments must be non-NULL; 3231 Purpose: 3231 Purpose: 3232 - normalize attributes 3232 - normalize attributes 3233 - check attributes for well-formedness 3233 - check attributes for well-formedness 3234 - generate namespace aware attribute names 3234 - generate namespace aware attribute names (URI, prefix) 3235 - build list of attributes for startElemen 3235 - build list of attributes for startElementHandler 3236 - default attributes 3236 - default attributes 3237 - process namespace declarations (check an 3237 - process namespace declarations (check and report them) 3238 - generate namespace aware element name (U 3238 - generate namespace aware element name (URI, prefix) 3239 */ 3239 */ 3240 static enum XML_Error 3240 static enum XML_Error 3241 storeAtts(XML_Parser parser, const ENCODING * 3241 storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr, 3242 TAG_NAME *tagNamePtr, BINDING **bin 3242 TAG_NAME *tagNamePtr, BINDING **bindingsPtr, 3243 enum XML_Account account) { 3243 enum XML_Account account) { 3244 DTD *const dtd = parser->m_dtd; /* save one 3244 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 3245 ELEMENT_TYPE *elementType; 3245 ELEMENT_TYPE *elementType; 3246 int nDefaultAtts; 3246 int nDefaultAtts; 3247 const XML_Char **appAtts; /* the attribute 3247 const XML_Char **appAtts; /* the attribute list for the application */ 3248 int attIndex = 0; 3248 int attIndex = 0; 3249 int prefixLen; 3249 int prefixLen; 3250 int i; 3250 int i; 3251 int n; 3251 int n; 3252 XML_Char *uri; 3252 XML_Char *uri; 3253 int nPrefixes = 0; 3253 int nPrefixes = 0; 3254 BINDING *binding; 3254 BINDING *binding; 3255 const XML_Char *localPart; 3255 const XML_Char *localPart; 3256 3256 3257 /* lookup the element type name */ 3257 /* lookup the element type name */ 3258 elementType 3258 elementType 3259 = (ELEMENT_TYPE *)lookup(parser, &dtd-> 3259 = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0); 3260 if (! elementType) { 3260 if (! elementType) { 3261 const XML_Char *name = poolCopyString(&dt 3261 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); 3262 if (! name) 3262 if (! name) 3263 return XML_ERROR_NO_MEMORY; 3263 return XML_ERROR_NO_MEMORY; 3264 elementType = (ELEMENT_TYPE *)lookup(pars 3264 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, 3265 size 3265 sizeof(ELEMENT_TYPE)); 3266 if (! elementType) 3266 if (! elementType) 3267 return XML_ERROR_NO_MEMORY; 3267 return XML_ERROR_NO_MEMORY; 3268 if (parser->m_ns && ! setElementTypePrefi 3268 if (parser->m_ns && ! setElementTypePrefix(parser, elementType)) 3269 return XML_ERROR_NO_MEMORY; 3269 return XML_ERROR_NO_MEMORY; 3270 } 3270 } 3271 nDefaultAtts = elementType->nDefaultAtts; 3271 nDefaultAtts = elementType->nDefaultAtts; 3272 3272 3273 /* get the attributes from the tokenizer */ 3273 /* get the attributes from the tokenizer */ 3274 n = XmlGetAttributes(enc, attStr, parser->m 3274 n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts); 3275 3275 3276 /* Detect and prevent integer overflow */ 3276 /* Detect and prevent integer overflow */ 3277 if (n > INT_MAX - nDefaultAtts) { 3277 if (n > INT_MAX - nDefaultAtts) { 3278 return XML_ERROR_NO_MEMORY; 3278 return XML_ERROR_NO_MEMORY; 3279 } 3279 } 3280 3280 3281 if (n + nDefaultAtts > parser->m_attsSize) 3281 if (n + nDefaultAtts > parser->m_attsSize) { 3282 int oldAttsSize = parser->m_attsSize; 3282 int oldAttsSize = parser->m_attsSize; 3283 ATTRIBUTE *temp; 3283 ATTRIBUTE *temp; 3284 #ifdef XML_ATTR_INFO 3284 #ifdef XML_ATTR_INFO 3285 XML_AttrInfo *temp2; 3285 XML_AttrInfo *temp2; 3286 #endif 3286 #endif 3287 3287 3288 /* Detect and prevent integer overflow */ 3288 /* Detect and prevent integer overflow */ 3289 if ((nDefaultAtts > INT_MAX - INIT_ATTS_S 3289 if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE) 3290 || (n > INT_MAX - (nDefaultAtts + INI 3290 || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) { 3291 return XML_ERROR_NO_MEMORY; 3291 return XML_ERROR_NO_MEMORY; 3292 } 3292 } 3293 3293 3294 parser->m_attsSize = n + nDefaultAtts + I 3294 parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; 3295 3295 3296 /* Detect and prevent integer overflow. 3296 /* Detect and prevent integer overflow. 3297 * The preprocessor guard addresses the " 3297 * The preprocessor guard addresses the "always false" warning 3298 * from -Wtype-limits on platforms where 3298 * from -Wtype-limits on platforms where 3299 * sizeof(unsigned int) < sizeof(size_t), 3299 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 3300 #if UINT_MAX >= SIZE_MAX 3300 #if UINT_MAX >= SIZE_MAX 3301 if ((unsigned)parser->m_attsSize > (size_ 3301 if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) { 3302 parser->m_attsSize = oldAttsSize; 3302 parser->m_attsSize = oldAttsSize; 3303 return XML_ERROR_NO_MEMORY; 3303 return XML_ERROR_NO_MEMORY; 3304 } 3304 } 3305 #endif 3305 #endif 3306 3306 3307 temp = (ATTRIBUTE *)REALLOC(parser, (void 3307 temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, 3308 parser->m_att 3308 parser->m_attsSize * sizeof(ATTRIBUTE)); 3309 if (temp == NULL) { 3309 if (temp == NULL) { 3310 parser->m_attsSize = oldAttsSize; 3310 parser->m_attsSize = oldAttsSize; 3311 return XML_ERROR_NO_MEMORY; 3311 return XML_ERROR_NO_MEMORY; 3312 } 3312 } 3313 parser->m_atts = temp; 3313 parser->m_atts = temp; 3314 #ifdef XML_ATTR_INFO 3314 #ifdef XML_ATTR_INFO 3315 /* Detect and prevent integer overflow. 3315 /* Detect and prevent integer overflow. 3316 * The preprocessor guard addresses the " 3316 * The preprocessor guard addresses the "always false" warning 3317 * from -Wtype-limits on platforms where 3317 * from -Wtype-limits on platforms where 3318 * sizeof(unsigned int) < sizeof(size_t), 3318 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 3319 # if UINT_MAX >= SIZE_MAX 3319 # if UINT_MAX >= SIZE_MAX 3320 if ((unsigned)parser->m_attsSize > (size_ 3320 if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(XML_AttrInfo)) { 3321 parser->m_attsSize = oldAttsSize; 3321 parser->m_attsSize = oldAttsSize; 3322 return XML_ERROR_NO_MEMORY; 3322 return XML_ERROR_NO_MEMORY; 3323 } 3323 } 3324 # endif 3324 # endif 3325 3325 3326 temp2 = (XML_AttrInfo *)REALLOC(parser, ( 3326 temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, 3327 parser->m 3327 parser->m_attsSize * sizeof(XML_AttrInfo)); 3328 if (temp2 == NULL) { 3328 if (temp2 == NULL) { 3329 parser->m_attsSize = oldAttsSize; 3329 parser->m_attsSize = oldAttsSize; 3330 return XML_ERROR_NO_MEMORY; 3330 return XML_ERROR_NO_MEMORY; 3331 } 3331 } 3332 parser->m_attInfo = temp2; 3332 parser->m_attInfo = temp2; 3333 #endif 3333 #endif 3334 if (n > oldAttsSize) 3334 if (n > oldAttsSize) 3335 XmlGetAttributes(enc, attStr, n, parser 3335 XmlGetAttributes(enc, attStr, n, parser->m_atts); 3336 } 3336 } 3337 3337 3338 appAtts = (const XML_Char **)parser->m_atts 3338 appAtts = (const XML_Char **)parser->m_atts; 3339 for (i = 0; i < n; i++) { 3339 for (i = 0; i < n; i++) { 3340 ATTRIBUTE *currAtt = &parser->m_atts[i]; 3340 ATTRIBUTE *currAtt = &parser->m_atts[i]; 3341 #ifdef XML_ATTR_INFO 3341 #ifdef XML_ATTR_INFO 3342 XML_AttrInfo *currAttInfo = &parser->m_at 3342 XML_AttrInfo *currAttInfo = &parser->m_attInfo[i]; 3343 #endif 3343 #endif 3344 /* add the name and value to the attribut 3344 /* add the name and value to the attribute list */ 3345 ATTRIBUTE_ID *attId 3345 ATTRIBUTE_ID *attId 3346 = getAttributeId(parser, enc, currAtt 3346 = getAttributeId(parser, enc, currAtt->name, 3347 currAtt->name + XmlN 3347 currAtt->name + XmlNameLength(enc, currAtt->name)); 3348 if (! attId) 3348 if (! attId) 3349 return XML_ERROR_NO_MEMORY; 3349 return XML_ERROR_NO_MEMORY; 3350 #ifdef XML_ATTR_INFO 3350 #ifdef XML_ATTR_INFO 3351 currAttInfo->nameStart 3351 currAttInfo->nameStart 3352 = parser->m_parseEndByteIndex - (pars 3352 = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name); 3353 currAttInfo->nameEnd 3353 currAttInfo->nameEnd 3354 = currAttInfo->nameStart + XmlNameLen 3354 = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name); 3355 currAttInfo->valueStart = parser->m_parse 3355 currAttInfo->valueStart = parser->m_parseEndByteIndex 3356 - (parser->m_pa 3356 - (parser->m_parseEndPtr - currAtt->valuePtr); 3357 currAttInfo->valueEnd = parser->m_parseEn 3357 currAttInfo->valueEnd = parser->m_parseEndByteIndex 3358 - (parser->m_pars 3358 - (parser->m_parseEndPtr - currAtt->valueEnd); 3359 #endif 3359 #endif 3360 /* Detect duplicate attributes by their Q 3360 /* Detect duplicate attributes by their QNames. This does not work when 3361 namespace processing is turned on and 3361 namespace processing is turned on and different prefixes for the same 3362 namespace are used. For this case we h 3362 namespace are used. For this case we have a check further down. 3363 */ 3363 */ 3364 if ((attId->name)[-1]) { 3364 if ((attId->name)[-1]) { 3365 if (enc == parser->m_encoding) 3365 if (enc == parser->m_encoding) 3366 parser->m_eventPtr = parser->m_atts[i 3366 parser->m_eventPtr = parser->m_atts[i].name; 3367 return XML_ERROR_DUPLICATE_ATTRIBUTE; 3367 return XML_ERROR_DUPLICATE_ATTRIBUTE; 3368 } 3368 } 3369 (attId->name)[-1] = 1; 3369 (attId->name)[-1] = 1; 3370 appAtts[attIndex++] = attId->name; 3370 appAtts[attIndex++] = attId->name; 3371 if (! parser->m_atts[i].normalized) { 3371 if (! parser->m_atts[i].normalized) { 3372 enum XML_Error result; 3372 enum XML_Error result; 3373 XML_Bool isCdata = XML_TRUE; 3373 XML_Bool isCdata = XML_TRUE; 3374 3374 3375 /* figure out whether declared as other 3375 /* figure out whether declared as other than CDATA */ 3376 if (attId->maybeTokenized) { 3376 if (attId->maybeTokenized) { 3377 int j; 3377 int j; 3378 for (j = 0; j < nDefaultAtts; j++) { 3378 for (j = 0; j < nDefaultAtts; j++) { 3379 if (attId == elementType->defaultAt 3379 if (attId == elementType->defaultAtts[j].id) { 3380 isCdata = elementType->defaultAtt 3380 isCdata = elementType->defaultAtts[j].isCdata; 3381 break; 3381 break; 3382 } 3382 } 3383 } 3383 } 3384 } 3384 } 3385 3385 3386 /* normalize the attribute value */ 3386 /* normalize the attribute value */ 3387 result = storeAttributeValue( 3387 result = storeAttributeValue( 3388 parser, enc, isCdata, parser->m_att 3388 parser, enc, isCdata, parser->m_atts[i].valuePtr, 3389 parser->m_atts[i].valueEnd, &parser 3389 parser->m_atts[i].valueEnd, &parser->m_tempPool, account); 3390 if (result) 3390 if (result) 3391 return result; 3391 return result; 3392 appAtts[attIndex] = poolStart(&parser-> 3392 appAtts[attIndex] = poolStart(&parser->m_tempPool); 3393 poolFinish(&parser->m_tempPool); 3393 poolFinish(&parser->m_tempPool); 3394 } else { 3394 } else { 3395 /* the value did not need normalizing * 3395 /* the value did not need normalizing */ 3396 appAtts[attIndex] = poolStoreString(&pa 3396 appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, 3397 par 3397 parser->m_atts[i].valuePtr, 3398 par 3398 parser->m_atts[i].valueEnd); 3399 if (appAtts[attIndex] == 0) 3399 if (appAtts[attIndex] == 0) 3400 return XML_ERROR_NO_MEMORY; 3400 return XML_ERROR_NO_MEMORY; 3401 poolFinish(&parser->m_tempPool); 3401 poolFinish(&parser->m_tempPool); 3402 } 3402 } 3403 /* handle prefixed attribute names */ 3403 /* handle prefixed attribute names */ 3404 if (attId->prefix) { 3404 if (attId->prefix) { 3405 if (attId->xmlns) { 3405 if (attId->xmlns) { 3406 /* deal with namespace declarations h 3406 /* deal with namespace declarations here */ 3407 enum XML_Error result = addBinding(pa 3407 enum XML_Error result = addBinding(parser, attId->prefix, attId, 3408 ap 3408 appAtts[attIndex], bindingsPtr); 3409 if (result) 3409 if (result) 3410 return result; 3410 return result; 3411 --attIndex; 3411 --attIndex; 3412 } else { 3412 } else { 3413 /* deal with other prefixed names lat 3413 /* deal with other prefixed names later */ 3414 attIndex++; 3414 attIndex++; 3415 nPrefixes++; 3415 nPrefixes++; 3416 (attId->name)[-1] = 2; 3416 (attId->name)[-1] = 2; 3417 } 3417 } 3418 } else 3418 } else 3419 attIndex++; 3419 attIndex++; 3420 } 3420 } 3421 3421 3422 /* set-up for XML_GetSpecifiedAttributeCoun 3422 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ 3423 parser->m_nSpecifiedAtts = attIndex; 3423 parser->m_nSpecifiedAtts = attIndex; 3424 if (elementType->idAtt && (elementType->idA 3424 if (elementType->idAtt && (elementType->idAtt->name)[-1]) { 3425 for (i = 0; i < attIndex; i += 2) 3425 for (i = 0; i < attIndex; i += 2) 3426 if (appAtts[i] == elementType->idAtt->n 3426 if (appAtts[i] == elementType->idAtt->name) { 3427 parser->m_idAttIndex = i; 3427 parser->m_idAttIndex = i; 3428 break; 3428 break; 3429 } 3429 } 3430 } else 3430 } else 3431 parser->m_idAttIndex = -1; 3431 parser->m_idAttIndex = -1; 3432 3432 3433 /* do attribute defaulting */ 3433 /* do attribute defaulting */ 3434 for (i = 0; i < nDefaultAtts; i++) { 3434 for (i = 0; i < nDefaultAtts; i++) { 3435 const DEFAULT_ATTRIBUTE *da = elementType 3435 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; 3436 if (! (da->id->name)[-1] && da->value) { 3436 if (! (da->id->name)[-1] && da->value) { 3437 if (da->id->prefix) { 3437 if (da->id->prefix) { 3438 if (da->id->xmlns) { 3438 if (da->id->xmlns) { 3439 enum XML_Error result = addBinding( 3439 enum XML_Error result = addBinding(parser, da->id->prefix, da->id, 3440 3440 da->value, bindingsPtr); 3441 if (result) 3441 if (result) 3442 return result; 3442 return result; 3443 } else { 3443 } else { 3444 (da->id->name)[-1] = 2; 3444 (da->id->name)[-1] = 2; 3445 nPrefixes++; 3445 nPrefixes++; 3446 appAtts[attIndex++] = da->id->name; 3446 appAtts[attIndex++] = da->id->name; 3447 appAtts[attIndex++] = da->value; 3447 appAtts[attIndex++] = da->value; 3448 } 3448 } 3449 } else { 3449 } else { 3450 (da->id->name)[-1] = 1; 3450 (da->id->name)[-1] = 1; 3451 appAtts[attIndex++] = da->id->name; 3451 appAtts[attIndex++] = da->id->name; 3452 appAtts[attIndex++] = da->value; 3452 appAtts[attIndex++] = da->value; 3453 } 3453 } 3454 } 3454 } 3455 } 3455 } 3456 appAtts[attIndex] = 0; 3456 appAtts[attIndex] = 0; 3457 3457 3458 /* expand prefixed attribute names, check f 3458 /* expand prefixed attribute names, check for duplicates, 3459 and clear flags that say whether attribu 3459 and clear flags that say whether attributes were specified */ 3460 i = 0; 3460 i = 0; 3461 if (nPrefixes) { 3461 if (nPrefixes) { 3462 int j; /* hash table index */ 3462 int j; /* hash table index */ 3463 unsigned long version = parser->m_nsAttsV 3463 unsigned long version = parser->m_nsAttsVersion; 3464 3464 3465 /* Detect and prevent invalid shift */ 3465 /* Detect and prevent invalid shift */ 3466 if (parser->m_nsAttsPower >= sizeof(unsig 3466 if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) { 3467 return XML_ERROR_NO_MEMORY; 3467 return XML_ERROR_NO_MEMORY; 3468 } 3468 } 3469 3469 3470 unsigned int nsAttsSize = 1u << parser->m 3470 unsigned int nsAttsSize = 1u << parser->m_nsAttsPower; 3471 unsigned char oldNsAttsPower = parser->m_ 3471 unsigned char oldNsAttsPower = parser->m_nsAttsPower; 3472 /* size of hash table must be at least 2 3472 /* size of hash table must be at least 2 * (# of prefixed attributes) */ 3473 if ((nPrefixes << 1) 3473 if ((nPrefixes << 1) 3474 >> parser->m_nsAttsPower) { /* true f 3474 >> parser->m_nsAttsPower) { /* true for m_nsAttsPower = 0 */ 3475 NS_ATT *temp; 3475 NS_ATT *temp; 3476 /* hash table size must also be a power 3476 /* hash table size must also be a power of 2 and >= 8 */ 3477 while (nPrefixes >> parser->m_nsAttsPow 3477 while (nPrefixes >> parser->m_nsAttsPower++) 3478 ; 3478 ; 3479 if (parser->m_nsAttsPower < 3) 3479 if (parser->m_nsAttsPower < 3) 3480 parser->m_nsAttsPower = 3; 3480 parser->m_nsAttsPower = 3; 3481 3481 3482 /* Detect and prevent invalid shift */ 3482 /* Detect and prevent invalid shift */ 3483 if (parser->m_nsAttsPower >= sizeof(nsA 3483 if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) { 3484 /* Restore actual size of memory in m 3484 /* Restore actual size of memory in m_nsAtts */ 3485 parser->m_nsAttsPower = oldNsAttsPowe 3485 parser->m_nsAttsPower = oldNsAttsPower; 3486 return XML_ERROR_NO_MEMORY; 3486 return XML_ERROR_NO_MEMORY; 3487 } 3487 } 3488 3488 3489 nsAttsSize = 1u << parser->m_nsAttsPowe 3489 nsAttsSize = 1u << parser->m_nsAttsPower; 3490 3490 3491 /* Detect and prevent integer overflow. 3491 /* Detect and prevent integer overflow. 3492 * The preprocessor guard addresses the 3492 * The preprocessor guard addresses the "always false" warning 3493 * from -Wtype-limits on platforms wher 3493 * from -Wtype-limits on platforms where 3494 * sizeof(unsigned int) < sizeof(size_t 3494 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 3495 #if UINT_MAX >= SIZE_MAX 3495 #if UINT_MAX >= SIZE_MAX 3496 if (nsAttsSize > (size_t)(-1) / sizeof( 3496 if (nsAttsSize > (size_t)(-1) / sizeof(NS_ATT)) { 3497 /* Restore actual size of memory in m 3497 /* Restore actual size of memory in m_nsAtts */ 3498 parser->m_nsAttsPower = oldNsAttsPowe 3498 parser->m_nsAttsPower = oldNsAttsPower; 3499 return XML_ERROR_NO_MEMORY; 3499 return XML_ERROR_NO_MEMORY; 3500 } 3500 } 3501 #endif 3501 #endif 3502 3502 3503 temp = (NS_ATT *)REALLOC(parser, parser 3503 temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, 3504 nsAttsSize * s 3504 nsAttsSize * sizeof(NS_ATT)); 3505 if (! temp) { 3505 if (! temp) { 3506 /* Restore actual size of memory in m 3506 /* Restore actual size of memory in m_nsAtts */ 3507 parser->m_nsAttsPower = oldNsAttsPowe 3507 parser->m_nsAttsPower = oldNsAttsPower; 3508 return XML_ERROR_NO_MEMORY; 3508 return XML_ERROR_NO_MEMORY; 3509 } 3509 } 3510 parser->m_nsAtts = temp; 3510 parser->m_nsAtts = temp; 3511 version = 0; /* force re-initialization 3511 version = 0; /* force re-initialization of m_nsAtts hash table */ 3512 } 3512 } 3513 /* using a version flag saves us from ini 3513 /* using a version flag saves us from initializing m_nsAtts every time */ 3514 if (! version) { /* initialize version fl 3514 if (! version) { /* initialize version flags when version wraps around */ 3515 version = INIT_ATTS_VERSION; 3515 version = INIT_ATTS_VERSION; 3516 for (j = nsAttsSize; j != 0;) 3516 for (j = nsAttsSize; j != 0;) 3517 parser->m_nsAtts[--j].version = versi 3517 parser->m_nsAtts[--j].version = version; 3518 } 3518 } 3519 parser->m_nsAttsVersion = --version; 3519 parser->m_nsAttsVersion = --version; 3520 3520 3521 /* expand prefixed names and check for du 3521 /* expand prefixed names and check for duplicates */ 3522 for (; i < attIndex; i += 2) { 3522 for (; i < attIndex; i += 2) { 3523 const XML_Char *s = appAtts[i]; 3523 const XML_Char *s = appAtts[i]; 3524 if (s[-1] == 2) { /* prefixed */ 3524 if (s[-1] == 2) { /* prefixed */ 3525 ATTRIBUTE_ID *id; 3525 ATTRIBUTE_ID *id; 3526 const BINDING *b; 3526 const BINDING *b; 3527 unsigned long uriHash; 3527 unsigned long uriHash; 3528 struct siphash sip_state; 3528 struct siphash sip_state; 3529 struct sipkey sip_key; 3529 struct sipkey sip_key; 3530 3530 3531 copy_salt_to_sipkey(parser, &sip_key) 3531 copy_salt_to_sipkey(parser, &sip_key); 3532 sip24_init(&sip_state, &sip_key); 3532 sip24_init(&sip_state, &sip_key); 3533 3533 3534 ((XML_Char *)s)[-1] = 0; /* clear fla 3534 ((XML_Char *)s)[-1] = 0; /* clear flag */ 3535 id = (ATTRIBUTE_ID *)lookup(parser, & 3535 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); 3536 if (! id || ! id->prefix) { 3536 if (! id || ! id->prefix) { 3537 /* This code is walking through the 3537 /* This code is walking through the appAtts array, dealing 3538 * with (in this case) a prefixed a 3538 * with (in this case) a prefixed attribute name. To be in 3539 * the array, the attribute must ha 3539 * the array, the attribute must have already been bound, so 3540 * has to have passed through the h 3540 * has to have passed through the hash table lookup once 3541 * already. That implies that an e 3541 * already. That implies that an entry for it already 3542 * exists, so the lookup above will 3542 * exists, so the lookup above will return a pointer to 3543 * already allocated memory. There 3543 * already allocated memory. There is no opportunaity for 3544 * the allocator to fail, so the co 3544 * the allocator to fail, so the condition above cannot be 3545 * fulfilled. 3545 * fulfilled. 3546 * 3546 * 3547 * Since it is difficult to be cert 3547 * Since it is difficult to be certain that the above 3548 * analysis is complete, we retain 3548 * analysis is complete, we retain the test and merely 3549 * remove the code from coverage te 3549 * remove the code from coverage tests. 3550 */ 3550 */ 3551 return XML_ERROR_NO_MEMORY; /* LCOV 3551 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ 3552 } 3552 } 3553 b = id->prefix->binding; 3553 b = id->prefix->binding; 3554 if (! b) 3554 if (! b) 3555 return XML_ERROR_UNBOUND_PREFIX; 3555 return XML_ERROR_UNBOUND_PREFIX; 3556 3556 3557 for (j = 0; j < b->uriLen; j++) { 3557 for (j = 0; j < b->uriLen; j++) { 3558 const XML_Char c = b->uri[j]; 3558 const XML_Char c = b->uri[j]; 3559 if (! poolAppendChar(&parser->m_tem 3559 if (! poolAppendChar(&parser->m_tempPool, c)) 3560 return XML_ERROR_NO_MEMORY; 3560 return XML_ERROR_NO_MEMORY; 3561 } 3561 } 3562 3562 3563 sip24_update(&sip_state, b->uri, b->u 3563 sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); 3564 3564 3565 while (*s++ != XML_T(ASCII_COLON)) 3565 while (*s++ != XML_T(ASCII_COLON)) 3566 ; 3566 ; 3567 3567 3568 sip24_update(&sip_state, s, keylen(s) 3568 sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); 3569 3569 3570 do { /* copies null terminator */ 3570 do { /* copies null terminator */ 3571 if (! poolAppendChar(&parser->m_tem 3571 if (! poolAppendChar(&parser->m_tempPool, *s)) 3572 return XML_ERROR_NO_MEMORY; 3572 return XML_ERROR_NO_MEMORY; 3573 } while (*s++); 3573 } while (*s++); 3574 3574 3575 uriHash = (unsigned long)sip24_final( 3575 uriHash = (unsigned long)sip24_final(&sip_state); 3576 3576 3577 { /* Check hash table for duplicate o 3577 { /* Check hash table for duplicate of expanded name (uriName). 3578 Derived from code in lookup(pars 3578 Derived from code in lookup(parser, HASH_TABLE *table, ...). 3579 */ 3579 */ 3580 unsigned char step = 0; 3580 unsigned char step = 0; 3581 unsigned long mask = nsAttsSize - 1 3581 unsigned long mask = nsAttsSize - 1; 3582 j = uriHash & mask; /* index into h 3582 j = uriHash & mask; /* index into hash table */ 3583 while (parser->m_nsAtts[j].version 3583 while (parser->m_nsAtts[j].version == version) { 3584 /* for speed we compare stored ha 3584 /* for speed we compare stored hash values first */ 3585 if (uriHash == parser->m_nsAtts[j 3585 if (uriHash == parser->m_nsAtts[j].hash) { 3586 const XML_Char *s1 = poolStart( 3586 const XML_Char *s1 = poolStart(&parser->m_tempPool); 3587 const XML_Char *s2 = parser->m_ 3587 const XML_Char *s2 = parser->m_nsAtts[j].uriName; 3588 /* s1 is null terminated, but n 3588 /* s1 is null terminated, but not s2 */ 3589 for (; *s1 == *s2 && *s1 != 0; 3589 for (; *s1 == *s2 && *s1 != 0; s1++, s2++) 3590 ; 3590 ; 3591 if (*s1 == 0) 3591 if (*s1 == 0) 3592 return XML_ERROR_DUPLICATE_AT 3592 return XML_ERROR_DUPLICATE_ATTRIBUTE; 3593 } 3593 } 3594 if (! step) 3594 if (! step) 3595 step = PROBE_STEP(uriHash, mask 3595 step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower); 3596 j < step ? (j += nsAttsSize - ste 3596 j < step ? (j += nsAttsSize - step) : (j -= step); 3597 } 3597 } 3598 } 3598 } 3599 3599 3600 if (parser->m_ns_triplets) { /* appen 3600 if (parser->m_ns_triplets) { /* append namespace separator and prefix */ 3601 parser->m_tempPool.ptr[-1] = parser 3601 parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator; 3602 s = b->prefix->name; 3602 s = b->prefix->name; 3603 do { 3603 do { 3604 if (! poolAppendChar(&parser->m_t 3604 if (! poolAppendChar(&parser->m_tempPool, *s)) 3605 return XML_ERROR_NO_MEMORY; 3605 return XML_ERROR_NO_MEMORY; 3606 } while (*s++); 3606 } while (*s++); 3607 } 3607 } 3608 3608 3609 /* store expanded name in attribute l 3609 /* store expanded name in attribute list */ 3610 s = poolStart(&parser->m_tempPool); 3610 s = poolStart(&parser->m_tempPool); 3611 poolFinish(&parser->m_tempPool); 3611 poolFinish(&parser->m_tempPool); 3612 appAtts[i] = s; 3612 appAtts[i] = s; 3613 3613 3614 /* fill empty slot with new version, 3614 /* fill empty slot with new version, uriName and hash value */ 3615 parser->m_nsAtts[j].version = version 3615 parser->m_nsAtts[j].version = version; 3616 parser->m_nsAtts[j].hash = uriHash; 3616 parser->m_nsAtts[j].hash = uriHash; 3617 parser->m_nsAtts[j].uriName = s; 3617 parser->m_nsAtts[j].uriName = s; 3618 3618 3619 if (! --nPrefixes) { 3619 if (! --nPrefixes) { 3620 i += 2; 3620 i += 2; 3621 break; 3621 break; 3622 } 3622 } 3623 } else /* not prefi 3623 } else /* not prefixed */ 3624 ((XML_Char *)s)[-1] = 0; /* clear fla 3624 ((XML_Char *)s)[-1] = 0; /* clear flag */ 3625 } 3625 } 3626 } 3626 } 3627 /* clear flags for the remaining attributes 3627 /* clear flags for the remaining attributes */ 3628 for (; i < attIndex; i += 2) 3628 for (; i < attIndex; i += 2) 3629 ((XML_Char *)(appAtts[i]))[-1] = 0; 3629 ((XML_Char *)(appAtts[i]))[-1] = 0; 3630 for (binding = *bindingsPtr; binding; bindi 3630 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) 3631 binding->attId->name[-1] = 0; 3631 binding->attId->name[-1] = 0; 3632 3632 3633 if (! parser->m_ns) 3633 if (! parser->m_ns) 3634 return XML_ERROR_NONE; 3634 return XML_ERROR_NONE; 3635 3635 3636 /* expand the element type name */ 3636 /* expand the element type name */ 3637 if (elementType->prefix) { 3637 if (elementType->prefix) { 3638 binding = elementType->prefix->binding; 3638 binding = elementType->prefix->binding; 3639 if (! binding) 3639 if (! binding) 3640 return XML_ERROR_UNBOUND_PREFIX; 3640 return XML_ERROR_UNBOUND_PREFIX; 3641 localPart = tagNamePtr->str; 3641 localPart = tagNamePtr->str; 3642 while (*localPart++ != XML_T(ASCII_COLON) 3642 while (*localPart++ != XML_T(ASCII_COLON)) 3643 ; 3643 ; 3644 } else if (dtd->defaultPrefix.binding) { 3644 } else if (dtd->defaultPrefix.binding) { 3645 binding = dtd->defaultPrefix.binding; 3645 binding = dtd->defaultPrefix.binding; 3646 localPart = tagNamePtr->str; 3646 localPart = tagNamePtr->str; 3647 } else 3647 } else 3648 return XML_ERROR_NONE; 3648 return XML_ERROR_NONE; 3649 prefixLen = 0; 3649 prefixLen = 0; 3650 if (parser->m_ns_triplets && binding->prefi 3650 if (parser->m_ns_triplets && binding->prefix->name) { 3651 for (; binding->prefix->name[prefixLen++] 3651 for (; binding->prefix->name[prefixLen++];) 3652 ; /* prefixLen includes null terminator 3652 ; /* prefixLen includes null terminator */ 3653 } 3653 } 3654 tagNamePtr->localPart = localPart; 3654 tagNamePtr->localPart = localPart; 3655 tagNamePtr->uriLen = binding->uriLen; 3655 tagNamePtr->uriLen = binding->uriLen; 3656 tagNamePtr->prefix = binding->prefix->name; 3656 tagNamePtr->prefix = binding->prefix->name; 3657 tagNamePtr->prefixLen = prefixLen; 3657 tagNamePtr->prefixLen = prefixLen; 3658 for (i = 0; localPart[i++];) 3658 for (i = 0; localPart[i++];) 3659 ; /* i includes null terminator */ 3659 ; /* i includes null terminator */ 3660 3660 3661 /* Detect and prevent integer overflow */ 3661 /* Detect and prevent integer overflow */ 3662 if (binding->uriLen > INT_MAX - prefixLen 3662 if (binding->uriLen > INT_MAX - prefixLen 3663 || i > INT_MAX - (binding->uriLen + pre 3663 || i > INT_MAX - (binding->uriLen + prefixLen)) { 3664 return XML_ERROR_NO_MEMORY; 3664 return XML_ERROR_NO_MEMORY; 3665 } 3665 } 3666 3666 3667 n = i + binding->uriLen + prefixLen; 3667 n = i + binding->uriLen + prefixLen; 3668 if (n > binding->uriAlloc) { 3668 if (n > binding->uriAlloc) { 3669 TAG *p; 3669 TAG *p; 3670 3670 3671 /* Detect and prevent integer overflow */ 3671 /* Detect and prevent integer overflow */ 3672 if (n > INT_MAX - EXPAND_SPARE) { 3672 if (n > INT_MAX - EXPAND_SPARE) { 3673 return XML_ERROR_NO_MEMORY; 3673 return XML_ERROR_NO_MEMORY; 3674 } 3674 } 3675 /* Detect and prevent integer overflow. 3675 /* Detect and prevent integer overflow. 3676 * The preprocessor guard addresses the " 3676 * The preprocessor guard addresses the "always false" warning 3677 * from -Wtype-limits on platforms where 3677 * from -Wtype-limits on platforms where 3678 * sizeof(unsigned int) < sizeof(size_t), 3678 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 3679 #if UINT_MAX >= SIZE_MAX 3679 #if UINT_MAX >= SIZE_MAX 3680 if ((unsigned)(n + EXPAND_SPARE) > (size_ 3680 if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { 3681 return XML_ERROR_NO_MEMORY; 3681 return XML_ERROR_NO_MEMORY; 3682 } 3682 } 3683 #endif 3683 #endif 3684 3684 3685 uri = (XML_Char *)MALLOC(parser, (n + EXP 3685 uri = (XML_Char *)MALLOC(parser, (n + EXPAND_SPARE) * sizeof(XML_Char)); 3686 if (! uri) 3686 if (! uri) 3687 return XML_ERROR_NO_MEMORY; 3687 return XML_ERROR_NO_MEMORY; 3688 binding->uriAlloc = n + EXPAND_SPARE; 3688 binding->uriAlloc = n + EXPAND_SPARE; 3689 memcpy(uri, binding->uri, binding->uriLen 3689 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); 3690 for (p = parser->m_tagStack; p; p = p->pa 3690 for (p = parser->m_tagStack; p; p = p->parent) 3691 if (p->name.str == binding->uri) 3691 if (p->name.str == binding->uri) 3692 p->name.str = uri; 3692 p->name.str = uri; 3693 FREE(parser, binding->uri); 3693 FREE(parser, binding->uri); 3694 binding->uri = uri; 3694 binding->uri = uri; 3695 } 3695 } 3696 /* if m_namespaceSeparator != '\0' then uri 3696 /* if m_namespaceSeparator != '\0' then uri includes it already */ 3697 uri = binding->uri + binding->uriLen; 3697 uri = binding->uri + binding->uriLen; 3698 memcpy(uri, localPart, i * sizeof(XML_Char) 3698 memcpy(uri, localPart, i * sizeof(XML_Char)); 3699 /* we always have a namespace separator bet 3699 /* we always have a namespace separator between localPart and prefix */ 3700 if (prefixLen) { 3700 if (prefixLen) { 3701 uri += i - 1; 3701 uri += i - 1; 3702 *uri = parser->m_namespaceSeparator; /* r 3702 *uri = parser->m_namespaceSeparator; /* replace null terminator */ 3703 memcpy(uri + 1, binding->prefix->name, pr 3703 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); 3704 } 3704 } 3705 tagNamePtr->str = binding->uri; 3705 tagNamePtr->str = binding->uri; 3706 return XML_ERROR_NONE; 3706 return XML_ERROR_NONE; 3707 } 3707 } 3708 3708 3709 static XML_Bool 3709 static XML_Bool 3710 is_rfc3986_uri_char(XML_Char candidate) { 3710 is_rfc3986_uri_char(XML_Char candidate) { 3711 // For the RFC 3986 ANBF grammar see 3711 // For the RFC 3986 ANBF grammar see 3712 // https://datatracker.ietf.org/doc/html/rf 3712 // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A 3713 3713 3714 switch (candidate) { 3714 switch (candidate) { 3715 // From rule "ALPHA" (uppercase half) 3715 // From rule "ALPHA" (uppercase half) 3716 case 'A': 3716 case 'A': 3717 case 'B': 3717 case 'B': 3718 case 'C': 3718 case 'C': 3719 case 'D': 3719 case 'D': 3720 case 'E': 3720 case 'E': 3721 case 'F': 3721 case 'F': 3722 case 'G': 3722 case 'G': 3723 case 'H': 3723 case 'H': 3724 case 'I': 3724 case 'I': 3725 case 'J': 3725 case 'J': 3726 case 'K': 3726 case 'K': 3727 case 'L': 3727 case 'L': 3728 case 'M': 3728 case 'M': 3729 case 'N': 3729 case 'N': 3730 case 'O': 3730 case 'O': 3731 case 'P': 3731 case 'P': 3732 case 'Q': 3732 case 'Q': 3733 case 'R': 3733 case 'R': 3734 case 'S': 3734 case 'S': 3735 case 'T': 3735 case 'T': 3736 case 'U': 3736 case 'U': 3737 case 'V': 3737 case 'V': 3738 case 'W': 3738 case 'W': 3739 case 'X': 3739 case 'X': 3740 case 'Y': 3740 case 'Y': 3741 case 'Z': 3741 case 'Z': 3742 3742 3743 // From rule "ALPHA" (lowercase half) 3743 // From rule "ALPHA" (lowercase half) 3744 case 'a': 3744 case 'a': 3745 case 'b': 3745 case 'b': 3746 case 'c': 3746 case 'c': 3747 case 'd': 3747 case 'd': 3748 case 'e': 3748 case 'e': 3749 case 'f': 3749 case 'f': 3750 case 'g': 3750 case 'g': 3751 case 'h': 3751 case 'h': 3752 case 'i': 3752 case 'i': 3753 case 'j': 3753 case 'j': 3754 case 'k': 3754 case 'k': 3755 case 'l': 3755 case 'l': 3756 case 'm': 3756 case 'm': 3757 case 'n': 3757 case 'n': 3758 case 'o': 3758 case 'o': 3759 case 'p': 3759 case 'p': 3760 case 'q': 3760 case 'q': 3761 case 'r': 3761 case 'r': 3762 case 's': 3762 case 's': 3763 case 't': 3763 case 't': 3764 case 'u': 3764 case 'u': 3765 case 'v': 3765 case 'v': 3766 case 'w': 3766 case 'w': 3767 case 'x': 3767 case 'x': 3768 case 'y': 3768 case 'y': 3769 case 'z': 3769 case 'z': 3770 3770 3771 // From rule "DIGIT" 3771 // From rule "DIGIT" 3772 case '0': 3772 case '0': 3773 case '1': 3773 case '1': 3774 case '2': 3774 case '2': 3775 case '3': 3775 case '3': 3776 case '4': 3776 case '4': 3777 case '5': 3777 case '5': 3778 case '6': 3778 case '6': 3779 case '7': 3779 case '7': 3780 case '8': 3780 case '8': 3781 case '9': 3781 case '9': 3782 3782 3783 // From rule "pct-encoded" 3783 // From rule "pct-encoded" 3784 case '%': 3784 case '%': 3785 3785 3786 // From rule "unreserved" 3786 // From rule "unreserved" 3787 case '-': 3787 case '-': 3788 case '.': 3788 case '.': 3789 case '_': 3789 case '_': 3790 case '~': 3790 case '~': 3791 3791 3792 // From rule "gen-delims" 3792 // From rule "gen-delims" 3793 case ':': 3793 case ':': 3794 case '/': 3794 case '/': 3795 case '?': 3795 case '?': 3796 case '#': 3796 case '#': 3797 case '[': 3797 case '[': 3798 case ']': 3798 case ']': 3799 case '@': 3799 case '@': 3800 3800 3801 // From rule "sub-delims" 3801 // From rule "sub-delims" 3802 case '!': 3802 case '!': 3803 case '$': 3803 case '$': 3804 case '&': 3804 case '&': 3805 case '\'': 3805 case '\'': 3806 case '(': 3806 case '(': 3807 case ')': 3807 case ')': 3808 case '*': 3808 case '*': 3809 case '+': 3809 case '+': 3810 case ',': 3810 case ',': 3811 case ';': 3811 case ';': 3812 case '=': 3812 case '=': 3813 return XML_TRUE; 3813 return XML_TRUE; 3814 3814 3815 default: 3815 default: 3816 return XML_FALSE; 3816 return XML_FALSE; 3817 } 3817 } 3818 } 3818 } 3819 3819 3820 /* addBinding() overwrites the value of prefi 3820 /* addBinding() overwrites the value of prefix->binding without checking. 3821 Therefore one must keep track of the old v 3821 Therefore one must keep track of the old value outside of addBinding(). 3822 */ 3822 */ 3823 static enum XML_Error 3823 static enum XML_Error 3824 addBinding(XML_Parser parser, PREFIX *prefix, 3824 addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, 3825 const XML_Char *uri, BINDING **bin 3825 const XML_Char *uri, BINDING **bindingsPtr) { 3826 // "http://www.w3.org/XML/1998/namespace" 3826 // "http://www.w3.org/XML/1998/namespace" 3827 static const XML_Char xmlNamespace[] 3827 static const XML_Char xmlNamespace[] 3828 = {ASCII_h, ASCII_t, ASCII_t, 3828 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, 3829 ASCII_SLASH, ASCII_SLASH, ASCII_w, 3829 ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, 3830 ASCII_PERIOD, ASCII_w, ASCII_3, 3830 ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, 3831 ASCII_r, ASCII_g, ASCII_SLA 3831 ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, 3832 ASCII_L, ASCII_SLASH, ASCII_1, 3832 ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, 3833 ASCII_8, ASCII_SLASH, ASCII_n, 3833 ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, 3834 ASCII_e, ASCII_s, ASCII_p, 3834 ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, 3835 ASCII_e, '\0'}; 3835 ASCII_e, '\0'}; 3836 static const int xmlLen = (int)sizeof(xmlNa 3836 static const int xmlLen = (int)sizeof(xmlNamespace) / sizeof(XML_Char) - 1; 3837 // "http://www.w3.org/2000/xmlns/" 3837 // "http://www.w3.org/2000/xmlns/" 3838 static const XML_Char xmlnsNamespace[] 3838 static const XML_Char xmlnsNamespace[] 3839 = {ASCII_h, ASCII_t, ASCII_t, 3839 = {ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, 3840 ASCII_SLASH, ASCII_w, ASCII_w, 3840 ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, 3841 ASCII_3, ASCII_PERIOD, ASCII_o, 3841 ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, 3842 ASCII_2, ASCII_0, ASCII_0, 3842 ASCII_2, ASCII_0, ASCII_0, ASCII_0, ASCII_SLASH, ASCII_x, 3843 ASCII_m, ASCII_l, ASCII_n, 3843 ASCII_m, ASCII_l, ASCII_n, ASCII_s, ASCII_SLASH, '\0'}; 3844 static const int xmlnsLen 3844 static const int xmlnsLen 3845 = (int)sizeof(xmlnsNamespace) / sizeof( 3845 = (int)sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1; 3846 3846 3847 XML_Bool mustBeXML = XML_FALSE; 3847 XML_Bool mustBeXML = XML_FALSE; 3848 XML_Bool isXML = XML_TRUE; 3848 XML_Bool isXML = XML_TRUE; 3849 XML_Bool isXMLNS = XML_TRUE; 3849 XML_Bool isXMLNS = XML_TRUE; 3850 3850 3851 BINDING *b; 3851 BINDING *b; 3852 int len; 3852 int len; 3853 3853 3854 /* empty URI is only valid for default name 3854 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ 3855 if (*uri == XML_T('\0') && prefix->name) 3855 if (*uri == XML_T('\0') && prefix->name) 3856 return XML_ERROR_UNDECLARING_PREFIX; 3856 return XML_ERROR_UNDECLARING_PREFIX; 3857 3857 3858 if (prefix->name && prefix->name[0] == XML_ 3858 if (prefix->name && prefix->name[0] == XML_T(ASCII_x) 3859 && prefix->name[1] == XML_T(ASCII_m) 3859 && prefix->name[1] == XML_T(ASCII_m) 3860 && prefix->name[2] == XML_T(ASCII_l)) { 3860 && prefix->name[2] == XML_T(ASCII_l)) { 3861 /* Not allowed to bind xmlns */ 3861 /* Not allowed to bind xmlns */ 3862 if (prefix->name[3] == XML_T(ASCII_n) && 3862 if (prefix->name[3] == XML_T(ASCII_n) && prefix->name[4] == XML_T(ASCII_s) 3863 && prefix->name[5] == XML_T('\0')) 3863 && prefix->name[5] == XML_T('\0')) 3864 return XML_ERROR_RESERVED_PREFIX_XMLNS; 3864 return XML_ERROR_RESERVED_PREFIX_XMLNS; 3865 3865 3866 if (prefix->name[3] == XML_T('\0')) 3866 if (prefix->name[3] == XML_T('\0')) 3867 mustBeXML = XML_TRUE; 3867 mustBeXML = XML_TRUE; 3868 } 3868 } 3869 3869 3870 for (len = 0; uri[len]; len++) { 3870 for (len = 0; uri[len]; len++) { 3871 if (isXML && (len > xmlLen || uri[len] != 3871 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) 3872 isXML = XML_FALSE; 3872 isXML = XML_FALSE; 3873 3873 3874 if (! mustBeXML && isXMLNS 3874 if (! mustBeXML && isXMLNS 3875 && (len > xmlnsLen || uri[len] != xml 3875 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) 3876 isXMLNS = XML_FALSE; 3876 isXMLNS = XML_FALSE; 3877 3877 3878 // NOTE: While Expat does not validate na 3878 // NOTE: While Expat does not validate namespace URIs against RFC 3986 3879 // today (and is not REQUIRED to do 3879 // today (and is not REQUIRED to do so with regard to the XML 1.0 3880 // namespaces specification) we hav 3880 // namespaces specification) we have to at least make sure, that 3881 // the application on top of Expat 3881 // the application on top of Expat (that is likely splitting expanded 3882 // element names ("qualified names" 3882 // element names ("qualified names") of form 3883 // "[uri sep] local [sep prefix] '\ 3883 // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces 3884 // in its element handler code) can 3884 // in its element handler code) cannot be confused by an attacker 3885 // putting additional namespace sep 3885 // putting additional namespace separator characters into namespace 3886 // declarations. That would be amb 3886 // declarations. That would be ambiguous and not to be expected. 3887 // 3887 // 3888 // While the HTML API docs of funct 3888 // While the HTML API docs of function XML_ParserCreateNS have been 3889 // advising against use of a namesp 3889 // advising against use of a namespace separator character that can 3890 // appear in a URI for >20 years no 3890 // appear in a URI for >20 years now, some widespread applications 3891 // are using URI characters (':' (c 3891 // are using URI characters (':' (colon) in particular) for a 3892 // namespace separator, in practice 3892 // namespace separator, in practice. To keep these applications 3893 // functional, we only reject names 3893 // functional, we only reject namespaces URIs containing the 3894 // application-chosen namespace sep 3894 // application-chosen namespace separator if the chosen separator 3895 // is a non-URI character with rega 3895 // is a non-URI character with regard to RFC 3986. 3896 if (parser->m_ns && (uri[len] == parser-> 3896 if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator) 3897 && ! is_rfc3986_uri_char(uri[len])) { 3897 && ! is_rfc3986_uri_char(uri[len])) { 3898 return XML_ERROR_SYNTAX; 3898 return XML_ERROR_SYNTAX; 3899 } 3899 } 3900 } 3900 } 3901 isXML = isXML && len == xmlLen; 3901 isXML = isXML && len == xmlLen; 3902 isXMLNS = isXMLNS && len == xmlnsLen; 3902 isXMLNS = isXMLNS && len == xmlnsLen; 3903 3903 3904 if (mustBeXML != isXML) 3904 if (mustBeXML != isXML) 3905 return mustBeXML ? XML_ERROR_RESERVED_PRE 3905 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML 3906 : XML_ERROR_RESERVED_NAM 3906 : XML_ERROR_RESERVED_NAMESPACE_URI; 3907 3907 3908 if (isXMLNS) 3908 if (isXMLNS) 3909 return XML_ERROR_RESERVED_NAMESPACE_URI; 3909 return XML_ERROR_RESERVED_NAMESPACE_URI; 3910 3910 3911 if (parser->m_namespaceSeparator) 3911 if (parser->m_namespaceSeparator) 3912 len++; 3912 len++; 3913 if (parser->m_freeBindingList) { 3913 if (parser->m_freeBindingList) { 3914 b = parser->m_freeBindingList; 3914 b = parser->m_freeBindingList; 3915 if (len > b->uriAlloc) { 3915 if (len > b->uriAlloc) { 3916 /* Detect and prevent integer overflow 3916 /* Detect and prevent integer overflow */ 3917 if (len > INT_MAX - EXPAND_SPARE) { 3917 if (len > INT_MAX - EXPAND_SPARE) { 3918 return XML_ERROR_NO_MEMORY; 3918 return XML_ERROR_NO_MEMORY; 3919 } 3919 } 3920 3920 3921 /* Detect and prevent integer overflow. 3921 /* Detect and prevent integer overflow. 3922 * The preprocessor guard addresses the 3922 * The preprocessor guard addresses the "always false" warning 3923 * from -Wtype-limits on platforms wher 3923 * from -Wtype-limits on platforms where 3924 * sizeof(unsigned int) < sizeof(size_t 3924 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 3925 #if UINT_MAX >= SIZE_MAX 3925 #if UINT_MAX >= SIZE_MAX 3926 if ((unsigned)(len + EXPAND_SPARE) > (s 3926 if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { 3927 return XML_ERROR_NO_MEMORY; 3927 return XML_ERROR_NO_MEMORY; 3928 } 3928 } 3929 #endif 3929 #endif 3930 3930 3931 XML_Char *temp = (XML_Char *)REALLOC( 3931 XML_Char *temp = (XML_Char *)REALLOC( 3932 parser, b->uri, sizeof(XML_Char) * 3932 parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE)); 3933 if (temp == NULL) 3933 if (temp == NULL) 3934 return XML_ERROR_NO_MEMORY; 3934 return XML_ERROR_NO_MEMORY; 3935 b->uri = temp; 3935 b->uri = temp; 3936 b->uriAlloc = len + EXPAND_SPARE; 3936 b->uriAlloc = len + EXPAND_SPARE; 3937 } 3937 } 3938 parser->m_freeBindingList = b->nextTagBin 3938 parser->m_freeBindingList = b->nextTagBinding; 3939 } else { 3939 } else { 3940 b = (BINDING *)MALLOC(parser, sizeof(BIND 3940 b = (BINDING *)MALLOC(parser, sizeof(BINDING)); 3941 if (! b) 3941 if (! b) 3942 return XML_ERROR_NO_MEMORY; 3942 return XML_ERROR_NO_MEMORY; 3943 3943 3944 /* Detect and prevent integer overflow */ 3944 /* Detect and prevent integer overflow */ 3945 if (len > INT_MAX - EXPAND_SPARE) { 3945 if (len > INT_MAX - EXPAND_SPARE) { 3946 return XML_ERROR_NO_MEMORY; 3946 return XML_ERROR_NO_MEMORY; 3947 } 3947 } 3948 /* Detect and prevent integer overflow. 3948 /* Detect and prevent integer overflow. 3949 * The preprocessor guard addresses the " 3949 * The preprocessor guard addresses the "always false" warning 3950 * from -Wtype-limits on platforms where 3950 * from -Wtype-limits on platforms where 3951 * sizeof(unsigned int) < sizeof(size_t), 3951 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 3952 #if UINT_MAX >= SIZE_MAX 3952 #if UINT_MAX >= SIZE_MAX 3953 if ((unsigned)(len + EXPAND_SPARE) > (siz 3953 if ((unsigned)(len + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) { 3954 return XML_ERROR_NO_MEMORY; 3954 return XML_ERROR_NO_MEMORY; 3955 } 3955 } 3956 #endif 3956 #endif 3957 3957 3958 b->uri 3958 b->uri 3959 = (XML_Char *)MALLOC(parser, sizeof(X 3959 = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE)); 3960 if (! b->uri) { 3960 if (! b->uri) { 3961 FREE(parser, b); 3961 FREE(parser, b); 3962 return XML_ERROR_NO_MEMORY; 3962 return XML_ERROR_NO_MEMORY; 3963 } 3963 } 3964 b->uriAlloc = len + EXPAND_SPARE; 3964 b->uriAlloc = len + EXPAND_SPARE; 3965 } 3965 } 3966 b->uriLen = len; 3966 b->uriLen = len; 3967 memcpy(b->uri, uri, len * sizeof(XML_Char)) 3967 memcpy(b->uri, uri, len * sizeof(XML_Char)); 3968 if (parser->m_namespaceSeparator) 3968 if (parser->m_namespaceSeparator) 3969 b->uri[len - 1] = parser->m_namespaceSepa 3969 b->uri[len - 1] = parser->m_namespaceSeparator; 3970 b->prefix = prefix; 3970 b->prefix = prefix; 3971 b->attId = attId; 3971 b->attId = attId; 3972 b->prevPrefixBinding = prefix->binding; 3972 b->prevPrefixBinding = prefix->binding; 3973 /* NULL binding when default namespace unde 3973 /* NULL binding when default namespace undeclared */ 3974 if (*uri == XML_T('\0') && prefix == &parse 3974 if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix) 3975 prefix->binding = NULL; 3975 prefix->binding = NULL; 3976 else 3976 else 3977 prefix->binding = b; 3977 prefix->binding = b; 3978 b->nextTagBinding = *bindingsPtr; 3978 b->nextTagBinding = *bindingsPtr; 3979 *bindingsPtr = b; 3979 *bindingsPtr = b; 3980 /* if attId == NULL then we are not startin 3980 /* if attId == NULL then we are not starting a namespace scope */ 3981 if (attId && parser->m_startNamespaceDeclHa 3981 if (attId && parser->m_startNamespaceDeclHandler) 3982 parser->m_startNamespaceDeclHandler(parse 3982 parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name, 3983 prefi 3983 prefix->binding ? uri : 0); 3984 return XML_ERROR_NONE; 3984 return XML_ERROR_NONE; 3985 } 3985 } 3986 3986 3987 /* The idea here is to avoid using stack for 3987 /* The idea here is to avoid using stack for each CDATA section when 3988 the whole file is parsed with one call. 3988 the whole file is parsed with one call. 3989 */ 3989 */ 3990 static enum XML_Error PTRCALL 3990 static enum XML_Error PTRCALL 3991 cdataSectionProcessor(XML_Parser parser, cons 3991 cdataSectionProcessor(XML_Parser parser, const char *start, const char *end, 3992 const char **endPtr) { 3992 const char **endPtr) { 3993 enum XML_Error result = doCdataSection( 3993 enum XML_Error result = doCdataSection( 3994 parser, parser->m_encoding, &start, end 3994 parser, parser->m_encoding, &start, end, endPtr, 3995 (XML_Bool)! parser->m_parsingStatus.fin 3995 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT); 3996 if (result != XML_ERROR_NONE) 3996 if (result != XML_ERROR_NONE) 3997 return result; 3997 return result; 3998 if (start) { 3998 if (start) { 3999 if (parser->m_parentParser) { /* we are p 3999 if (parser->m_parentParser) { /* we are parsing an external entity */ 4000 parser->m_processor = externalEntityCon 4000 parser->m_processor = externalEntityContentProcessor; 4001 return externalEntityContentProcessor(p 4001 return externalEntityContentProcessor(parser, start, end, endPtr); 4002 } else { 4002 } else { 4003 parser->m_processor = contentProcessor; 4003 parser->m_processor = contentProcessor; 4004 return contentProcessor(parser, start, 4004 return contentProcessor(parser, start, end, endPtr); 4005 } 4005 } 4006 } 4006 } 4007 return result; 4007 return result; 4008 } 4008 } 4009 4009 4010 /* startPtr gets set to non-null if the secti 4010 /* startPtr gets set to non-null if the section is closed, and to null if 4011 the section is not yet closed. 4011 the section is not yet closed. 4012 */ 4012 */ 4013 static enum XML_Error 4013 static enum XML_Error 4014 doCdataSection(XML_Parser parser, const ENCOD 4014 doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, 4015 const char *end, const char ** 4015 const char *end, const char **nextPtr, XML_Bool haveMore, 4016 enum XML_Account account) { 4016 enum XML_Account account) { 4017 const char *s = *startPtr; 4017 const char *s = *startPtr; 4018 const char **eventPP; 4018 const char **eventPP; 4019 const char **eventEndPP; 4019 const char **eventEndPP; 4020 if (enc == parser->m_encoding) { 4020 if (enc == parser->m_encoding) { 4021 eventPP = &parser->m_eventPtr; 4021 eventPP = &parser->m_eventPtr; 4022 *eventPP = s; 4022 *eventPP = s; 4023 eventEndPP = &parser->m_eventEndPtr; 4023 eventEndPP = &parser->m_eventEndPtr; 4024 } else { 4024 } else { 4025 eventPP = &(parser->m_openInternalEntitie 4025 eventPP = &(parser->m_openInternalEntities->internalEventPtr); 4026 eventEndPP = &(parser->m_openInternalEnti 4026 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 4027 } 4027 } 4028 *eventPP = s; 4028 *eventPP = s; 4029 *startPtr = NULL; 4029 *startPtr = NULL; 4030 4030 4031 for (;;) { 4031 for (;;) { 4032 const char *next = s; /* in case of XML_T 4032 const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ 4033 int tok = XmlCdataSectionTok(enc, s, end, 4033 int tok = XmlCdataSectionTok(enc, s, end, &next); 4034 #ifdef XML_DTD 4034 #ifdef XML_DTD 4035 if (! accountingDiffTolerated(parser, tok 4035 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { 4036 accountingOnAbort(parser); 4036 accountingOnAbort(parser); 4037 return XML_ERROR_AMPLIFICATION_LIMIT_BR 4037 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4038 } 4038 } 4039 #else 4039 #else 4040 UNUSED_P(account); 4040 UNUSED_P(account); 4041 #endif 4041 #endif 4042 *eventEndPP = next; 4042 *eventEndPP = next; 4043 switch (tok) { 4043 switch (tok) { 4044 case XML_TOK_CDATA_SECT_CLOSE: 4044 case XML_TOK_CDATA_SECT_CLOSE: 4045 if (parser->m_endCdataSectionHandler) 4045 if (parser->m_endCdataSectionHandler) 4046 parser->m_endCdataSectionHandler(pars 4046 parser->m_endCdataSectionHandler(parser->m_handlerArg); 4047 /* BEGIN disabled code */ 4047 /* BEGIN disabled code */ 4048 /* see comment under XML_TOK_CDATA_SECT 4048 /* see comment under XML_TOK_CDATA_SECT_OPEN */ 4049 else if (0 && parser->m_characterDataHa 4049 else if (0 && parser->m_characterDataHandler) 4050 parser->m_characterDataHandler(parser 4050 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 4051 0); 4051 0); 4052 /* END disabled code */ 4052 /* END disabled code */ 4053 else if (parser->m_defaultHandler) 4053 else if (parser->m_defaultHandler) 4054 reportDefault(parser, enc, s, next); 4054 reportDefault(parser, enc, s, next); 4055 *startPtr = next; 4055 *startPtr = next; 4056 *nextPtr = next; 4056 *nextPtr = next; 4057 if (parser->m_parsingStatus.parsing == 4057 if (parser->m_parsingStatus.parsing == XML_FINISHED) 4058 return XML_ERROR_ABORTED; 4058 return XML_ERROR_ABORTED; 4059 else 4059 else 4060 return XML_ERROR_NONE; 4060 return XML_ERROR_NONE; 4061 case XML_TOK_DATA_NEWLINE: 4061 case XML_TOK_DATA_NEWLINE: 4062 if (parser->m_characterDataHandler) { 4062 if (parser->m_characterDataHandler) { 4063 XML_Char c = 0xA; 4063 XML_Char c = 0xA; 4064 parser->m_characterDataHandler(parser 4064 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1); 4065 } else if (parser->m_defaultHandler) 4065 } else if (parser->m_defaultHandler) 4066 reportDefault(parser, enc, s, next); 4066 reportDefault(parser, enc, s, next); 4067 break; 4067 break; 4068 case XML_TOK_DATA_CHARS: { 4068 case XML_TOK_DATA_CHARS: { 4069 XML_CharacterDataHandler charDataHandle 4069 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler; 4070 if (charDataHandler) { 4070 if (charDataHandler) { 4071 if (MUST_CONVERT(enc, s)) { 4071 if (MUST_CONVERT(enc, s)) { 4072 for (;;) { 4072 for (;;) { 4073 ICHAR *dataPtr = (ICHAR *)parser- 4073 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; 4074 const enum XML_Convert_Result con 4074 const enum XML_Convert_Result convert_res = XmlConvert( 4075 enc, &s, next, &dataPtr, (ICH 4075 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd); 4076 *eventEndPP = next; 4076 *eventEndPP = next; 4077 charDataHandler(parser->m_handler 4077 charDataHandler(parser->m_handlerArg, parser->m_dataBuf, 4078 (int)(dataPtr - ( 4078 (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); 4079 if ((convert_res == XML_CONVERT_C 4079 if ((convert_res == XML_CONVERT_COMPLETED) 4080 || (convert_res == XML_CONVER 4080 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) 4081 break; 4081 break; 4082 *eventPP = s; 4082 *eventPP = s; 4083 } 4083 } 4084 } else 4084 } else 4085 charDataHandler(parser->m_handlerAr 4085 charDataHandler(parser->m_handlerArg, (XML_Char *)s, 4086 (int)((XML_Char *)n 4086 (int)((XML_Char *)next - (XML_Char *)s)); 4087 } else if (parser->m_defaultHandler) 4087 } else if (parser->m_defaultHandler) 4088 reportDefault(parser, enc, s, next); 4088 reportDefault(parser, enc, s, next); 4089 } break; 4089 } break; 4090 case XML_TOK_INVALID: 4090 case XML_TOK_INVALID: 4091 *eventPP = next; 4091 *eventPP = next; 4092 return XML_ERROR_INVALID_TOKEN; 4092 return XML_ERROR_INVALID_TOKEN; 4093 case XML_TOK_PARTIAL_CHAR: 4093 case XML_TOK_PARTIAL_CHAR: 4094 if (haveMore) { 4094 if (haveMore) { 4095 *nextPtr = s; 4095 *nextPtr = s; 4096 return XML_ERROR_NONE; 4096 return XML_ERROR_NONE; 4097 } 4097 } 4098 return XML_ERROR_PARTIAL_CHAR; 4098 return XML_ERROR_PARTIAL_CHAR; 4099 case XML_TOK_PARTIAL: 4099 case XML_TOK_PARTIAL: 4100 case XML_TOK_NONE: 4100 case XML_TOK_NONE: 4101 if (haveMore) { 4101 if (haveMore) { 4102 *nextPtr = s; 4102 *nextPtr = s; 4103 return XML_ERROR_NONE; 4103 return XML_ERROR_NONE; 4104 } 4104 } 4105 return XML_ERROR_UNCLOSED_CDATA_SECTION 4105 return XML_ERROR_UNCLOSED_CDATA_SECTION; 4106 default: 4106 default: 4107 /* Every token returned by XmlCdataSect 4107 /* Every token returned by XmlCdataSectionTok() has its own 4108 * explicit case, so this default case 4108 * explicit case, so this default case will never be executed. 4109 * We retain it as a safety net and exc 4109 * We retain it as a safety net and exclude it from the coverage 4110 * statistics. 4110 * statistics. 4111 * 4111 * 4112 * LCOV_EXCL_START 4112 * LCOV_EXCL_START 4113 */ 4113 */ 4114 *eventPP = next; 4114 *eventPP = next; 4115 return XML_ERROR_UNEXPECTED_STATE; 4115 return XML_ERROR_UNEXPECTED_STATE; 4116 /* LCOV_EXCL_STOP */ 4116 /* LCOV_EXCL_STOP */ 4117 } 4117 } 4118 4118 4119 *eventPP = s = next; 4119 *eventPP = s = next; 4120 switch (parser->m_parsingStatus.parsing) 4120 switch (parser->m_parsingStatus.parsing) { 4121 case XML_SUSPENDED: 4121 case XML_SUSPENDED: 4122 *nextPtr = next; 4122 *nextPtr = next; 4123 return XML_ERROR_NONE; 4123 return XML_ERROR_NONE; 4124 case XML_FINISHED: 4124 case XML_FINISHED: 4125 return XML_ERROR_ABORTED; 4125 return XML_ERROR_ABORTED; 4126 default:; 4126 default:; 4127 } 4127 } 4128 } 4128 } 4129 /* not reached */ 4129 /* not reached */ 4130 } 4130 } 4131 4131 4132 #ifdef XML_DTD 4132 #ifdef XML_DTD 4133 4133 4134 /* The idea here is to avoid using stack for 4134 /* The idea here is to avoid using stack for each IGNORE section when 4135 the whole file is parsed with one call. 4135 the whole file is parsed with one call. 4136 */ 4136 */ 4137 static enum XML_Error PTRCALL 4137 static enum XML_Error PTRCALL 4138 ignoreSectionProcessor(XML_Parser parser, con 4138 ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end, 4139 const char **endPtr) { 4139 const char **endPtr) { 4140 enum XML_Error result 4140 enum XML_Error result 4141 = doIgnoreSection(parser, parser->m_enc 4141 = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr, 4142 (XML_Bool)! parser->m 4142 (XML_Bool)! parser->m_parsingStatus.finalBuffer); 4143 if (result != XML_ERROR_NONE) 4143 if (result != XML_ERROR_NONE) 4144 return result; 4144 return result; 4145 if (start) { 4145 if (start) { 4146 parser->m_processor = prologProcessor; 4146 parser->m_processor = prologProcessor; 4147 return prologProcessor(parser, start, end 4147 return prologProcessor(parser, start, end, endPtr); 4148 } 4148 } 4149 return result; 4149 return result; 4150 } 4150 } 4151 4151 4152 /* startPtr gets set to non-null is the secti 4152 /* startPtr gets set to non-null is the section is closed, and to null 4153 if the section is not yet closed. 4153 if the section is not yet closed. 4154 */ 4154 */ 4155 static enum XML_Error 4155 static enum XML_Error 4156 doIgnoreSection(XML_Parser parser, const ENCO 4156 doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, 4157 const char *end, const char * 4157 const char *end, const char **nextPtr, XML_Bool haveMore) { 4158 const char *next = *startPtr; /* in case of 4158 const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */ 4159 int tok; 4159 int tok; 4160 const char *s = *startPtr; 4160 const char *s = *startPtr; 4161 const char **eventPP; 4161 const char **eventPP; 4162 const char **eventEndPP; 4162 const char **eventEndPP; 4163 if (enc == parser->m_encoding) { 4163 if (enc == parser->m_encoding) { 4164 eventPP = &parser->m_eventPtr; 4164 eventPP = &parser->m_eventPtr; 4165 *eventPP = s; 4165 *eventPP = s; 4166 eventEndPP = &parser->m_eventEndPtr; 4166 eventEndPP = &parser->m_eventEndPtr; 4167 } else { 4167 } else { 4168 /* It's not entirely clear, but it seems 4168 /* It's not entirely clear, but it seems the following two lines 4169 * of code cannot be executed. The only 4169 * of code cannot be executed. The only occasions on which 'enc' 4170 * is not 'encoding' are when this functi 4170 * is not 'encoding' are when this function is called 4171 * from the internal entity processing, a 4171 * from the internal entity processing, and IGNORE sections are an 4172 * error in internal entities. 4172 * error in internal entities. 4173 * 4173 * 4174 * Since it really isn't clear that this 4174 * Since it really isn't clear that this is true, we keep the code 4175 * and just remove it from our coverage t 4175 * and just remove it from our coverage tests. 4176 * 4176 * 4177 * LCOV_EXCL_START 4177 * LCOV_EXCL_START 4178 */ 4178 */ 4179 eventPP = &(parser->m_openInternalEntitie 4179 eventPP = &(parser->m_openInternalEntities->internalEventPtr); 4180 eventEndPP = &(parser->m_openInternalEnti 4180 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 4181 /* LCOV_EXCL_STOP */ 4181 /* LCOV_EXCL_STOP */ 4182 } 4182 } 4183 *eventPP = s; 4183 *eventPP = s; 4184 *startPtr = NULL; 4184 *startPtr = NULL; 4185 tok = XmlIgnoreSectionTok(enc, s, end, &nex 4185 tok = XmlIgnoreSectionTok(enc, s, end, &next); 4186 # ifdef XML_DTD 4186 # ifdef XML_DTD 4187 if (! accountingDiffTolerated(parser, tok, 4187 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 4188 XML_ACCOUNT_D 4188 XML_ACCOUNT_DIRECT)) { 4189 accountingOnAbort(parser); 4189 accountingOnAbort(parser); 4190 return XML_ERROR_AMPLIFICATION_LIMIT_BREA 4190 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4191 } 4191 } 4192 # endif 4192 # endif 4193 *eventEndPP = next; 4193 *eventEndPP = next; 4194 switch (tok) { 4194 switch (tok) { 4195 case XML_TOK_IGNORE_SECT: 4195 case XML_TOK_IGNORE_SECT: 4196 if (parser->m_defaultHandler) 4196 if (parser->m_defaultHandler) 4197 reportDefault(parser, enc, s, next); 4197 reportDefault(parser, enc, s, next); 4198 *startPtr = next; 4198 *startPtr = next; 4199 *nextPtr = next; 4199 *nextPtr = next; 4200 if (parser->m_parsingStatus.parsing == XM 4200 if (parser->m_parsingStatus.parsing == XML_FINISHED) 4201 return XML_ERROR_ABORTED; 4201 return XML_ERROR_ABORTED; 4202 else 4202 else 4203 return XML_ERROR_NONE; 4203 return XML_ERROR_NONE; 4204 case XML_TOK_INVALID: 4204 case XML_TOK_INVALID: 4205 *eventPP = next; 4205 *eventPP = next; 4206 return XML_ERROR_INVALID_TOKEN; 4206 return XML_ERROR_INVALID_TOKEN; 4207 case XML_TOK_PARTIAL_CHAR: 4207 case XML_TOK_PARTIAL_CHAR: 4208 if (haveMore) { 4208 if (haveMore) { 4209 *nextPtr = s; 4209 *nextPtr = s; 4210 return XML_ERROR_NONE; 4210 return XML_ERROR_NONE; 4211 } 4211 } 4212 return XML_ERROR_PARTIAL_CHAR; 4212 return XML_ERROR_PARTIAL_CHAR; 4213 case XML_TOK_PARTIAL: 4213 case XML_TOK_PARTIAL: 4214 case XML_TOK_NONE: 4214 case XML_TOK_NONE: 4215 if (haveMore) { 4215 if (haveMore) { 4216 *nextPtr = s; 4216 *nextPtr = s; 4217 return XML_ERROR_NONE; 4217 return XML_ERROR_NONE; 4218 } 4218 } 4219 return XML_ERROR_SYNTAX; /* XML_ERROR_UNC 4219 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ 4220 default: 4220 default: 4221 /* All of the tokens that XmlIgnoreSectio 4221 /* All of the tokens that XmlIgnoreSectionTok() returns have 4222 * explicit cases to handle them, so this 4222 * explicit cases to handle them, so this default case is never 4223 * executed. We keep it as a safety net 4223 * executed. We keep it as a safety net anyway, and remove it 4224 * from our test coverage statistics. 4224 * from our test coverage statistics. 4225 * 4225 * 4226 * LCOV_EXCL_START 4226 * LCOV_EXCL_START 4227 */ 4227 */ 4228 *eventPP = next; 4228 *eventPP = next; 4229 return XML_ERROR_UNEXPECTED_STATE; 4229 return XML_ERROR_UNEXPECTED_STATE; 4230 /* LCOV_EXCL_STOP */ 4230 /* LCOV_EXCL_STOP */ 4231 } 4231 } 4232 /* not reached */ 4232 /* not reached */ 4233 } 4233 } 4234 4234 4235 #endif /* XML_DTD */ 4235 #endif /* XML_DTD */ 4236 4236 4237 static enum XML_Error 4237 static enum XML_Error 4238 initializeEncoding(XML_Parser parser) { 4238 initializeEncoding(XML_Parser parser) { 4239 const char *s; 4239 const char *s; 4240 #ifdef XML_UNICODE 4240 #ifdef XML_UNICODE 4241 char encodingBuf[128]; 4241 char encodingBuf[128]; 4242 /* See comments about `protocolEncodingName 4242 /* See comments about `protocolEncodingName` in parserInit() */ 4243 if (! parser->m_protocolEncodingName) 4243 if (! parser->m_protocolEncodingName) 4244 s = NULL; 4244 s = NULL; 4245 else { 4245 else { 4246 int i; 4246 int i; 4247 for (i = 0; parser->m_protocolEncodingNam 4247 for (i = 0; parser->m_protocolEncodingName[i]; i++) { 4248 if (i == sizeof(encodingBuf) - 1 4248 if (i == sizeof(encodingBuf) - 1 4249 || (parser->m_protocolEncodingName[ 4249 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) { 4250 encodingBuf[0] = '\0'; 4250 encodingBuf[0] = '\0'; 4251 break; 4251 break; 4252 } 4252 } 4253 encodingBuf[i] = (char)parser->m_protoc 4253 encodingBuf[i] = (char)parser->m_protocolEncodingName[i]; 4254 } 4254 } 4255 encodingBuf[i] = '\0'; 4255 encodingBuf[i] = '\0'; 4256 s = encodingBuf; 4256 s = encodingBuf; 4257 } 4257 } 4258 #else 4258 #else 4259 s = parser->m_protocolEncodingName; 4259 s = parser->m_protocolEncodingName; 4260 #endif 4260 #endif 4261 if ((parser->m_ns ? XmlInitEncodingNS : Xml 4261 if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)( 4262 &parser->m_initEncoding, &parser->m 4262 &parser->m_initEncoding, &parser->m_encoding, s)) 4263 return XML_ERROR_NONE; 4263 return XML_ERROR_NONE; 4264 return handleUnknownEncoding(parser, parser 4264 return handleUnknownEncoding(parser, parser->m_protocolEncodingName); 4265 } 4265 } 4266 4266 4267 static enum XML_Error 4267 static enum XML_Error 4268 processXmlDecl(XML_Parser parser, int isGener 4268 processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, 4269 const char *next) { 4269 const char *next) { 4270 const char *encodingName = NULL; 4270 const char *encodingName = NULL; 4271 const XML_Char *storedEncName = NULL; 4271 const XML_Char *storedEncName = NULL; 4272 const ENCODING *newEncoding = NULL; 4272 const ENCODING *newEncoding = NULL; 4273 const char *version = NULL; 4273 const char *version = NULL; 4274 const char *versionend = NULL; 4274 const char *versionend = NULL; 4275 const XML_Char *storedversion = NULL; 4275 const XML_Char *storedversion = NULL; 4276 int standalone = -1; 4276 int standalone = -1; 4277 4277 4278 #ifdef XML_DTD 4278 #ifdef XML_DTD 4279 if (! accountingDiffTolerated(parser, XML_T 4279 if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__, 4280 XML_ACCOUNT_D 4280 XML_ACCOUNT_DIRECT)) { 4281 accountingOnAbort(parser); 4281 accountingOnAbort(parser); 4282 return XML_ERROR_AMPLIFICATION_LIMIT_BREA 4282 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4283 } 4283 } 4284 #endif 4284 #endif 4285 4285 4286 if (! (parser->m_ns ? XmlParseXmlDeclNS : X 4286 if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)( 4287 isGeneralTextEntity, parser->m_enco 4287 isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr, 4288 &version, &versionend, &encodingNam 4288 &version, &versionend, &encodingName, &newEncoding, &standalone)) { 4289 if (isGeneralTextEntity) 4289 if (isGeneralTextEntity) 4290 return XML_ERROR_TEXT_DECL; 4290 return XML_ERROR_TEXT_DECL; 4291 else 4291 else 4292 return XML_ERROR_XML_DECL; 4292 return XML_ERROR_XML_DECL; 4293 } 4293 } 4294 if (! isGeneralTextEntity && standalone == 4294 if (! isGeneralTextEntity && standalone == 1) { 4295 parser->m_dtd->standalone = XML_TRUE; 4295 parser->m_dtd->standalone = XML_TRUE; 4296 #ifdef XML_DTD 4296 #ifdef XML_DTD 4297 if (parser->m_paramEntityParsing 4297 if (parser->m_paramEntityParsing 4298 == XML_PARAM_ENTITY_PARSING_UNLESS_ST 4298 == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) 4299 parser->m_paramEntityParsing = XML_PARA 4299 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; 4300 #endif /* XML_DTD */ 4300 #endif /* XML_DTD */ 4301 } 4301 } 4302 if (parser->m_xmlDeclHandler) { 4302 if (parser->m_xmlDeclHandler) { 4303 if (encodingName != NULL) { 4303 if (encodingName != NULL) { 4304 storedEncName = poolStoreString( 4304 storedEncName = poolStoreString( 4305 &parser->m_temp2Pool, parser->m_enc 4305 &parser->m_temp2Pool, parser->m_encoding, encodingName, 4306 encodingName + XmlNameLength(parser 4306 encodingName + XmlNameLength(parser->m_encoding, encodingName)); 4307 if (! storedEncName) 4307 if (! storedEncName) 4308 return XML_ERROR_NO_MEMORY; 4308 return XML_ERROR_NO_MEMORY; 4309 poolFinish(&parser->m_temp2Pool); 4309 poolFinish(&parser->m_temp2Pool); 4310 } 4310 } 4311 if (version) { 4311 if (version) { 4312 storedversion 4312 storedversion 4313 = poolStoreString(&parser->m_temp2P 4313 = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version, 4314 versionend - pars 4314 versionend - parser->m_encoding->minBytesPerChar); 4315 if (! storedversion) 4315 if (! storedversion) 4316 return XML_ERROR_NO_MEMORY; 4316 return XML_ERROR_NO_MEMORY; 4317 } 4317 } 4318 parser->m_xmlDeclHandler(parser->m_handle 4318 parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, 4319 standalone); 4319 standalone); 4320 } else if (parser->m_defaultHandler) 4320 } else if (parser->m_defaultHandler) 4321 reportDefault(parser, parser->m_encoding, 4321 reportDefault(parser, parser->m_encoding, s, next); 4322 if (parser->m_protocolEncodingName == NULL) 4322 if (parser->m_protocolEncodingName == NULL) { 4323 if (newEncoding) { 4323 if (newEncoding) { 4324 /* Check that the specified encoding do 4324 /* Check that the specified encoding does not conflict with what 4325 * the parser has already deduced. Do 4325 * the parser has already deduced. Do we have the same number 4326 * of bytes in the smallest representat 4326 * of bytes in the smallest representation of a character? If 4327 * this is UTF-16, is it the same endia 4327 * this is UTF-16, is it the same endianness? 4328 */ 4328 */ 4329 if (newEncoding->minBytesPerChar != par 4329 if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar 4330 || (newEncoding->minBytesPerChar == 4330 || (newEncoding->minBytesPerChar == 2 4331 && newEncoding != parser->m_enc 4331 && newEncoding != parser->m_encoding)) { 4332 parser->m_eventPtr = encodingName; 4332 parser->m_eventPtr = encodingName; 4333 return XML_ERROR_INCORRECT_ENCODING; 4333 return XML_ERROR_INCORRECT_ENCODING; 4334 } 4334 } 4335 parser->m_encoding = newEncoding; 4335 parser->m_encoding = newEncoding; 4336 } else if (encodingName) { 4336 } else if (encodingName) { 4337 enum XML_Error result; 4337 enum XML_Error result; 4338 if (! storedEncName) { 4338 if (! storedEncName) { 4339 storedEncName = poolStoreString( 4339 storedEncName = poolStoreString( 4340 &parser->m_temp2Pool, parser->m_e 4340 &parser->m_temp2Pool, parser->m_encoding, encodingName, 4341 encodingName + XmlNameLength(pars 4341 encodingName + XmlNameLength(parser->m_encoding, encodingName)); 4342 if (! storedEncName) 4342 if (! storedEncName) 4343 return XML_ERROR_NO_MEMORY; 4343 return XML_ERROR_NO_MEMORY; 4344 } 4344 } 4345 result = handleUnknownEncoding(parser, 4345 result = handleUnknownEncoding(parser, storedEncName); 4346 poolClear(&parser->m_temp2Pool); 4346 poolClear(&parser->m_temp2Pool); 4347 if (result == XML_ERROR_UNKNOWN_ENCODIN 4347 if (result == XML_ERROR_UNKNOWN_ENCODING) 4348 parser->m_eventPtr = encodingName; 4348 parser->m_eventPtr = encodingName; 4349 return result; 4349 return result; 4350 } 4350 } 4351 } 4351 } 4352 4352 4353 if (storedEncName || storedversion) 4353 if (storedEncName || storedversion) 4354 poolClear(&parser->m_temp2Pool); 4354 poolClear(&parser->m_temp2Pool); 4355 4355 4356 return XML_ERROR_NONE; 4356 return XML_ERROR_NONE; 4357 } 4357 } 4358 4358 4359 static enum XML_Error 4359 static enum XML_Error 4360 handleUnknownEncoding(XML_Parser parser, cons 4360 handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { 4361 if (parser->m_unknownEncodingHandler) { 4361 if (parser->m_unknownEncodingHandler) { 4362 XML_Encoding info; 4362 XML_Encoding info; 4363 int i; 4363 int i; 4364 for (i = 0; i < 256; i++) 4364 for (i = 0; i < 256; i++) 4365 info.map[i] = -1; 4365 info.map[i] = -1; 4366 info.convert = NULL; 4366 info.convert = NULL; 4367 info.data = NULL; 4367 info.data = NULL; 4368 info.release = NULL; 4368 info.release = NULL; 4369 if (parser->m_unknownEncodingHandler(pars 4369 if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, 4370 enco 4370 encodingName, &info)) { 4371 ENCODING *enc; 4371 ENCODING *enc; 4372 parser->m_unknownEncodingMem = MALLOC(p 4372 parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding()); 4373 if (! parser->m_unknownEncodingMem) { 4373 if (! parser->m_unknownEncodingMem) { 4374 if (info.release) 4374 if (info.release) 4375 info.release(info.data); 4375 info.release(info.data); 4376 return XML_ERROR_NO_MEMORY; 4376 return XML_ERROR_NO_MEMORY; 4377 } 4377 } 4378 enc = (parser->m_ns ? XmlInitUnknownEnc 4378 enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)( 4379 parser->m_unknownEncodingMem, info. 4379 parser->m_unknownEncodingMem, info.map, info.convert, info.data); 4380 if (enc) { 4380 if (enc) { 4381 parser->m_unknownEncodingData = info. 4381 parser->m_unknownEncodingData = info.data; 4382 parser->m_unknownEncodingRelease = in 4382 parser->m_unknownEncodingRelease = info.release; 4383 parser->m_encoding = enc; 4383 parser->m_encoding = enc; 4384 return XML_ERROR_NONE; 4384 return XML_ERROR_NONE; 4385 } 4385 } 4386 } 4386 } 4387 if (info.release != NULL) 4387 if (info.release != NULL) 4388 info.release(info.data); 4388 info.release(info.data); 4389 } 4389 } 4390 return XML_ERROR_UNKNOWN_ENCODING; 4390 return XML_ERROR_UNKNOWN_ENCODING; 4391 } 4391 } 4392 4392 4393 static enum XML_Error PTRCALL 4393 static enum XML_Error PTRCALL 4394 prologInitProcessor(XML_Parser parser, const 4394 prologInitProcessor(XML_Parser parser, const char *s, const char *end, 4395 const char **nextPtr) { 4395 const char **nextPtr) { 4396 enum XML_Error result = initializeEncoding( 4396 enum XML_Error result = initializeEncoding(parser); 4397 if (result != XML_ERROR_NONE) 4397 if (result != XML_ERROR_NONE) 4398 return result; 4398 return result; 4399 parser->m_processor = prologProcessor; 4399 parser->m_processor = prologProcessor; 4400 return prologProcessor(parser, s, end, next 4400 return prologProcessor(parser, s, end, nextPtr); 4401 } 4401 } 4402 4402 4403 #ifdef XML_DTD 4403 #ifdef XML_DTD 4404 4404 4405 static enum XML_Error PTRCALL 4405 static enum XML_Error PTRCALL 4406 externalParEntInitProcessor(XML_Parser parser 4406 externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end, 4407 const char **next 4407 const char **nextPtr) { 4408 enum XML_Error result = initializeEncoding( 4408 enum XML_Error result = initializeEncoding(parser); 4409 if (result != XML_ERROR_NONE) 4409 if (result != XML_ERROR_NONE) 4410 return result; 4410 return result; 4411 4411 4412 /* we know now that XML_Parse(Buffer) has b 4412 /* we know now that XML_Parse(Buffer) has been called, 4413 so we consider the external parameter en 4413 so we consider the external parameter entity read */ 4414 parser->m_dtd->paramEntityRead = XML_TRUE; 4414 parser->m_dtd->paramEntityRead = XML_TRUE; 4415 4415 4416 if (parser->m_prologState.inEntityValue) { 4416 if (parser->m_prologState.inEntityValue) { 4417 parser->m_processor = entityValueInitProc 4417 parser->m_processor = entityValueInitProcessor; 4418 return entityValueInitProcessor(parser, s 4418 return entityValueInitProcessor(parser, s, end, nextPtr); 4419 } else { 4419 } else { 4420 parser->m_processor = externalParEntProce 4420 parser->m_processor = externalParEntProcessor; 4421 return externalParEntProcessor(parser, s, 4421 return externalParEntProcessor(parser, s, end, nextPtr); 4422 } 4422 } 4423 } 4423 } 4424 4424 4425 static enum XML_Error PTRCALL 4425 static enum XML_Error PTRCALL 4426 entityValueInitProcessor(XML_Parser parser, c 4426 entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, 4427 const char **nextPtr 4427 const char **nextPtr) { 4428 int tok; 4428 int tok; 4429 const char *start = s; 4429 const char *start = s; 4430 const char *next = start; 4430 const char *next = start; 4431 parser->m_eventPtr = start; 4431 parser->m_eventPtr = start; 4432 4432 4433 for (;;) { 4433 for (;;) { 4434 tok = XmlPrologTok(parser->m_encoding, st 4434 tok = XmlPrologTok(parser->m_encoding, start, end, &next); 4435 /* Note: Except for XML_TOK_BOM below, th 4435 /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in: 4436 - storeEntityValue 4436 - storeEntityValue 4437 - processXmlDecl 4437 - processXmlDecl 4438 */ 4438 */ 4439 parser->m_eventEndPtr = next; 4439 parser->m_eventEndPtr = next; 4440 if (tok <= 0) { 4440 if (tok <= 0) { 4441 if (! parser->m_parsingStatus.finalBuff 4441 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { 4442 *nextPtr = s; 4442 *nextPtr = s; 4443 return XML_ERROR_NONE; 4443 return XML_ERROR_NONE; 4444 } 4444 } 4445 switch (tok) { 4445 switch (tok) { 4446 case XML_TOK_INVALID: 4446 case XML_TOK_INVALID: 4447 return XML_ERROR_INVALID_TOKEN; 4447 return XML_ERROR_INVALID_TOKEN; 4448 case XML_TOK_PARTIAL: 4448 case XML_TOK_PARTIAL: 4449 return XML_ERROR_UNCLOSED_TOKEN; 4449 return XML_ERROR_UNCLOSED_TOKEN; 4450 case XML_TOK_PARTIAL_CHAR: 4450 case XML_TOK_PARTIAL_CHAR: 4451 return XML_ERROR_PARTIAL_CHAR; 4451 return XML_ERROR_PARTIAL_CHAR; 4452 case XML_TOK_NONE: /* start == end */ 4452 case XML_TOK_NONE: /* start == end */ 4453 default: 4453 default: 4454 break; 4454 break; 4455 } 4455 } 4456 /* found end of entity value - can stor 4456 /* found end of entity value - can store it now */ 4457 return storeEntityValue(parser, parser- 4457 return storeEntityValue(parser, parser->m_encoding, s, end, 4458 XML_ACCOUNT_DIR 4458 XML_ACCOUNT_DIRECT); 4459 } else if (tok == XML_TOK_XML_DECL) { 4459 } else if (tok == XML_TOK_XML_DECL) { 4460 enum XML_Error result; 4460 enum XML_Error result; 4461 result = processXmlDecl(parser, 0, star 4461 result = processXmlDecl(parser, 0, start, next); 4462 if (result != XML_ERROR_NONE) 4462 if (result != XML_ERROR_NONE) 4463 return result; 4463 return result; 4464 /* At this point, m_parsingStatus.parsi 4464 /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For 4465 * that to happen, a parameter entity p 4465 * that to happen, a parameter entity parsing handler must have attempted 4466 * to suspend the parser, which fails a 4466 * to suspend the parser, which fails and raises an error. The parser can 4467 * be aborted, but can't be suspended. 4467 * be aborted, but can't be suspended. 4468 */ 4468 */ 4469 if (parser->m_parsingStatus.parsing == 4469 if (parser->m_parsingStatus.parsing == XML_FINISHED) 4470 return XML_ERROR_ABORTED; 4470 return XML_ERROR_ABORTED; 4471 *nextPtr = next; 4471 *nextPtr = next; 4472 /* stop scanning for text declaration - 4472 /* stop scanning for text declaration - we found one */ 4473 parser->m_processor = entityValueProces 4473 parser->m_processor = entityValueProcessor; 4474 return entityValueProcessor(parser, nex 4474 return entityValueProcessor(parser, next, end, nextPtr); 4475 } 4475 } 4476 /* If we are at the end of the buffer, th 4476 /* If we are at the end of the buffer, this would cause XmlPrologTok to 4477 return XML_TOK_NONE on the next call, 4477 return XML_TOK_NONE on the next call, which would then cause the 4478 function to exit with *nextPtr set to 4478 function to exit with *nextPtr set to s - that is what we want for other 4479 tokens, but not for the BOM - we would 4479 tokens, but not for the BOM - we would rather like to skip it; 4480 then, when this routine is entered the 4480 then, when this routine is entered the next time, XmlPrologTok will 4481 return XML_TOK_INVALID, since the BOM 4481 return XML_TOK_INVALID, since the BOM is still in the buffer 4482 */ 4482 */ 4483 else if (tok == XML_TOK_BOM && next == en 4483 else if (tok == XML_TOK_BOM && next == end 4484 && ! parser->m_parsingStatus.fin 4484 && ! parser->m_parsingStatus.finalBuffer) { 4485 # ifdef XML_DTD 4485 # ifdef XML_DTD 4486 if (! accountingDiffTolerated(parser, t 4486 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 4487 XML_ACCOU 4487 XML_ACCOUNT_DIRECT)) { 4488 accountingOnAbort(parser); 4488 accountingOnAbort(parser); 4489 return XML_ERROR_AMPLIFICATION_LIMIT_ 4489 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4490 } 4490 } 4491 # endif 4491 # endif 4492 4492 4493 *nextPtr = next; 4493 *nextPtr = next; 4494 return XML_ERROR_NONE; 4494 return XML_ERROR_NONE; 4495 } 4495 } 4496 /* If we get this token, we have the star 4496 /* If we get this token, we have the start of what might be a 4497 normal tag, but not a declaration (i.e 4497 normal tag, but not a declaration (i.e. it doesn't begin with 4498 "<!"). In a DTD context, that isn't l 4498 "<!"). In a DTD context, that isn't legal. 4499 */ 4499 */ 4500 else if (tok == XML_TOK_INSTANCE_START) { 4500 else if (tok == XML_TOK_INSTANCE_START) { 4501 *nextPtr = next; 4501 *nextPtr = next; 4502 return XML_ERROR_SYNTAX; 4502 return XML_ERROR_SYNTAX; 4503 } 4503 } 4504 start = next; 4504 start = next; 4505 parser->m_eventPtr = start; 4505 parser->m_eventPtr = start; 4506 } 4506 } 4507 } 4507 } 4508 4508 4509 static enum XML_Error PTRCALL 4509 static enum XML_Error PTRCALL 4510 externalParEntProcessor(XML_Parser parser, co 4510 externalParEntProcessor(XML_Parser parser, const char *s, const char *end, 4511 const char **nextPtr) 4511 const char **nextPtr) { 4512 const char *next = s; 4512 const char *next = s; 4513 int tok; 4513 int tok; 4514 4514 4515 tok = XmlPrologTok(parser->m_encoding, s, e 4515 tok = XmlPrologTok(parser->m_encoding, s, end, &next); 4516 if (tok <= 0) { 4516 if (tok <= 0) { 4517 if (! parser->m_parsingStatus.finalBuffer 4517 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { 4518 *nextPtr = s; 4518 *nextPtr = s; 4519 return XML_ERROR_NONE; 4519 return XML_ERROR_NONE; 4520 } 4520 } 4521 switch (tok) { 4521 switch (tok) { 4522 case XML_TOK_INVALID: 4522 case XML_TOK_INVALID: 4523 return XML_ERROR_INVALID_TOKEN; 4523 return XML_ERROR_INVALID_TOKEN; 4524 case XML_TOK_PARTIAL: 4524 case XML_TOK_PARTIAL: 4525 return XML_ERROR_UNCLOSED_TOKEN; 4525 return XML_ERROR_UNCLOSED_TOKEN; 4526 case XML_TOK_PARTIAL_CHAR: 4526 case XML_TOK_PARTIAL_CHAR: 4527 return XML_ERROR_PARTIAL_CHAR; 4527 return XML_ERROR_PARTIAL_CHAR; 4528 case XML_TOK_NONE: /* start == end */ 4528 case XML_TOK_NONE: /* start == end */ 4529 default: 4529 default: 4530 break; 4530 break; 4531 } 4531 } 4532 } 4532 } 4533 /* This would cause the next stage, i.e. do 4533 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. 4534 However, when parsing an external subset 4534 However, when parsing an external subset, doProlog will not accept a BOM 4535 as valid, and report a syntax error, so 4535 as valid, and report a syntax error, so we have to skip the BOM, and 4536 account for the BOM bytes. 4536 account for the BOM bytes. 4537 */ 4537 */ 4538 else if (tok == XML_TOK_BOM) { 4538 else if (tok == XML_TOK_BOM) { 4539 if (! accountingDiffTolerated(parser, tok 4539 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 4540 XML_ACCOUNT 4540 XML_ACCOUNT_DIRECT)) { 4541 accountingOnAbort(parser); 4541 accountingOnAbort(parser); 4542 return XML_ERROR_AMPLIFICATION_LIMIT_BR 4542 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4543 } 4543 } 4544 4544 4545 s = next; 4545 s = next; 4546 tok = XmlPrologTok(parser->m_encoding, s, 4546 tok = XmlPrologTok(parser->m_encoding, s, end, &next); 4547 } 4547 } 4548 4548 4549 parser->m_processor = prologProcessor; 4549 parser->m_processor = prologProcessor; 4550 return doProlog(parser, parser->m_encoding, 4550 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 4551 (XML_Bool)! parser->m_parsi 4551 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 4552 XML_ACCOUNT_DIRECT); 4552 XML_ACCOUNT_DIRECT); 4553 } 4553 } 4554 4554 4555 static enum XML_Error PTRCALL 4555 static enum XML_Error PTRCALL 4556 entityValueProcessor(XML_Parser parser, const 4556 entityValueProcessor(XML_Parser parser, const char *s, const char *end, 4557 const char **nextPtr) { 4557 const char **nextPtr) { 4558 const char *start = s; 4558 const char *start = s; 4559 const char *next = s; 4559 const char *next = s; 4560 const ENCODING *enc = parser->m_encoding; 4560 const ENCODING *enc = parser->m_encoding; 4561 int tok; 4561 int tok; 4562 4562 4563 for (;;) { 4563 for (;;) { 4564 tok = XmlPrologTok(enc, start, end, &next 4564 tok = XmlPrologTok(enc, start, end, &next); 4565 /* Note: These bytes are accounted later 4565 /* Note: These bytes are accounted later in: 4566 - storeEntityValue 4566 - storeEntityValue 4567 */ 4567 */ 4568 if (tok <= 0) { 4568 if (tok <= 0) { 4569 if (! parser->m_parsingStatus.finalBuff 4569 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) { 4570 *nextPtr = s; 4570 *nextPtr = s; 4571 return XML_ERROR_NONE; 4571 return XML_ERROR_NONE; 4572 } 4572 } 4573 switch (tok) { 4573 switch (tok) { 4574 case XML_TOK_INVALID: 4574 case XML_TOK_INVALID: 4575 return XML_ERROR_INVALID_TOKEN; 4575 return XML_ERROR_INVALID_TOKEN; 4576 case XML_TOK_PARTIAL: 4576 case XML_TOK_PARTIAL: 4577 return XML_ERROR_UNCLOSED_TOKEN; 4577 return XML_ERROR_UNCLOSED_TOKEN; 4578 case XML_TOK_PARTIAL_CHAR: 4578 case XML_TOK_PARTIAL_CHAR: 4579 return XML_ERROR_PARTIAL_CHAR; 4579 return XML_ERROR_PARTIAL_CHAR; 4580 case XML_TOK_NONE: /* start == end */ 4580 case XML_TOK_NONE: /* start == end */ 4581 default: 4581 default: 4582 break; 4582 break; 4583 } 4583 } 4584 /* found end of entity value - can stor 4584 /* found end of entity value - can store it now */ 4585 return storeEntityValue(parser, enc, s, 4585 return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT); 4586 } 4586 } 4587 start = next; 4587 start = next; 4588 } 4588 } 4589 } 4589 } 4590 4590 4591 #endif /* XML_DTD */ 4591 #endif /* XML_DTD */ 4592 4592 4593 static enum XML_Error PTRCALL 4593 static enum XML_Error PTRCALL 4594 prologProcessor(XML_Parser parser, const char 4594 prologProcessor(XML_Parser parser, const char *s, const char *end, 4595 const char **nextPtr) { 4595 const char **nextPtr) { 4596 const char *next = s; 4596 const char *next = s; 4597 int tok = XmlPrologTok(parser->m_encoding, 4597 int tok = XmlPrologTok(parser->m_encoding, s, end, &next); 4598 return doProlog(parser, parser->m_encoding, 4598 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 4599 (XML_Bool)! parser->m_parsi 4599 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 4600 XML_ACCOUNT_DIRECT); 4600 XML_ACCOUNT_DIRECT); 4601 } 4601 } 4602 4602 4603 static enum XML_Error 4603 static enum XML_Error 4604 doProlog(XML_Parser parser, const ENCODING *e 4604 doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end, 4605 int tok, const char *next, const cha 4605 int tok, const char *next, const char **nextPtr, XML_Bool haveMore, 4606 XML_Bool allowClosingDoctype, enum X 4606 XML_Bool allowClosingDoctype, enum XML_Account account) { 4607 #ifdef XML_DTD 4607 #ifdef XML_DTD 4608 static const XML_Char externalSubsetName[] 4608 static const XML_Char externalSubsetName[] = {ASCII_HASH, '\0'}; 4609 #endif /* XML_DTD */ 4609 #endif /* XML_DTD */ 4610 static const XML_Char atypeCDATA[] 4610 static const XML_Char atypeCDATA[] 4611 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, 4611 = {ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0'}; 4612 static const XML_Char atypeID[] = {ASCII_I, 4612 static const XML_Char atypeID[] = {ASCII_I, ASCII_D, '\0'}; 4613 static const XML_Char atypeIDREF[] 4613 static const XML_Char atypeIDREF[] 4614 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, 4614 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0'}; 4615 static const XML_Char atypeIDREFS[] 4615 static const XML_Char atypeIDREFS[] 4616 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, 4616 = {ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0'}; 4617 static const XML_Char atypeENTITY[] 4617 static const XML_Char atypeENTITY[] 4618 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, 4618 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0'}; 4619 static const XML_Char atypeENTITIES[] 4619 static const XML_Char atypeENTITIES[] 4620 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, 4620 = {ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, 4621 ASCII_I, ASCII_E, ASCII_S, '\0'}; 4621 ASCII_I, ASCII_E, ASCII_S, '\0'}; 4622 static const XML_Char atypeNMTOKEN[] 4622 static const XML_Char atypeNMTOKEN[] 4623 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, 4623 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0'}; 4624 static const XML_Char atypeNMTOKENS[] 4624 static const XML_Char atypeNMTOKENS[] 4625 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, 4625 = {ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, 4626 ASCII_E, ASCII_N, ASCII_S, '\0'}; 4626 ASCII_E, ASCII_N, ASCII_S, '\0'}; 4627 static const XML_Char notationPrefix[] 4627 static const XML_Char notationPrefix[] 4628 = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, 4628 = {ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, 4629 ASCII_I, ASCII_O, ASCII_N, ASCII_LPA 4629 ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0'}; 4630 static const XML_Char enumValueSep[] = {ASC 4630 static const XML_Char enumValueSep[] = {ASCII_PIPE, '\0'}; 4631 static const XML_Char enumValueStart[] = {A 4631 static const XML_Char enumValueStart[] = {ASCII_LPAREN, '\0'}; 4632 4632 4633 #ifndef XML_DTD 4633 #ifndef XML_DTD 4634 UNUSED_P(account); 4634 UNUSED_P(account); 4635 #endif 4635 #endif 4636 4636 4637 /* save one level of indirection */ 4637 /* save one level of indirection */ 4638 DTD *const dtd = parser->m_dtd; 4638 DTD *const dtd = parser->m_dtd; 4639 4639 4640 const char **eventPP; 4640 const char **eventPP; 4641 const char **eventEndPP; 4641 const char **eventEndPP; 4642 enum XML_Content_Quant quant; 4642 enum XML_Content_Quant quant; 4643 4643 4644 if (enc == parser->m_encoding) { 4644 if (enc == parser->m_encoding) { 4645 eventPP = &parser->m_eventPtr; 4645 eventPP = &parser->m_eventPtr; 4646 eventEndPP = &parser->m_eventEndPtr; 4646 eventEndPP = &parser->m_eventEndPtr; 4647 } else { 4647 } else { 4648 eventPP = &(parser->m_openInternalEntitie 4648 eventPP = &(parser->m_openInternalEntities->internalEventPtr); 4649 eventEndPP = &(parser->m_openInternalEnti 4649 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 4650 } 4650 } 4651 4651 4652 for (;;) { 4652 for (;;) { 4653 int role; 4653 int role; 4654 XML_Bool handleDefault = XML_TRUE; 4654 XML_Bool handleDefault = XML_TRUE; 4655 *eventPP = s; 4655 *eventPP = s; 4656 *eventEndPP = next; 4656 *eventEndPP = next; 4657 if (tok <= 0) { 4657 if (tok <= 0) { 4658 if (haveMore && tok != XML_TOK_INVALID) 4658 if (haveMore && tok != XML_TOK_INVALID) { 4659 *nextPtr = s; 4659 *nextPtr = s; 4660 return XML_ERROR_NONE; 4660 return XML_ERROR_NONE; 4661 } 4661 } 4662 switch (tok) { 4662 switch (tok) { 4663 case XML_TOK_INVALID: 4663 case XML_TOK_INVALID: 4664 *eventPP = next; 4664 *eventPP = next; 4665 return XML_ERROR_INVALID_TOKEN; 4665 return XML_ERROR_INVALID_TOKEN; 4666 case XML_TOK_PARTIAL: 4666 case XML_TOK_PARTIAL: 4667 return XML_ERROR_UNCLOSED_TOKEN; 4667 return XML_ERROR_UNCLOSED_TOKEN; 4668 case XML_TOK_PARTIAL_CHAR: 4668 case XML_TOK_PARTIAL_CHAR: 4669 return XML_ERROR_PARTIAL_CHAR; 4669 return XML_ERROR_PARTIAL_CHAR; 4670 case -XML_TOK_PROLOG_S: 4670 case -XML_TOK_PROLOG_S: 4671 tok = -tok; 4671 tok = -tok; 4672 break; 4672 break; 4673 case XML_TOK_NONE: 4673 case XML_TOK_NONE: 4674 #ifdef XML_DTD 4674 #ifdef XML_DTD 4675 /* for internal PE NOT referenced bet 4675 /* for internal PE NOT referenced between declarations */ 4676 if (enc != parser->m_encoding 4676 if (enc != parser->m_encoding 4677 && ! parser->m_openInternalEntiti 4677 && ! parser->m_openInternalEntities->betweenDecl) { 4678 *nextPtr = s; 4678 *nextPtr = s; 4679 return XML_ERROR_NONE; 4679 return XML_ERROR_NONE; 4680 } 4680 } 4681 /* WFC: PE Between Declarations - mus 4681 /* WFC: PE Between Declarations - must check that PE contains 4682 complete markup, not only for exte 4682 complete markup, not only for external PEs, but also for 4683 internal PEs if the reference occu 4683 internal PEs if the reference occurs between declarations. 4684 */ 4684 */ 4685 if (parser->m_isParamEntity || enc != 4685 if (parser->m_isParamEntity || enc != parser->m_encoding) { 4686 if (XmlTokenRole(&parser->m_prologS 4686 if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc) 4687 == XML_ROLE_ERROR) 4687 == XML_ROLE_ERROR) 4688 return XML_ERROR_INCOMPLETE_PE; 4688 return XML_ERROR_INCOMPLETE_PE; 4689 *nextPtr = s; 4689 *nextPtr = s; 4690 return XML_ERROR_NONE; 4690 return XML_ERROR_NONE; 4691 } 4691 } 4692 #endif /* XML_DTD */ 4692 #endif /* XML_DTD */ 4693 return XML_ERROR_NO_ELEMENTS; 4693 return XML_ERROR_NO_ELEMENTS; 4694 default: 4694 default: 4695 tok = -tok; 4695 tok = -tok; 4696 next = end; 4696 next = end; 4697 break; 4697 break; 4698 } 4698 } 4699 } 4699 } 4700 role = XmlTokenRole(&parser->m_prologStat 4700 role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc); 4701 #ifdef XML_DTD 4701 #ifdef XML_DTD 4702 switch (role) { 4702 switch (role) { 4703 case XML_ROLE_INSTANCE_START: // bytes ac 4703 case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor 4704 case XML_ROLE_XML_DECL: // bytes ac 4704 case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl 4705 case XML_ROLE_TEXT_DECL: // bytes ac 4705 case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl 4706 break; 4706 break; 4707 default: 4707 default: 4708 if (! accountingDiffTolerated(parser, t 4708 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) { 4709 accountingOnAbort(parser); 4709 accountingOnAbort(parser); 4710 return XML_ERROR_AMPLIFICATION_LIMIT_ 4710 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 4711 } 4711 } 4712 } 4712 } 4713 #endif 4713 #endif 4714 switch (role) { 4714 switch (role) { 4715 case XML_ROLE_XML_DECL: { 4715 case XML_ROLE_XML_DECL: { 4716 enum XML_Error result = processXmlDecl( 4716 enum XML_Error result = processXmlDecl(parser, 0, s, next); 4717 if (result != XML_ERROR_NONE) 4717 if (result != XML_ERROR_NONE) 4718 return result; 4718 return result; 4719 enc = parser->m_encoding; 4719 enc = parser->m_encoding; 4720 handleDefault = XML_FALSE; 4720 handleDefault = XML_FALSE; 4721 } break; 4721 } break; 4722 case XML_ROLE_DOCTYPE_NAME: 4722 case XML_ROLE_DOCTYPE_NAME: 4723 if (parser->m_startDoctypeDeclHandler) 4723 if (parser->m_startDoctypeDeclHandler) { 4724 parser->m_doctypeName 4724 parser->m_doctypeName 4725 = poolStoreString(&parser->m_temp 4725 = poolStoreString(&parser->m_tempPool, enc, s, next); 4726 if (! parser->m_doctypeName) 4726 if (! parser->m_doctypeName) 4727 return XML_ERROR_NO_MEMORY; 4727 return XML_ERROR_NO_MEMORY; 4728 poolFinish(&parser->m_tempPool); 4728 poolFinish(&parser->m_tempPool); 4729 parser->m_doctypePubid = NULL; 4729 parser->m_doctypePubid = NULL; 4730 handleDefault = XML_FALSE; 4730 handleDefault = XML_FALSE; 4731 } 4731 } 4732 parser->m_doctypeSysid = NULL; /* alway 4732 parser->m_doctypeSysid = NULL; /* always initialize to NULL */ 4733 break; 4733 break; 4734 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: 4734 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: 4735 if (parser->m_startDoctypeDeclHandler) 4735 if (parser->m_startDoctypeDeclHandler) { 4736 parser->m_startDoctypeDeclHandler( 4736 parser->m_startDoctypeDeclHandler( 4737 parser->m_handlerArg, parser->m_d 4737 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, 4738 parser->m_doctypePubid, 1); 4738 parser->m_doctypePubid, 1); 4739 parser->m_doctypeName = NULL; 4739 parser->m_doctypeName = NULL; 4740 poolClear(&parser->m_tempPool); 4740 poolClear(&parser->m_tempPool); 4741 handleDefault = XML_FALSE; 4741 handleDefault = XML_FALSE; 4742 } 4742 } 4743 break; 4743 break; 4744 #ifdef XML_DTD 4744 #ifdef XML_DTD 4745 case XML_ROLE_TEXT_DECL: { 4745 case XML_ROLE_TEXT_DECL: { 4746 enum XML_Error result = processXmlDecl( 4746 enum XML_Error result = processXmlDecl(parser, 1, s, next); 4747 if (result != XML_ERROR_NONE) 4747 if (result != XML_ERROR_NONE) 4748 return result; 4748 return result; 4749 enc = parser->m_encoding; 4749 enc = parser->m_encoding; 4750 handleDefault = XML_FALSE; 4750 handleDefault = XML_FALSE; 4751 } break; 4751 } break; 4752 #endif /* XML_DTD */ 4752 #endif /* XML_DTD */ 4753 case XML_ROLE_DOCTYPE_PUBLIC_ID: 4753 case XML_ROLE_DOCTYPE_PUBLIC_ID: 4754 #ifdef XML_DTD 4754 #ifdef XML_DTD 4755 parser->m_useForeignDTD = XML_FALSE; 4755 parser->m_useForeignDTD = XML_FALSE; 4756 parser->m_declEntity = (ENTITY *)lookup 4756 parser->m_declEntity = (ENTITY *)lookup( 4757 parser, &dtd->paramEntities, extern 4757 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); 4758 if (! parser->m_declEntity) 4758 if (! parser->m_declEntity) 4759 return XML_ERROR_NO_MEMORY; 4759 return XML_ERROR_NO_MEMORY; 4760 #endif /* XML_DTD */ 4760 #endif /* XML_DTD */ 4761 dtd->hasParamEntityRefs = XML_TRUE; 4761 dtd->hasParamEntityRefs = XML_TRUE; 4762 if (parser->m_startDoctypeDeclHandler) 4762 if (parser->m_startDoctypeDeclHandler) { 4763 XML_Char *pubId; 4763 XML_Char *pubId; 4764 if (! XmlIsPublicId(enc, s, next, eve 4764 if (! XmlIsPublicId(enc, s, next, eventPP)) 4765 return XML_ERROR_PUBLICID; 4765 return XML_ERROR_PUBLICID; 4766 pubId = poolStoreString(&parser->m_te 4766 pubId = poolStoreString(&parser->m_tempPool, enc, 4767 s + enc->minB 4767 s + enc->minBytesPerChar, 4768 next - enc->m 4768 next - enc->minBytesPerChar); 4769 if (! pubId) 4769 if (! pubId) 4770 return XML_ERROR_NO_MEMORY; 4770 return XML_ERROR_NO_MEMORY; 4771 normalizePublicId(pubId); 4771 normalizePublicId(pubId); 4772 poolFinish(&parser->m_tempPool); 4772 poolFinish(&parser->m_tempPool); 4773 parser->m_doctypePubid = pubId; 4773 parser->m_doctypePubid = pubId; 4774 handleDefault = XML_FALSE; 4774 handleDefault = XML_FALSE; 4775 goto alreadyChecked; 4775 goto alreadyChecked; 4776 } 4776 } 4777 /* fall through */ 4777 /* fall through */ 4778 case XML_ROLE_ENTITY_PUBLIC_ID: 4778 case XML_ROLE_ENTITY_PUBLIC_ID: 4779 if (! XmlIsPublicId(enc, s, next, event 4779 if (! XmlIsPublicId(enc, s, next, eventPP)) 4780 return XML_ERROR_PUBLICID; 4780 return XML_ERROR_PUBLICID; 4781 alreadyChecked: 4781 alreadyChecked: 4782 if (dtd->keepProcessing && parser->m_de 4782 if (dtd->keepProcessing && parser->m_declEntity) { 4783 XML_Char *tem 4783 XML_Char *tem 4784 = poolStoreString(&dtd->pool, enc 4784 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, 4785 next - enc->min 4785 next - enc->minBytesPerChar); 4786 if (! tem) 4786 if (! tem) 4787 return XML_ERROR_NO_MEMORY; 4787 return XML_ERROR_NO_MEMORY; 4788 normalizePublicId(tem); 4788 normalizePublicId(tem); 4789 parser->m_declEntity->publicId = tem; 4789 parser->m_declEntity->publicId = tem; 4790 poolFinish(&dtd->pool); 4790 poolFinish(&dtd->pool); 4791 /* Don't suppress the default handler 4791 /* Don't suppress the default handler if we fell through from 4792 * the XML_ROLE_DOCTYPE_PUBLIC_ID cas 4792 * the XML_ROLE_DOCTYPE_PUBLIC_ID case. 4793 */ 4793 */ 4794 if (parser->m_entityDeclHandler && ro 4794 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID) 4795 handleDefault = XML_FALSE; 4795 handleDefault = XML_FALSE; 4796 } 4796 } 4797 break; 4797 break; 4798 case XML_ROLE_DOCTYPE_CLOSE: 4798 case XML_ROLE_DOCTYPE_CLOSE: 4799 if (allowClosingDoctype != XML_TRUE) { 4799 if (allowClosingDoctype != XML_TRUE) { 4800 /* Must not close doctype from within 4800 /* Must not close doctype from within expanded parameter entities */ 4801 return XML_ERROR_INVALID_TOKEN; 4801 return XML_ERROR_INVALID_TOKEN; 4802 } 4802 } 4803 4803 4804 if (parser->m_doctypeName) { 4804 if (parser->m_doctypeName) { 4805 parser->m_startDoctypeDeclHandler( 4805 parser->m_startDoctypeDeclHandler( 4806 parser->m_handlerArg, parser->m_d 4806 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid, 4807 parser->m_doctypePubid, 0); 4807 parser->m_doctypePubid, 0); 4808 poolClear(&parser->m_tempPool); 4808 poolClear(&parser->m_tempPool); 4809 handleDefault = XML_FALSE; 4809 handleDefault = XML_FALSE; 4810 } 4810 } 4811 /* parser->m_doctypeSysid will be non-N 4811 /* parser->m_doctypeSysid will be non-NULL in the case of a previous 4812 XML_ROLE_DOCTYPE_SYSTEM_ID, even if 4812 XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler 4813 was not set, indicating an external 4813 was not set, indicating an external subset 4814 */ 4814 */ 4815 #ifdef XML_DTD 4815 #ifdef XML_DTD 4816 if (parser->m_doctypeSysid || parser->m 4816 if (parser->m_doctypeSysid || parser->m_useForeignDTD) { 4817 XML_Bool hadParamEntityRefs = dtd->ha 4817 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 4818 dtd->hasParamEntityRefs = XML_TRUE; 4818 dtd->hasParamEntityRefs = XML_TRUE; 4819 if (parser->m_paramEntityParsing 4819 if (parser->m_paramEntityParsing 4820 && parser->m_externalEntityRefHan 4820 && parser->m_externalEntityRefHandler) { 4821 ENTITY *entity = (ENTITY *)lookup(p 4821 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, 4822 e 4822 externalSubsetName, sizeof(ENTITY)); 4823 if (! entity) { 4823 if (! entity) { 4824 /* The external subset name "#" w 4824 /* The external subset name "#" will have already been 4825 * inserted into the hash table a 4825 * inserted into the hash table at the start of the 4826 * external entity parsing, so no 4826 * external entity parsing, so no allocation will happen 4827 * and lookup() cannot fail. 4827 * and lookup() cannot fail. 4828 */ 4828 */ 4829 return XML_ERROR_NO_MEMORY; /* LC 4829 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */ 4830 } 4830 } 4831 if (parser->m_useForeignDTD) 4831 if (parser->m_useForeignDTD) 4832 entity->base = parser->m_curBase; 4832 entity->base = parser->m_curBase; 4833 dtd->paramEntityRead = XML_FALSE; 4833 dtd->paramEntityRead = XML_FALSE; 4834 if (! parser->m_externalEntityRefHa 4834 if (! parser->m_externalEntityRefHandler( 4835 parser->m_externalEntityRef 4835 parser->m_externalEntityRefHandlerArg, 0, entity->base, 4836 entity->systemId, entity->p 4836 entity->systemId, entity->publicId)) 4837 return XML_ERROR_EXTERNAL_ENTITY_ 4837 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 4838 if (dtd->paramEntityRead) { 4838 if (dtd->paramEntityRead) { 4839 if (! dtd->standalone && parser-> 4839 if (! dtd->standalone && parser->m_notStandaloneHandler 4840 && ! parser->m_notStandaloneH 4840 && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) 4841 return XML_ERROR_NOT_STANDALONE 4841 return XML_ERROR_NOT_STANDALONE; 4842 } 4842 } 4843 /* if we didn't read the foreign DT 4843 /* if we didn't read the foreign DTD then this means that there 4844 is no external subset and we mus 4844 is no external subset and we must reset dtd->hasParamEntityRefs 4845 */ 4845 */ 4846 else if (! parser->m_doctypeSysid) 4846 else if (! parser->m_doctypeSysid) 4847 dtd->hasParamEntityRefs = hadPara 4847 dtd->hasParamEntityRefs = hadParamEntityRefs; 4848 /* end of DTD - no need to update d 4848 /* end of DTD - no need to update dtd->keepProcessing */ 4849 } 4849 } 4850 parser->m_useForeignDTD = XML_FALSE; 4850 parser->m_useForeignDTD = XML_FALSE; 4851 } 4851 } 4852 #endif /* XML_DTD */ 4852 #endif /* XML_DTD */ 4853 if (parser->m_endDoctypeDeclHandler) { 4853 if (parser->m_endDoctypeDeclHandler) { 4854 parser->m_endDoctypeDeclHandler(parse 4854 parser->m_endDoctypeDeclHandler(parser->m_handlerArg); 4855 handleDefault = XML_FALSE; 4855 handleDefault = XML_FALSE; 4856 } 4856 } 4857 break; 4857 break; 4858 case XML_ROLE_INSTANCE_START: 4858 case XML_ROLE_INSTANCE_START: 4859 #ifdef XML_DTD 4859 #ifdef XML_DTD 4860 /* if there is no DOCTYPE declaration t 4860 /* if there is no DOCTYPE declaration then now is the 4861 last chance to read the foreign DTD 4861 last chance to read the foreign DTD 4862 */ 4862 */ 4863 if (parser->m_useForeignDTD) { 4863 if (parser->m_useForeignDTD) { 4864 XML_Bool hadParamEntityRefs = dtd->ha 4864 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; 4865 dtd->hasParamEntityRefs = XML_TRUE; 4865 dtd->hasParamEntityRefs = XML_TRUE; 4866 if (parser->m_paramEntityParsing 4866 if (parser->m_paramEntityParsing 4867 && parser->m_externalEntityRefHan 4867 && parser->m_externalEntityRefHandler) { 4868 ENTITY *entity = (ENTITY *)lookup(p 4868 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities, 4869 e 4869 externalSubsetName, sizeof(ENTITY)); 4870 if (! entity) 4870 if (! entity) 4871 return XML_ERROR_NO_MEMORY; 4871 return XML_ERROR_NO_MEMORY; 4872 entity->base = parser->m_curBase; 4872 entity->base = parser->m_curBase; 4873 dtd->paramEntityRead = XML_FALSE; 4873 dtd->paramEntityRead = XML_FALSE; 4874 if (! parser->m_externalEntityRefHa 4874 if (! parser->m_externalEntityRefHandler( 4875 parser->m_externalEntityRef 4875 parser->m_externalEntityRefHandlerArg, 0, entity->base, 4876 entity->systemId, entity->p 4876 entity->systemId, entity->publicId)) 4877 return XML_ERROR_EXTERNAL_ENTITY_ 4877 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 4878 if (dtd->paramEntityRead) { 4878 if (dtd->paramEntityRead) { 4879 if (! dtd->standalone && parser-> 4879 if (! dtd->standalone && parser->m_notStandaloneHandler 4880 && ! parser->m_notStandaloneH 4880 && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) 4881 return XML_ERROR_NOT_STANDALONE 4881 return XML_ERROR_NOT_STANDALONE; 4882 } 4882 } 4883 /* if we didn't read the foreign DT 4883 /* if we didn't read the foreign DTD then this means that there 4884 is no external subset and we mus 4884 is no external subset and we must reset dtd->hasParamEntityRefs 4885 */ 4885 */ 4886 else 4886 else 4887 dtd->hasParamEntityRefs = hadPara 4887 dtd->hasParamEntityRefs = hadParamEntityRefs; 4888 /* end of DTD - no need to update d 4888 /* end of DTD - no need to update dtd->keepProcessing */ 4889 } 4889 } 4890 } 4890 } 4891 #endif /* XML_DTD */ 4891 #endif /* XML_DTD */ 4892 parser->m_processor = contentProcessor; 4892 parser->m_processor = contentProcessor; 4893 return contentProcessor(parser, s, end, 4893 return contentProcessor(parser, s, end, nextPtr); 4894 case XML_ROLE_ATTLIST_ELEMENT_NAME: 4894 case XML_ROLE_ATTLIST_ELEMENT_NAME: 4895 parser->m_declElementType = getElementT 4895 parser->m_declElementType = getElementType(parser, enc, s, next); 4896 if (! parser->m_declElementType) 4896 if (! parser->m_declElementType) 4897 return XML_ERROR_NO_MEMORY; 4897 return XML_ERROR_NO_MEMORY; 4898 goto checkAttListDeclHandler; 4898 goto checkAttListDeclHandler; 4899 case XML_ROLE_ATTRIBUTE_NAME: 4899 case XML_ROLE_ATTRIBUTE_NAME: 4900 parser->m_declAttributeId = getAttribut 4900 parser->m_declAttributeId = getAttributeId(parser, enc, s, next); 4901 if (! parser->m_declAttributeId) 4901 if (! parser->m_declAttributeId) 4902 return XML_ERROR_NO_MEMORY; 4902 return XML_ERROR_NO_MEMORY; 4903 parser->m_declAttributeIsCdata = XML_FA 4903 parser->m_declAttributeIsCdata = XML_FALSE; 4904 parser->m_declAttributeType = NULL; 4904 parser->m_declAttributeType = NULL; 4905 parser->m_declAttributeIsId = XML_FALSE 4905 parser->m_declAttributeIsId = XML_FALSE; 4906 goto checkAttListDeclHandler; 4906 goto checkAttListDeclHandler; 4907 case XML_ROLE_ATTRIBUTE_TYPE_CDATA: 4907 case XML_ROLE_ATTRIBUTE_TYPE_CDATA: 4908 parser->m_declAttributeIsCdata = XML_TR 4908 parser->m_declAttributeIsCdata = XML_TRUE; 4909 parser->m_declAttributeType = atypeCDAT 4909 parser->m_declAttributeType = atypeCDATA; 4910 goto checkAttListDeclHandler; 4910 goto checkAttListDeclHandler; 4911 case XML_ROLE_ATTRIBUTE_TYPE_ID: 4911 case XML_ROLE_ATTRIBUTE_TYPE_ID: 4912 parser->m_declAttributeIsId = XML_TRUE; 4912 parser->m_declAttributeIsId = XML_TRUE; 4913 parser->m_declAttributeType = atypeID; 4913 parser->m_declAttributeType = atypeID; 4914 goto checkAttListDeclHandler; 4914 goto checkAttListDeclHandler; 4915 case XML_ROLE_ATTRIBUTE_TYPE_IDREF: 4915 case XML_ROLE_ATTRIBUTE_TYPE_IDREF: 4916 parser->m_declAttributeType = atypeIDRE 4916 parser->m_declAttributeType = atypeIDREF; 4917 goto checkAttListDeclHandler; 4917 goto checkAttListDeclHandler; 4918 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: 4918 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: 4919 parser->m_declAttributeType = atypeIDRE 4919 parser->m_declAttributeType = atypeIDREFS; 4920 goto checkAttListDeclHandler; 4920 goto checkAttListDeclHandler; 4921 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: 4921 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: 4922 parser->m_declAttributeType = atypeENTI 4922 parser->m_declAttributeType = atypeENTITY; 4923 goto checkAttListDeclHandler; 4923 goto checkAttListDeclHandler; 4924 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: 4924 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: 4925 parser->m_declAttributeType = atypeENTI 4925 parser->m_declAttributeType = atypeENTITIES; 4926 goto checkAttListDeclHandler; 4926 goto checkAttListDeclHandler; 4927 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: 4927 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: 4928 parser->m_declAttributeType = atypeNMTO 4928 parser->m_declAttributeType = atypeNMTOKEN; 4929 goto checkAttListDeclHandler; 4929 goto checkAttListDeclHandler; 4930 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: 4930 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: 4931 parser->m_declAttributeType = atypeNMTO 4931 parser->m_declAttributeType = atypeNMTOKENS; 4932 checkAttListDeclHandler: 4932 checkAttListDeclHandler: 4933 if (dtd->keepProcessing && parser->m_at 4933 if (dtd->keepProcessing && parser->m_attlistDeclHandler) 4934 handleDefault = XML_FALSE; 4934 handleDefault = XML_FALSE; 4935 break; 4935 break; 4936 case XML_ROLE_ATTRIBUTE_ENUM_VALUE: 4936 case XML_ROLE_ATTRIBUTE_ENUM_VALUE: 4937 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: 4937 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: 4938 if (dtd->keepProcessing && parser->m_at 4938 if (dtd->keepProcessing && parser->m_attlistDeclHandler) { 4939 const XML_Char *prefix; 4939 const XML_Char *prefix; 4940 if (parser->m_declAttributeType) { 4940 if (parser->m_declAttributeType) { 4941 prefix = enumValueSep; 4941 prefix = enumValueSep; 4942 } else { 4942 } else { 4943 prefix = (role == XML_ROLE_ATTRIBUT 4943 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix 4944 4944 : enumValueStart); 4945 } 4945 } 4946 if (! poolAppendString(&parser->m_tem 4946 if (! poolAppendString(&parser->m_tempPool, prefix)) 4947 return XML_ERROR_NO_MEMORY; 4947 return XML_ERROR_NO_MEMORY; 4948 if (! poolAppend(&parser->m_tempPool, 4948 if (! poolAppend(&parser->m_tempPool, enc, s, next)) 4949 return XML_ERROR_NO_MEMORY; 4949 return XML_ERROR_NO_MEMORY; 4950 parser->m_declAttributeType = parser- 4950 parser->m_declAttributeType = parser->m_tempPool.start; 4951 handleDefault = XML_FALSE; 4951 handleDefault = XML_FALSE; 4952 } 4952 } 4953 break; 4953 break; 4954 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: 4954 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: 4955 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: 4955 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: 4956 if (dtd->keepProcessing) { 4956 if (dtd->keepProcessing) { 4957 if (! defineAttribute(parser->m_declE 4957 if (! defineAttribute(parser->m_declElementType, 4958 parser->m_declA 4958 parser->m_declAttributeId, 4959 parser->m_declA 4959 parser->m_declAttributeIsCdata, 4960 parser->m_declA 4960 parser->m_declAttributeIsId, 0, parser)) 4961 return XML_ERROR_NO_MEMORY; 4961 return XML_ERROR_NO_MEMORY; 4962 if (parser->m_attlistDeclHandler && p 4962 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { 4963 if (*parser->m_declAttributeType == 4963 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) 4964 || (*parser->m_declAttributeTyp 4964 || (*parser->m_declAttributeType == XML_T(ASCII_N) 4965 && parser->m_declAttributeT 4965 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { 4966 /* Enumerated or Notation type */ 4966 /* Enumerated or Notation type */ 4967 if (! poolAppendChar(&parser->m_t 4967 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) 4968 || ! poolAppendChar(&parser-> 4968 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 4969 return XML_ERROR_NO_MEMORY; 4969 return XML_ERROR_NO_MEMORY; 4970 parser->m_declAttributeType = par 4970 parser->m_declAttributeType = parser->m_tempPool.start; 4971 poolFinish(&parser->m_tempPool); 4971 poolFinish(&parser->m_tempPool); 4972 } 4972 } 4973 *eventEndPP = s; 4973 *eventEndPP = s; 4974 parser->m_attlistDeclHandler( 4974 parser->m_attlistDeclHandler( 4975 parser->m_handlerArg, parser->m 4975 parser->m_handlerArg, parser->m_declElementType->name, 4976 parser->m_declAttributeId->name 4976 parser->m_declAttributeId->name, parser->m_declAttributeType, 0, 4977 role == XML_ROLE_REQUIRED_ATTRI 4977 role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); 4978 poolClear(&parser->m_tempPool); 4978 poolClear(&parser->m_tempPool); 4979 handleDefault = XML_FALSE; 4979 handleDefault = XML_FALSE; 4980 } 4980 } 4981 } 4981 } 4982 break; 4982 break; 4983 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: 4983 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: 4984 case XML_ROLE_FIXED_ATTRIBUTE_VALUE: 4984 case XML_ROLE_FIXED_ATTRIBUTE_VALUE: 4985 if (dtd->keepProcessing) { 4985 if (dtd->keepProcessing) { 4986 const XML_Char *attVal; 4986 const XML_Char *attVal; 4987 enum XML_Error result = storeAttribut 4987 enum XML_Error result = storeAttributeValue( 4988 parser, enc, parser->m_declAttrib 4988 parser, enc, parser->m_declAttributeIsCdata, 4989 s + enc->minBytesPerChar, next - 4989 s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool, 4990 XML_ACCOUNT_NONE); 4990 XML_ACCOUNT_NONE); 4991 if (result) 4991 if (result) 4992 return result; 4992 return result; 4993 attVal = poolStart(&dtd->pool); 4993 attVal = poolStart(&dtd->pool); 4994 poolFinish(&dtd->pool); 4994 poolFinish(&dtd->pool); 4995 /* ID attributes aren't allowed to ha 4995 /* ID attributes aren't allowed to have a default */ 4996 if (! defineAttribute( 4996 if (! defineAttribute( 4997 parser->m_declElementType, pa 4997 parser->m_declElementType, parser->m_declAttributeId, 4998 parser->m_declAttributeIsCdat 4998 parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser)) 4999 return XML_ERROR_NO_MEMORY; 4999 return XML_ERROR_NO_MEMORY; 5000 if (parser->m_attlistDeclHandler && p 5000 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) { 5001 if (*parser->m_declAttributeType == 5001 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN) 5002 || (*parser->m_declAttributeTyp 5002 || (*parser->m_declAttributeType == XML_T(ASCII_N) 5003 && parser->m_declAttributeT 5003 && parser->m_declAttributeType[1] == XML_T(ASCII_O))) { 5004 /* Enumerated or Notation type */ 5004 /* Enumerated or Notation type */ 5005 if (! poolAppendChar(&parser->m_t 5005 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)) 5006 || ! poolAppendChar(&parser-> 5006 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 5007 return XML_ERROR_NO_MEMORY; 5007 return XML_ERROR_NO_MEMORY; 5008 parser->m_declAttributeType = par 5008 parser->m_declAttributeType = parser->m_tempPool.start; 5009 poolFinish(&parser->m_tempPool); 5009 poolFinish(&parser->m_tempPool); 5010 } 5010 } 5011 *eventEndPP = s; 5011 *eventEndPP = s; 5012 parser->m_attlistDeclHandler( 5012 parser->m_attlistDeclHandler( 5013 parser->m_handlerArg, parser->m 5013 parser->m_handlerArg, parser->m_declElementType->name, 5014 parser->m_declAttributeId->name 5014 parser->m_declAttributeId->name, parser->m_declAttributeType, 5015 attVal, role == XML_ROLE_FIXED_ 5015 attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); 5016 poolClear(&parser->m_tempPool); 5016 poolClear(&parser->m_tempPool); 5017 handleDefault = XML_FALSE; 5017 handleDefault = XML_FALSE; 5018 } 5018 } 5019 } 5019 } 5020 break; 5020 break; 5021 case XML_ROLE_ENTITY_VALUE: 5021 case XML_ROLE_ENTITY_VALUE: 5022 if (dtd->keepProcessing) { 5022 if (dtd->keepProcessing) { 5023 enum XML_Error result 5023 enum XML_Error result 5024 = storeEntityValue(parser, enc, s 5024 = storeEntityValue(parser, enc, s + enc->minBytesPerChar, 5025 next - enc->mi 5025 next - enc->minBytesPerChar, XML_ACCOUNT_NONE); 5026 if (parser->m_declEntity) { 5026 if (parser->m_declEntity) { 5027 parser->m_declEntity->textPtr = poo 5027 parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool); 5028 parser->m_declEntity->textLen 5028 parser->m_declEntity->textLen 5029 = (int)(poolLength(&dtd->entity 5029 = (int)(poolLength(&dtd->entityValuePool)); 5030 poolFinish(&dtd->entityValuePool); 5030 poolFinish(&dtd->entityValuePool); 5031 if (parser->m_entityDeclHandler) { 5031 if (parser->m_entityDeclHandler) { 5032 *eventEndPP = s; 5032 *eventEndPP = s; 5033 parser->m_entityDeclHandler( 5033 parser->m_entityDeclHandler( 5034 parser->m_handlerArg, parser- 5034 parser->m_handlerArg, parser->m_declEntity->name, 5035 parser->m_declEntity->is_para 5035 parser->m_declEntity->is_param, parser->m_declEntity->textPtr, 5036 parser->m_declEntity->textLen 5036 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0); 5037 handleDefault = XML_FALSE; 5037 handleDefault = XML_FALSE; 5038 } 5038 } 5039 } else 5039 } else 5040 poolDiscard(&dtd->entityValuePool); 5040 poolDiscard(&dtd->entityValuePool); 5041 if (result != XML_ERROR_NONE) 5041 if (result != XML_ERROR_NONE) 5042 return result; 5042 return result; 5043 } 5043 } 5044 break; 5044 break; 5045 case XML_ROLE_DOCTYPE_SYSTEM_ID: 5045 case XML_ROLE_DOCTYPE_SYSTEM_ID: 5046 #ifdef XML_DTD 5046 #ifdef XML_DTD 5047 parser->m_useForeignDTD = XML_FALSE; 5047 parser->m_useForeignDTD = XML_FALSE; 5048 #endif /* XML_DTD */ 5048 #endif /* XML_DTD */ 5049 dtd->hasParamEntityRefs = XML_TRUE; 5049 dtd->hasParamEntityRefs = XML_TRUE; 5050 if (parser->m_startDoctypeDeclHandler) 5050 if (parser->m_startDoctypeDeclHandler) { 5051 parser->m_doctypeSysid = poolStoreStr 5051 parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc, 5052 5052 s + enc->minBytesPerChar, 5053 5053 next - enc->minBytesPerChar); 5054 if (parser->m_doctypeSysid == NULL) 5054 if (parser->m_doctypeSysid == NULL) 5055 return XML_ERROR_NO_MEMORY; 5055 return XML_ERROR_NO_MEMORY; 5056 poolFinish(&parser->m_tempPool); 5056 poolFinish(&parser->m_tempPool); 5057 handleDefault = XML_FALSE; 5057 handleDefault = XML_FALSE; 5058 } 5058 } 5059 #ifdef XML_DTD 5059 #ifdef XML_DTD 5060 else 5060 else 5061 /* use externalSubsetName to make par 5061 /* use externalSubsetName to make parser->m_doctypeSysid non-NULL 5062 for the case where no parser->m_st 5062 for the case where no parser->m_startDoctypeDeclHandler is set */ 5063 parser->m_doctypeSysid = externalSubs 5063 parser->m_doctypeSysid = externalSubsetName; 5064 #endif /* XML_DTD */ 5064 #endif /* XML_DTD */ 5065 if (! dtd->standalone 5065 if (! dtd->standalone 5066 #ifdef XML_DTD 5066 #ifdef XML_DTD 5067 && ! parser->m_paramEntityParsing 5067 && ! parser->m_paramEntityParsing 5068 #endif /* XML_DTD */ 5068 #endif /* XML_DTD */ 5069 && parser->m_notStandaloneHandler 5069 && parser->m_notStandaloneHandler 5070 && ! parser->m_notStandaloneHandler 5070 && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) 5071 return XML_ERROR_NOT_STANDALONE; 5071 return XML_ERROR_NOT_STANDALONE; 5072 #ifndef XML_DTD 5072 #ifndef XML_DTD 5073 break; 5073 break; 5074 #else /* XML_DTD */ 5074 #else /* XML_DTD */ 5075 if (! parser->m_declEntity) { 5075 if (! parser->m_declEntity) { 5076 parser->m_declEntity = (ENTITY *)look 5076 parser->m_declEntity = (ENTITY *)lookup( 5077 parser, &dtd->paramEntities, exte 5077 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY)); 5078 if (! parser->m_declEntity) 5078 if (! parser->m_declEntity) 5079 return XML_ERROR_NO_MEMORY; 5079 return XML_ERROR_NO_MEMORY; 5080 parser->m_declEntity->publicId = NULL 5080 parser->m_declEntity->publicId = NULL; 5081 } 5081 } 5082 #endif /* XML_DTD */ 5082 #endif /* XML_DTD */ 5083 /* fall through */ 5083 /* fall through */ 5084 case XML_ROLE_ENTITY_SYSTEM_ID: 5084 case XML_ROLE_ENTITY_SYSTEM_ID: 5085 if (dtd->keepProcessing && parser->m_de 5085 if (dtd->keepProcessing && parser->m_declEntity) { 5086 parser->m_declEntity->systemId 5086 parser->m_declEntity->systemId 5087 = poolStoreString(&dtd->pool, enc 5087 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, 5088 next - enc->min 5088 next - enc->minBytesPerChar); 5089 if (! parser->m_declEntity->systemId) 5089 if (! parser->m_declEntity->systemId) 5090 return XML_ERROR_NO_MEMORY; 5090 return XML_ERROR_NO_MEMORY; 5091 parser->m_declEntity->base = parser-> 5091 parser->m_declEntity->base = parser->m_curBase; 5092 poolFinish(&dtd->pool); 5092 poolFinish(&dtd->pool); 5093 /* Don't suppress the default handler 5093 /* Don't suppress the default handler if we fell through from 5094 * the XML_ROLE_DOCTYPE_SYSTEM_ID cas 5094 * the XML_ROLE_DOCTYPE_SYSTEM_ID case. 5095 */ 5095 */ 5096 if (parser->m_entityDeclHandler && ro 5096 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID) 5097 handleDefault = XML_FALSE; 5097 handleDefault = XML_FALSE; 5098 } 5098 } 5099 break; 5099 break; 5100 case XML_ROLE_ENTITY_COMPLETE: 5100 case XML_ROLE_ENTITY_COMPLETE: 5101 if (dtd->keepProcessing && parser->m_de 5101 if (dtd->keepProcessing && parser->m_declEntity 5102 && parser->m_entityDeclHandler) { 5102 && parser->m_entityDeclHandler) { 5103 *eventEndPP = s; 5103 *eventEndPP = s; 5104 parser->m_entityDeclHandler( 5104 parser->m_entityDeclHandler( 5105 parser->m_handlerArg, parser->m_d 5105 parser->m_handlerArg, parser->m_declEntity->name, 5106 parser->m_declEntity->is_param, 0 5106 parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base, 5107 parser->m_declEntity->systemId, p 5107 parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0); 5108 handleDefault = XML_FALSE; 5108 handleDefault = XML_FALSE; 5109 } 5109 } 5110 break; 5110 break; 5111 case XML_ROLE_ENTITY_NOTATION_NAME: 5111 case XML_ROLE_ENTITY_NOTATION_NAME: 5112 if (dtd->keepProcessing && parser->m_de 5112 if (dtd->keepProcessing && parser->m_declEntity) { 5113 parser->m_declEntity->notation 5113 parser->m_declEntity->notation 5114 = poolStoreString(&dtd->pool, enc 5114 = poolStoreString(&dtd->pool, enc, s, next); 5115 if (! parser->m_declEntity->notation) 5115 if (! parser->m_declEntity->notation) 5116 return XML_ERROR_NO_MEMORY; 5116 return XML_ERROR_NO_MEMORY; 5117 poolFinish(&dtd->pool); 5117 poolFinish(&dtd->pool); 5118 if (parser->m_unparsedEntityDeclHandl 5118 if (parser->m_unparsedEntityDeclHandler) { 5119 *eventEndPP = s; 5119 *eventEndPP = s; 5120 parser->m_unparsedEntityDeclHandler 5120 parser->m_unparsedEntityDeclHandler( 5121 parser->m_handlerArg, parser->m 5121 parser->m_handlerArg, parser->m_declEntity->name, 5122 parser->m_declEntity->base, par 5122 parser->m_declEntity->base, parser->m_declEntity->systemId, 5123 parser->m_declEntity->publicId, 5123 parser->m_declEntity->publicId, parser->m_declEntity->notation); 5124 handleDefault = XML_FALSE; 5124 handleDefault = XML_FALSE; 5125 } else if (parser->m_entityDeclHandle 5125 } else if (parser->m_entityDeclHandler) { 5126 *eventEndPP = s; 5126 *eventEndPP = s; 5127 parser->m_entityDeclHandler( 5127 parser->m_entityDeclHandler( 5128 parser->m_handlerArg, parser->m 5128 parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0, 5129 parser->m_declEntity->base, par 5129 parser->m_declEntity->base, parser->m_declEntity->systemId, 5130 parser->m_declEntity->publicId, 5130 parser->m_declEntity->publicId, parser->m_declEntity->notation); 5131 handleDefault = XML_FALSE; 5131 handleDefault = XML_FALSE; 5132 } 5132 } 5133 } 5133 } 5134 break; 5134 break; 5135 case XML_ROLE_GENERAL_ENTITY_NAME: { 5135 case XML_ROLE_GENERAL_ENTITY_NAME: { 5136 if (XmlPredefinedEntityName(enc, s, nex 5136 if (XmlPredefinedEntityName(enc, s, next)) { 5137 parser->m_declEntity = NULL; 5137 parser->m_declEntity = NULL; 5138 break; 5138 break; 5139 } 5139 } 5140 if (dtd->keepProcessing) { 5140 if (dtd->keepProcessing) { 5141 const XML_Char *name = poolStoreStrin 5141 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); 5142 if (! name) 5142 if (! name) 5143 return XML_ERROR_NO_MEMORY; 5143 return XML_ERROR_NO_MEMORY; 5144 parser->m_declEntity = (ENTITY *)look 5144 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, 5145 5145 name, sizeof(ENTITY)); 5146 if (! parser->m_declEntity) 5146 if (! parser->m_declEntity) 5147 return XML_ERROR_NO_MEMORY; 5147 return XML_ERROR_NO_MEMORY; 5148 if (parser->m_declEntity->name != nam 5148 if (parser->m_declEntity->name != name) { 5149 poolDiscard(&dtd->pool); 5149 poolDiscard(&dtd->pool); 5150 parser->m_declEntity = NULL; 5150 parser->m_declEntity = NULL; 5151 } else { 5151 } else { 5152 poolFinish(&dtd->pool); 5152 poolFinish(&dtd->pool); 5153 parser->m_declEntity->publicId = NU 5153 parser->m_declEntity->publicId = NULL; 5154 parser->m_declEntity->is_param = XM 5154 parser->m_declEntity->is_param = XML_FALSE; 5155 /* if we have a parent parser or ar 5155 /* if we have a parent parser or are reading an internal parameter 5156 entity, then the entity declarat 5156 entity, then the entity declaration is not considered "internal" 5157 */ 5157 */ 5158 parser->m_declEntity->is_internal 5158 parser->m_declEntity->is_internal 5159 = ! (parser->m_parentParser || 5159 = ! (parser->m_parentParser || parser->m_openInternalEntities); 5160 if (parser->m_entityDeclHandler) 5160 if (parser->m_entityDeclHandler) 5161 handleDefault = XML_FALSE; 5161 handleDefault = XML_FALSE; 5162 } 5162 } 5163 } else { 5163 } else { 5164 poolDiscard(&dtd->pool); 5164 poolDiscard(&dtd->pool); 5165 parser->m_declEntity = NULL; 5165 parser->m_declEntity = NULL; 5166 } 5166 } 5167 } break; 5167 } break; 5168 case XML_ROLE_PARAM_ENTITY_NAME: 5168 case XML_ROLE_PARAM_ENTITY_NAME: 5169 #ifdef XML_DTD 5169 #ifdef XML_DTD 5170 if (dtd->keepProcessing) { 5170 if (dtd->keepProcessing) { 5171 const XML_Char *name = poolStoreStrin 5171 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); 5172 if (! name) 5172 if (! name) 5173 return XML_ERROR_NO_MEMORY; 5173 return XML_ERROR_NO_MEMORY; 5174 parser->m_declEntity = (ENTITY *)look 5174 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities, 5175 5175 name, sizeof(ENTITY)); 5176 if (! parser->m_declEntity) 5176 if (! parser->m_declEntity) 5177 return XML_ERROR_NO_MEMORY; 5177 return XML_ERROR_NO_MEMORY; 5178 if (parser->m_declEntity->name != nam 5178 if (parser->m_declEntity->name != name) { 5179 poolDiscard(&dtd->pool); 5179 poolDiscard(&dtd->pool); 5180 parser->m_declEntity = NULL; 5180 parser->m_declEntity = NULL; 5181 } else { 5181 } else { 5182 poolFinish(&dtd->pool); 5182 poolFinish(&dtd->pool); 5183 parser->m_declEntity->publicId = NU 5183 parser->m_declEntity->publicId = NULL; 5184 parser->m_declEntity->is_param = XM 5184 parser->m_declEntity->is_param = XML_TRUE; 5185 /* if we have a parent parser or ar 5185 /* if we have a parent parser or are reading an internal parameter 5186 entity, then the entity declarat 5186 entity, then the entity declaration is not considered "internal" 5187 */ 5187 */ 5188 parser->m_declEntity->is_internal 5188 parser->m_declEntity->is_internal 5189 = ! (parser->m_parentParser || 5189 = ! (parser->m_parentParser || parser->m_openInternalEntities); 5190 if (parser->m_entityDeclHandler) 5190 if (parser->m_entityDeclHandler) 5191 handleDefault = XML_FALSE; 5191 handleDefault = XML_FALSE; 5192 } 5192 } 5193 } else { 5193 } else { 5194 poolDiscard(&dtd->pool); 5194 poolDiscard(&dtd->pool); 5195 parser->m_declEntity = NULL; 5195 parser->m_declEntity = NULL; 5196 } 5196 } 5197 #else /* not XML_DTD */ 5197 #else /* not XML_DTD */ 5198 parser->m_declEntity = NULL; 5198 parser->m_declEntity = NULL; 5199 #endif /* XML_DTD */ 5199 #endif /* XML_DTD */ 5200 break; 5200 break; 5201 case XML_ROLE_NOTATION_NAME: 5201 case XML_ROLE_NOTATION_NAME: 5202 parser->m_declNotationPublicId = NULL; 5202 parser->m_declNotationPublicId = NULL; 5203 parser->m_declNotationName = NULL; 5203 parser->m_declNotationName = NULL; 5204 if (parser->m_notationDeclHandler) { 5204 if (parser->m_notationDeclHandler) { 5205 parser->m_declNotationName 5205 parser->m_declNotationName 5206 = poolStoreString(&parser->m_temp 5206 = poolStoreString(&parser->m_tempPool, enc, s, next); 5207 if (! parser->m_declNotationName) 5207 if (! parser->m_declNotationName) 5208 return XML_ERROR_NO_MEMORY; 5208 return XML_ERROR_NO_MEMORY; 5209 poolFinish(&parser->m_tempPool); 5209 poolFinish(&parser->m_tempPool); 5210 handleDefault = XML_FALSE; 5210 handleDefault = XML_FALSE; 5211 } 5211 } 5212 break; 5212 break; 5213 case XML_ROLE_NOTATION_PUBLIC_ID: 5213 case XML_ROLE_NOTATION_PUBLIC_ID: 5214 if (! XmlIsPublicId(enc, s, next, event 5214 if (! XmlIsPublicId(enc, s, next, eventPP)) 5215 return XML_ERROR_PUBLICID; 5215 return XML_ERROR_PUBLICID; 5216 if (parser 5216 if (parser 5217 ->m_declNotationName) { /* mean 5217 ->m_declNotationName) { /* means m_notationDeclHandler != NULL */ 5218 XML_Char *tem = poolStoreString(&pars 5218 XML_Char *tem = poolStoreString(&parser->m_tempPool, enc, 5219 s + e 5219 s + enc->minBytesPerChar, 5220 next 5220 next - enc->minBytesPerChar); 5221 if (! tem) 5221 if (! tem) 5222 return XML_ERROR_NO_MEMORY; 5222 return XML_ERROR_NO_MEMORY; 5223 normalizePublicId(tem); 5223 normalizePublicId(tem); 5224 parser->m_declNotationPublicId = tem; 5224 parser->m_declNotationPublicId = tem; 5225 poolFinish(&parser->m_tempPool); 5225 poolFinish(&parser->m_tempPool); 5226 handleDefault = XML_FALSE; 5226 handleDefault = XML_FALSE; 5227 } 5227 } 5228 break; 5228 break; 5229 case XML_ROLE_NOTATION_SYSTEM_ID: 5229 case XML_ROLE_NOTATION_SYSTEM_ID: 5230 if (parser->m_declNotationName && parse 5230 if (parser->m_declNotationName && parser->m_notationDeclHandler) { 5231 const XML_Char *systemId = poolStoreS 5231 const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc, 5232 5232 s + enc->minBytesPerChar, 5233 5233 next - enc->minBytesPerChar); 5234 if (! systemId) 5234 if (! systemId) 5235 return XML_ERROR_NO_MEMORY; 5235 return XML_ERROR_NO_MEMORY; 5236 *eventEndPP = s; 5236 *eventEndPP = s; 5237 parser->m_notationDeclHandler( 5237 parser->m_notationDeclHandler( 5238 parser->m_handlerArg, parser->m_d 5238 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, 5239 systemId, parser->m_declNotationP 5239 systemId, parser->m_declNotationPublicId); 5240 handleDefault = XML_FALSE; 5240 handleDefault = XML_FALSE; 5241 } 5241 } 5242 poolClear(&parser->m_tempPool); 5242 poolClear(&parser->m_tempPool); 5243 break; 5243 break; 5244 case XML_ROLE_NOTATION_NO_SYSTEM_ID: 5244 case XML_ROLE_NOTATION_NO_SYSTEM_ID: 5245 if (parser->m_declNotationPublicId && p 5245 if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) { 5246 *eventEndPP = s; 5246 *eventEndPP = s; 5247 parser->m_notationDeclHandler( 5247 parser->m_notationDeclHandler( 5248 parser->m_handlerArg, parser->m_d 5248 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase, 5249 0, parser->m_declNotationPublicId 5249 0, parser->m_declNotationPublicId); 5250 handleDefault = XML_FALSE; 5250 handleDefault = XML_FALSE; 5251 } 5251 } 5252 poolClear(&parser->m_tempPool); 5252 poolClear(&parser->m_tempPool); 5253 break; 5253 break; 5254 case XML_ROLE_ERROR: 5254 case XML_ROLE_ERROR: 5255 switch (tok) { 5255 switch (tok) { 5256 case XML_TOK_PARAM_ENTITY_REF: 5256 case XML_TOK_PARAM_ENTITY_REF: 5257 /* PE references in internal subset a 5257 /* PE references in internal subset are 5258 not allowed within declarations. * 5258 not allowed within declarations. */ 5259 return XML_ERROR_PARAM_ENTITY_REF; 5259 return XML_ERROR_PARAM_ENTITY_REF; 5260 case XML_TOK_XML_DECL: 5260 case XML_TOK_XML_DECL: 5261 return XML_ERROR_MISPLACED_XML_PI; 5261 return XML_ERROR_MISPLACED_XML_PI; 5262 default: 5262 default: 5263 return XML_ERROR_SYNTAX; 5263 return XML_ERROR_SYNTAX; 5264 } 5264 } 5265 #ifdef XML_DTD 5265 #ifdef XML_DTD 5266 case XML_ROLE_IGNORE_SECT: { 5266 case XML_ROLE_IGNORE_SECT: { 5267 enum XML_Error result; 5267 enum XML_Error result; 5268 if (parser->m_defaultHandler) 5268 if (parser->m_defaultHandler) 5269 reportDefault(parser, enc, s, next); 5269 reportDefault(parser, enc, s, next); 5270 handleDefault = XML_FALSE; 5270 handleDefault = XML_FALSE; 5271 result = doIgnoreSection(parser, enc, & 5271 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); 5272 if (result != XML_ERROR_NONE) 5272 if (result != XML_ERROR_NONE) 5273 return result; 5273 return result; 5274 else if (! next) { 5274 else if (! next) { 5275 parser->m_processor = ignoreSectionPr 5275 parser->m_processor = ignoreSectionProcessor; 5276 return result; 5276 return result; 5277 } 5277 } 5278 } break; 5278 } break; 5279 #endif /* XML_DTD */ 5279 #endif /* XML_DTD */ 5280 case XML_ROLE_GROUP_OPEN: 5280 case XML_ROLE_GROUP_OPEN: 5281 if (parser->m_prologState.level >= pars 5281 if (parser->m_prologState.level >= parser->m_groupSize) { 5282 if (parser->m_groupSize) { 5282 if (parser->m_groupSize) { 5283 { 5283 { 5284 /* Detect and prevent integer ove 5284 /* Detect and prevent integer overflow */ 5285 if (parser->m_groupSize > (unsign 5285 if (parser->m_groupSize > (unsigned int)(-1) / 2u) { 5286 return XML_ERROR_NO_MEMORY; 5286 return XML_ERROR_NO_MEMORY; 5287 } 5287 } 5288 5288 5289 char *const new_connector = (char 5289 char *const new_connector = (char *)REALLOC( 5290 parser, parser->m_groupConnec 5290 parser, parser->m_groupConnector, parser->m_groupSize *= 2); 5291 if (new_connector == NULL) { 5291 if (new_connector == NULL) { 5292 parser->m_groupSize /= 2; 5292 parser->m_groupSize /= 2; 5293 return XML_ERROR_NO_MEMORY; 5293 return XML_ERROR_NO_MEMORY; 5294 } 5294 } 5295 parser->m_groupConnector = new_co 5295 parser->m_groupConnector = new_connector; 5296 } 5296 } 5297 5297 5298 if (dtd->scaffIndex) { 5298 if (dtd->scaffIndex) { 5299 /* Detect and prevent integer ove 5299 /* Detect and prevent integer overflow. 5300 * The preprocessor guard address 5300 * The preprocessor guard addresses the "always false" warning 5301 * from -Wtype-limits on platform 5301 * from -Wtype-limits on platforms where 5302 * sizeof(unsigned int) < sizeof( 5302 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 5303 #if UINT_MAX >= SIZE_MAX 5303 #if UINT_MAX >= SIZE_MAX 5304 if (parser->m_groupSize > (size_t 5304 if (parser->m_groupSize > (size_t)(-1) / sizeof(int)) { 5305 return XML_ERROR_NO_MEMORY; 5305 return XML_ERROR_NO_MEMORY; 5306 } 5306 } 5307 #endif 5307 #endif 5308 5308 5309 int *const new_scaff_index = (int 5309 int *const new_scaff_index = (int *)REALLOC( 5310 parser, dtd->scaffIndex, pars 5310 parser, dtd->scaffIndex, parser->m_groupSize * sizeof(int)); 5311 if (new_scaff_index == NULL) 5311 if (new_scaff_index == NULL) 5312 return XML_ERROR_NO_MEMORY; 5312 return XML_ERROR_NO_MEMORY; 5313 dtd->scaffIndex = new_scaff_index 5313 dtd->scaffIndex = new_scaff_index; 5314 } 5314 } 5315 } else { 5315 } else { 5316 parser->m_groupConnector 5316 parser->m_groupConnector 5317 = (char *)MALLOC(parser, parser 5317 = (char *)MALLOC(parser, parser->m_groupSize = 32); 5318 if (! parser->m_groupConnector) { 5318 if (! parser->m_groupConnector) { 5319 parser->m_groupSize = 0; 5319 parser->m_groupSize = 0; 5320 return XML_ERROR_NO_MEMORY; 5320 return XML_ERROR_NO_MEMORY; 5321 } 5321 } 5322 } 5322 } 5323 } 5323 } 5324 parser->m_groupConnector[parser->m_prol 5324 parser->m_groupConnector[parser->m_prologState.level] = 0; 5325 if (dtd->in_eldecl) { 5325 if (dtd->in_eldecl) { 5326 int myindex = nextScaffoldPart(parser 5326 int myindex = nextScaffoldPart(parser); 5327 if (myindex < 0) 5327 if (myindex < 0) 5328 return XML_ERROR_NO_MEMORY; 5328 return XML_ERROR_NO_MEMORY; 5329 assert(dtd->scaffIndex != NULL); 5329 assert(dtd->scaffIndex != NULL); 5330 dtd->scaffIndex[dtd->scaffLevel] = my 5330 dtd->scaffIndex[dtd->scaffLevel] = myindex; 5331 dtd->scaffLevel++; 5331 dtd->scaffLevel++; 5332 dtd->scaffold[myindex].type = XML_CTY 5332 dtd->scaffold[myindex].type = XML_CTYPE_SEQ; 5333 if (parser->m_elementDeclHandler) 5333 if (parser->m_elementDeclHandler) 5334 handleDefault = XML_FALSE; 5334 handleDefault = XML_FALSE; 5335 } 5335 } 5336 break; 5336 break; 5337 case XML_ROLE_GROUP_SEQUENCE: 5337 case XML_ROLE_GROUP_SEQUENCE: 5338 if (parser->m_groupConnector[parser->m_ 5338 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE) 5339 return XML_ERROR_SYNTAX; 5339 return XML_ERROR_SYNTAX; 5340 parser->m_groupConnector[parser->m_prol 5340 parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA; 5341 if (dtd->in_eldecl && parser->m_element 5341 if (dtd->in_eldecl && parser->m_elementDeclHandler) 5342 handleDefault = XML_FALSE; 5342 handleDefault = XML_FALSE; 5343 break; 5343 break; 5344 case XML_ROLE_GROUP_CHOICE: 5344 case XML_ROLE_GROUP_CHOICE: 5345 if (parser->m_groupConnector[parser->m_ 5345 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA) 5346 return XML_ERROR_SYNTAX; 5346 return XML_ERROR_SYNTAX; 5347 if (dtd->in_eldecl 5347 if (dtd->in_eldecl 5348 && ! parser->m_groupConnector[parse 5348 && ! parser->m_groupConnector[parser->m_prologState.level] 5349 && (dtd->scaffold[dtd->scaffIndex[d 5349 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 5350 != XML_CTYPE_MIXED)) { 5350 != XML_CTYPE_MIXED)) { 5351 dtd->scaffold[dtd->scaffIndex[dtd->sc 5351 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 5352 = XML_CTYPE_CHOICE; 5352 = XML_CTYPE_CHOICE; 5353 if (parser->m_elementDeclHandler) 5353 if (parser->m_elementDeclHandler) 5354 handleDefault = XML_FALSE; 5354 handleDefault = XML_FALSE; 5355 } 5355 } 5356 parser->m_groupConnector[parser->m_prol 5356 parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE; 5357 break; 5357 break; 5358 case XML_ROLE_PARAM_ENTITY_REF: 5358 case XML_ROLE_PARAM_ENTITY_REF: 5359 #ifdef XML_DTD 5359 #ifdef XML_DTD 5360 case XML_ROLE_INNER_PARAM_ENTITY_REF: 5360 case XML_ROLE_INNER_PARAM_ENTITY_REF: 5361 dtd->hasParamEntityRefs = XML_TRUE; 5361 dtd->hasParamEntityRefs = XML_TRUE; 5362 if (! parser->m_paramEntityParsing) 5362 if (! parser->m_paramEntityParsing) 5363 dtd->keepProcessing = dtd->standalone 5363 dtd->keepProcessing = dtd->standalone; 5364 else { 5364 else { 5365 const XML_Char *name; 5365 const XML_Char *name; 5366 ENTITY *entity; 5366 ENTITY *entity; 5367 name = poolStoreString(&dtd->pool, en 5367 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar, 5368 next - enc->mi 5368 next - enc->minBytesPerChar); 5369 if (! name) 5369 if (! name) 5370 return XML_ERROR_NO_MEMORY; 5370 return XML_ERROR_NO_MEMORY; 5371 entity = (ENTITY *)lookup(parser, &dt 5371 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); 5372 poolDiscard(&dtd->pool); 5372 poolDiscard(&dtd->pool); 5373 /* first, determine if a check for an 5373 /* first, determine if a check for an existing declaration is needed; 5374 if yes, check that the entity exis 5374 if yes, check that the entity exists, and that it is internal, 5375 otherwise call the skipped entity 5375 otherwise call the skipped entity handler 5376 */ 5376 */ 5377 if (parser->m_prologState.documentEnt 5377 if (parser->m_prologState.documentEntity 5378 && (dtd->standalone ? ! parser->m 5378 && (dtd->standalone ? ! parser->m_openInternalEntities 5379 : ! dtd->hasP 5379 : ! dtd->hasParamEntityRefs)) { 5380 if (! entity) 5380 if (! entity) 5381 return XML_ERROR_UNDEFINED_ENTITY 5381 return XML_ERROR_UNDEFINED_ENTITY; 5382 else if (! entity->is_internal) { 5382 else if (! entity->is_internal) { 5383 /* It's hard to exhaustively sear 5383 /* It's hard to exhaustively search the code to be sure, 5384 * but there doesn't seem to be a 5384 * but there doesn't seem to be a way of executing the 5385 * following line. There are two 5385 * following line. There are two cases: 5386 * 5386 * 5387 * If 'standalone' is false, the 5387 * If 'standalone' is false, the DTD must have no 5388 * parameter entities or we would 5388 * parameter entities or we wouldn't have passed the outer 5389 * 'if' statement. That means th 5389 * 'if' statement. That means the only entity in the hash 5390 * table is the external subset n 5390 * table is the external subset name "#" which cannot be 5391 * given as a parameter entity na 5391 * given as a parameter entity name in XML syntax, so the 5392 * lookup must have returned NULL 5392 * lookup must have returned NULL and we don't even reach 5393 * the test for an internal entit 5393 * the test for an internal entity. 5394 * 5394 * 5395 * If 'standalone' is true, it do 5395 * If 'standalone' is true, it does not seem to be 5396 * possible to create entities ta 5396 * possible to create entities taking this code path that 5397 * are not internal entities, so 5397 * are not internal entities, so fail the test above. 5398 * 5398 * 5399 * Because this analysis is very 5399 * Because this analysis is very uncertain, the code is 5400 * being left in place and merely 5400 * being left in place and merely removed from the 5401 * coverage test statistics. 5401 * coverage test statistics. 5402 */ 5402 */ 5403 return XML_ERROR_ENTITY_DECLARED_ 5403 return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */ 5404 } 5404 } 5405 } else if (! entity) { 5405 } else if (! entity) { 5406 dtd->keepProcessing = dtd->standalo 5406 dtd->keepProcessing = dtd->standalone; 5407 /* cannot report skipped entities i 5407 /* cannot report skipped entities in declarations */ 5408 if ((role == XML_ROLE_PARAM_ENTITY_ 5408 if ((role == XML_ROLE_PARAM_ENTITY_REF) 5409 && parser->m_skippedEntityHandl 5409 && parser->m_skippedEntityHandler) { 5410 parser->m_skippedEntityHandler(pa 5410 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1); 5411 handleDefault = XML_FALSE; 5411 handleDefault = XML_FALSE; 5412 } 5412 } 5413 break; 5413 break; 5414 } 5414 } 5415 if (entity->open) 5415 if (entity->open) 5416 return XML_ERROR_RECURSIVE_ENTITY_R 5416 return XML_ERROR_RECURSIVE_ENTITY_REF; 5417 if (entity->textPtr) { 5417 if (entity->textPtr) { 5418 enum XML_Error result; 5418 enum XML_Error result; 5419 XML_Bool betweenDecl 5419 XML_Bool betweenDecl 5420 = (role == XML_ROLE_PARAM_ENTIT 5420 = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); 5421 result = processInternalEntity(pars 5421 result = processInternalEntity(parser, entity, betweenDecl); 5422 if (result != XML_ERROR_NONE) 5422 if (result != XML_ERROR_NONE) 5423 return result; 5423 return result; 5424 handleDefault = XML_FALSE; 5424 handleDefault = XML_FALSE; 5425 break; 5425 break; 5426 } 5426 } 5427 if (parser->m_externalEntityRefHandle 5427 if (parser->m_externalEntityRefHandler) { 5428 dtd->paramEntityRead = XML_FALSE; 5428 dtd->paramEntityRead = XML_FALSE; 5429 entity->open = XML_TRUE; 5429 entity->open = XML_TRUE; 5430 entityTrackingOnOpen(parser, entity 5430 entityTrackingOnOpen(parser, entity, __LINE__); 5431 if (! parser->m_externalEntityRefHa 5431 if (! parser->m_externalEntityRefHandler( 5432 parser->m_externalEntityRef 5432 parser->m_externalEntityRefHandlerArg, 0, entity->base, 5433 entity->systemId, entity->p 5433 entity->systemId, entity->publicId)) { 5434 entityTrackingOnClose(parser, ent 5434 entityTrackingOnClose(parser, entity, __LINE__); 5435 entity->open = XML_FALSE; 5435 entity->open = XML_FALSE; 5436 return XML_ERROR_EXTERNAL_ENTITY_ 5436 return XML_ERROR_EXTERNAL_ENTITY_HANDLING; 5437 } 5437 } 5438 entityTrackingOnClose(parser, entit 5438 entityTrackingOnClose(parser, entity, __LINE__); 5439 entity->open = XML_FALSE; 5439 entity->open = XML_FALSE; 5440 handleDefault = XML_FALSE; 5440 handleDefault = XML_FALSE; 5441 if (! dtd->paramEntityRead) { 5441 if (! dtd->paramEntityRead) { 5442 dtd->keepProcessing = dtd->standa 5442 dtd->keepProcessing = dtd->standalone; 5443 break; 5443 break; 5444 } 5444 } 5445 } else { 5445 } else { 5446 dtd->keepProcessing = dtd->standalo 5446 dtd->keepProcessing = dtd->standalone; 5447 break; 5447 break; 5448 } 5448 } 5449 } 5449 } 5450 #endif /* XML_DTD */ 5450 #endif /* XML_DTD */ 5451 if (! dtd->standalone && parser->m_notS 5451 if (! dtd->standalone && parser->m_notStandaloneHandler 5452 && ! parser->m_notStandaloneHandler 5452 && ! parser->m_notStandaloneHandler(parser->m_handlerArg)) 5453 return XML_ERROR_NOT_STANDALONE; 5453 return XML_ERROR_NOT_STANDALONE; 5454 break; 5454 break; 5455 5455 5456 /* Element declaration stuff */ 5456 /* Element declaration stuff */ 5457 5457 5458 case XML_ROLE_ELEMENT_NAME: 5458 case XML_ROLE_ELEMENT_NAME: 5459 if (parser->m_elementDeclHandler) { 5459 if (parser->m_elementDeclHandler) { 5460 parser->m_declElementType = getElemen 5460 parser->m_declElementType = getElementType(parser, enc, s, next); 5461 if (! parser->m_declElementType) 5461 if (! parser->m_declElementType) 5462 return XML_ERROR_NO_MEMORY; 5462 return XML_ERROR_NO_MEMORY; 5463 dtd->scaffLevel = 0; 5463 dtd->scaffLevel = 0; 5464 dtd->scaffCount = 0; 5464 dtd->scaffCount = 0; 5465 dtd->in_eldecl = XML_TRUE; 5465 dtd->in_eldecl = XML_TRUE; 5466 handleDefault = XML_FALSE; 5466 handleDefault = XML_FALSE; 5467 } 5467 } 5468 break; 5468 break; 5469 5469 5470 case XML_ROLE_CONTENT_ANY: 5470 case XML_ROLE_CONTENT_ANY: 5471 case XML_ROLE_CONTENT_EMPTY: 5471 case XML_ROLE_CONTENT_EMPTY: 5472 if (dtd->in_eldecl) { 5472 if (dtd->in_eldecl) { 5473 if (parser->m_elementDeclHandler) { 5473 if (parser->m_elementDeclHandler) { 5474 XML_Content *content 5474 XML_Content *content 5475 = (XML_Content *)MALLOC(parser, 5475 = (XML_Content *)MALLOC(parser, sizeof(XML_Content)); 5476 if (! content) 5476 if (! content) 5477 return XML_ERROR_NO_MEMORY; 5477 return XML_ERROR_NO_MEMORY; 5478 content->quant = XML_CQUANT_NONE; 5478 content->quant = XML_CQUANT_NONE; 5479 content->name = NULL; 5479 content->name = NULL; 5480 content->numchildren = 0; 5480 content->numchildren = 0; 5481 content->children = NULL; 5481 content->children = NULL; 5482 content->type = ((role == XML_ROLE_ 5482 content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY 5483 5483 : XML_CTYPE_EMPTY); 5484 *eventEndPP = s; 5484 *eventEndPP = s; 5485 parser->m_elementDeclHandler( 5485 parser->m_elementDeclHandler( 5486 parser->m_handlerArg, parser->m 5486 parser->m_handlerArg, parser->m_declElementType->name, content); 5487 handleDefault = XML_FALSE; 5487 handleDefault = XML_FALSE; 5488 } 5488 } 5489 dtd->in_eldecl = XML_FALSE; 5489 dtd->in_eldecl = XML_FALSE; 5490 } 5490 } 5491 break; 5491 break; 5492 5492 5493 case XML_ROLE_CONTENT_PCDATA: 5493 case XML_ROLE_CONTENT_PCDATA: 5494 if (dtd->in_eldecl) { 5494 if (dtd->in_eldecl) { 5495 dtd->scaffold[dtd->scaffIndex[dtd->sc 5495 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type 5496 = XML_CTYPE_MIXED; 5496 = XML_CTYPE_MIXED; 5497 if (parser->m_elementDeclHandler) 5497 if (parser->m_elementDeclHandler) 5498 handleDefault = XML_FALSE; 5498 handleDefault = XML_FALSE; 5499 } 5499 } 5500 break; 5500 break; 5501 5501 5502 case XML_ROLE_CONTENT_ELEMENT: 5502 case XML_ROLE_CONTENT_ELEMENT: 5503 quant = XML_CQUANT_NONE; 5503 quant = XML_CQUANT_NONE; 5504 goto elementContent; 5504 goto elementContent; 5505 case XML_ROLE_CONTENT_ELEMENT_OPT: 5505 case XML_ROLE_CONTENT_ELEMENT_OPT: 5506 quant = XML_CQUANT_OPT; 5506 quant = XML_CQUANT_OPT; 5507 goto elementContent; 5507 goto elementContent; 5508 case XML_ROLE_CONTENT_ELEMENT_REP: 5508 case XML_ROLE_CONTENT_ELEMENT_REP: 5509 quant = XML_CQUANT_REP; 5509 quant = XML_CQUANT_REP; 5510 goto elementContent; 5510 goto elementContent; 5511 case XML_ROLE_CONTENT_ELEMENT_PLUS: 5511 case XML_ROLE_CONTENT_ELEMENT_PLUS: 5512 quant = XML_CQUANT_PLUS; 5512 quant = XML_CQUANT_PLUS; 5513 elementContent: 5513 elementContent: 5514 if (dtd->in_eldecl) { 5514 if (dtd->in_eldecl) { 5515 ELEMENT_TYPE *el; 5515 ELEMENT_TYPE *el; 5516 const XML_Char *name; 5516 const XML_Char *name; 5517 size_t nameLen; 5517 size_t nameLen; 5518 const char *nxt 5518 const char *nxt 5519 = (quant == XML_CQUANT_NONE ? nex 5519 = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar); 5520 int myindex = nextScaffoldPart(parser 5520 int myindex = nextScaffoldPart(parser); 5521 if (myindex < 0) 5521 if (myindex < 0) 5522 return XML_ERROR_NO_MEMORY; 5522 return XML_ERROR_NO_MEMORY; 5523 dtd->scaffold[myindex].type = XML_CTY 5523 dtd->scaffold[myindex].type = XML_CTYPE_NAME; 5524 dtd->scaffold[myindex].quant = quant; 5524 dtd->scaffold[myindex].quant = quant; 5525 el = getElementType(parser, enc, s, n 5525 el = getElementType(parser, enc, s, nxt); 5526 if (! el) 5526 if (! el) 5527 return XML_ERROR_NO_MEMORY; 5527 return XML_ERROR_NO_MEMORY; 5528 name = el->name; 5528 name = el->name; 5529 dtd->scaffold[myindex].name = name; 5529 dtd->scaffold[myindex].name = name; 5530 nameLen = 0; 5530 nameLen = 0; 5531 for (; name[nameLen++];) 5531 for (; name[nameLen++];) 5532 ; 5532 ; 5533 5533 5534 /* Detect and prevent integer overflo 5534 /* Detect and prevent integer overflow */ 5535 if (nameLen > UINT_MAX - dtd->content 5535 if (nameLen > UINT_MAX - dtd->contentStringLen) { 5536 return XML_ERROR_NO_MEMORY; 5536 return XML_ERROR_NO_MEMORY; 5537 } 5537 } 5538 5538 5539 dtd->contentStringLen += (unsigned)na 5539 dtd->contentStringLen += (unsigned)nameLen; 5540 if (parser->m_elementDeclHandler) 5540 if (parser->m_elementDeclHandler) 5541 handleDefault = XML_FALSE; 5541 handleDefault = XML_FALSE; 5542 } 5542 } 5543 break; 5543 break; 5544 5544 5545 case XML_ROLE_GROUP_CLOSE: 5545 case XML_ROLE_GROUP_CLOSE: 5546 quant = XML_CQUANT_NONE; 5546 quant = XML_CQUANT_NONE; 5547 goto closeGroup; 5547 goto closeGroup; 5548 case XML_ROLE_GROUP_CLOSE_OPT: 5548 case XML_ROLE_GROUP_CLOSE_OPT: 5549 quant = XML_CQUANT_OPT; 5549 quant = XML_CQUANT_OPT; 5550 goto closeGroup; 5550 goto closeGroup; 5551 case XML_ROLE_GROUP_CLOSE_REP: 5551 case XML_ROLE_GROUP_CLOSE_REP: 5552 quant = XML_CQUANT_REP; 5552 quant = XML_CQUANT_REP; 5553 goto closeGroup; 5553 goto closeGroup; 5554 case XML_ROLE_GROUP_CLOSE_PLUS: 5554 case XML_ROLE_GROUP_CLOSE_PLUS: 5555 quant = XML_CQUANT_PLUS; 5555 quant = XML_CQUANT_PLUS; 5556 closeGroup: 5556 closeGroup: 5557 if (dtd->in_eldecl) { 5557 if (dtd->in_eldecl) { 5558 if (parser->m_elementDeclHandler) 5558 if (parser->m_elementDeclHandler) 5559 handleDefault = XML_FALSE; 5559 handleDefault = XML_FALSE; 5560 dtd->scaffLevel--; 5560 dtd->scaffLevel--; 5561 dtd->scaffold[dtd->scaffIndex[dtd->sc 5561 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; 5562 if (dtd->scaffLevel == 0) { 5562 if (dtd->scaffLevel == 0) { 5563 if (! handleDefault) { 5563 if (! handleDefault) { 5564 XML_Content *model = build_model( 5564 XML_Content *model = build_model(parser); 5565 if (! model) 5565 if (! model) 5566 return XML_ERROR_NO_MEMORY; 5566 return XML_ERROR_NO_MEMORY; 5567 *eventEndPP = s; 5567 *eventEndPP = s; 5568 parser->m_elementDeclHandler( 5568 parser->m_elementDeclHandler( 5569 parser->m_handlerArg, parser- 5569 parser->m_handlerArg, parser->m_declElementType->name, model); 5570 } 5570 } 5571 dtd->in_eldecl = XML_FALSE; 5571 dtd->in_eldecl = XML_FALSE; 5572 dtd->contentStringLen = 0; 5572 dtd->contentStringLen = 0; 5573 } 5573 } 5574 } 5574 } 5575 break; 5575 break; 5576 /* End element declaration stuff */ 5576 /* End element declaration stuff */ 5577 5577 5578 case XML_ROLE_PI: 5578 case XML_ROLE_PI: 5579 if (! reportProcessingInstruction(parse 5579 if (! reportProcessingInstruction(parser, enc, s, next)) 5580 return XML_ERROR_NO_MEMORY; 5580 return XML_ERROR_NO_MEMORY; 5581 handleDefault = XML_FALSE; 5581 handleDefault = XML_FALSE; 5582 break; 5582 break; 5583 case XML_ROLE_COMMENT: 5583 case XML_ROLE_COMMENT: 5584 if (! reportComment(parser, enc, s, nex 5584 if (! reportComment(parser, enc, s, next)) 5585 return XML_ERROR_NO_MEMORY; 5585 return XML_ERROR_NO_MEMORY; 5586 handleDefault = XML_FALSE; 5586 handleDefault = XML_FALSE; 5587 break; 5587 break; 5588 case XML_ROLE_NONE: 5588 case XML_ROLE_NONE: 5589 switch (tok) { 5589 switch (tok) { 5590 case XML_TOK_BOM: 5590 case XML_TOK_BOM: 5591 handleDefault = XML_FALSE; 5591 handleDefault = XML_FALSE; 5592 break; 5592 break; 5593 } 5593 } 5594 break; 5594 break; 5595 case XML_ROLE_DOCTYPE_NONE: 5595 case XML_ROLE_DOCTYPE_NONE: 5596 if (parser->m_startDoctypeDeclHandler) 5596 if (parser->m_startDoctypeDeclHandler) 5597 handleDefault = XML_FALSE; 5597 handleDefault = XML_FALSE; 5598 break; 5598 break; 5599 case XML_ROLE_ENTITY_NONE: 5599 case XML_ROLE_ENTITY_NONE: 5600 if (dtd->keepProcessing && parser->m_en 5600 if (dtd->keepProcessing && parser->m_entityDeclHandler) 5601 handleDefault = XML_FALSE; 5601 handleDefault = XML_FALSE; 5602 break; 5602 break; 5603 case XML_ROLE_NOTATION_NONE: 5603 case XML_ROLE_NOTATION_NONE: 5604 if (parser->m_notationDeclHandler) 5604 if (parser->m_notationDeclHandler) 5605 handleDefault = XML_FALSE; 5605 handleDefault = XML_FALSE; 5606 break; 5606 break; 5607 case XML_ROLE_ATTLIST_NONE: 5607 case XML_ROLE_ATTLIST_NONE: 5608 if (dtd->keepProcessing && parser->m_at 5608 if (dtd->keepProcessing && parser->m_attlistDeclHandler) 5609 handleDefault = XML_FALSE; 5609 handleDefault = XML_FALSE; 5610 break; 5610 break; 5611 case XML_ROLE_ELEMENT_NONE: 5611 case XML_ROLE_ELEMENT_NONE: 5612 if (parser->m_elementDeclHandler) 5612 if (parser->m_elementDeclHandler) 5613 handleDefault = XML_FALSE; 5613 handleDefault = XML_FALSE; 5614 break; 5614 break; 5615 } /* end of big switch */ 5615 } /* end of big switch */ 5616 5616 5617 if (handleDefault && parser->m_defaultHan 5617 if (handleDefault && parser->m_defaultHandler) 5618 reportDefault(parser, enc, s, next); 5618 reportDefault(parser, enc, s, next); 5619 5619 5620 switch (parser->m_parsingStatus.parsing) 5620 switch (parser->m_parsingStatus.parsing) { 5621 case XML_SUSPENDED: 5621 case XML_SUSPENDED: 5622 *nextPtr = next; 5622 *nextPtr = next; 5623 return XML_ERROR_NONE; 5623 return XML_ERROR_NONE; 5624 case XML_FINISHED: 5624 case XML_FINISHED: 5625 return XML_ERROR_ABORTED; 5625 return XML_ERROR_ABORTED; 5626 default: 5626 default: 5627 s = next; 5627 s = next; 5628 tok = XmlPrologTok(enc, s, end, &next); 5628 tok = XmlPrologTok(enc, s, end, &next); 5629 } 5629 } 5630 } 5630 } 5631 /* not reached */ 5631 /* not reached */ 5632 } 5632 } 5633 5633 5634 static enum XML_Error PTRCALL 5634 static enum XML_Error PTRCALL 5635 epilogProcessor(XML_Parser parser, const char 5635 epilogProcessor(XML_Parser parser, const char *s, const char *end, 5636 const char **nextPtr) { 5636 const char **nextPtr) { 5637 parser->m_processor = epilogProcessor; 5637 parser->m_processor = epilogProcessor; 5638 parser->m_eventPtr = s; 5638 parser->m_eventPtr = s; 5639 for (;;) { 5639 for (;;) { 5640 const char *next = NULL; 5640 const char *next = NULL; 5641 int tok = XmlPrologTok(parser->m_encoding 5641 int tok = XmlPrologTok(parser->m_encoding, s, end, &next); 5642 #ifdef XML_DTD 5642 #ifdef XML_DTD 5643 if (! accountingDiffTolerated(parser, tok 5643 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, 5644 XML_ACCOUNT 5644 XML_ACCOUNT_DIRECT)) { 5645 accountingOnAbort(parser); 5645 accountingOnAbort(parser); 5646 return XML_ERROR_AMPLIFICATION_LIMIT_BR 5646 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 5647 } 5647 } 5648 #endif 5648 #endif 5649 parser->m_eventEndPtr = next; 5649 parser->m_eventEndPtr = next; 5650 switch (tok) { 5650 switch (tok) { 5651 /* report partial linebreak - it might be 5651 /* report partial linebreak - it might be the last token */ 5652 case -XML_TOK_PROLOG_S: 5652 case -XML_TOK_PROLOG_S: 5653 if (parser->m_defaultHandler) { 5653 if (parser->m_defaultHandler) { 5654 reportDefault(parser, parser->m_encod 5654 reportDefault(parser, parser->m_encoding, s, next); 5655 if (parser->m_parsingStatus.parsing = 5655 if (parser->m_parsingStatus.parsing == XML_FINISHED) 5656 return XML_ERROR_ABORTED; 5656 return XML_ERROR_ABORTED; 5657 } 5657 } 5658 *nextPtr = next; 5658 *nextPtr = next; 5659 return XML_ERROR_NONE; 5659 return XML_ERROR_NONE; 5660 case XML_TOK_NONE: 5660 case XML_TOK_NONE: 5661 *nextPtr = s; 5661 *nextPtr = s; 5662 return XML_ERROR_NONE; 5662 return XML_ERROR_NONE; 5663 case XML_TOK_PROLOG_S: 5663 case XML_TOK_PROLOG_S: 5664 if (parser->m_defaultHandler) 5664 if (parser->m_defaultHandler) 5665 reportDefault(parser, parser->m_encod 5665 reportDefault(parser, parser->m_encoding, s, next); 5666 break; 5666 break; 5667 case XML_TOK_PI: 5667 case XML_TOK_PI: 5668 if (! reportProcessingInstruction(parse 5668 if (! reportProcessingInstruction(parser, parser->m_encoding, s, next)) 5669 return XML_ERROR_NO_MEMORY; 5669 return XML_ERROR_NO_MEMORY; 5670 break; 5670 break; 5671 case XML_TOK_COMMENT: 5671 case XML_TOK_COMMENT: 5672 if (! reportComment(parser, parser->m_e 5672 if (! reportComment(parser, parser->m_encoding, s, next)) 5673 return XML_ERROR_NO_MEMORY; 5673 return XML_ERROR_NO_MEMORY; 5674 break; 5674 break; 5675 case XML_TOK_INVALID: 5675 case XML_TOK_INVALID: 5676 parser->m_eventPtr = next; 5676 parser->m_eventPtr = next; 5677 return XML_ERROR_INVALID_TOKEN; 5677 return XML_ERROR_INVALID_TOKEN; 5678 case XML_TOK_PARTIAL: 5678 case XML_TOK_PARTIAL: 5679 if (! parser->m_parsingStatus.finalBuff 5679 if (! parser->m_parsingStatus.finalBuffer) { 5680 *nextPtr = s; 5680 *nextPtr = s; 5681 return XML_ERROR_NONE; 5681 return XML_ERROR_NONE; 5682 } 5682 } 5683 return XML_ERROR_UNCLOSED_TOKEN; 5683 return XML_ERROR_UNCLOSED_TOKEN; 5684 case XML_TOK_PARTIAL_CHAR: 5684 case XML_TOK_PARTIAL_CHAR: 5685 if (! parser->m_parsingStatus.finalBuff 5685 if (! parser->m_parsingStatus.finalBuffer) { 5686 *nextPtr = s; 5686 *nextPtr = s; 5687 return XML_ERROR_NONE; 5687 return XML_ERROR_NONE; 5688 } 5688 } 5689 return XML_ERROR_PARTIAL_CHAR; 5689 return XML_ERROR_PARTIAL_CHAR; 5690 default: 5690 default: 5691 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT 5691 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; 5692 } 5692 } 5693 parser->m_eventPtr = s = next; 5693 parser->m_eventPtr = s = next; 5694 switch (parser->m_parsingStatus.parsing) 5694 switch (parser->m_parsingStatus.parsing) { 5695 case XML_SUSPENDED: 5695 case XML_SUSPENDED: 5696 *nextPtr = next; 5696 *nextPtr = next; 5697 return XML_ERROR_NONE; 5697 return XML_ERROR_NONE; 5698 case XML_FINISHED: 5698 case XML_FINISHED: 5699 return XML_ERROR_ABORTED; 5699 return XML_ERROR_ABORTED; 5700 default:; 5700 default:; 5701 } 5701 } 5702 } 5702 } 5703 } 5703 } 5704 5704 5705 static enum XML_Error 5705 static enum XML_Error 5706 processInternalEntity(XML_Parser parser, ENTI 5706 processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) { 5707 const char *textStart, *textEnd; 5707 const char *textStart, *textEnd; 5708 const char *next; 5708 const char *next; 5709 enum XML_Error result; 5709 enum XML_Error result; 5710 OPEN_INTERNAL_ENTITY *openEntity; 5710 OPEN_INTERNAL_ENTITY *openEntity; 5711 5711 5712 if (parser->m_freeInternalEntities) { 5712 if (parser->m_freeInternalEntities) { 5713 openEntity = parser->m_freeInternalEntiti 5713 openEntity = parser->m_freeInternalEntities; 5714 parser->m_freeInternalEntities = openEnti 5714 parser->m_freeInternalEntities = openEntity->next; 5715 } else { 5715 } else { 5716 openEntity 5716 openEntity 5717 = (OPEN_INTERNAL_ENTITY *)MALLOC(pars 5717 = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY)); 5718 if (! openEntity) 5718 if (! openEntity) 5719 return XML_ERROR_NO_MEMORY; 5719 return XML_ERROR_NO_MEMORY; 5720 } 5720 } 5721 entity->open = XML_TRUE; 5721 entity->open = XML_TRUE; 5722 #ifdef XML_DTD 5722 #ifdef XML_DTD 5723 entityTrackingOnOpen(parser, entity, __LINE 5723 entityTrackingOnOpen(parser, entity, __LINE__); 5724 #endif 5724 #endif 5725 entity->processed = 0; 5725 entity->processed = 0; 5726 openEntity->next = parser->m_openInternalEn 5726 openEntity->next = parser->m_openInternalEntities; 5727 parser->m_openInternalEntities = openEntity 5727 parser->m_openInternalEntities = openEntity; 5728 openEntity->entity = entity; 5728 openEntity->entity = entity; 5729 openEntity->startTagLevel = parser->m_tagLe 5729 openEntity->startTagLevel = parser->m_tagLevel; 5730 openEntity->betweenDecl = betweenDecl; 5730 openEntity->betweenDecl = betweenDecl; 5731 openEntity->internalEventPtr = NULL; 5731 openEntity->internalEventPtr = NULL; 5732 openEntity->internalEventEndPtr = NULL; 5732 openEntity->internalEventEndPtr = NULL; 5733 textStart = (const char *)entity->textPtr; 5733 textStart = (const char *)entity->textPtr; 5734 textEnd = (const char *)(entity->textPtr + 5734 textEnd = (const char *)(entity->textPtr + entity->textLen); 5735 /* Set a safe default value in case 'next' 5735 /* Set a safe default value in case 'next' does not get set */ 5736 next = textStart; 5736 next = textStart; 5737 5737 5738 #ifdef XML_DTD 5738 #ifdef XML_DTD 5739 if (entity->is_param) { 5739 if (entity->is_param) { 5740 int tok 5740 int tok 5741 = XmlPrologTok(parser->m_internalEnco 5741 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); 5742 result = doProlog(parser, parser->m_inter 5742 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, 5743 tok, next, &next, XML_F 5743 tok, next, &next, XML_FALSE, XML_FALSE, 5744 XML_ACCOUNT_ENTITY_EXPA 5744 XML_ACCOUNT_ENTITY_EXPANSION); 5745 } else 5745 } else 5746 #endif /* XML_DTD */ 5746 #endif /* XML_DTD */ 5747 result = doContent(parser, parser->m_tagL 5747 result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, 5748 textStart, textEnd, &n 5748 textStart, textEnd, &next, XML_FALSE, 5749 XML_ACCOUNT_ENTITY_EXP 5749 XML_ACCOUNT_ENTITY_EXPANSION); 5750 5750 5751 if (result == XML_ERROR_NONE) { 5751 if (result == XML_ERROR_NONE) { 5752 if (textEnd != next && parser->m_parsingS 5752 if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) { 5753 entity->processed = (int)(next - textSt 5753 entity->processed = (int)(next - textStart); 5754 parser->m_processor = internalEntityPro 5754 parser->m_processor = internalEntityProcessor; 5755 } else { 5755 } else { 5756 #ifdef XML_DTD 5756 #ifdef XML_DTD 5757 entityTrackingOnClose(parser, entity, _ 5757 entityTrackingOnClose(parser, entity, __LINE__); 5758 #endif /* XML_DTD */ 5758 #endif /* XML_DTD */ 5759 entity->open = XML_FALSE; 5759 entity->open = XML_FALSE; 5760 parser->m_openInternalEntities = openEn 5760 parser->m_openInternalEntities = openEntity->next; 5761 /* put openEntity back in list of free 5761 /* put openEntity back in list of free instances */ 5762 openEntity->next = parser->m_freeIntern 5762 openEntity->next = parser->m_freeInternalEntities; 5763 parser->m_freeInternalEntities = openEn 5763 parser->m_freeInternalEntities = openEntity; 5764 } 5764 } 5765 } 5765 } 5766 return result; 5766 return result; 5767 } 5767 } 5768 5768 5769 static enum XML_Error PTRCALL 5769 static enum XML_Error PTRCALL 5770 internalEntityProcessor(XML_Parser parser, co 5770 internalEntityProcessor(XML_Parser parser, const char *s, const char *end, 5771 const char **nextPtr) 5771 const char **nextPtr) { 5772 ENTITY *entity; 5772 ENTITY *entity; 5773 const char *textStart, *textEnd; 5773 const char *textStart, *textEnd; 5774 const char *next; 5774 const char *next; 5775 enum XML_Error result; 5775 enum XML_Error result; 5776 OPEN_INTERNAL_ENTITY *openEntity = parser-> 5776 OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities; 5777 if (! openEntity) 5777 if (! openEntity) 5778 return XML_ERROR_UNEXPECTED_STATE; 5778 return XML_ERROR_UNEXPECTED_STATE; 5779 5779 5780 entity = openEntity->entity; 5780 entity = openEntity->entity; 5781 textStart = ((const char *)entity->textPtr) 5781 textStart = ((const char *)entity->textPtr) + entity->processed; 5782 textEnd = (const char *)(entity->textPtr + 5782 textEnd = (const char *)(entity->textPtr + entity->textLen); 5783 /* Set a safe default value in case 'next' 5783 /* Set a safe default value in case 'next' does not get set */ 5784 next = textStart; 5784 next = textStart; 5785 5785 5786 #ifdef XML_DTD 5786 #ifdef XML_DTD 5787 if (entity->is_param) { 5787 if (entity->is_param) { 5788 int tok 5788 int tok 5789 = XmlPrologTok(parser->m_internalEnco 5789 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next); 5790 result = doProlog(parser, parser->m_inter 5790 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, 5791 tok, next, &next, XML_F 5791 tok, next, &next, XML_FALSE, XML_TRUE, 5792 XML_ACCOUNT_ENTITY_EXPA 5792 XML_ACCOUNT_ENTITY_EXPANSION); 5793 } else 5793 } else 5794 #endif /* XML_DTD */ 5794 #endif /* XML_DTD */ 5795 result = doContent(parser, openEntity->st 5795 result = doContent(parser, openEntity->startTagLevel, 5796 parser->m_internalEnco 5796 parser->m_internalEncoding, textStart, textEnd, &next, 5797 XML_FALSE, XML_ACCOUNT 5797 XML_FALSE, XML_ACCOUNT_ENTITY_EXPANSION); 5798 5798 5799 if (result != XML_ERROR_NONE) 5799 if (result != XML_ERROR_NONE) 5800 return result; 5800 return result; 5801 else if (textEnd != next 5801 else if (textEnd != next 5802 && parser->m_parsingStatus.parsing 5802 && parser->m_parsingStatus.parsing == XML_SUSPENDED) { 5803 entity->processed = (int)(next - (const c 5803 entity->processed = (int)(next - (const char *)entity->textPtr); 5804 return result; 5804 return result; 5805 } else { 5805 } else { 5806 #ifdef XML_DTD 5806 #ifdef XML_DTD 5807 entityTrackingOnClose(parser, entity, __L 5807 entityTrackingOnClose(parser, entity, __LINE__); 5808 #endif 5808 #endif 5809 entity->open = XML_FALSE; 5809 entity->open = XML_FALSE; 5810 parser->m_openInternalEntities = openEnti 5810 parser->m_openInternalEntities = openEntity->next; 5811 /* put openEntity back in list of free in 5811 /* put openEntity back in list of free instances */ 5812 openEntity->next = parser->m_freeInternal 5812 openEntity->next = parser->m_freeInternalEntities; 5813 parser->m_freeInternalEntities = openEnti 5813 parser->m_freeInternalEntities = openEntity; 5814 } 5814 } 5815 5815 5816 #ifdef XML_DTD 5816 #ifdef XML_DTD 5817 if (entity->is_param) { 5817 if (entity->is_param) { 5818 int tok; 5818 int tok; 5819 parser->m_processor = prologProcessor; 5819 parser->m_processor = prologProcessor; 5820 tok = XmlPrologTok(parser->m_encoding, s, 5820 tok = XmlPrologTok(parser->m_encoding, s, end, &next); 5821 return doProlog(parser, parser->m_encodin 5821 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr, 5822 (XML_Bool)! parser->m_par 5822 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE, 5823 XML_ACCOUNT_DIRECT); 5823 XML_ACCOUNT_DIRECT); 5824 } else 5824 } else 5825 #endif /* XML_DTD */ 5825 #endif /* XML_DTD */ 5826 { 5826 { 5827 parser->m_processor = contentProcessor; 5827 parser->m_processor = contentProcessor; 5828 /* see externalEntityContentProcessor vs 5828 /* see externalEntityContentProcessor vs contentProcessor */ 5829 result = doContent(parser, parser->m_pare 5829 result = doContent(parser, parser->m_parentParser ? 1 : 0, 5830 parser->m_encoding, s, 5830 parser->m_encoding, s, end, nextPtr, 5831 (XML_Bool)! parser->m_ 5831 (XML_Bool)! parser->m_parsingStatus.finalBuffer, 5832 XML_ACCOUNT_DIRECT); 5832 XML_ACCOUNT_DIRECT); 5833 if (result == XML_ERROR_NONE) { 5833 if (result == XML_ERROR_NONE) { 5834 if (! storeRawNames(parser)) 5834 if (! storeRawNames(parser)) 5835 return XML_ERROR_NO_MEMORY; 5835 return XML_ERROR_NO_MEMORY; 5836 } 5836 } 5837 return result; 5837 return result; 5838 } 5838 } 5839 } 5839 } 5840 5840 5841 static enum XML_Error PTRCALL 5841 static enum XML_Error PTRCALL 5842 errorProcessor(XML_Parser parser, const char 5842 errorProcessor(XML_Parser parser, const char *s, const char *end, 5843 const char **nextPtr) { 5843 const char **nextPtr) { 5844 UNUSED_P(s); 5844 UNUSED_P(s); 5845 UNUSED_P(end); 5845 UNUSED_P(end); 5846 UNUSED_P(nextPtr); 5846 UNUSED_P(nextPtr); 5847 return parser->m_errorCode; 5847 return parser->m_errorCode; 5848 } 5848 } 5849 5849 5850 static enum XML_Error 5850 static enum XML_Error 5851 storeAttributeValue(XML_Parser parser, const 5851 storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 5852 const char *ptr, const ch 5852 const char *ptr, const char *end, STRING_POOL *pool, 5853 enum XML_Account account) 5853 enum XML_Account account) { 5854 enum XML_Error result 5854 enum XML_Error result 5855 = appendAttributeValue(parser, enc, isC 5855 = appendAttributeValue(parser, enc, isCdata, ptr, end, pool, account); 5856 if (result) 5856 if (result) 5857 return result; 5857 return result; 5858 if (! isCdata && poolLength(pool) && poolLa 5858 if (! isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) 5859 poolChop(pool); 5859 poolChop(pool); 5860 if (! poolAppendChar(pool, XML_T('\0'))) 5860 if (! poolAppendChar(pool, XML_T('\0'))) 5861 return XML_ERROR_NO_MEMORY; 5861 return XML_ERROR_NO_MEMORY; 5862 return XML_ERROR_NONE; 5862 return XML_ERROR_NONE; 5863 } 5863 } 5864 5864 5865 static enum XML_Error 5865 static enum XML_Error 5866 appendAttributeValue(XML_Parser parser, const 5866 appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, 5867 const char *ptr, const c 5867 const char *ptr, const char *end, STRING_POOL *pool, 5868 enum XML_Account account 5868 enum XML_Account account) { 5869 DTD *const dtd = parser->m_dtd; /* save one 5869 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 5870 #ifndef XML_DTD 5870 #ifndef XML_DTD 5871 UNUSED_P(account); 5871 UNUSED_P(account); 5872 #endif 5872 #endif 5873 5873 5874 for (;;) { 5874 for (;;) { 5875 const char *next 5875 const char *next 5876 = ptr; /* XmlAttributeValueTok doesn' 5876 = ptr; /* XmlAttributeValueTok doesn't always set the last arg */ 5877 int tok = XmlAttributeValueTok(enc, ptr, 5877 int tok = XmlAttributeValueTok(enc, ptr, end, &next); 5878 #ifdef XML_DTD 5878 #ifdef XML_DTD 5879 if (! accountingDiffTolerated(parser, tok 5879 if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) { 5880 accountingOnAbort(parser); 5880 accountingOnAbort(parser); 5881 return XML_ERROR_AMPLIFICATION_LIMIT_BR 5881 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 5882 } 5882 } 5883 #endif 5883 #endif 5884 switch (tok) { 5884 switch (tok) { 5885 case XML_TOK_NONE: 5885 case XML_TOK_NONE: 5886 return XML_ERROR_NONE; 5886 return XML_ERROR_NONE; 5887 case XML_TOK_INVALID: 5887 case XML_TOK_INVALID: 5888 if (enc == parser->m_encoding) 5888 if (enc == parser->m_encoding) 5889 parser->m_eventPtr = next; 5889 parser->m_eventPtr = next; 5890 return XML_ERROR_INVALID_TOKEN; 5890 return XML_ERROR_INVALID_TOKEN; 5891 case XML_TOK_PARTIAL: 5891 case XML_TOK_PARTIAL: 5892 if (enc == parser->m_encoding) 5892 if (enc == parser->m_encoding) 5893 parser->m_eventPtr = ptr; 5893 parser->m_eventPtr = ptr; 5894 return XML_ERROR_INVALID_TOKEN; 5894 return XML_ERROR_INVALID_TOKEN; 5895 case XML_TOK_CHAR_REF: { 5895 case XML_TOK_CHAR_REF: { 5896 XML_Char buf[XML_ENCODE_MAX]; 5896 XML_Char buf[XML_ENCODE_MAX]; 5897 int i; 5897 int i; 5898 int n = XmlCharRefNumber(enc, ptr); 5898 int n = XmlCharRefNumber(enc, ptr); 5899 if (n < 0) { 5899 if (n < 0) { 5900 if (enc == parser->m_encoding) 5900 if (enc == parser->m_encoding) 5901 parser->m_eventPtr = ptr; 5901 parser->m_eventPtr = ptr; 5902 return XML_ERROR_BAD_CHAR_REF; 5902 return XML_ERROR_BAD_CHAR_REF; 5903 } 5903 } 5904 if (! isCdata && n == 0x20 /* space */ 5904 if (! isCdata && n == 0x20 /* space */ 5905 && (poolLength(pool) == 0 || poolLa 5905 && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 5906 break; 5906 break; 5907 n = XmlEncode(n, (ICHAR *)buf); 5907 n = XmlEncode(n, (ICHAR *)buf); 5908 /* The XmlEncode() functions can never 5908 /* The XmlEncode() functions can never return 0 here. That 5909 * error return happens if the code poi 5909 * error return happens if the code point passed in is either 5910 * negative or greater than or equal to 5910 * negative or greater than or equal to 0x110000. The 5911 * XmlCharRefNumber() functions will al 5911 * XmlCharRefNumber() functions will all return a number 5912 * strictly less than 0x110000 or a neg 5912 * strictly less than 0x110000 or a negative value if an error 5913 * occurred. The negative value is int 5913 * occurred. The negative value is intercepted above, so 5914 * XmlEncode() is never passed a value 5914 * XmlEncode() is never passed a value it might return an 5915 * error for. 5915 * error for. 5916 */ 5916 */ 5917 for (i = 0; i < n; i++) { 5917 for (i = 0; i < n; i++) { 5918 if (! poolAppendChar(pool, buf[i])) 5918 if (! poolAppendChar(pool, buf[i])) 5919 return XML_ERROR_NO_MEMORY; 5919 return XML_ERROR_NO_MEMORY; 5920 } 5920 } 5921 } break; 5921 } break; 5922 case XML_TOK_DATA_CHARS: 5922 case XML_TOK_DATA_CHARS: 5923 if (! poolAppend(pool, enc, ptr, next)) 5923 if (! poolAppend(pool, enc, ptr, next)) 5924 return XML_ERROR_NO_MEMORY; 5924 return XML_ERROR_NO_MEMORY; 5925 break; 5925 break; 5926 case XML_TOK_TRAILING_CR: 5926 case XML_TOK_TRAILING_CR: 5927 next = ptr + enc->minBytesPerChar; 5927 next = ptr + enc->minBytesPerChar; 5928 /* fall through */ 5928 /* fall through */ 5929 case XML_TOK_ATTRIBUTE_VALUE_S: 5929 case XML_TOK_ATTRIBUTE_VALUE_S: 5930 case XML_TOK_DATA_NEWLINE: 5930 case XML_TOK_DATA_NEWLINE: 5931 if (! isCdata && (poolLength(pool) == 0 5931 if (! isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) 5932 break; 5932 break; 5933 if (! poolAppendChar(pool, 0x20)) 5933 if (! poolAppendChar(pool, 0x20)) 5934 return XML_ERROR_NO_MEMORY; 5934 return XML_ERROR_NO_MEMORY; 5935 break; 5935 break; 5936 case XML_TOK_ENTITY_REF: { 5936 case XML_TOK_ENTITY_REF: { 5937 const XML_Char *name; 5937 const XML_Char *name; 5938 ENTITY *entity; 5938 ENTITY *entity; 5939 char checkEntityDecl; 5939 char checkEntityDecl; 5940 XML_Char ch = (XML_Char)XmlPredefinedEn 5940 XML_Char ch = (XML_Char)XmlPredefinedEntityName( 5941 enc, ptr + enc->minBytesPerChar, ne 5941 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); 5942 if (ch) { 5942 if (ch) { 5943 #ifdef XML_DTD 5943 #ifdef XML_DTD 5944 /* NOTE: We are replacing 4-6 charact 5944 /* NOTE: We are replacing 4-6 characters original input for 1 character 5945 * so there is no amplification 5945 * so there is no amplification and hence recording without 5946 * protection. */ 5946 * protection. */ 5947 accountingDiffTolerated(parser, tok, 5947 accountingDiffTolerated(parser, tok, (char *)&ch, 5948 ((char *)&ch) 5948 ((char *)&ch) + sizeof(XML_Char), __LINE__, 5949 XML_ACCOUNT_E 5949 XML_ACCOUNT_ENTITY_EXPANSION); 5950 #endif /* XML_DTD */ 5950 #endif /* XML_DTD */ 5951 if (! poolAppendChar(pool, ch)) 5951 if (! poolAppendChar(pool, ch)) 5952 return XML_ERROR_NO_MEMORY; 5952 return XML_ERROR_NO_MEMORY; 5953 break; 5953 break; 5954 } 5954 } 5955 name = poolStoreString(&parser->m_temp2 5955 name = poolStoreString(&parser->m_temp2Pool, enc, 5956 ptr + enc->minBy 5956 ptr + enc->minBytesPerChar, 5957 next - enc->minB 5957 next - enc->minBytesPerChar); 5958 if (! name) 5958 if (! name) 5959 return XML_ERROR_NO_MEMORY; 5959 return XML_ERROR_NO_MEMORY; 5960 entity = (ENTITY *)lookup(parser, &dtd- 5960 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0); 5961 poolDiscard(&parser->m_temp2Pool); 5961 poolDiscard(&parser->m_temp2Pool); 5962 /* First, determine if a check for an e 5962 /* First, determine if a check for an existing declaration is needed; 5963 if yes, check that the entity exists 5963 if yes, check that the entity exists, and that it is internal. 5964 */ 5964 */ 5965 if (pool == &dtd->pool) /* are we calle 5965 if (pool == &dtd->pool) /* are we called from prolog? */ 5966 checkEntityDecl = 5966 checkEntityDecl = 5967 #ifdef XML_DTD 5967 #ifdef XML_DTD 5968 parser->m_prologState.documentEnt 5968 parser->m_prologState.documentEntity && 5969 #endif /* XML_DTD */ 5969 #endif /* XML_DTD */ 5970 (dtd->standalone ? ! parser->m_op 5970 (dtd->standalone ? ! parser->m_openInternalEntities 5971 : ! dtd->hasPara 5971 : ! dtd->hasParamEntityRefs); 5972 else /* if (pool == &parser->m_tempPool 5972 else /* if (pool == &parser->m_tempPool): we are called from content */ 5973 checkEntityDecl = ! dtd->hasParamEnti 5973 checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone; 5974 if (checkEntityDecl) { 5974 if (checkEntityDecl) { 5975 if (! entity) 5975 if (! entity) 5976 return XML_ERROR_UNDEFINED_ENTITY; 5976 return XML_ERROR_UNDEFINED_ENTITY; 5977 else if (! entity->is_internal) 5977 else if (! entity->is_internal) 5978 return XML_ERROR_ENTITY_DECLARED_IN 5978 return XML_ERROR_ENTITY_DECLARED_IN_PE; 5979 } else if (! entity) { 5979 } else if (! entity) { 5980 /* Cannot report skipped entity here 5980 /* Cannot report skipped entity here - see comments on 5981 parser->m_skippedEntityHandler. 5981 parser->m_skippedEntityHandler. 5982 if (parser->m_skippedEntityHandler) 5982 if (parser->m_skippedEntityHandler) 5983 parser->m_skippedEntityHandler(pars 5983 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); 5984 */ 5984 */ 5985 /* Cannot call the default handler be 5985 /* Cannot call the default handler because this would be 5986 out of sync with the call to the s 5986 out of sync with the call to the startElementHandler. 5987 if ((pool == &parser->m_tempPool) && 5987 if ((pool == &parser->m_tempPool) && parser->m_defaultHandler) 5988 reportDefault(parser, enc, ptr, nex 5988 reportDefault(parser, enc, ptr, next); 5989 */ 5989 */ 5990 break; 5990 break; 5991 } 5991 } 5992 if (entity->open) { 5992 if (entity->open) { 5993 if (enc == parser->m_encoding) { 5993 if (enc == parser->m_encoding) { 5994 /* It does not appear that this lin 5994 /* It does not appear that this line can be executed. 5995 * 5995 * 5996 * The "if (entity->open)" check ca 5996 * The "if (entity->open)" check catches recursive entity 5997 * definitions. In order to be cal 5997 * definitions. In order to be called with an open 5998 * entity, it must have gone throug 5998 * entity, it must have gone through this code before and 5999 * been through the recursive call 5999 * been through the recursive call to 6000 * appendAttributeValue() some line 6000 * appendAttributeValue() some lines below. That call 6001 * sets the local encoding ("enc") 6001 * sets the local encoding ("enc") to the parser's 6002 * internal encoding (internal_utf8 6002 * internal encoding (internal_utf8 or internal_utf16), 6003 * which can never be the same as t 6003 * which can never be the same as the principle encoding. 6004 * It doesn't appear there is anoth 6004 * It doesn't appear there is another code path that gets 6005 * here with entity->open being TRU 6005 * here with entity->open being TRUE. 6006 * 6006 * 6007 * Since it is not certain that thi 6007 * Since it is not certain that this logic is watertight, 6008 * we keep the line and merely excl 6008 * we keep the line and merely exclude it from coverage 6009 * tests. 6009 * tests. 6010 */ 6010 */ 6011 parser->m_eventPtr = ptr; /* LCOV_E 6011 parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */ 6012 } 6012 } 6013 return XML_ERROR_RECURSIVE_ENTITY_REF 6013 return XML_ERROR_RECURSIVE_ENTITY_REF; 6014 } 6014 } 6015 if (entity->notation) { 6015 if (entity->notation) { 6016 if (enc == parser->m_encoding) 6016 if (enc == parser->m_encoding) 6017 parser->m_eventPtr = ptr; 6017 parser->m_eventPtr = ptr; 6018 return XML_ERROR_BINARY_ENTITY_REF; 6018 return XML_ERROR_BINARY_ENTITY_REF; 6019 } 6019 } 6020 if (! entity->textPtr) { 6020 if (! entity->textPtr) { 6021 if (enc == parser->m_encoding) 6021 if (enc == parser->m_encoding) 6022 parser->m_eventPtr = ptr; 6022 parser->m_eventPtr = ptr; 6023 return XML_ERROR_ATTRIBUTE_EXTERNAL_E 6023 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; 6024 } else { 6024 } else { 6025 enum XML_Error result; 6025 enum XML_Error result; 6026 const XML_Char *textEnd = entity->tex 6026 const XML_Char *textEnd = entity->textPtr + entity->textLen; 6027 entity->open = XML_TRUE; 6027 entity->open = XML_TRUE; 6028 #ifdef XML_DTD 6028 #ifdef XML_DTD 6029 entityTrackingOnOpen(parser, entity, 6029 entityTrackingOnOpen(parser, entity, __LINE__); 6030 #endif 6030 #endif 6031 result = appendAttributeValue(parser, 6031 result = appendAttributeValue(parser, parser->m_internalEncoding, 6032 isCdata 6032 isCdata, (const char *)entity->textPtr, 6033 (const 6033 (const char *)textEnd, pool, 6034 XML_ACC 6034 XML_ACCOUNT_ENTITY_EXPANSION); 6035 #ifdef XML_DTD 6035 #ifdef XML_DTD 6036 entityTrackingOnClose(parser, entity, 6036 entityTrackingOnClose(parser, entity, __LINE__); 6037 #endif 6037 #endif 6038 entity->open = XML_FALSE; 6038 entity->open = XML_FALSE; 6039 if (result) 6039 if (result) 6040 return result; 6040 return result; 6041 } 6041 } 6042 } break; 6042 } break; 6043 default: 6043 default: 6044 /* The only token returned by XmlAttrib 6044 /* The only token returned by XmlAttributeValueTok() that does 6045 * not have an explicit case here is XM 6045 * not have an explicit case here is XML_TOK_PARTIAL_CHAR. 6046 * Getting that would require an entity 6046 * Getting that would require an entity name to contain an 6047 * incomplete XML character (e.g. \xE2\ 6047 * incomplete XML character (e.g. \xE2\x82); however previous 6048 * tokenisers will have already recogni 6048 * tokenisers will have already recognised and rejected such 6049 * names before XmlAttributeValueTok() 6049 * names before XmlAttributeValueTok() gets a look-in. This 6050 * default case should be retained as a 6050 * default case should be retained as a safety net, but the code 6051 * excluded from coverage tests. 6051 * excluded from coverage tests. 6052 * 6052 * 6053 * LCOV_EXCL_START 6053 * LCOV_EXCL_START 6054 */ 6054 */ 6055 if (enc == parser->m_encoding) 6055 if (enc == parser->m_encoding) 6056 parser->m_eventPtr = ptr; 6056 parser->m_eventPtr = ptr; 6057 return XML_ERROR_UNEXPECTED_STATE; 6057 return XML_ERROR_UNEXPECTED_STATE; 6058 /* LCOV_EXCL_STOP */ 6058 /* LCOV_EXCL_STOP */ 6059 } 6059 } 6060 ptr = next; 6060 ptr = next; 6061 } 6061 } 6062 /* not reached */ 6062 /* not reached */ 6063 } 6063 } 6064 6064 6065 static enum XML_Error 6065 static enum XML_Error 6066 storeEntityValue(XML_Parser parser, const ENC 6066 storeEntityValue(XML_Parser parser, const ENCODING *enc, 6067 const char *entityTextPtr, c 6067 const char *entityTextPtr, const char *entityTextEnd, 6068 enum XML_Account account) { 6068 enum XML_Account account) { 6069 DTD *const dtd = parser->m_dtd; /* save one 6069 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 6070 STRING_POOL *pool = &(dtd->entityValuePool) 6070 STRING_POOL *pool = &(dtd->entityValuePool); 6071 enum XML_Error result = XML_ERROR_NONE; 6071 enum XML_Error result = XML_ERROR_NONE; 6072 #ifdef XML_DTD 6072 #ifdef XML_DTD 6073 int oldInEntityValue = parser->m_prologStat 6073 int oldInEntityValue = parser->m_prologState.inEntityValue; 6074 parser->m_prologState.inEntityValue = 1; 6074 parser->m_prologState.inEntityValue = 1; 6075 #else 6075 #else 6076 UNUSED_P(account); 6076 UNUSED_P(account); 6077 #endif /* XML_DTD */ 6077 #endif /* XML_DTD */ 6078 /* never return Null for the value argument 6078 /* never return Null for the value argument in EntityDeclHandler, 6079 since this would indicate an external en 6079 since this would indicate an external entity; therefore we 6080 have to make sure that entityValuePool.s 6080 have to make sure that entityValuePool.start is not null */ 6081 if (! pool->blocks) { 6081 if (! pool->blocks) { 6082 if (! poolGrow(pool)) 6082 if (! poolGrow(pool)) 6083 return XML_ERROR_NO_MEMORY; 6083 return XML_ERROR_NO_MEMORY; 6084 } 6084 } 6085 6085 6086 for (;;) { 6086 for (;;) { 6087 const char *next 6087 const char *next 6088 = entityTextPtr; /* XmlEntityValueTok 6088 = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */ 6089 int tok = XmlEntityValueTok(enc, entityTe 6089 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); 6090 6090 6091 #ifdef XML_DTD 6091 #ifdef XML_DTD 6092 if (! accountingDiffTolerated(parser, tok 6092 if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__, 6093 account)) { 6093 account)) { 6094 accountingOnAbort(parser); 6094 accountingOnAbort(parser); 6095 result = XML_ERROR_AMPLIFICATION_LIMIT_ 6095 result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH; 6096 goto endEntityValue; 6096 goto endEntityValue; 6097 } 6097 } 6098 #endif 6098 #endif 6099 6099 6100 switch (tok) { 6100 switch (tok) { 6101 case XML_TOK_PARAM_ENTITY_REF: 6101 case XML_TOK_PARAM_ENTITY_REF: 6102 #ifdef XML_DTD 6102 #ifdef XML_DTD 6103 if (parser->m_isParamEntity || enc != p 6103 if (parser->m_isParamEntity || enc != parser->m_encoding) { 6104 const XML_Char *name; 6104 const XML_Char *name; 6105 ENTITY *entity; 6105 ENTITY *entity; 6106 name = poolStoreString(&parser->m_tem 6106 name = poolStoreString(&parser->m_tempPool, enc, 6107 entityTextPtr 6107 entityTextPtr + enc->minBytesPerChar, 6108 next - enc->mi 6108 next - enc->minBytesPerChar); 6109 if (! name) { 6109 if (! name) { 6110 result = XML_ERROR_NO_MEMORY; 6110 result = XML_ERROR_NO_MEMORY; 6111 goto endEntityValue; 6111 goto endEntityValue; 6112 } 6112 } 6113 entity = (ENTITY *)lookup(parser, &dt 6113 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0); 6114 poolDiscard(&parser->m_tempPool); 6114 poolDiscard(&parser->m_tempPool); 6115 if (! entity) { 6115 if (! entity) { 6116 /* not a well-formedness error - se 6116 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ 6117 /* cannot report skipped entity her 6117 /* cannot report skipped entity here - see comments on 6118 parser->m_skippedEntityHandler 6118 parser->m_skippedEntityHandler 6119 if (parser->m_skippedEntityHandler) 6119 if (parser->m_skippedEntityHandler) 6120 parser->m_skippedEntityHandler(pa 6120 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0); 6121 */ 6121 */ 6122 dtd->keepProcessing = dtd->standalo 6122 dtd->keepProcessing = dtd->standalone; 6123 goto endEntityValue; 6123 goto endEntityValue; 6124 } 6124 } 6125 if (entity->open) { 6125 if (entity->open) { 6126 if (enc == parser->m_encoding) 6126 if (enc == parser->m_encoding) 6127 parser->m_eventPtr = entityTextPt 6127 parser->m_eventPtr = entityTextPtr; 6128 result = XML_ERROR_RECURSIVE_ENTITY 6128 result = XML_ERROR_RECURSIVE_ENTITY_REF; 6129 goto endEntityValue; 6129 goto endEntityValue; 6130 } 6130 } 6131 if (entity->systemId) { 6131 if (entity->systemId) { 6132 if (parser->m_externalEntityRefHand 6132 if (parser->m_externalEntityRefHandler) { 6133 dtd->paramEntityRead = XML_FALSE; 6133 dtd->paramEntityRead = XML_FALSE; 6134 entity->open = XML_TRUE; 6134 entity->open = XML_TRUE; 6135 entityTrackingOnOpen(parser, enti 6135 entityTrackingOnOpen(parser, entity, __LINE__); 6136 if (! parser->m_externalEntityRef 6136 if (! parser->m_externalEntityRefHandler( 6137 parser->m_externalEntityR 6137 parser->m_externalEntityRefHandlerArg, 0, entity->base, 6138 entity->systemId, entity- 6138 entity->systemId, entity->publicId)) { 6139 entityTrackingOnClose(parser, e 6139 entityTrackingOnClose(parser, entity, __LINE__); 6140 entity->open = XML_FALSE; 6140 entity->open = XML_FALSE; 6141 result = XML_ERROR_EXTERNAL_ENT 6141 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; 6142 goto endEntityValue; 6142 goto endEntityValue; 6143 } 6143 } 6144 entityTrackingOnClose(parser, ent 6144 entityTrackingOnClose(parser, entity, __LINE__); 6145 entity->open = XML_FALSE; 6145 entity->open = XML_FALSE; 6146 if (! dtd->paramEntityRead) 6146 if (! dtd->paramEntityRead) 6147 dtd->keepProcessing = dtd->stan 6147 dtd->keepProcessing = dtd->standalone; 6148 } else 6148 } else 6149 dtd->keepProcessing = dtd->standa 6149 dtd->keepProcessing = dtd->standalone; 6150 } else { 6150 } else { 6151 entity->open = XML_TRUE; 6151 entity->open = XML_TRUE; 6152 entityTrackingOnOpen(parser, entity 6152 entityTrackingOnOpen(parser, entity, __LINE__); 6153 result = storeEntityValue( 6153 result = storeEntityValue( 6154 parser, parser->m_internalEncod 6154 parser, parser->m_internalEncoding, (const char *)entity->textPtr, 6155 (const char *)(entity->textPtr 6155 (const char *)(entity->textPtr + entity->textLen), 6156 XML_ACCOUNT_ENTITY_EXPANSION); 6156 XML_ACCOUNT_ENTITY_EXPANSION); 6157 entityTrackingOnClose(parser, entit 6157 entityTrackingOnClose(parser, entity, __LINE__); 6158 entity->open = XML_FALSE; 6158 entity->open = XML_FALSE; 6159 if (result) 6159 if (result) 6160 goto endEntityValue; 6160 goto endEntityValue; 6161 } 6161 } 6162 break; 6162 break; 6163 } 6163 } 6164 #endif /* XML_DTD */ 6164 #endif /* XML_DTD */ 6165 /* In the internal subset, PE reference 6165 /* In the internal subset, PE references are not legal 6166 within markup declarations, e.g enti 6166 within markup declarations, e.g entity values in this case. */ 6167 parser->m_eventPtr = entityTextPtr; 6167 parser->m_eventPtr = entityTextPtr; 6168 result = XML_ERROR_PARAM_ENTITY_REF; 6168 result = XML_ERROR_PARAM_ENTITY_REF; 6169 goto endEntityValue; 6169 goto endEntityValue; 6170 case XML_TOK_NONE: 6170 case XML_TOK_NONE: 6171 result = XML_ERROR_NONE; 6171 result = XML_ERROR_NONE; 6172 goto endEntityValue; 6172 goto endEntityValue; 6173 case XML_TOK_ENTITY_REF: 6173 case XML_TOK_ENTITY_REF: 6174 case XML_TOK_DATA_CHARS: 6174 case XML_TOK_DATA_CHARS: 6175 if (! poolAppend(pool, enc, entityTextP 6175 if (! poolAppend(pool, enc, entityTextPtr, next)) { 6176 result = XML_ERROR_NO_MEMORY; 6176 result = XML_ERROR_NO_MEMORY; 6177 goto endEntityValue; 6177 goto endEntityValue; 6178 } 6178 } 6179 break; 6179 break; 6180 case XML_TOK_TRAILING_CR: 6180 case XML_TOK_TRAILING_CR: 6181 next = entityTextPtr + enc->minBytesPer 6181 next = entityTextPtr + enc->minBytesPerChar; 6182 /* fall through */ 6182 /* fall through */ 6183 case XML_TOK_DATA_NEWLINE: 6183 case XML_TOK_DATA_NEWLINE: 6184 if (pool->end == pool->ptr && ! poolGro 6184 if (pool->end == pool->ptr && ! poolGrow(pool)) { 6185 result = XML_ERROR_NO_MEMORY; 6185 result = XML_ERROR_NO_MEMORY; 6186 goto endEntityValue; 6186 goto endEntityValue; 6187 } 6187 } 6188 *(pool->ptr)++ = 0xA; 6188 *(pool->ptr)++ = 0xA; 6189 break; 6189 break; 6190 case XML_TOK_CHAR_REF: { 6190 case XML_TOK_CHAR_REF: { 6191 XML_Char buf[XML_ENCODE_MAX]; 6191 XML_Char buf[XML_ENCODE_MAX]; 6192 int i; 6192 int i; 6193 int n = XmlCharRefNumber(enc, entityTex 6193 int n = XmlCharRefNumber(enc, entityTextPtr); 6194 if (n < 0) { 6194 if (n < 0) { 6195 if (enc == parser->m_encoding) 6195 if (enc == parser->m_encoding) 6196 parser->m_eventPtr = entityTextPtr; 6196 parser->m_eventPtr = entityTextPtr; 6197 result = XML_ERROR_BAD_CHAR_REF; 6197 result = XML_ERROR_BAD_CHAR_REF; 6198 goto endEntityValue; 6198 goto endEntityValue; 6199 } 6199 } 6200 n = XmlEncode(n, (ICHAR *)buf); 6200 n = XmlEncode(n, (ICHAR *)buf); 6201 /* The XmlEncode() functions can never 6201 /* The XmlEncode() functions can never return 0 here. That 6202 * error return happens if the code poi 6202 * error return happens if the code point passed in is either 6203 * negative or greater than or equal to 6203 * negative or greater than or equal to 0x110000. The 6204 * XmlCharRefNumber() functions will al 6204 * XmlCharRefNumber() functions will all return a number 6205 * strictly less than 0x110000 or a neg 6205 * strictly less than 0x110000 or a negative value if an error 6206 * occurred. The negative value is int 6206 * occurred. The negative value is intercepted above, so 6207 * XmlEncode() is never passed a value 6207 * XmlEncode() is never passed a value it might return an 6208 * error for. 6208 * error for. 6209 */ 6209 */ 6210 for (i = 0; i < n; i++) { 6210 for (i = 0; i < n; i++) { 6211 if (pool->end == pool->ptr && ! poolG 6211 if (pool->end == pool->ptr && ! poolGrow(pool)) { 6212 result = XML_ERROR_NO_MEMORY; 6212 result = XML_ERROR_NO_MEMORY; 6213 goto endEntityValue; 6213 goto endEntityValue; 6214 } 6214 } 6215 *(pool->ptr)++ = buf[i]; 6215 *(pool->ptr)++ = buf[i]; 6216 } 6216 } 6217 } break; 6217 } break; 6218 case XML_TOK_PARTIAL: 6218 case XML_TOK_PARTIAL: 6219 if (enc == parser->m_encoding) 6219 if (enc == parser->m_encoding) 6220 parser->m_eventPtr = entityTextPtr; 6220 parser->m_eventPtr = entityTextPtr; 6221 result = XML_ERROR_INVALID_TOKEN; 6221 result = XML_ERROR_INVALID_TOKEN; 6222 goto endEntityValue; 6222 goto endEntityValue; 6223 case XML_TOK_INVALID: 6223 case XML_TOK_INVALID: 6224 if (enc == parser->m_encoding) 6224 if (enc == parser->m_encoding) 6225 parser->m_eventPtr = next; 6225 parser->m_eventPtr = next; 6226 result = XML_ERROR_INVALID_TOKEN; 6226 result = XML_ERROR_INVALID_TOKEN; 6227 goto endEntityValue; 6227 goto endEntityValue; 6228 default: 6228 default: 6229 /* This default case should be unnecess 6229 /* This default case should be unnecessary -- all the tokens 6230 * that XmlEntityValueTok() can return 6230 * that XmlEntityValueTok() can return have their own explicit 6231 * cases -- but should be retained for 6231 * cases -- but should be retained for safety. We do however 6232 * exclude it from the coverage statist 6232 * exclude it from the coverage statistics. 6233 * 6233 * 6234 * LCOV_EXCL_START 6234 * LCOV_EXCL_START 6235 */ 6235 */ 6236 if (enc == parser->m_encoding) 6236 if (enc == parser->m_encoding) 6237 parser->m_eventPtr = entityTextPtr; 6237 parser->m_eventPtr = entityTextPtr; 6238 result = XML_ERROR_UNEXPECTED_STATE; 6238 result = XML_ERROR_UNEXPECTED_STATE; 6239 goto endEntityValue; 6239 goto endEntityValue; 6240 /* LCOV_EXCL_STOP */ 6240 /* LCOV_EXCL_STOP */ 6241 } 6241 } 6242 entityTextPtr = next; 6242 entityTextPtr = next; 6243 } 6243 } 6244 endEntityValue: 6244 endEntityValue: 6245 #ifdef XML_DTD 6245 #ifdef XML_DTD 6246 parser->m_prologState.inEntityValue = oldIn 6246 parser->m_prologState.inEntityValue = oldInEntityValue; 6247 #endif /* XML_DTD */ 6247 #endif /* XML_DTD */ 6248 return result; 6248 return result; 6249 } 6249 } 6250 6250 6251 static void FASTCALL 6251 static void FASTCALL 6252 normalizeLines(XML_Char *s) { 6252 normalizeLines(XML_Char *s) { 6253 XML_Char *p; 6253 XML_Char *p; 6254 for (;; s++) { 6254 for (;; s++) { 6255 if (*s == XML_T('\0')) 6255 if (*s == XML_T('\0')) 6256 return; 6256 return; 6257 if (*s == 0xD) 6257 if (*s == 0xD) 6258 break; 6258 break; 6259 } 6259 } 6260 p = s; 6260 p = s; 6261 do { 6261 do { 6262 if (*s == 0xD) { 6262 if (*s == 0xD) { 6263 *p++ = 0xA; 6263 *p++ = 0xA; 6264 if (*++s == 0xA) 6264 if (*++s == 0xA) 6265 s++; 6265 s++; 6266 } else 6266 } else 6267 *p++ = *s++; 6267 *p++ = *s++; 6268 } while (*s); 6268 } while (*s); 6269 *p = XML_T('\0'); 6269 *p = XML_T('\0'); 6270 } 6270 } 6271 6271 6272 static int 6272 static int 6273 reportProcessingInstruction(XML_Parser parser 6273 reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, 6274 const char *start 6274 const char *start, const char *end) { 6275 const XML_Char *target; 6275 const XML_Char *target; 6276 XML_Char *data; 6276 XML_Char *data; 6277 const char *tem; 6277 const char *tem; 6278 if (! parser->m_processingInstructionHandle 6278 if (! parser->m_processingInstructionHandler) { 6279 if (parser->m_defaultHandler) 6279 if (parser->m_defaultHandler) 6280 reportDefault(parser, enc, start, end); 6280 reportDefault(parser, enc, start, end); 6281 return 1; 6281 return 1; 6282 } 6282 } 6283 start += enc->minBytesPerChar * 2; 6283 start += enc->minBytesPerChar * 2; 6284 tem = start + XmlNameLength(enc, start); 6284 tem = start + XmlNameLength(enc, start); 6285 target = poolStoreString(&parser->m_tempPoo 6285 target = poolStoreString(&parser->m_tempPool, enc, start, tem); 6286 if (! target) 6286 if (! target) 6287 return 0; 6287 return 0; 6288 poolFinish(&parser->m_tempPool); 6288 poolFinish(&parser->m_tempPool); 6289 data = poolStoreString(&parser->m_tempPool, 6289 data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem), 6290 end - enc->minBytesP 6290 end - enc->minBytesPerChar * 2); 6291 if (! data) 6291 if (! data) 6292 return 0; 6292 return 0; 6293 normalizeLines(data); 6293 normalizeLines(data); 6294 parser->m_processingInstructionHandler(pars 6294 parser->m_processingInstructionHandler(parser->m_handlerArg, target, data); 6295 poolClear(&parser->m_tempPool); 6295 poolClear(&parser->m_tempPool); 6296 return 1; 6296 return 1; 6297 } 6297 } 6298 6298 6299 static int 6299 static int 6300 reportComment(XML_Parser parser, const ENCODI 6300 reportComment(XML_Parser parser, const ENCODING *enc, const char *start, 6301 const char *end) { 6301 const char *end) { 6302 XML_Char *data; 6302 XML_Char *data; 6303 if (! parser->m_commentHandler) { 6303 if (! parser->m_commentHandler) { 6304 if (parser->m_defaultHandler) 6304 if (parser->m_defaultHandler) 6305 reportDefault(parser, enc, start, end); 6305 reportDefault(parser, enc, start, end); 6306 return 1; 6306 return 1; 6307 } 6307 } 6308 data = poolStoreString(&parser->m_tempPool, 6308 data = poolStoreString(&parser->m_tempPool, enc, 6309 start + enc->minByte 6309 start + enc->minBytesPerChar * 4, 6310 end - enc->minBytesP 6310 end - enc->minBytesPerChar * 3); 6311 if (! data) 6311 if (! data) 6312 return 0; 6312 return 0; 6313 normalizeLines(data); 6313 normalizeLines(data); 6314 parser->m_commentHandler(parser->m_handlerA 6314 parser->m_commentHandler(parser->m_handlerArg, data); 6315 poolClear(&parser->m_tempPool); 6315 poolClear(&parser->m_tempPool); 6316 return 1; 6316 return 1; 6317 } 6317 } 6318 6318 6319 static void 6319 static void 6320 reportDefault(XML_Parser parser, const ENCODI 6320 reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, 6321 const char *end) { 6321 const char *end) { 6322 if (MUST_CONVERT(enc, s)) { 6322 if (MUST_CONVERT(enc, s)) { 6323 enum XML_Convert_Result convert_res; 6323 enum XML_Convert_Result convert_res; 6324 const char **eventPP; 6324 const char **eventPP; 6325 const char **eventEndPP; 6325 const char **eventEndPP; 6326 if (enc == parser->m_encoding) { 6326 if (enc == parser->m_encoding) { 6327 eventPP = &parser->m_eventPtr; 6327 eventPP = &parser->m_eventPtr; 6328 eventEndPP = &parser->m_eventEndPtr; 6328 eventEndPP = &parser->m_eventEndPtr; 6329 } else { 6329 } else { 6330 /* To get here, two things must be true 6330 /* To get here, two things must be true; the parser must be 6331 * using a character encoding that is n 6331 * using a character encoding that is not the same as the 6332 * encoding passed in, and the encoding 6332 * encoding passed in, and the encoding passed in must need 6333 * conversion to the internal format (U 6333 * conversion to the internal format (UTF-8 unless XML_UNICODE 6334 * is defined). The only occasions on 6334 * is defined). The only occasions on which the encoding passed 6335 * in is not the same as the parser's e 6335 * in is not the same as the parser's encoding are when it is 6336 * the internal encoding (e.g. a previo 6336 * the internal encoding (e.g. a previously defined parameter 6337 * entity, already converted to interna 6337 * entity, already converted to internal format). This by 6338 * definition doesn't need conversion, 6338 * definition doesn't need conversion, so the whole branch never 6339 * gets executed. 6339 * gets executed. 6340 * 6340 * 6341 * For safety's sake we don't delete th 6341 * For safety's sake we don't delete these lines and merely 6342 * exclude them from coverage statistic 6342 * exclude them from coverage statistics. 6343 * 6343 * 6344 * LCOV_EXCL_START 6344 * LCOV_EXCL_START 6345 */ 6345 */ 6346 eventPP = &(parser->m_openInternalEntit 6346 eventPP = &(parser->m_openInternalEntities->internalEventPtr); 6347 eventEndPP = &(parser->m_openInternalEn 6347 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr); 6348 /* LCOV_EXCL_STOP */ 6348 /* LCOV_EXCL_STOP */ 6349 } 6349 } 6350 do { 6350 do { 6351 ICHAR *dataPtr = (ICHAR *)parser->m_dat 6351 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf; 6352 convert_res 6352 convert_res 6353 = XmlConvert(enc, &s, end, &dataPtr 6353 = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd); 6354 *eventEndPP = s; 6354 *eventEndPP = s; 6355 parser->m_defaultHandler(parser->m_hand 6355 parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, 6356 (int)(dataPtr 6356 (int)(dataPtr - (ICHAR *)parser->m_dataBuf)); 6357 *eventPP = s; 6357 *eventPP = s; 6358 } while ((convert_res != XML_CONVERT_COMP 6358 } while ((convert_res != XML_CONVERT_COMPLETED) 6359 && (convert_res != XML_CONVERT_I 6359 && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); 6360 } else 6360 } else 6361 parser->m_defaultHandler(parser->m_handle 6361 parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, 6362 (int)((XML_Char 6362 (int)((XML_Char *)end - (XML_Char *)s)); 6363 } 6363 } 6364 6364 6365 static int 6365 static int 6366 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE 6366 defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, 6367 XML_Bool isId, const XML_Char 6367 XML_Bool isId, const XML_Char *value, XML_Parser parser) { 6368 DEFAULT_ATTRIBUTE *att; 6368 DEFAULT_ATTRIBUTE *att; 6369 if (value || isId) { 6369 if (value || isId) { 6370 /* The handling of default attributes get 6370 /* The handling of default attributes gets messed up if we have 6371 a default which duplicates a non-defau 6371 a default which duplicates a non-default. */ 6372 int i; 6372 int i; 6373 for (i = 0; i < type->nDefaultAtts; i++) 6373 for (i = 0; i < type->nDefaultAtts; i++) 6374 if (attId == type->defaultAtts[i].id) 6374 if (attId == type->defaultAtts[i].id) 6375 return 1; 6375 return 1; 6376 if (isId && ! type->idAtt && ! attId->xml 6376 if (isId && ! type->idAtt && ! attId->xmlns) 6377 type->idAtt = attId; 6377 type->idAtt = attId; 6378 } 6378 } 6379 if (type->nDefaultAtts == type->allocDefaul 6379 if (type->nDefaultAtts == type->allocDefaultAtts) { 6380 if (type->allocDefaultAtts == 0) { 6380 if (type->allocDefaultAtts == 0) { 6381 type->allocDefaultAtts = 8; 6381 type->allocDefaultAtts = 8; 6382 type->defaultAtts = (DEFAULT_ATTRIBUTE 6382 type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC( 6383 parser, type->allocDefaultAtts * si 6383 parser, type->allocDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); 6384 if (! type->defaultAtts) { 6384 if (! type->defaultAtts) { 6385 type->allocDefaultAtts = 0; 6385 type->allocDefaultAtts = 0; 6386 return 0; 6386 return 0; 6387 } 6387 } 6388 } else { 6388 } else { 6389 DEFAULT_ATTRIBUTE *temp; 6389 DEFAULT_ATTRIBUTE *temp; 6390 6390 6391 /* Detect and prevent integer overflow 6391 /* Detect and prevent integer overflow */ 6392 if (type->allocDefaultAtts > INT_MAX / 6392 if (type->allocDefaultAtts > INT_MAX / 2) { 6393 return 0; 6393 return 0; 6394 } 6394 } 6395 6395 6396 int count = type->allocDefaultAtts * 2; 6396 int count = type->allocDefaultAtts * 2; 6397 6397 6398 /* Detect and prevent integer overflow. 6398 /* Detect and prevent integer overflow. 6399 * The preprocessor guard addresses the 6399 * The preprocessor guard addresses the "always false" warning 6400 * from -Wtype-limits on platforms wher 6400 * from -Wtype-limits on platforms where 6401 * sizeof(unsigned int) < sizeof(size_t 6401 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 6402 #if UINT_MAX >= SIZE_MAX 6402 #if UINT_MAX >= SIZE_MAX 6403 if ((unsigned)count > (size_t)(-1) / si 6403 if ((unsigned)count > (size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE)) { 6404 return 0; 6404 return 0; 6405 } 6405 } 6406 #endif 6406 #endif 6407 6407 6408 temp = (DEFAULT_ATTRIBUTE *)REALLOC(par 6408 temp = (DEFAULT_ATTRIBUTE *)REALLOC(parser, type->defaultAtts, 6409 (co 6409 (count * sizeof(DEFAULT_ATTRIBUTE))); 6410 if (temp == NULL) 6410 if (temp == NULL) 6411 return 0; 6411 return 0; 6412 type->allocDefaultAtts = count; 6412 type->allocDefaultAtts = count; 6413 type->defaultAtts = temp; 6413 type->defaultAtts = temp; 6414 } 6414 } 6415 } 6415 } 6416 att = type->defaultAtts + type->nDefaultAtt 6416 att = type->defaultAtts + type->nDefaultAtts; 6417 att->id = attId; 6417 att->id = attId; 6418 att->value = value; 6418 att->value = value; 6419 att->isCdata = isCdata; 6419 att->isCdata = isCdata; 6420 if (! isCdata) 6420 if (! isCdata) 6421 attId->maybeTokenized = XML_TRUE; 6421 attId->maybeTokenized = XML_TRUE; 6422 type->nDefaultAtts += 1; 6422 type->nDefaultAtts += 1; 6423 return 1; 6423 return 1; 6424 } 6424 } 6425 6425 6426 static int 6426 static int 6427 setElementTypePrefix(XML_Parser parser, ELEME 6427 setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { 6428 DTD *const dtd = parser->m_dtd; /* save one 6428 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 6429 const XML_Char *name; 6429 const XML_Char *name; 6430 for (name = elementType->name; *name; name+ 6430 for (name = elementType->name; *name; name++) { 6431 if (*name == XML_T(ASCII_COLON)) { 6431 if (*name == XML_T(ASCII_COLON)) { 6432 PREFIX *prefix; 6432 PREFIX *prefix; 6433 const XML_Char *s; 6433 const XML_Char *s; 6434 for (s = elementType->name; s != name; 6434 for (s = elementType->name; s != name; s++) { 6435 if (! poolAppendChar(&dtd->pool, *s)) 6435 if (! poolAppendChar(&dtd->pool, *s)) 6436 return 0; 6436 return 0; 6437 } 6437 } 6438 if (! poolAppendChar(&dtd->pool, XML_T( 6438 if (! poolAppendChar(&dtd->pool, XML_T('\0'))) 6439 return 0; 6439 return 0; 6440 prefix = (PREFIX *)lookup(parser, &dtd- 6440 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool), 6441 sizeof(PREFIX 6441 sizeof(PREFIX)); 6442 if (! prefix) 6442 if (! prefix) 6443 return 0; 6443 return 0; 6444 if (prefix->name == poolStart(&dtd->poo 6444 if (prefix->name == poolStart(&dtd->pool)) 6445 poolFinish(&dtd->pool); 6445 poolFinish(&dtd->pool); 6446 else 6446 else 6447 poolDiscard(&dtd->pool); 6447 poolDiscard(&dtd->pool); 6448 elementType->prefix = prefix; 6448 elementType->prefix = prefix; 6449 break; 6449 break; 6450 } 6450 } 6451 } 6451 } 6452 return 1; 6452 return 1; 6453 } 6453 } 6454 6454 6455 static ATTRIBUTE_ID * 6455 static ATTRIBUTE_ID * 6456 getAttributeId(XML_Parser parser, const ENCOD 6456 getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, 6457 const char *end) { 6457 const char *end) { 6458 DTD *const dtd = parser->m_dtd; /* save one 6458 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 6459 ATTRIBUTE_ID *id; 6459 ATTRIBUTE_ID *id; 6460 const XML_Char *name; 6460 const XML_Char *name; 6461 if (! poolAppendChar(&dtd->pool, XML_T('\0' 6461 if (! poolAppendChar(&dtd->pool, XML_T('\0'))) 6462 return NULL; 6462 return NULL; 6463 name = poolStoreString(&dtd->pool, enc, sta 6463 name = poolStoreString(&dtd->pool, enc, start, end); 6464 if (! name) 6464 if (! name) 6465 return NULL; 6465 return NULL; 6466 /* skip quotation mark - its storage will b 6466 /* skip quotation mark - its storage will be re-used (like in name[-1]) */ 6467 ++name; 6467 ++name; 6468 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->a 6468 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, 6469 sizeof(ATTRIBUT 6469 sizeof(ATTRIBUTE_ID)); 6470 if (! id) 6470 if (! id) 6471 return NULL; 6471 return NULL; 6472 if (id->name != name) 6472 if (id->name != name) 6473 poolDiscard(&dtd->pool); 6473 poolDiscard(&dtd->pool); 6474 else { 6474 else { 6475 poolFinish(&dtd->pool); 6475 poolFinish(&dtd->pool); 6476 if (! parser->m_ns) 6476 if (! parser->m_ns) 6477 ; 6477 ; 6478 else if (name[0] == XML_T(ASCII_x) && nam 6478 else if (name[0] == XML_T(ASCII_x) && name[1] == XML_T(ASCII_m) 6479 && name[2] == XML_T(ASCII_l) && 6479 && name[2] == XML_T(ASCII_l) && name[3] == XML_T(ASCII_n) 6480 && name[4] == XML_T(ASCII_s) 6480 && name[4] == XML_T(ASCII_s) 6481 && (name[5] == XML_T('\0') || na 6481 && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { 6482 if (name[5] == XML_T('\0')) 6482 if (name[5] == XML_T('\0')) 6483 id->prefix = &dtd->defaultPrefix; 6483 id->prefix = &dtd->defaultPrefix; 6484 else 6484 else 6485 id->prefix = (PREFIX *)lookup(parser, 6485 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, 6486 sizeof( 6486 sizeof(PREFIX)); 6487 id->xmlns = XML_TRUE; 6487 id->xmlns = XML_TRUE; 6488 } else { 6488 } else { 6489 int i; 6489 int i; 6490 for (i = 0; name[i]; i++) { 6490 for (i = 0; name[i]; i++) { 6491 /* attributes without prefix are *not 6491 /* attributes without prefix are *not* in the default namespace */ 6492 if (name[i] == XML_T(ASCII_COLON)) { 6492 if (name[i] == XML_T(ASCII_COLON)) { 6493 int j; 6493 int j; 6494 for (j = 0; j < i; j++) { 6494 for (j = 0; j < i; j++) { 6495 if (! poolAppendChar(&dtd->pool, 6495 if (! poolAppendChar(&dtd->pool, name[j])) 6496 return NULL; 6496 return NULL; 6497 } 6497 } 6498 if (! poolAppendChar(&dtd->pool, XM 6498 if (! poolAppendChar(&dtd->pool, XML_T('\0'))) 6499 return NULL; 6499 return NULL; 6500 id->prefix = (PREFIX *)lookup(parse 6500 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, 6501 poolS 6501 poolStart(&dtd->pool), sizeof(PREFIX)); 6502 if (! id->prefix) 6502 if (! id->prefix) 6503 return NULL; 6503 return NULL; 6504 if (id->prefix->name == poolStart(& 6504 if (id->prefix->name == poolStart(&dtd->pool)) 6505 poolFinish(&dtd->pool); 6505 poolFinish(&dtd->pool); 6506 else 6506 else 6507 poolDiscard(&dtd->pool); 6507 poolDiscard(&dtd->pool); 6508 break; 6508 break; 6509 } 6509 } 6510 } 6510 } 6511 } 6511 } 6512 } 6512 } 6513 return id; 6513 return id; 6514 } 6514 } 6515 6515 6516 #define CONTEXT_SEP XML_T(ASCII_FF) 6516 #define CONTEXT_SEP XML_T(ASCII_FF) 6517 6517 6518 static const XML_Char * 6518 static const XML_Char * 6519 getContext(XML_Parser parser) { 6519 getContext(XML_Parser parser) { 6520 DTD *const dtd = parser->m_dtd; /* save one 6520 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 6521 HASH_TABLE_ITER iter; 6521 HASH_TABLE_ITER iter; 6522 XML_Bool needSep = XML_FALSE; 6522 XML_Bool needSep = XML_FALSE; 6523 6523 6524 if (dtd->defaultPrefix.binding) { 6524 if (dtd->defaultPrefix.binding) { 6525 int i; 6525 int i; 6526 int len; 6526 int len; 6527 if (! poolAppendChar(&parser->m_tempPool, 6527 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) 6528 return NULL; 6528 return NULL; 6529 len = dtd->defaultPrefix.binding->uriLen; 6529 len = dtd->defaultPrefix.binding->uriLen; 6530 if (parser->m_namespaceSeparator) 6530 if (parser->m_namespaceSeparator) 6531 len--; 6531 len--; 6532 for (i = 0; i < len; i++) { 6532 for (i = 0; i < len; i++) { 6533 if (! poolAppendChar(&parser->m_tempPoo 6533 if (! poolAppendChar(&parser->m_tempPool, 6534 dtd->defaultPrefix 6534 dtd->defaultPrefix.binding->uri[i])) { 6535 /* Because of memory caching, I don't 6535 /* Because of memory caching, I don't believe this line can be 6536 * executed. 6536 * executed. 6537 * 6537 * 6538 * This is part of a loop copying the 6538 * This is part of a loop copying the default prefix binding 6539 * URI into the parser's temporary st 6539 * URI into the parser's temporary string pool. Previously, 6540 * that URI was copied into the same 6540 * that URI was copied into the same string pool, with a 6541 * terminating NUL character, as part 6541 * terminating NUL character, as part of setContext(). When 6542 * the pool was cleared, that leaves 6542 * the pool was cleared, that leaves a block definitely big 6543 * enough to hold the URI on the free 6543 * enough to hold the URI on the free block list of the pool. 6544 * The URI copy in getContext() there 6544 * The URI copy in getContext() therefore cannot run out of 6545 * memory. 6545 * memory. 6546 * 6546 * 6547 * If the pool is used between the se 6547 * If the pool is used between the setContext() and 6548 * getContext() calls, the worst it c 6548 * getContext() calls, the worst it can do is leave a bigger 6549 * block on the front of the free lis 6549 * block on the front of the free list. Given that this is 6550 * all somewhat inobvious and program 6550 * all somewhat inobvious and program logic can be changed, we 6551 * don't delete the line but we do ex 6551 * don't delete the line but we do exclude it from the test 6552 * coverage statistics. 6552 * coverage statistics. 6553 */ 6553 */ 6554 return NULL; /* LCOV_EXCL_LINE */ 6554 return NULL; /* LCOV_EXCL_LINE */ 6555 } 6555 } 6556 } 6556 } 6557 needSep = XML_TRUE; 6557 needSep = XML_TRUE; 6558 } 6558 } 6559 6559 6560 hashTableIterInit(&iter, &(dtd->prefixes)); 6560 hashTableIterInit(&iter, &(dtd->prefixes)); 6561 for (;;) { 6561 for (;;) { 6562 int i; 6562 int i; 6563 int len; 6563 int len; 6564 const XML_Char *s; 6564 const XML_Char *s; 6565 PREFIX *prefix = (PREFIX *)hashTableIterN 6565 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); 6566 if (! prefix) 6566 if (! prefix) 6567 break; 6567 break; 6568 if (! prefix->binding) { 6568 if (! prefix->binding) { 6569 /* This test appears to be (justifiable 6569 /* This test appears to be (justifiable) paranoia. There does 6570 * not seem to be a way of injecting a 6570 * not seem to be a way of injecting a prefix without a binding 6571 * that doesn't get errored long before 6571 * that doesn't get errored long before this function is called. 6572 * The test should remain for safety's 6572 * The test should remain for safety's sake, so we instead 6573 * exclude the following line from the 6573 * exclude the following line from the coverage statistics. 6574 */ 6574 */ 6575 continue; /* LCOV_EXCL_LINE */ 6575 continue; /* LCOV_EXCL_LINE */ 6576 } 6576 } 6577 if (needSep && ! poolAppendChar(&parser-> 6577 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) 6578 return NULL; 6578 return NULL; 6579 for (s = prefix->name; *s; s++) 6579 for (s = prefix->name; *s; s++) 6580 if (! poolAppendChar(&parser->m_tempPoo 6580 if (! poolAppendChar(&parser->m_tempPool, *s)) 6581 return NULL; 6581 return NULL; 6582 if (! poolAppendChar(&parser->m_tempPool, 6582 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS))) 6583 return NULL; 6583 return NULL; 6584 len = prefix->binding->uriLen; 6584 len = prefix->binding->uriLen; 6585 if (parser->m_namespaceSeparator) 6585 if (parser->m_namespaceSeparator) 6586 len--; 6586 len--; 6587 for (i = 0; i < len; i++) 6587 for (i = 0; i < len; i++) 6588 if (! poolAppendChar(&parser->m_tempPoo 6588 if (! poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i])) 6589 return NULL; 6589 return NULL; 6590 needSep = XML_TRUE; 6590 needSep = XML_TRUE; 6591 } 6591 } 6592 6592 6593 hashTableIterInit(&iter, &(dtd->generalEnti 6593 hashTableIterInit(&iter, &(dtd->generalEntities)); 6594 for (;;) { 6594 for (;;) { 6595 const XML_Char *s; 6595 const XML_Char *s; 6596 ENTITY *e = (ENTITY *)hashTableIterNext(& 6596 ENTITY *e = (ENTITY *)hashTableIterNext(&iter); 6597 if (! e) 6597 if (! e) 6598 break; 6598 break; 6599 if (! e->open) 6599 if (! e->open) 6600 continue; 6600 continue; 6601 if (needSep && ! poolAppendChar(&parser-> 6601 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP)) 6602 return NULL; 6602 return NULL; 6603 for (s = e->name; *s; s++) 6603 for (s = e->name; *s; s++) 6604 if (! poolAppendChar(&parser->m_tempPoo 6604 if (! poolAppendChar(&parser->m_tempPool, *s)) 6605 return 0; 6605 return 0; 6606 needSep = XML_TRUE; 6606 needSep = XML_TRUE; 6607 } 6607 } 6608 6608 6609 if (! poolAppendChar(&parser->m_tempPool, X 6609 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 6610 return NULL; 6610 return NULL; 6611 return parser->m_tempPool.start; 6611 return parser->m_tempPool.start; 6612 } 6612 } 6613 6613 6614 static XML_Bool 6614 static XML_Bool 6615 setContext(XML_Parser parser, const XML_Char 6615 setContext(XML_Parser parser, const XML_Char *context) { 6616 DTD *const dtd = parser->m_dtd; /* save one 6616 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 6617 const XML_Char *s = context; 6617 const XML_Char *s = context; 6618 6618 6619 while (*context != XML_T('\0')) { 6619 while (*context != XML_T('\0')) { 6620 if (*s == CONTEXT_SEP || *s == XML_T('\0' 6620 if (*s == CONTEXT_SEP || *s == XML_T('\0')) { 6621 ENTITY *e; 6621 ENTITY *e; 6622 if (! poolAppendChar(&parser->m_tempPoo 6622 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 6623 return XML_FALSE; 6623 return XML_FALSE; 6624 e = (ENTITY *)lookup(parser, &dtd->gene 6624 e = (ENTITY *)lookup(parser, &dtd->generalEntities, 6625 poolStart(&parser- 6625 poolStart(&parser->m_tempPool), 0); 6626 if (e) 6626 if (e) 6627 e->open = XML_TRUE; 6627 e->open = XML_TRUE; 6628 if (*s != XML_T('\0')) 6628 if (*s != XML_T('\0')) 6629 s++; 6629 s++; 6630 context = s; 6630 context = s; 6631 poolDiscard(&parser->m_tempPool); 6631 poolDiscard(&parser->m_tempPool); 6632 } else if (*s == XML_T(ASCII_EQUALS)) { 6632 } else if (*s == XML_T(ASCII_EQUALS)) { 6633 PREFIX *prefix; 6633 PREFIX *prefix; 6634 if (poolLength(&parser->m_tempPool) == 6634 if (poolLength(&parser->m_tempPool) == 0) 6635 prefix = &dtd->defaultPrefix; 6635 prefix = &dtd->defaultPrefix; 6636 else { 6636 else { 6637 if (! poolAppendChar(&parser->m_tempP 6637 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 6638 return XML_FALSE; 6638 return XML_FALSE; 6639 prefix 6639 prefix 6640 = (PREFIX *)lookup(parser, &dtd-> 6640 = (PREFIX *)lookup(parser, &dtd->prefixes, 6641 poolStart(&par 6641 poolStart(&parser->m_tempPool), sizeof(PREFIX)); 6642 if (! prefix) 6642 if (! prefix) 6643 return XML_FALSE; 6643 return XML_FALSE; 6644 if (prefix->name == poolStart(&parser 6644 if (prefix->name == poolStart(&parser->m_tempPool)) { 6645 prefix->name = poolCopyString(&dtd- 6645 prefix->name = poolCopyString(&dtd->pool, prefix->name); 6646 if (! prefix->name) 6646 if (! prefix->name) 6647 return XML_FALSE; 6647 return XML_FALSE; 6648 } 6648 } 6649 poolDiscard(&parser->m_tempPool); 6649 poolDiscard(&parser->m_tempPool); 6650 } 6650 } 6651 for (context = s + 1; *context != CONTE 6651 for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); 6652 context++) 6652 context++) 6653 if (! poolAppendChar(&parser->m_tempP 6653 if (! poolAppendChar(&parser->m_tempPool, *context)) 6654 return XML_FALSE; 6654 return XML_FALSE; 6655 if (! poolAppendChar(&parser->m_tempPoo 6655 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) 6656 return XML_FALSE; 6656 return XML_FALSE; 6657 if (addBinding(parser, prefix, NULL, po 6657 if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool), 6658 &parser->m_inheritedBind 6658 &parser->m_inheritedBindings) 6659 != XML_ERROR_NONE) 6659 != XML_ERROR_NONE) 6660 return XML_FALSE; 6660 return XML_FALSE; 6661 poolDiscard(&parser->m_tempPool); 6661 poolDiscard(&parser->m_tempPool); 6662 if (*context != XML_T('\0')) 6662 if (*context != XML_T('\0')) 6663 ++context; 6663 ++context; 6664 s = context; 6664 s = context; 6665 } else { 6665 } else { 6666 if (! poolAppendChar(&parser->m_tempPoo 6666 if (! poolAppendChar(&parser->m_tempPool, *s)) 6667 return XML_FALSE; 6667 return XML_FALSE; 6668 s++; 6668 s++; 6669 } 6669 } 6670 } 6670 } 6671 return XML_TRUE; 6671 return XML_TRUE; 6672 } 6672 } 6673 6673 6674 static void FASTCALL 6674 static void FASTCALL 6675 normalizePublicId(XML_Char *publicId) { 6675 normalizePublicId(XML_Char *publicId) { 6676 XML_Char *p = publicId; 6676 XML_Char *p = publicId; 6677 XML_Char *s; 6677 XML_Char *s; 6678 for (s = publicId; *s; s++) { 6678 for (s = publicId; *s; s++) { 6679 switch (*s) { 6679 switch (*s) { 6680 case 0x20: 6680 case 0x20: 6681 case 0xD: 6681 case 0xD: 6682 case 0xA: 6682 case 0xA: 6683 if (p != publicId && p[-1] != 0x20) 6683 if (p != publicId && p[-1] != 0x20) 6684 *p++ = 0x20; 6684 *p++ = 0x20; 6685 break; 6685 break; 6686 default: 6686 default: 6687 *p++ = *s; 6687 *p++ = *s; 6688 } 6688 } 6689 } 6689 } 6690 if (p != publicId && p[-1] == 0x20) 6690 if (p != publicId && p[-1] == 0x20) 6691 --p; 6691 --p; 6692 *p = XML_T('\0'); 6692 *p = XML_T('\0'); 6693 } 6693 } 6694 6694 6695 static DTD * 6695 static DTD * 6696 dtdCreate(const XML_Memory_Handling_Suite *ms 6696 dtdCreate(const XML_Memory_Handling_Suite *ms) { 6697 DTD *p = ms->malloc_fcn(sizeof(DTD)); 6697 DTD *p = ms->malloc_fcn(sizeof(DTD)); 6698 if (p == NULL) 6698 if (p == NULL) 6699 return p; 6699 return p; 6700 poolInit(&(p->pool), ms); 6700 poolInit(&(p->pool), ms); 6701 poolInit(&(p->entityValuePool), ms); 6701 poolInit(&(p->entityValuePool), ms); 6702 hashTableInit(&(p->generalEntities), ms); 6702 hashTableInit(&(p->generalEntities), ms); 6703 hashTableInit(&(p->elementTypes), ms); 6703 hashTableInit(&(p->elementTypes), ms); 6704 hashTableInit(&(p->attributeIds), ms); 6704 hashTableInit(&(p->attributeIds), ms); 6705 hashTableInit(&(p->prefixes), ms); 6705 hashTableInit(&(p->prefixes), ms); 6706 #ifdef XML_DTD 6706 #ifdef XML_DTD 6707 p->paramEntityRead = XML_FALSE; 6707 p->paramEntityRead = XML_FALSE; 6708 hashTableInit(&(p->paramEntities), ms); 6708 hashTableInit(&(p->paramEntities), ms); 6709 #endif /* XML_DTD */ 6709 #endif /* XML_DTD */ 6710 p->defaultPrefix.name = NULL; 6710 p->defaultPrefix.name = NULL; 6711 p->defaultPrefix.binding = NULL; 6711 p->defaultPrefix.binding = NULL; 6712 6712 6713 p->in_eldecl = XML_FALSE; 6713 p->in_eldecl = XML_FALSE; 6714 p->scaffIndex = NULL; 6714 p->scaffIndex = NULL; 6715 p->scaffold = NULL; 6715 p->scaffold = NULL; 6716 p->scaffLevel = 0; 6716 p->scaffLevel = 0; 6717 p->scaffSize = 0; 6717 p->scaffSize = 0; 6718 p->scaffCount = 0; 6718 p->scaffCount = 0; 6719 p->contentStringLen = 0; 6719 p->contentStringLen = 0; 6720 6720 6721 p->keepProcessing = XML_TRUE; 6721 p->keepProcessing = XML_TRUE; 6722 p->hasParamEntityRefs = XML_FALSE; 6722 p->hasParamEntityRefs = XML_FALSE; 6723 p->standalone = XML_FALSE; 6723 p->standalone = XML_FALSE; 6724 return p; 6724 return p; 6725 } 6725 } 6726 6726 6727 static void 6727 static void 6728 dtdReset(DTD *p, const XML_Memory_Handling_Su 6728 dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) { 6729 HASH_TABLE_ITER iter; 6729 HASH_TABLE_ITER iter; 6730 hashTableIterInit(&iter, &(p->elementTypes) 6730 hashTableIterInit(&iter, &(p->elementTypes)); 6731 for (;;) { 6731 for (;;) { 6732 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTab 6732 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); 6733 if (! e) 6733 if (! e) 6734 break; 6734 break; 6735 if (e->allocDefaultAtts != 0) 6735 if (e->allocDefaultAtts != 0) 6736 ms->free_fcn(e->defaultAtts); 6736 ms->free_fcn(e->defaultAtts); 6737 } 6737 } 6738 hashTableClear(&(p->generalEntities)); 6738 hashTableClear(&(p->generalEntities)); 6739 #ifdef XML_DTD 6739 #ifdef XML_DTD 6740 p->paramEntityRead = XML_FALSE; 6740 p->paramEntityRead = XML_FALSE; 6741 hashTableClear(&(p->paramEntities)); 6741 hashTableClear(&(p->paramEntities)); 6742 #endif /* XML_DTD */ 6742 #endif /* XML_DTD */ 6743 hashTableClear(&(p->elementTypes)); 6743 hashTableClear(&(p->elementTypes)); 6744 hashTableClear(&(p->attributeIds)); 6744 hashTableClear(&(p->attributeIds)); 6745 hashTableClear(&(p->prefixes)); 6745 hashTableClear(&(p->prefixes)); 6746 poolClear(&(p->pool)); 6746 poolClear(&(p->pool)); 6747 poolClear(&(p->entityValuePool)); 6747 poolClear(&(p->entityValuePool)); 6748 p->defaultPrefix.name = NULL; 6748 p->defaultPrefix.name = NULL; 6749 p->defaultPrefix.binding = NULL; 6749 p->defaultPrefix.binding = NULL; 6750 6750 6751 p->in_eldecl = XML_FALSE; 6751 p->in_eldecl = XML_FALSE; 6752 6752 6753 ms->free_fcn(p->scaffIndex); 6753 ms->free_fcn(p->scaffIndex); 6754 p->scaffIndex = NULL; 6754 p->scaffIndex = NULL; 6755 ms->free_fcn(p->scaffold); 6755 ms->free_fcn(p->scaffold); 6756 p->scaffold = NULL; 6756 p->scaffold = NULL; 6757 6757 6758 p->scaffLevel = 0; 6758 p->scaffLevel = 0; 6759 p->scaffSize = 0; 6759 p->scaffSize = 0; 6760 p->scaffCount = 0; 6760 p->scaffCount = 0; 6761 p->contentStringLen = 0; 6761 p->contentStringLen = 0; 6762 6762 6763 p->keepProcessing = XML_TRUE; 6763 p->keepProcessing = XML_TRUE; 6764 p->hasParamEntityRefs = XML_FALSE; 6764 p->hasParamEntityRefs = XML_FALSE; 6765 p->standalone = XML_FALSE; 6765 p->standalone = XML_FALSE; 6766 } 6766 } 6767 6767 6768 static void 6768 static void 6769 dtdDestroy(DTD *p, XML_Bool isDocEntity, cons 6769 dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) { 6770 HASH_TABLE_ITER iter; 6770 HASH_TABLE_ITER iter; 6771 hashTableIterInit(&iter, &(p->elementTypes) 6771 hashTableIterInit(&iter, &(p->elementTypes)); 6772 for (;;) { 6772 for (;;) { 6773 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTab 6773 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); 6774 if (! e) 6774 if (! e) 6775 break; 6775 break; 6776 if (e->allocDefaultAtts != 0) 6776 if (e->allocDefaultAtts != 0) 6777 ms->free_fcn(e->defaultAtts); 6777 ms->free_fcn(e->defaultAtts); 6778 } 6778 } 6779 hashTableDestroy(&(p->generalEntities)); 6779 hashTableDestroy(&(p->generalEntities)); 6780 #ifdef XML_DTD 6780 #ifdef XML_DTD 6781 hashTableDestroy(&(p->paramEntities)); 6781 hashTableDestroy(&(p->paramEntities)); 6782 #endif /* XML_DTD */ 6782 #endif /* XML_DTD */ 6783 hashTableDestroy(&(p->elementTypes)); 6783 hashTableDestroy(&(p->elementTypes)); 6784 hashTableDestroy(&(p->attributeIds)); 6784 hashTableDestroy(&(p->attributeIds)); 6785 hashTableDestroy(&(p->prefixes)); 6785 hashTableDestroy(&(p->prefixes)); 6786 poolDestroy(&(p->pool)); 6786 poolDestroy(&(p->pool)); 6787 poolDestroy(&(p->entityValuePool)); 6787 poolDestroy(&(p->entityValuePool)); 6788 if (isDocEntity) { 6788 if (isDocEntity) { 6789 ms->free_fcn(p->scaffIndex); 6789 ms->free_fcn(p->scaffIndex); 6790 ms->free_fcn(p->scaffold); 6790 ms->free_fcn(p->scaffold); 6791 } 6791 } 6792 ms->free_fcn(p); 6792 ms->free_fcn(p); 6793 } 6793 } 6794 6794 6795 /* Do a deep copy of the DTD. Return 0 for ou 6795 /* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. 6796 The new DTD has already been initialized. 6796 The new DTD has already been initialized. 6797 */ 6797 */ 6798 static int 6798 static int 6799 dtdCopy(XML_Parser oldParser, DTD *newDtd, co 6799 dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, 6800 const XML_Memory_Handling_Suite *ms) 6800 const XML_Memory_Handling_Suite *ms) { 6801 HASH_TABLE_ITER iter; 6801 HASH_TABLE_ITER iter; 6802 6802 6803 /* Copy the prefix table. */ 6803 /* Copy the prefix table. */ 6804 6804 6805 hashTableIterInit(&iter, &(oldDtd->prefixes 6805 hashTableIterInit(&iter, &(oldDtd->prefixes)); 6806 for (;;) { 6806 for (;;) { 6807 const XML_Char *name; 6807 const XML_Char *name; 6808 const PREFIX *oldP = (PREFIX *)hashTableI 6808 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); 6809 if (! oldP) 6809 if (! oldP) 6810 break; 6810 break; 6811 name = poolCopyString(&(newDtd->pool), ol 6811 name = poolCopyString(&(newDtd->pool), oldP->name); 6812 if (! name) 6812 if (! name) 6813 return 0; 6813 return 0; 6814 if (! lookup(oldParser, &(newDtd->prefixe 6814 if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX))) 6815 return 0; 6815 return 0; 6816 } 6816 } 6817 6817 6818 hashTableIterInit(&iter, &(oldDtd->attribut 6818 hashTableIterInit(&iter, &(oldDtd->attributeIds)); 6819 6819 6820 /* Copy the attribute id table. */ 6820 /* Copy the attribute id table. */ 6821 6821 6822 for (;;) { 6822 for (;;) { 6823 ATTRIBUTE_ID *newA; 6823 ATTRIBUTE_ID *newA; 6824 const XML_Char *name; 6824 const XML_Char *name; 6825 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID 6825 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); 6826 6826 6827 if (! oldA) 6827 if (! oldA) 6828 break; 6828 break; 6829 /* Remember to allocate the scratch byte 6829 /* Remember to allocate the scratch byte before the name. */ 6830 if (! poolAppendChar(&(newDtd->pool), XML 6830 if (! poolAppendChar(&(newDtd->pool), XML_T('\0'))) 6831 return 0; 6831 return 0; 6832 name = poolCopyString(&(newDtd->pool), ol 6832 name = poolCopyString(&(newDtd->pool), oldA->name); 6833 if (! name) 6833 if (! name) 6834 return 0; 6834 return 0; 6835 ++name; 6835 ++name; 6836 newA = (ATTRIBUTE_ID *)lookup(oldParser, 6836 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name, 6837 sizeof(ATTR 6837 sizeof(ATTRIBUTE_ID)); 6838 if (! newA) 6838 if (! newA) 6839 return 0; 6839 return 0; 6840 newA->maybeTokenized = oldA->maybeTokeniz 6840 newA->maybeTokenized = oldA->maybeTokenized; 6841 if (oldA->prefix) { 6841 if (oldA->prefix) { 6842 newA->xmlns = oldA->xmlns; 6842 newA->xmlns = oldA->xmlns; 6843 if (oldA->prefix == &oldDtd->defaultPre 6843 if (oldA->prefix == &oldDtd->defaultPrefix) 6844 newA->prefix = &newDtd->defaultPrefix 6844 newA->prefix = &newDtd->defaultPrefix; 6845 else 6845 else 6846 newA->prefix = (PREFIX *)lookup(oldPa 6846 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), 6847 oldA- 6847 oldA->prefix->name, 0); 6848 } 6848 } 6849 } 6849 } 6850 6850 6851 /* Copy the element type table. */ 6851 /* Copy the element type table. */ 6852 6852 6853 hashTableIterInit(&iter, &(oldDtd->elementT 6853 hashTableIterInit(&iter, &(oldDtd->elementTypes)); 6854 6854 6855 for (;;) { 6855 for (;;) { 6856 int i; 6856 int i; 6857 ELEMENT_TYPE *newE; 6857 ELEMENT_TYPE *newE; 6858 const XML_Char *name; 6858 const XML_Char *name; 6859 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE 6859 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); 6860 if (! oldE) 6860 if (! oldE) 6861 break; 6861 break; 6862 name = poolCopyString(&(newDtd->pool), ol 6862 name = poolCopyString(&(newDtd->pool), oldE->name); 6863 if (! name) 6863 if (! name) 6864 return 0; 6864 return 0; 6865 newE = (ELEMENT_TYPE *)lookup(oldParser, 6865 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name, 6866 sizeof(ELEM 6866 sizeof(ELEMENT_TYPE)); 6867 if (! newE) 6867 if (! newE) 6868 return 0; 6868 return 0; 6869 if (oldE->nDefaultAtts) { 6869 if (oldE->nDefaultAtts) { 6870 newE->defaultAtts 6870 newE->defaultAtts 6871 = ms->malloc_fcn(oldE->nDefaultAtts 6871 = ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); 6872 if (! newE->defaultAtts) { 6872 if (! newE->defaultAtts) { 6873 return 0; 6873 return 0; 6874 } 6874 } 6875 } 6875 } 6876 if (oldE->idAtt) 6876 if (oldE->idAtt) 6877 newE->idAtt = (ATTRIBUTE_ID *)lookup(ol 6877 newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), 6878 ol 6878 oldE->idAtt->name, 0); 6879 newE->allocDefaultAtts = newE->nDefaultAt 6879 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; 6880 if (oldE->prefix) 6880 if (oldE->prefix) 6881 newE->prefix = (PREFIX *)lookup(oldPars 6881 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes), 6882 oldE->p 6882 oldE->prefix->name, 0); 6883 for (i = 0; i < newE->nDefaultAtts; i++) 6883 for (i = 0; i < newE->nDefaultAtts; i++) { 6884 newE->defaultAtts[i].id = (ATTRIBUTE_ID 6884 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup( 6885 oldParser, &(newDtd->attributeIds), 6885 oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); 6886 newE->defaultAtts[i].isCdata = oldE->de 6886 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; 6887 if (oldE->defaultAtts[i].value) { 6887 if (oldE->defaultAtts[i].value) { 6888 newE->defaultAtts[i].value 6888 newE->defaultAtts[i].value 6889 = poolCopyString(&(newDtd->pool), 6889 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); 6890 if (! newE->defaultAtts[i].value) 6890 if (! newE->defaultAtts[i].value) 6891 return 0; 6891 return 0; 6892 } else 6892 } else 6893 newE->defaultAtts[i].value = NULL; 6893 newE->defaultAtts[i].value = NULL; 6894 } 6894 } 6895 } 6895 } 6896 6896 6897 /* Copy the entity tables. */ 6897 /* Copy the entity tables. */ 6898 if (! copyEntityTable(oldParser, &(newDtd-> 6898 if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool), 6899 &(oldDtd->generalEnti 6899 &(oldDtd->generalEntities))) 6900 return 0; 6900 return 0; 6901 6901 6902 #ifdef XML_DTD 6902 #ifdef XML_DTD 6903 if (! copyEntityTable(oldParser, &(newDtd-> 6903 if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool), 6904 &(oldDtd->paramEntiti 6904 &(oldDtd->paramEntities))) 6905 return 0; 6905 return 0; 6906 newDtd->paramEntityRead = oldDtd->paramEnti 6906 newDtd->paramEntityRead = oldDtd->paramEntityRead; 6907 #endif /* XML_DTD */ 6907 #endif /* XML_DTD */ 6908 6908 6909 newDtd->keepProcessing = oldDtd->keepProces 6909 newDtd->keepProcessing = oldDtd->keepProcessing; 6910 newDtd->hasParamEntityRefs = oldDtd->hasPar 6910 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; 6911 newDtd->standalone = oldDtd->standalone; 6911 newDtd->standalone = oldDtd->standalone; 6912 6912 6913 /* Don't want deep copying for scaffolding 6913 /* Don't want deep copying for scaffolding */ 6914 newDtd->in_eldecl = oldDtd->in_eldecl; 6914 newDtd->in_eldecl = oldDtd->in_eldecl; 6915 newDtd->scaffold = oldDtd->scaffold; 6915 newDtd->scaffold = oldDtd->scaffold; 6916 newDtd->contentStringLen = oldDtd->contentS 6916 newDtd->contentStringLen = oldDtd->contentStringLen; 6917 newDtd->scaffSize = oldDtd->scaffSize; 6917 newDtd->scaffSize = oldDtd->scaffSize; 6918 newDtd->scaffLevel = oldDtd->scaffLevel; 6918 newDtd->scaffLevel = oldDtd->scaffLevel; 6919 newDtd->scaffIndex = oldDtd->scaffIndex; 6919 newDtd->scaffIndex = oldDtd->scaffIndex; 6920 6920 6921 return 1; 6921 return 1; 6922 } /* End dtdCopy */ 6922 } /* End dtdCopy */ 6923 6923 6924 static int 6924 static int 6925 copyEntityTable(XML_Parser oldParser, HASH_TA 6925 copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable, 6926 STRING_POOL *newPool, const H 6926 STRING_POOL *newPool, const HASH_TABLE *oldTable) { 6927 HASH_TABLE_ITER iter; 6927 HASH_TABLE_ITER iter; 6928 const XML_Char *cachedOldBase = NULL; 6928 const XML_Char *cachedOldBase = NULL; 6929 const XML_Char *cachedNewBase = NULL; 6929 const XML_Char *cachedNewBase = NULL; 6930 6930 6931 hashTableIterInit(&iter, oldTable); 6931 hashTableIterInit(&iter, oldTable); 6932 6932 6933 for (;;) { 6933 for (;;) { 6934 ENTITY *newE; 6934 ENTITY *newE; 6935 const XML_Char *name; 6935 const XML_Char *name; 6936 const ENTITY *oldE = (ENTITY *)hashTableI 6936 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); 6937 if (! oldE) 6937 if (! oldE) 6938 break; 6938 break; 6939 name = poolCopyString(newPool, oldE->name 6939 name = poolCopyString(newPool, oldE->name); 6940 if (! name) 6940 if (! name) 6941 return 0; 6941 return 0; 6942 newE = (ENTITY *)lookup(oldParser, newTab 6942 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY)); 6943 if (! newE) 6943 if (! newE) 6944 return 0; 6944 return 0; 6945 if (oldE->systemId) { 6945 if (oldE->systemId) { 6946 const XML_Char *tem = poolCopyString(ne 6946 const XML_Char *tem = poolCopyString(newPool, oldE->systemId); 6947 if (! tem) 6947 if (! tem) 6948 return 0; 6948 return 0; 6949 newE->systemId = tem; 6949 newE->systemId = tem; 6950 if (oldE->base) { 6950 if (oldE->base) { 6951 if (oldE->base == cachedOldBase) 6951 if (oldE->base == cachedOldBase) 6952 newE->base = cachedNewBase; 6952 newE->base = cachedNewBase; 6953 else { 6953 else { 6954 cachedOldBase = oldE->base; 6954 cachedOldBase = oldE->base; 6955 tem = poolCopyString(newPool, cache 6955 tem = poolCopyString(newPool, cachedOldBase); 6956 if (! tem) 6956 if (! tem) 6957 return 0; 6957 return 0; 6958 cachedNewBase = newE->base = tem; 6958 cachedNewBase = newE->base = tem; 6959 } 6959 } 6960 } 6960 } 6961 if (oldE->publicId) { 6961 if (oldE->publicId) { 6962 tem = poolCopyString(newPool, oldE->p 6962 tem = poolCopyString(newPool, oldE->publicId); 6963 if (! tem) 6963 if (! tem) 6964 return 0; 6964 return 0; 6965 newE->publicId = tem; 6965 newE->publicId = tem; 6966 } 6966 } 6967 } else { 6967 } else { 6968 const XML_Char *tem 6968 const XML_Char *tem 6969 = poolCopyStringN(newPool, oldE->te 6969 = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen); 6970 if (! tem) 6970 if (! tem) 6971 return 0; 6971 return 0; 6972 newE->textPtr = tem; 6972 newE->textPtr = tem; 6973 newE->textLen = oldE->textLen; 6973 newE->textLen = oldE->textLen; 6974 } 6974 } 6975 if (oldE->notation) { 6975 if (oldE->notation) { 6976 const XML_Char *tem = poolCopyString(ne 6976 const XML_Char *tem = poolCopyString(newPool, oldE->notation); 6977 if (! tem) 6977 if (! tem) 6978 return 0; 6978 return 0; 6979 newE->notation = tem; 6979 newE->notation = tem; 6980 } 6980 } 6981 newE->is_param = oldE->is_param; 6981 newE->is_param = oldE->is_param; 6982 newE->is_internal = oldE->is_internal; 6982 newE->is_internal = oldE->is_internal; 6983 } 6983 } 6984 return 1; 6984 return 1; 6985 } 6985 } 6986 6986 6987 #define INIT_POWER 6 6987 #define INIT_POWER 6 6988 6988 6989 static XML_Bool FASTCALL 6989 static XML_Bool FASTCALL 6990 keyeq(KEY s1, KEY s2) { 6990 keyeq(KEY s1, KEY s2) { 6991 for (; *s1 == *s2; s1++, s2++) 6991 for (; *s1 == *s2; s1++, s2++) 6992 if (*s1 == 0) 6992 if (*s1 == 0) 6993 return XML_TRUE; 6993 return XML_TRUE; 6994 return XML_FALSE; 6994 return XML_FALSE; 6995 } 6995 } 6996 6996 6997 static size_t 6997 static size_t 6998 keylen(KEY s) { 6998 keylen(KEY s) { 6999 size_t len = 0; 6999 size_t len = 0; 7000 for (; *s; s++, len++) 7000 for (; *s; s++, len++) 7001 ; 7001 ; 7002 return len; 7002 return len; 7003 } 7003 } 7004 7004 7005 static void 7005 static void 7006 copy_salt_to_sipkey(XML_Parser parser, struct 7006 copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) { 7007 key->k[0] = 0; 7007 key->k[0] = 0; 7008 key->k[1] = get_hash_secret_salt(parser); 7008 key->k[1] = get_hash_secret_salt(parser); 7009 } 7009 } 7010 7010 7011 static unsigned long FASTCALL 7011 static unsigned long FASTCALL 7012 hash(XML_Parser parser, KEY s) { 7012 hash(XML_Parser parser, KEY s) { 7013 struct siphash state; 7013 struct siphash state; 7014 struct sipkey key; 7014 struct sipkey key; 7015 (void)sip24_valid; 7015 (void)sip24_valid; 7016 copy_salt_to_sipkey(parser, &key); 7016 copy_salt_to_sipkey(parser, &key); 7017 sip24_init(&state, &key); 7017 sip24_init(&state, &key); 7018 sip24_update(&state, s, keylen(s) * sizeof( 7018 sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); 7019 return (unsigned long)sip24_final(&state); 7019 return (unsigned long)sip24_final(&state); 7020 } 7020 } 7021 7021 7022 static NAMED * 7022 static NAMED * 7023 lookup(XML_Parser parser, HASH_TABLE *table, 7023 lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { 7024 size_t i; 7024 size_t i; 7025 if (table->size == 0) { 7025 if (table->size == 0) { 7026 size_t tsize; 7026 size_t tsize; 7027 if (! createSize) 7027 if (! createSize) 7028 return NULL; 7028 return NULL; 7029 table->power = INIT_POWER; 7029 table->power = INIT_POWER; 7030 /* table->size is a power of 2 */ 7030 /* table->size is a power of 2 */ 7031 table->size = (size_t)1 << INIT_POWER; 7031 table->size = (size_t)1 << INIT_POWER; 7032 tsize = table->size * sizeof(NAMED *); 7032 tsize = table->size * sizeof(NAMED *); 7033 table->v = table->mem->malloc_fcn(tsize); 7033 table->v = table->mem->malloc_fcn(tsize); 7034 if (! table->v) { 7034 if (! table->v) { 7035 table->size = 0; 7035 table->size = 0; 7036 return NULL; 7036 return NULL; 7037 } 7037 } 7038 memset(table->v, 0, tsize); 7038 memset(table->v, 0, tsize); 7039 i = hash(parser, name) & ((unsigned long) 7039 i = hash(parser, name) & ((unsigned long)table->size - 1); 7040 } else { 7040 } else { 7041 unsigned long h = hash(parser, name); 7041 unsigned long h = hash(parser, name); 7042 unsigned long mask = (unsigned long)table 7042 unsigned long mask = (unsigned long)table->size - 1; 7043 unsigned char step = 0; 7043 unsigned char step = 0; 7044 i = h & mask; 7044 i = h & mask; 7045 while (table->v[i]) { 7045 while (table->v[i]) { 7046 if (keyeq(name, table->v[i]->name)) 7046 if (keyeq(name, table->v[i]->name)) 7047 return table->v[i]; 7047 return table->v[i]; 7048 if (! step) 7048 if (! step) 7049 step = PROBE_STEP(h, mask, table->pow 7049 step = PROBE_STEP(h, mask, table->power); 7050 i < step ? (i += table->size - step) : 7050 i < step ? (i += table->size - step) : (i -= step); 7051 } 7051 } 7052 if (! createSize) 7052 if (! createSize) 7053 return NULL; 7053 return NULL; 7054 7054 7055 /* check for overflow (table is half full 7055 /* check for overflow (table is half full) */ 7056 if (table->used >> (table->power - 1)) { 7056 if (table->used >> (table->power - 1)) { 7057 unsigned char newPower = table->power + 7057 unsigned char newPower = table->power + 1; 7058 7058 7059 /* Detect and prevent invalid shift */ 7059 /* Detect and prevent invalid shift */ 7060 if (newPower >= sizeof(unsigned long) * 7060 if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) { 7061 return NULL; 7061 return NULL; 7062 } 7062 } 7063 7063 7064 size_t newSize = (size_t)1 << newPower; 7064 size_t newSize = (size_t)1 << newPower; 7065 unsigned long newMask = (unsigned long) 7065 unsigned long newMask = (unsigned long)newSize - 1; 7066 7066 7067 /* Detect and prevent integer overflow 7067 /* Detect and prevent integer overflow */ 7068 if (newSize > (size_t)(-1) / sizeof(NAM 7068 if (newSize > (size_t)(-1) / sizeof(NAMED *)) { 7069 return NULL; 7069 return NULL; 7070 } 7070 } 7071 7071 7072 size_t tsize = newSize * sizeof(NAMED * 7072 size_t tsize = newSize * sizeof(NAMED *); 7073 NAMED **newV = table->mem->malloc_fcn(t 7073 NAMED **newV = table->mem->malloc_fcn(tsize); 7074 if (! newV) 7074 if (! newV) 7075 return NULL; 7075 return NULL; 7076 memset(newV, 0, tsize); 7076 memset(newV, 0, tsize); 7077 for (i = 0; i < table->size; i++) 7077 for (i = 0; i < table->size; i++) 7078 if (table->v[i]) { 7078 if (table->v[i]) { 7079 unsigned long newHash = hash(parser 7079 unsigned long newHash = hash(parser, table->v[i]->name); 7080 size_t j = newHash & newMask; 7080 size_t j = newHash & newMask; 7081 step = 0; 7081 step = 0; 7082 while (newV[j]) { 7082 while (newV[j]) { 7083 if (! step) 7083 if (! step) 7084 step = PROBE_STEP(newHash, newM 7084 step = PROBE_STEP(newHash, newMask, newPower); 7085 j < step ? (j += newSize - step) 7085 j < step ? (j += newSize - step) : (j -= step); 7086 } 7086 } 7087 newV[j] = table->v[i]; 7087 newV[j] = table->v[i]; 7088 } 7088 } 7089 table->mem->free_fcn(table->v); 7089 table->mem->free_fcn(table->v); 7090 table->v = newV; 7090 table->v = newV; 7091 table->power = newPower; 7091 table->power = newPower; 7092 table->size = newSize; 7092 table->size = newSize; 7093 i = h & newMask; 7093 i = h & newMask; 7094 step = 0; 7094 step = 0; 7095 while (table->v[i]) { 7095 while (table->v[i]) { 7096 if (! step) 7096 if (! step) 7097 step = PROBE_STEP(h, newMask, newPo 7097 step = PROBE_STEP(h, newMask, newPower); 7098 i < step ? (i += newSize - step) : (i 7098 i < step ? (i += newSize - step) : (i -= step); 7099 } 7099 } 7100 } 7100 } 7101 } 7101 } 7102 table->v[i] = table->mem->malloc_fcn(create 7102 table->v[i] = table->mem->malloc_fcn(createSize); 7103 if (! table->v[i]) 7103 if (! table->v[i]) 7104 return NULL; 7104 return NULL; 7105 memset(table->v[i], 0, createSize); 7105 memset(table->v[i], 0, createSize); 7106 table->v[i]->name = name; 7106 table->v[i]->name = name; 7107 (table->used)++; 7107 (table->used)++; 7108 return table->v[i]; 7108 return table->v[i]; 7109 } 7109 } 7110 7110 7111 static void FASTCALL 7111 static void FASTCALL 7112 hashTableClear(HASH_TABLE *table) { 7112 hashTableClear(HASH_TABLE *table) { 7113 size_t i; 7113 size_t i; 7114 for (i = 0; i < table->size; i++) { 7114 for (i = 0; i < table->size; i++) { 7115 table->mem->free_fcn(table->v[i]); 7115 table->mem->free_fcn(table->v[i]); 7116 table->v[i] = NULL; 7116 table->v[i] = NULL; 7117 } 7117 } 7118 table->used = 0; 7118 table->used = 0; 7119 } 7119 } 7120 7120 7121 static void FASTCALL 7121 static void FASTCALL 7122 hashTableDestroy(HASH_TABLE *table) { 7122 hashTableDestroy(HASH_TABLE *table) { 7123 size_t i; 7123 size_t i; 7124 for (i = 0; i < table->size; i++) 7124 for (i = 0; i < table->size; i++) 7125 table->mem->free_fcn(table->v[i]); 7125 table->mem->free_fcn(table->v[i]); 7126 table->mem->free_fcn(table->v); 7126 table->mem->free_fcn(table->v); 7127 } 7127 } 7128 7128 7129 static void FASTCALL 7129 static void FASTCALL 7130 hashTableInit(HASH_TABLE *p, const XML_Memory 7130 hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) { 7131 p->power = 0; 7131 p->power = 0; 7132 p->size = 0; 7132 p->size = 0; 7133 p->used = 0; 7133 p->used = 0; 7134 p->v = NULL; 7134 p->v = NULL; 7135 p->mem = ms; 7135 p->mem = ms; 7136 } 7136 } 7137 7137 7138 static void FASTCALL 7138 static void FASTCALL 7139 hashTableIterInit(HASH_TABLE_ITER *iter, cons 7139 hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) { 7140 iter->p = table->v; 7140 iter->p = table->v; 7141 iter->end = iter->p ? iter->p + table->size 7141 iter->end = iter->p ? iter->p + table->size : NULL; 7142 } 7142 } 7143 7143 7144 static NAMED *FASTCALL 7144 static NAMED *FASTCALL 7145 hashTableIterNext(HASH_TABLE_ITER *iter) { 7145 hashTableIterNext(HASH_TABLE_ITER *iter) { 7146 while (iter->p != iter->end) { 7146 while (iter->p != iter->end) { 7147 NAMED *tem = *(iter->p)++; 7147 NAMED *tem = *(iter->p)++; 7148 if (tem) 7148 if (tem) 7149 return tem; 7149 return tem; 7150 } 7150 } 7151 return NULL; 7151 return NULL; 7152 } 7152 } 7153 7153 7154 static void FASTCALL 7154 static void FASTCALL 7155 poolInit(STRING_POOL *pool, const XML_Memory_ 7155 poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) { 7156 pool->blocks = NULL; 7156 pool->blocks = NULL; 7157 pool->freeBlocks = NULL; 7157 pool->freeBlocks = NULL; 7158 pool->start = NULL; 7158 pool->start = NULL; 7159 pool->ptr = NULL; 7159 pool->ptr = NULL; 7160 pool->end = NULL; 7160 pool->end = NULL; 7161 pool->mem = ms; 7161 pool->mem = ms; 7162 } 7162 } 7163 7163 7164 static void FASTCALL 7164 static void FASTCALL 7165 poolClear(STRING_POOL *pool) { 7165 poolClear(STRING_POOL *pool) { 7166 if (! pool->freeBlocks) 7166 if (! pool->freeBlocks) 7167 pool->freeBlocks = pool->blocks; 7167 pool->freeBlocks = pool->blocks; 7168 else { 7168 else { 7169 BLOCK *p = pool->blocks; 7169 BLOCK *p = pool->blocks; 7170 while (p) { 7170 while (p) { 7171 BLOCK *tem = p->next; 7171 BLOCK *tem = p->next; 7172 p->next = pool->freeBlocks; 7172 p->next = pool->freeBlocks; 7173 pool->freeBlocks = p; 7173 pool->freeBlocks = p; 7174 p = tem; 7174 p = tem; 7175 } 7175 } 7176 } 7176 } 7177 pool->blocks = NULL; 7177 pool->blocks = NULL; 7178 pool->start = NULL; 7178 pool->start = NULL; 7179 pool->ptr = NULL; 7179 pool->ptr = NULL; 7180 pool->end = NULL; 7180 pool->end = NULL; 7181 } 7181 } 7182 7182 7183 static void FASTCALL 7183 static void FASTCALL 7184 poolDestroy(STRING_POOL *pool) { 7184 poolDestroy(STRING_POOL *pool) { 7185 BLOCK *p = pool->blocks; 7185 BLOCK *p = pool->blocks; 7186 while (p) { 7186 while (p) { 7187 BLOCK *tem = p->next; 7187 BLOCK *tem = p->next; 7188 pool->mem->free_fcn(p); 7188 pool->mem->free_fcn(p); 7189 p = tem; 7189 p = tem; 7190 } 7190 } 7191 p = pool->freeBlocks; 7191 p = pool->freeBlocks; 7192 while (p) { 7192 while (p) { 7193 BLOCK *tem = p->next; 7193 BLOCK *tem = p->next; 7194 pool->mem->free_fcn(p); 7194 pool->mem->free_fcn(p); 7195 p = tem; 7195 p = tem; 7196 } 7196 } 7197 } 7197 } 7198 7198 7199 static XML_Char * 7199 static XML_Char * 7200 poolAppend(STRING_POOL *pool, const ENCODING 7200 poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, 7201 const char *end) { 7201 const char *end) { 7202 if (! pool->ptr && ! poolGrow(pool)) 7202 if (! pool->ptr && ! poolGrow(pool)) 7203 return NULL; 7203 return NULL; 7204 for (;;) { 7204 for (;;) { 7205 const enum XML_Convert_Result convert_res 7205 const enum XML_Convert_Result convert_res = XmlConvert( 7206 enc, &ptr, end, (ICHAR **)&(pool->ptr 7206 enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); 7207 if ((convert_res == XML_CONVERT_COMPLETED 7207 if ((convert_res == XML_CONVERT_COMPLETED) 7208 || (convert_res == XML_CONVERT_INPUT_ 7208 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) 7209 break; 7209 break; 7210 if (! poolGrow(pool)) 7210 if (! poolGrow(pool)) 7211 return NULL; 7211 return NULL; 7212 } 7212 } 7213 return pool->start; 7213 return pool->start; 7214 } 7214 } 7215 7215 7216 static const XML_Char *FASTCALL 7216 static const XML_Char *FASTCALL 7217 poolCopyString(STRING_POOL *pool, const XML_C 7217 poolCopyString(STRING_POOL *pool, const XML_Char *s) { 7218 do { 7218 do { 7219 if (! poolAppendChar(pool, *s)) 7219 if (! poolAppendChar(pool, *s)) 7220 return NULL; 7220 return NULL; 7221 } while (*s++); 7221 } while (*s++); 7222 s = pool->start; 7222 s = pool->start; 7223 poolFinish(pool); 7223 poolFinish(pool); 7224 return s; 7224 return s; 7225 } 7225 } 7226 7226 7227 static const XML_Char * 7227 static const XML_Char * 7228 poolCopyStringN(STRING_POOL *pool, const XML_ 7228 poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { 7229 if (! pool->ptr && ! poolGrow(pool)) { 7229 if (! pool->ptr && ! poolGrow(pool)) { 7230 /* The following line is unreachable give 7230 /* The following line is unreachable given the current usage of 7231 * poolCopyStringN(). Currently it is ca 7231 * poolCopyStringN(). Currently it is called from exactly one 7232 * place to copy the text of a simple gen 7232 * place to copy the text of a simple general entity. By that 7233 * point, the name of the entity is alrea 7233 * point, the name of the entity is already stored in the pool, so 7234 * pool->ptr cannot be NULL. 7234 * pool->ptr cannot be NULL. 7235 * 7235 * 7236 * If poolCopyStringN() is used elsewhere 7236 * If poolCopyStringN() is used elsewhere as it well might be, 7237 * this line may well become executable a 7237 * this line may well become executable again. Regardless, this 7238 * sort of check shouldn't be removed lig 7238 * sort of check shouldn't be removed lightly, so we just exclude 7239 * it from the coverage statistics. 7239 * it from the coverage statistics. 7240 */ 7240 */ 7241 return NULL; /* LCOV_EXCL_LINE */ 7241 return NULL; /* LCOV_EXCL_LINE */ 7242 } 7242 } 7243 for (; n > 0; --n, s++) { 7243 for (; n > 0; --n, s++) { 7244 if (! poolAppendChar(pool, *s)) 7244 if (! poolAppendChar(pool, *s)) 7245 return NULL; 7245 return NULL; 7246 } 7246 } 7247 s = pool->start; 7247 s = pool->start; 7248 poolFinish(pool); 7248 poolFinish(pool); 7249 return s; 7249 return s; 7250 } 7250 } 7251 7251 7252 static const XML_Char *FASTCALL 7252 static const XML_Char *FASTCALL 7253 poolAppendString(STRING_POOL *pool, const XML 7253 poolAppendString(STRING_POOL *pool, const XML_Char *s) { 7254 while (*s) { 7254 while (*s) { 7255 if (! poolAppendChar(pool, *s)) 7255 if (! poolAppendChar(pool, *s)) 7256 return NULL; 7256 return NULL; 7257 s++; 7257 s++; 7258 } 7258 } 7259 return pool->start; 7259 return pool->start; 7260 } 7260 } 7261 7261 7262 static XML_Char * 7262 static XML_Char * 7263 poolStoreString(STRING_POOL *pool, const ENCO 7263 poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, 7264 const char *end) { 7264 const char *end) { 7265 if (! poolAppend(pool, enc, ptr, end)) 7265 if (! poolAppend(pool, enc, ptr, end)) 7266 return NULL; 7266 return NULL; 7267 if (pool->ptr == pool->end && ! poolGrow(po 7267 if (pool->ptr == pool->end && ! poolGrow(pool)) 7268 return NULL; 7268 return NULL; 7269 *(pool->ptr)++ = 0; 7269 *(pool->ptr)++ = 0; 7270 return pool->start; 7270 return pool->start; 7271 } 7271 } 7272 7272 7273 static size_t 7273 static size_t 7274 poolBytesToAllocateFor(int blockSize) { 7274 poolBytesToAllocateFor(int blockSize) { 7275 /* Unprotected math would be: 7275 /* Unprotected math would be: 7276 ** return offsetof(BLOCK, s) + blockSize * 7276 ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); 7277 ** 7277 ** 7278 ** Detect overflow, avoiding _signed_ overf 7278 ** Detect overflow, avoiding _signed_ overflow undefined behavior 7279 ** For a + b * c we check b * c in isolatio 7279 ** For a + b * c we check b * c in isolation first, so that addition of a 7280 ** on top has no chance of making us accept 7280 ** on top has no chance of making us accept a small non-negative number 7281 */ 7281 */ 7282 const size_t stretch = sizeof(XML_Char); /* 7282 const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ 7283 7283 7284 if (blockSize <= 0) 7284 if (blockSize <= 0) 7285 return 0; 7285 return 0; 7286 7286 7287 if (blockSize > (int)(INT_MAX / stretch)) 7287 if (blockSize > (int)(INT_MAX / stretch)) 7288 return 0; 7288 return 0; 7289 7289 7290 { 7290 { 7291 const int stretchedBlockSize = blockSize 7291 const int stretchedBlockSize = blockSize * (int)stretch; 7292 const int bytesToAllocate 7292 const int bytesToAllocate 7293 = (int)(offsetof(BLOCK, s) + (unsigne 7293 = (int)(offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); 7294 if (bytesToAllocate < 0) 7294 if (bytesToAllocate < 0) 7295 return 0; 7295 return 0; 7296 7296 7297 return (size_t)bytesToAllocate; 7297 return (size_t)bytesToAllocate; 7298 } 7298 } 7299 } 7299 } 7300 7300 7301 static XML_Bool FASTCALL 7301 static XML_Bool FASTCALL 7302 poolGrow(STRING_POOL *pool) { 7302 poolGrow(STRING_POOL *pool) { 7303 if (pool->freeBlocks) { 7303 if (pool->freeBlocks) { 7304 if (pool->start == 0) { 7304 if (pool->start == 0) { 7305 pool->blocks = pool->freeBlocks; 7305 pool->blocks = pool->freeBlocks; 7306 pool->freeBlocks = pool->freeBlocks->ne 7306 pool->freeBlocks = pool->freeBlocks->next; 7307 pool->blocks->next = NULL; 7307 pool->blocks->next = NULL; 7308 pool->start = pool->blocks->s; 7308 pool->start = pool->blocks->s; 7309 pool->end = pool->start + pool->blocks- 7309 pool->end = pool->start + pool->blocks->size; 7310 pool->ptr = pool->start; 7310 pool->ptr = pool->start; 7311 return XML_TRUE; 7311 return XML_TRUE; 7312 } 7312 } 7313 if (pool->end - pool->start < pool->freeB 7313 if (pool->end - pool->start < pool->freeBlocks->size) { 7314 BLOCK *tem = pool->freeBlocks->next; 7314 BLOCK *tem = pool->freeBlocks->next; 7315 pool->freeBlocks->next = pool->blocks; 7315 pool->freeBlocks->next = pool->blocks; 7316 pool->blocks = pool->freeBlocks; 7316 pool->blocks = pool->freeBlocks; 7317 pool->freeBlocks = tem; 7317 pool->freeBlocks = tem; 7318 memcpy(pool->blocks->s, pool->start, 7318 memcpy(pool->blocks->s, pool->start, 7319 (pool->end - pool->start) * size 7319 (pool->end - pool->start) * sizeof(XML_Char)); 7320 pool->ptr = pool->blocks->s + (pool->pt 7320 pool->ptr = pool->blocks->s + (pool->ptr - pool->start); 7321 pool->start = pool->blocks->s; 7321 pool->start = pool->blocks->s; 7322 pool->end = pool->start + pool->blocks- 7322 pool->end = pool->start + pool->blocks->size; 7323 return XML_TRUE; 7323 return XML_TRUE; 7324 } 7324 } 7325 } 7325 } 7326 if (pool->blocks && pool->start == pool->bl 7326 if (pool->blocks && pool->start == pool->blocks->s) { 7327 BLOCK *temp; 7327 BLOCK *temp; 7328 int blockSize = (int)((unsigned)(pool->en 7328 int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U); 7329 size_t bytesToAllocate; 7329 size_t bytesToAllocate; 7330 7330 7331 /* NOTE: Needs to be calculated prior to 7331 /* NOTE: Needs to be calculated prior to calling `realloc` 7332 to avoid dangling pointers: */ 7332 to avoid dangling pointers: */ 7333 const ptrdiff_t offsetInsideBlock = pool- 7333 const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start; 7334 7334 7335 if (blockSize < 0) { 7335 if (blockSize < 0) { 7336 /* This condition traps a situation whe 7336 /* This condition traps a situation where either more than 7337 * INT_MAX/2 bytes have already been al 7337 * INT_MAX/2 bytes have already been allocated. This isn't 7338 * readily testable, since it is unlike 7338 * readily testable, since it is unlikely that an average 7339 * machine will have that much memory, 7339 * machine will have that much memory, so we exclude it from the 7340 * coverage statistics. 7340 * coverage statistics. 7341 */ 7341 */ 7342 return XML_FALSE; /* LCOV_EXCL_LINE */ 7342 return XML_FALSE; /* LCOV_EXCL_LINE */ 7343 } 7343 } 7344 7344 7345 bytesToAllocate = poolBytesToAllocateFor( 7345 bytesToAllocate = poolBytesToAllocateFor(blockSize); 7346 if (bytesToAllocate == 0) 7346 if (bytesToAllocate == 0) 7347 return XML_FALSE; 7347 return XML_FALSE; 7348 7348 7349 temp = (BLOCK *)pool->mem->realloc_fcn(po 7349 temp = (BLOCK *)pool->mem->realloc_fcn(pool->blocks, 7350 (u 7350 (unsigned)bytesToAllocate); 7351 if (temp == NULL) 7351 if (temp == NULL) 7352 return XML_FALSE; 7352 return XML_FALSE; 7353 pool->blocks = temp; 7353 pool->blocks = temp; 7354 pool->blocks->size = blockSize; 7354 pool->blocks->size = blockSize; 7355 pool->ptr = pool->blocks->s + offsetInsid 7355 pool->ptr = pool->blocks->s + offsetInsideBlock; 7356 pool->start = pool->blocks->s; 7356 pool->start = pool->blocks->s; 7357 pool->end = pool->start + blockSize; 7357 pool->end = pool->start + blockSize; 7358 } else { 7358 } else { 7359 BLOCK *tem; 7359 BLOCK *tem; 7360 int blockSize = (int)(pool->end - pool->s 7360 int blockSize = (int)(pool->end - pool->start); 7361 size_t bytesToAllocate; 7361 size_t bytesToAllocate; 7362 7362 7363 if (blockSize < 0) { 7363 if (blockSize < 0) { 7364 /* This condition traps a situation whe 7364 /* This condition traps a situation where either more than 7365 * INT_MAX bytes have already been allo 7365 * INT_MAX bytes have already been allocated (which is prevented 7366 * by various pieces of program logic, 7366 * by various pieces of program logic, not least this one, never 7367 * mind the unlikelihood of actually ha 7367 * mind the unlikelihood of actually having that much memory) or 7368 * the pool control fields have been co 7368 * the pool control fields have been corrupted (which could 7369 * conceivably happen in an extremely b 7369 * conceivably happen in an extremely buggy user handler 7370 * function). Either way it isn't read 7370 * function). Either way it isn't readily testable, so we 7371 * exclude it from the coverage statist 7371 * exclude it from the coverage statistics. 7372 */ 7372 */ 7373 return XML_FALSE; /* LCOV_EXCL_LINE */ 7373 return XML_FALSE; /* LCOV_EXCL_LINE */ 7374 } 7374 } 7375 7375 7376 if (blockSize < INIT_BLOCK_SIZE) 7376 if (blockSize < INIT_BLOCK_SIZE) 7377 blockSize = INIT_BLOCK_SIZE; 7377 blockSize = INIT_BLOCK_SIZE; 7378 else { 7378 else { 7379 /* Detect overflow, avoiding _signed_ o 7379 /* Detect overflow, avoiding _signed_ overflow undefined behavior */ 7380 if ((int)((unsigned)blockSize * 2U) < 0 7380 if ((int)((unsigned)blockSize * 2U) < 0) { 7381 return XML_FALSE; 7381 return XML_FALSE; 7382 } 7382 } 7383 blockSize *= 2; 7383 blockSize *= 2; 7384 } 7384 } 7385 7385 7386 bytesToAllocate = poolBytesToAllocateFor( 7386 bytesToAllocate = poolBytesToAllocateFor(blockSize); 7387 if (bytesToAllocate == 0) 7387 if (bytesToAllocate == 0) 7388 return XML_FALSE; 7388 return XML_FALSE; 7389 7389 7390 tem = pool->mem->malloc_fcn(bytesToAlloca 7390 tem = pool->mem->malloc_fcn(bytesToAllocate); 7391 if (! tem) 7391 if (! tem) 7392 return XML_FALSE; 7392 return XML_FALSE; 7393 tem->size = blockSize; 7393 tem->size = blockSize; 7394 tem->next = pool->blocks; 7394 tem->next = pool->blocks; 7395 pool->blocks = tem; 7395 pool->blocks = tem; 7396 if (pool->ptr != pool->start) 7396 if (pool->ptr != pool->start) 7397 memcpy(tem->s, pool->start, (pool->ptr 7397 memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); 7398 pool->ptr = tem->s + (pool->ptr - pool->s 7398 pool->ptr = tem->s + (pool->ptr - pool->start); 7399 pool->start = tem->s; 7399 pool->start = tem->s; 7400 pool->end = tem->s + blockSize; 7400 pool->end = tem->s + blockSize; 7401 } 7401 } 7402 return XML_TRUE; 7402 return XML_TRUE; 7403 } 7403 } 7404 7404 7405 static int FASTCALL 7405 static int FASTCALL 7406 nextScaffoldPart(XML_Parser parser) { 7406 nextScaffoldPart(XML_Parser parser) { 7407 DTD *const dtd = parser->m_dtd; /* save one 7407 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 7408 CONTENT_SCAFFOLD *me; 7408 CONTENT_SCAFFOLD *me; 7409 int next; 7409 int next; 7410 7410 7411 if (! dtd->scaffIndex) { 7411 if (! dtd->scaffIndex) { 7412 dtd->scaffIndex = (int *)MALLOC(parser, p 7412 dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int)); 7413 if (! dtd->scaffIndex) 7413 if (! dtd->scaffIndex) 7414 return -1; 7414 return -1; 7415 dtd->scaffIndex[0] = 0; 7415 dtd->scaffIndex[0] = 0; 7416 } 7416 } 7417 7417 7418 if (dtd->scaffCount >= dtd->scaffSize) { 7418 if (dtd->scaffCount >= dtd->scaffSize) { 7419 CONTENT_SCAFFOLD *temp; 7419 CONTENT_SCAFFOLD *temp; 7420 if (dtd->scaffold) { 7420 if (dtd->scaffold) { 7421 /* Detect and prevent integer overflow 7421 /* Detect and prevent integer overflow */ 7422 if (dtd->scaffSize > UINT_MAX / 2u) { 7422 if (dtd->scaffSize > UINT_MAX / 2u) { 7423 return -1; 7423 return -1; 7424 } 7424 } 7425 /* Detect and prevent integer overflow. 7425 /* Detect and prevent integer overflow. 7426 * The preprocessor guard addresses the 7426 * The preprocessor guard addresses the "always false" warning 7427 * from -Wtype-limits on platforms wher 7427 * from -Wtype-limits on platforms where 7428 * sizeof(unsigned int) < sizeof(size_t 7428 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 7429 #if UINT_MAX >= SIZE_MAX 7429 #if UINT_MAX >= SIZE_MAX 7430 if (dtd->scaffSize > (size_t)(-1) / 2u 7430 if (dtd->scaffSize > (size_t)(-1) / 2u / sizeof(CONTENT_SCAFFOLD)) { 7431 return -1; 7431 return -1; 7432 } 7432 } 7433 #endif 7433 #endif 7434 7434 7435 temp = (CONTENT_SCAFFOLD *)REALLOC( 7435 temp = (CONTENT_SCAFFOLD *)REALLOC( 7436 parser, dtd->scaffold, dtd->scaffSi 7436 parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); 7437 if (temp == NULL) 7437 if (temp == NULL) 7438 return -1; 7438 return -1; 7439 dtd->scaffSize *= 2; 7439 dtd->scaffSize *= 2; 7440 } else { 7440 } else { 7441 temp = (CONTENT_SCAFFOLD *)MALLOC(parse 7441 temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS 7442 7442 * sizeof(CONTENT_SCAFFOLD)); 7443 if (temp == NULL) 7443 if (temp == NULL) 7444 return -1; 7444 return -1; 7445 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS 7445 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; 7446 } 7446 } 7447 dtd->scaffold = temp; 7447 dtd->scaffold = temp; 7448 } 7448 } 7449 next = dtd->scaffCount++; 7449 next = dtd->scaffCount++; 7450 me = &dtd->scaffold[next]; 7450 me = &dtd->scaffold[next]; 7451 if (dtd->scaffLevel) { 7451 if (dtd->scaffLevel) { 7452 CONTENT_SCAFFOLD *parent 7452 CONTENT_SCAFFOLD *parent 7453 = &dtd->scaffold[dtd->scaffIndex[dtd- 7453 = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]]; 7454 if (parent->lastchild) { 7454 if (parent->lastchild) { 7455 dtd->scaffold[parent->lastchild].nextsi 7455 dtd->scaffold[parent->lastchild].nextsib = next; 7456 } 7456 } 7457 if (! parent->childcnt) 7457 if (! parent->childcnt) 7458 parent->firstchild = next; 7458 parent->firstchild = next; 7459 parent->lastchild = next; 7459 parent->lastchild = next; 7460 parent->childcnt++; 7460 parent->childcnt++; 7461 } 7461 } 7462 me->firstchild = me->lastchild = me->childc 7462 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; 7463 return next; 7463 return next; 7464 } 7464 } 7465 7465 7466 static XML_Content * 7466 static XML_Content * 7467 build_model(XML_Parser parser) { 7467 build_model(XML_Parser parser) { 7468 /* Function build_model transforms the exis 7468 /* Function build_model transforms the existing parser->m_dtd->scaffold 7469 * array of CONTENT_SCAFFOLD tree nodes int 7469 * array of CONTENT_SCAFFOLD tree nodes into a new array of 7470 * XML_Content tree nodes followed by a gap 7470 * XML_Content tree nodes followed by a gapless list of zero-terminated 7471 * strings. */ 7471 * strings. */ 7472 DTD *const dtd = parser->m_dtd; /* save one 7472 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 7473 XML_Content *ret; 7473 XML_Content *ret; 7474 XML_Char *str; /* the current string writin 7474 XML_Char *str; /* the current string writing location */ 7475 7475 7476 /* Detect and prevent integer overflow. 7476 /* Detect and prevent integer overflow. 7477 * The preprocessor guard addresses the "al 7477 * The preprocessor guard addresses the "always false" warning 7478 * from -Wtype-limits on platforms where 7478 * from -Wtype-limits on platforms where 7479 * sizeof(unsigned int) < sizeof(size_t), e 7479 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */ 7480 #if UINT_MAX >= SIZE_MAX 7480 #if UINT_MAX >= SIZE_MAX 7481 if (dtd->scaffCount > (size_t)(-1) / sizeof 7481 if (dtd->scaffCount > (size_t)(-1) / sizeof(XML_Content)) { 7482 return NULL; 7482 return NULL; 7483 } 7483 } 7484 if (dtd->contentStringLen > (size_t)(-1) / 7484 if (dtd->contentStringLen > (size_t)(-1) / sizeof(XML_Char)) { 7485 return NULL; 7485 return NULL; 7486 } 7486 } 7487 #endif 7487 #endif 7488 if (dtd->scaffCount * sizeof(XML_Content) 7488 if (dtd->scaffCount * sizeof(XML_Content) 7489 > (size_t)(-1) - dtd->contentStringLen 7489 > (size_t)(-1) - dtd->contentStringLen * sizeof(XML_Char)) { 7490 return NULL; 7490 return NULL; 7491 } 7491 } 7492 7492 7493 const size_t allocsize = (dtd->scaffCount * 7493 const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content) 7494 + (dtd->contentSt 7494 + (dtd->contentStringLen * sizeof(XML_Char))); 7495 7495 7496 ret = (XML_Content *)MALLOC(parser, allocsi 7496 ret = (XML_Content *)MALLOC(parser, allocsize); 7497 if (! ret) 7497 if (! ret) 7498 return NULL; 7498 return NULL; 7499 7499 7500 /* What follows is an iterative implementat 7500 /* What follows is an iterative implementation (of what was previously done 7501 * recursively in a dedicated function call 7501 * recursively in a dedicated function called "build_node". The old recursive 7502 * build_node could be forced into stack ex 7502 * build_node could be forced into stack exhaustion from input as small as a 7503 * few megabyte, and so that was a security 7503 * few megabyte, and so that was a security issue. Hence, a function call 7504 * stack is avoided now by resolving recurs 7504 * stack is avoided now by resolving recursion.) 7505 * 7505 * 7506 * The iterative approach works as follows: 7506 * The iterative approach works as follows: 7507 * 7507 * 7508 * - We have two writing pointers, both wal 7508 * - We have two writing pointers, both walking up the result array; one does 7509 * the work, the other creates "jobs" for 7509 * the work, the other creates "jobs" for its colleague to do, and leads 7510 * the way: 7510 * the way: 7511 * 7511 * 7512 * - The faster one, pointer jobDest, alw 7512 * - The faster one, pointer jobDest, always leads and writes "what job 7513 * to do" by the other, once they reach 7513 * to do" by the other, once they reach that place in the 7514 * array: leader "jobDest" stores the s 7514 * array: leader "jobDest" stores the source node array index (relative 7515 * to array dtd->scaffold) in field "nu 7515 * to array dtd->scaffold) in field "numchildren". 7516 * 7516 * 7517 * - The slower one, pointer dest, looks 7517 * - The slower one, pointer dest, looks at the value stored in the 7518 * "numchildren" field (which actually 7518 * "numchildren" field (which actually holds a source node array index 7519 * at that time) and puts the real data 7519 * at that time) and puts the real data from dtd->scaffold in. 7520 * 7520 * 7521 * - Before the loop starts, jobDest writes 7521 * - Before the loop starts, jobDest writes source array index 0 7522 * (where the root node is located) so th 7522 * (where the root node is located) so that dest will have something to do 7523 * when it starts operation. 7523 * when it starts operation. 7524 * 7524 * 7525 * - Whenever nodes with children are encou 7525 * - Whenever nodes with children are encountered, jobDest appends 7526 * them as new jobs, in order. As a resu 7526 * them as new jobs, in order. As a result, tree node siblings are 7527 * adjacent in the resulting array, for e 7527 * adjacent in the resulting array, for example: 7528 * 7528 * 7529 * [0] root, has two children 7529 * [0] root, has two children 7530 * [1] first child of 0, has three ch 7530 * [1] first child of 0, has three children 7531 * [3] first child of 1, does not h 7531 * [3] first child of 1, does not have children 7532 * [4] second child of 1, does not 7532 * [4] second child of 1, does not have children 7533 * [5] third child of 1, does not h 7533 * [5] third child of 1, does not have children 7534 * [2] second child of 0, does not ha 7534 * [2] second child of 0, does not have children 7535 * 7535 * 7536 * Or (the same data) presented in flat a 7536 * Or (the same data) presented in flat array view: 7537 * 7537 * 7538 * [0] root, has two children 7538 * [0] root, has two children 7539 * 7539 * 7540 * [1] first child of 0, has three chil 7540 * [1] first child of 0, has three children 7541 * [2] second child of 0, does not have 7541 * [2] second child of 0, does not have children 7542 * 7542 * 7543 * [3] first child of 1, does not have 7543 * [3] first child of 1, does not have children 7544 * [4] second child of 1, does not have 7544 * [4] second child of 1, does not have children 7545 * [5] third child of 1, does not have 7545 * [5] third child of 1, does not have children 7546 * 7546 * 7547 * - The algorithm repeats until all target 7547 * - The algorithm repeats until all target array indices have been processed. 7548 */ 7548 */ 7549 XML_Content *dest = ret; /* tree node writi 7549 XML_Content *dest = ret; /* tree node writing location, moves upwards */ 7550 XML_Content *const destLimit = &ret[dtd->sc 7550 XML_Content *const destLimit = &ret[dtd->scaffCount]; 7551 XML_Content *jobDest = ret; /* next free wr 7551 XML_Content *jobDest = ret; /* next free writing location in target array */ 7552 str = (XML_Char *)&ret[dtd->scaffCount]; 7552 str = (XML_Char *)&ret[dtd->scaffCount]; 7553 7553 7554 /* Add the starting job, the root node (ind 7554 /* Add the starting job, the root node (index 0) of the source tree */ 7555 (jobDest++)->numchildren = 0; 7555 (jobDest++)->numchildren = 0; 7556 7556 7557 for (; dest < destLimit; dest++) { 7557 for (; dest < destLimit; dest++) { 7558 /* Retrieve source tree array index from 7558 /* Retrieve source tree array index from job storage */ 7559 const int src_node = (int)dest->numchildr 7559 const int src_node = (int)dest->numchildren; 7560 7560 7561 /* Convert item */ 7561 /* Convert item */ 7562 dest->type = dtd->scaffold[src_node].type 7562 dest->type = dtd->scaffold[src_node].type; 7563 dest->quant = dtd->scaffold[src_node].qua 7563 dest->quant = dtd->scaffold[src_node].quant; 7564 if (dest->type == XML_CTYPE_NAME) { 7564 if (dest->type == XML_CTYPE_NAME) { 7565 const XML_Char *src; 7565 const XML_Char *src; 7566 dest->name = str; 7566 dest->name = str; 7567 src = dtd->scaffold[src_node].name; 7567 src = dtd->scaffold[src_node].name; 7568 for (;;) { 7568 for (;;) { 7569 *str++ = *src; 7569 *str++ = *src; 7570 if (! *src) 7570 if (! *src) 7571 break; 7571 break; 7572 src++; 7572 src++; 7573 } 7573 } 7574 dest->numchildren = 0; 7574 dest->numchildren = 0; 7575 dest->children = NULL; 7575 dest->children = NULL; 7576 } else { 7576 } else { 7577 unsigned int i; 7577 unsigned int i; 7578 int cn; 7578 int cn; 7579 dest->name = NULL; 7579 dest->name = NULL; 7580 dest->numchildren = dtd->scaffold[src_n 7580 dest->numchildren = dtd->scaffold[src_node].childcnt; 7581 dest->children = jobDest; 7581 dest->children = jobDest; 7582 7582 7583 /* Append scaffold indices of children 7583 /* Append scaffold indices of children to array */ 7584 for (i = 0, cn = dtd->scaffold[src_node 7584 for (i = 0, cn = dtd->scaffold[src_node].firstchild; 7585 i < dest->numchildren; i++, cn = d 7585 i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib) 7586 (jobDest++)->numchildren = (unsigned 7586 (jobDest++)->numchildren = (unsigned int)cn; 7587 } 7587 } 7588 } 7588 } 7589 7589 7590 return ret; 7590 return ret; 7591 } 7591 } 7592 7592 7593 static ELEMENT_TYPE * 7593 static ELEMENT_TYPE * 7594 getElementType(XML_Parser parser, const ENCOD 7594 getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, 7595 const char *end) { 7595 const char *end) { 7596 DTD *const dtd = parser->m_dtd; /* save one 7596 DTD *const dtd = parser->m_dtd; /* save one level of indirection */ 7597 const XML_Char *name = poolStoreString(&dtd 7597 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); 7598 ELEMENT_TYPE *ret; 7598 ELEMENT_TYPE *ret; 7599 7599 7600 if (! name) 7600 if (! name) 7601 return NULL; 7601 return NULL; 7602 ret = (ELEMENT_TYPE *)lookup(parser, &dtd-> 7602 ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name, 7603 sizeof(ELEMENT 7603 sizeof(ELEMENT_TYPE)); 7604 if (! ret) 7604 if (! ret) 7605 return NULL; 7605 return NULL; 7606 if (ret->name != name) 7606 if (ret->name != name) 7607 poolDiscard(&dtd->pool); 7607 poolDiscard(&dtd->pool); 7608 else { 7608 else { 7609 poolFinish(&dtd->pool); 7609 poolFinish(&dtd->pool); 7610 if (! setElementTypePrefix(parser, ret)) 7610 if (! setElementTypePrefix(parser, ret)) 7611 return NULL; 7611 return NULL; 7612 } 7612 } 7613 return ret; 7613 return ret; 7614 } 7614 } 7615 7615 7616 static XML_Char * 7616 static XML_Char * 7617 copyString(const XML_Char *s, const XML_Memor 7617 copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) { 7618 size_t charsRequired = 0; 7618 size_t charsRequired = 0; 7619 XML_Char *result; 7619 XML_Char *result; 7620 7620 7621 /* First determine how long the string is * 7621 /* First determine how long the string is */ 7622 while (s[charsRequired] != 0) { 7622 while (s[charsRequired] != 0) { 7623 charsRequired++; 7623 charsRequired++; 7624 } 7624 } 7625 /* Include the terminator */ 7625 /* Include the terminator */ 7626 charsRequired++; 7626 charsRequired++; 7627 7627 7628 /* Now allocate space for the copy */ 7628 /* Now allocate space for the copy */ 7629 result = memsuite->malloc_fcn(charsRequired 7629 result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char)); 7630 if (result == NULL) 7630 if (result == NULL) 7631 return NULL; 7631 return NULL; 7632 /* Copy the original into place */ 7632 /* Copy the original into place */ 7633 memcpy(result, s, charsRequired * sizeof(XM 7633 memcpy(result, s, charsRequired * sizeof(XML_Char)); 7634 return result; 7634 return result; 7635 } 7635 } 7636 7636 7637 #ifdef XML_DTD 7637 #ifdef XML_DTD 7638 7638 7639 static float 7639 static float 7640 accountingGetCurrentAmplification(XML_Parser 7640 accountingGetCurrentAmplification(XML_Parser rootParser) { 7641 const XmlBigCount countBytesOutput 7641 const XmlBigCount countBytesOutput 7642 = rootParser->m_accounting.countBytesDi 7642 = rootParser->m_accounting.countBytesDirect 7643 + rootParser->m_accounting.countBytes 7643 + rootParser->m_accounting.countBytesIndirect; 7644 const float amplificationFactor 7644 const float amplificationFactor 7645 = rootParser->m_accounting.countBytesDi 7645 = rootParser->m_accounting.countBytesDirect 7646 ? (countBytesOutput 7646 ? (countBytesOutput 7647 / (float)(rootParser->m_accoun 7647 / (float)(rootParser->m_accounting.countBytesDirect)) 7648 : 1.0f; 7648 : 1.0f; 7649 assert(! rootParser->m_parentParser); 7649 assert(! rootParser->m_parentParser); 7650 return amplificationFactor; 7650 return amplificationFactor; 7651 } 7651 } 7652 7652 7653 static void 7653 static void 7654 accountingReportStats(XML_Parser originParser 7654 accountingReportStats(XML_Parser originParser, const char *epilog) { 7655 const XML_Parser rootParser = getRootParser 7655 const XML_Parser rootParser = getRootParserOf(originParser, NULL); 7656 assert(! rootParser->m_parentParser); 7656 assert(! rootParser->m_parentParser); 7657 7657 7658 if (rootParser->m_accounting.debugLevel < 1 7658 if (rootParser->m_accounting.debugLevel < 1) { 7659 return; 7659 return; 7660 } 7660 } 7661 7661 7662 const float amplificationFactor 7662 const float amplificationFactor 7663 = accountingGetCurrentAmplification(roo 7663 = accountingGetCurrentAmplification(rootParser); 7664 fprintf(stderr, 7664 fprintf(stderr, 7665 "expat: Accounting(%p): Direct " EX 7665 "expat: Accounting(%p): Direct " EXPAT_FMT_ULL( 7666 "10") ", indirect " EXPAT_FMT_U 7666 "10") ", indirect " EXPAT_FMT_ULL("10") ", amplification %8.2f%s", 7667 (void *)rootParser, rootParser->m_a 7667 (void *)rootParser, rootParser->m_accounting.countBytesDirect, 7668 rootParser->m_accounting.countBytes 7668 rootParser->m_accounting.countBytesIndirect, 7669 (double)amplificationFactor, epilog 7669 (double)amplificationFactor, epilog); 7670 } 7670 } 7671 7671 7672 static void 7672 static void 7673 accountingOnAbort(XML_Parser originParser) { 7673 accountingOnAbort(XML_Parser originParser) { 7674 accountingReportStats(originParser, " ABORT 7674 accountingReportStats(originParser, " ABORTING\n"); 7675 } 7675 } 7676 7676 7677 static void 7677 static void 7678 accountingReportDiff(XML_Parser rootParser, 7678 accountingReportDiff(XML_Parser rootParser, 7679 unsigned int levelsAwayF 7679 unsigned int levelsAwayFromRootParser, const char *before, 7680 const char *after, ptrdi 7680 const char *after, ptrdiff_t bytesMore, int source_line, 7681 enum XML_Account account 7681 enum XML_Account account) { 7682 assert(! rootParser->m_parentParser); 7682 assert(! rootParser->m_parentParser); 7683 7683 7684 fprintf(stderr, 7684 fprintf(stderr, 7685 " (+" EXPAT_FMT_PTRDIFF_T("6") " by 7685 " (+" EXPAT_FMT_PTRDIFF_T("6") " bytes %s|%d, xmlparse.c:%d) %*s\"", 7686 bytesMore, (account == XML_ACCOUNT_ 7686 bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP", 7687 levelsAwayFromRootParser, source_li 7687 levelsAwayFromRootParser, source_line, 10, ""); 7688 7688 7689 const char ellipis[] = "[..]"; 7689 const char ellipis[] = "[..]"; 7690 const size_t ellipsisLength = sizeof(ellipi 7690 const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1; 7691 const unsigned int contextLength = 10; 7691 const unsigned int contextLength = 10; 7692 7692 7693 /* Note: Performance is of no concern here 7693 /* Note: Performance is of no concern here */ 7694 const char *walker = before; 7694 const char *walker = before; 7695 if ((rootParser->m_accounting.debugLevel >= 7695 if ((rootParser->m_accounting.debugLevel >= 3) 7696 || (after - before) 7696 || (after - before) 7697 <= (ptrdiff_t)(contextLength + e 7697 <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) { 7698 for (; walker < after; walker++) { 7698 for (; walker < after; walker++) { 7699 fprintf(stderr, "%s", unsignedCharToPri 7699 fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 7700 } 7700 } 7701 } else { 7701 } else { 7702 for (; walker < before + contextLength; w 7702 for (; walker < before + contextLength; walker++) { 7703 fprintf(stderr, "%s", unsignedCharToPri 7703 fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 7704 } 7704 } 7705 fprintf(stderr, ellipis); 7705 fprintf(stderr, ellipis); 7706 walker = after - contextLength; 7706 walker = after - contextLength; 7707 for (; walker < after; walker++) { 7707 for (; walker < after; walker++) { 7708 fprintf(stderr, "%s", unsignedCharToPri 7708 fprintf(stderr, "%s", unsignedCharToPrintable(walker[0])); 7709 } 7709 } 7710 } 7710 } 7711 fprintf(stderr, "\"\n"); 7711 fprintf(stderr, "\"\n"); 7712 } 7712 } 7713 7713 7714 static XML_Bool 7714 static XML_Bool 7715 accountingDiffTolerated(XML_Parser originPars 7715 accountingDiffTolerated(XML_Parser originParser, int tok, const char *before, 7716 const char *after, in 7716 const char *after, int source_line, 7717 enum XML_Account acco 7717 enum XML_Account account) { 7718 /* Note: We need to check the token type *f 7718 /* Note: We need to check the token type *first* to be sure that 7719 * we can even access variable <after 7719 * we can even access variable <after>, safely. 7720 * E.g. for XML_TOK_NONE <after> may 7720 * E.g. for XML_TOK_NONE <after> may hold an invalid pointer. */ 7721 switch (tok) { 7721 switch (tok) { 7722 case XML_TOK_INVALID: 7722 case XML_TOK_INVALID: 7723 case XML_TOK_PARTIAL: 7723 case XML_TOK_PARTIAL: 7724 case XML_TOK_PARTIAL_CHAR: 7724 case XML_TOK_PARTIAL_CHAR: 7725 case XML_TOK_NONE: 7725 case XML_TOK_NONE: 7726 return XML_TRUE; 7726 return XML_TRUE; 7727 } 7727 } 7728 7728 7729 if (account == XML_ACCOUNT_NONE) 7729 if (account == XML_ACCOUNT_NONE) 7730 return XML_TRUE; /* because these bytes h 7730 return XML_TRUE; /* because these bytes have been accounted for, already */ 7731 7731 7732 unsigned int levelsAwayFromRootParser; 7732 unsigned int levelsAwayFromRootParser; 7733 const XML_Parser rootParser 7733 const XML_Parser rootParser 7734 = getRootParserOf(originParser, &levels 7734 = getRootParserOf(originParser, &levelsAwayFromRootParser); 7735 assert(! rootParser->m_parentParser); 7735 assert(! rootParser->m_parentParser); 7736 7736 7737 const int isDirect 7737 const int isDirect 7738 = (account == XML_ACCOUNT_DIRECT) && (o 7738 = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser); 7739 const ptrdiff_t bytesMore = after - before; 7739 const ptrdiff_t bytesMore = after - before; 7740 7740 7741 XmlBigCount *const additionTarget 7741 XmlBigCount *const additionTarget 7742 = isDirect ? &rootParser->m_accounting. 7742 = isDirect ? &rootParser->m_accounting.countBytesDirect 7743 : &rootParser->m_accounting. 7743 : &rootParser->m_accounting.countBytesIndirect; 7744 7744 7745 /* Detect and avoid integer overflow */ 7745 /* Detect and avoid integer overflow */ 7746 if (*additionTarget > (XmlBigCount)(-1) - ( 7746 if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore) 7747 return XML_FALSE; 7747 return XML_FALSE; 7748 *additionTarget += bytesMore; 7748 *additionTarget += bytesMore; 7749 7749 7750 const XmlBigCount countBytesOutput 7750 const XmlBigCount countBytesOutput 7751 = rootParser->m_accounting.countBytesDi 7751 = rootParser->m_accounting.countBytesDirect 7752 + rootParser->m_accounting.countBytes 7752 + rootParser->m_accounting.countBytesIndirect; 7753 const float amplificationFactor 7753 const float amplificationFactor 7754 = accountingGetCurrentAmplification(roo 7754 = accountingGetCurrentAmplification(rootParser); 7755 const XML_Bool tolerated 7755 const XML_Bool tolerated 7756 = (countBytesOutput < rootParser->m_acc 7756 = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes) 7757 || (amplificationFactor 7757 || (amplificationFactor 7758 <= rootParser->m_accounting.maxim 7758 <= rootParser->m_accounting.maximumAmplificationFactor); 7759 7759 7760 if (rootParser->m_accounting.debugLevel >= 7760 if (rootParser->m_accounting.debugLevel >= 2) { 7761 accountingReportStats(rootParser, ""); 7761 accountingReportStats(rootParser, ""); 7762 accountingReportDiff(rootParser, levelsAw 7762 accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after, 7763 bytesMore, source_li 7763 bytesMore, source_line, account); 7764 } 7764 } 7765 7765 7766 return tolerated; 7766 return tolerated; 7767 } 7767 } 7768 7768 7769 unsigned long long 7769 unsigned long long 7770 testingAccountingGetCountBytesDirect(XML_Pars 7770 testingAccountingGetCountBytesDirect(XML_Parser parser) { 7771 if (! parser) 7771 if (! parser) 7772 return 0; 7772 return 0; 7773 return parser->m_accounting.countBytesDirec 7773 return parser->m_accounting.countBytesDirect; 7774 } 7774 } 7775 7775 7776 unsigned long long 7776 unsigned long long 7777 testingAccountingGetCountBytesIndirect(XML_Pa 7777 testingAccountingGetCountBytesIndirect(XML_Parser parser) { 7778 if (! parser) 7778 if (! parser) 7779 return 0; 7779 return 0; 7780 return parser->m_accounting.countBytesIndir 7780 return parser->m_accounting.countBytesIndirect; 7781 } 7781 } 7782 7782 7783 static void 7783 static void 7784 entityTrackingReportStats(XML_Parser rootPars 7784 entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity, 7785 const char *action, 7785 const char *action, int sourceLine) { 7786 assert(! rootParser->m_parentParser); 7786 assert(! rootParser->m_parentParser); 7787 if (rootParser->m_entity_stats.debugLevel < 7787 if (rootParser->m_entity_stats.debugLevel < 1) 7788 return; 7788 return; 7789 7789 7790 # if defined(XML_UNICODE) 7790 # if defined(XML_UNICODE) 7791 const char *const entityName = "[..]"; 7791 const char *const entityName = "[..]"; 7792 # else 7792 # else 7793 const char *const entityName = entity->name 7793 const char *const entityName = entity->name; 7794 # endif 7794 # endif 7795 7795 7796 fprintf( 7796 fprintf( 7797 stderr, 7797 stderr, 7798 "expat: Entities(%p): Count %9d, depth 7798 "expat: Entities(%p): Count %9d, depth %2d/%2d %*s%s%s; %s length %d (xmlparse.c:%d)\n", 7799 (void *)rootParser, rootParser->m_entit 7799 (void *)rootParser, rootParser->m_entity_stats.countEverOpened, 7800 rootParser->m_entity_stats.currentDepth 7800 rootParser->m_entity_stats.currentDepth, 7801 rootParser->m_entity_stats.maximumDepth 7801 rootParser->m_entity_stats.maximumDepthSeen, 7802 (rootParser->m_entity_stats.currentDept 7802 (rootParser->m_entity_stats.currentDepth - 1) * 2, "", 7803 entity->is_param ? "%" : "&", entityNam 7803 entity->is_param ? "%" : "&", entityName, action, entity->textLen, 7804 sourceLine); 7804 sourceLine); 7805 } 7805 } 7806 7806 7807 static void 7807 static void 7808 entityTrackingOnOpen(XML_Parser originParser, 7808 entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) { 7809 const XML_Parser rootParser = getRootParser 7809 const XML_Parser rootParser = getRootParserOf(originParser, NULL); 7810 assert(! rootParser->m_parentParser); 7810 assert(! rootParser->m_parentParser); 7811 7811 7812 rootParser->m_entity_stats.countEverOpened+ 7812 rootParser->m_entity_stats.countEverOpened++; 7813 rootParser->m_entity_stats.currentDepth++; 7813 rootParser->m_entity_stats.currentDepth++; 7814 if (rootParser->m_entity_stats.currentDepth 7814 if (rootParser->m_entity_stats.currentDepth 7815 > rootParser->m_entity_stats.maximumDep 7815 > rootParser->m_entity_stats.maximumDepthSeen) { 7816 rootParser->m_entity_stats.maximumDepthSe 7816 rootParser->m_entity_stats.maximumDepthSeen++; 7817 } 7817 } 7818 7818 7819 entityTrackingReportStats(rootParser, entit 7819 entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine); 7820 } 7820 } 7821 7821 7822 static void 7822 static void 7823 entityTrackingOnClose(XML_Parser originParser 7823 entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) { 7824 const XML_Parser rootParser = getRootParser 7824 const XML_Parser rootParser = getRootParserOf(originParser, NULL); 7825 assert(! rootParser->m_parentParser); 7825 assert(! rootParser->m_parentParser); 7826 7826 7827 entityTrackingReportStats(rootParser, entit 7827 entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine); 7828 rootParser->m_entity_stats.currentDepth--; 7828 rootParser->m_entity_stats.currentDepth--; 7829 } 7829 } 7830 7830 7831 static XML_Parser 7831 static XML_Parser 7832 getRootParserOf(XML_Parser parser, unsigned i 7832 getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) { 7833 XML_Parser rootParser = parser; 7833 XML_Parser rootParser = parser; 7834 unsigned int stepsTakenUpwards = 0; 7834 unsigned int stepsTakenUpwards = 0; 7835 while (rootParser->m_parentParser) { 7835 while (rootParser->m_parentParser) { 7836 rootParser = rootParser->m_parentParser; 7836 rootParser = rootParser->m_parentParser; 7837 stepsTakenUpwards++; 7837 stepsTakenUpwards++; 7838 } 7838 } 7839 assert(! rootParser->m_parentParser); 7839 assert(! rootParser->m_parentParser); 7840 if (outLevelDiff != NULL) { 7840 if (outLevelDiff != NULL) { 7841 *outLevelDiff = stepsTakenUpwards; 7841 *outLevelDiff = stepsTakenUpwards; 7842 } 7842 } 7843 return rootParser; 7843 return rootParser; 7844 } 7844 } 7845 7845 7846 const char * 7846 const char * 7847 unsignedCharToPrintable(unsigned char c) { 7847 unsignedCharToPrintable(unsigned char c) { 7848 switch (c) { 7848 switch (c) { 7849 case 0: 7849 case 0: 7850 return "\\0"; 7850 return "\\0"; 7851 case 1: 7851 case 1: 7852 return "\\x1"; 7852 return "\\x1"; 7853 case 2: 7853 case 2: 7854 return "\\x2"; 7854 return "\\x2"; 7855 case 3: 7855 case 3: 7856 return "\\x3"; 7856 return "\\x3"; 7857 case 4: 7857 case 4: 7858 return "\\x4"; 7858 return "\\x4"; 7859 case 5: 7859 case 5: 7860 return "\\x5"; 7860 return "\\x5"; 7861 case 6: 7861 case 6: 7862 return "\\x6"; 7862 return "\\x6"; 7863 case 7: 7863 case 7: 7864 return "\\x7"; 7864 return "\\x7"; 7865 case 8: 7865 case 8: 7866 return "\\x8"; 7866 return "\\x8"; 7867 case 9: 7867 case 9: 7868 return "\\t"; 7868 return "\\t"; 7869 case 10: 7869 case 10: 7870 return "\\n"; 7870 return "\\n"; 7871 case 11: 7871 case 11: 7872 return "\\xB"; 7872 return "\\xB"; 7873 case 12: 7873 case 12: 7874 return "\\xC"; 7874 return "\\xC"; 7875 case 13: 7875 case 13: 7876 return "\\r"; 7876 return "\\r"; 7877 case 14: 7877 case 14: 7878 return "\\xE"; 7878 return "\\xE"; 7879 case 15: 7879 case 15: 7880 return "\\xF"; 7880 return "\\xF"; 7881 case 16: 7881 case 16: 7882 return "\\x10"; 7882 return "\\x10"; 7883 case 17: 7883 case 17: 7884 return "\\x11"; 7884 return "\\x11"; 7885 case 18: 7885 case 18: 7886 return "\\x12"; 7886 return "\\x12"; 7887 case 19: 7887 case 19: 7888 return "\\x13"; 7888 return "\\x13"; 7889 case 20: 7889 case 20: 7890 return "\\x14"; 7890 return "\\x14"; 7891 case 21: 7891 case 21: 7892 return "\\x15"; 7892 return "\\x15"; 7893 case 22: 7893 case 22: 7894 return "\\x16"; 7894 return "\\x16"; 7895 case 23: 7895 case 23: 7896 return "\\x17"; 7896 return "\\x17"; 7897 case 24: 7897 case 24: 7898 return "\\x18"; 7898 return "\\x18"; 7899 case 25: 7899 case 25: 7900 return "\\x19"; 7900 return "\\x19"; 7901 case 26: 7901 case 26: 7902 return "\\x1A"; 7902 return "\\x1A"; 7903 case 27: 7903 case 27: 7904 return "\\x1B"; 7904 return "\\x1B"; 7905 case 28: 7905 case 28: 7906 return "\\x1C"; 7906 return "\\x1C"; 7907 case 29: 7907 case 29: 7908 return "\\x1D"; 7908 return "\\x1D"; 7909 case 30: 7909 case 30: 7910 return "\\x1E"; 7910 return "\\x1E"; 7911 case 31: 7911 case 31: 7912 return "\\x1F"; 7912 return "\\x1F"; 7913 case 32: 7913 case 32: 7914 return " "; 7914 return " "; 7915 case 33: 7915 case 33: 7916 return "!"; 7916 return "!"; 7917 case 34: 7917 case 34: 7918 return "\\\""; 7918 return "\\\""; 7919 case 35: 7919 case 35: 7920 return "#"; 7920 return "#"; 7921 case 36: 7921 case 36: 7922 return "$"; 7922 return "$"; 7923 case 37: 7923 case 37: 7924 return "%"; 7924 return "%"; 7925 case 38: 7925 case 38: 7926 return "&"; 7926 return "&"; 7927 case 39: 7927 case 39: 7928 return "'"; 7928 return "'"; 7929 case 40: 7929 case 40: 7930 return "("; 7930 return "("; 7931 case 41: 7931 case 41: 7932 return ")"; 7932 return ")"; 7933 case 42: 7933 case 42: 7934 return "*"; 7934 return "*"; 7935 case 43: 7935 case 43: 7936 return "+"; 7936 return "+"; 7937 case 44: 7937 case 44: 7938 return ","; 7938 return ","; 7939 case 45: 7939 case 45: 7940 return "-"; 7940 return "-"; 7941 case 46: 7941 case 46: 7942 return "."; 7942 return "."; 7943 case 47: 7943 case 47: 7944 return "/"; 7944 return "/"; 7945 case 48: 7945 case 48: 7946 return "0"; 7946 return "0"; 7947 case 49: 7947 case 49: 7948 return "1"; 7948 return "1"; 7949 case 50: 7949 case 50: 7950 return "2"; 7950 return "2"; 7951 case 51: 7951 case 51: 7952 return "3"; 7952 return "3"; 7953 case 52: 7953 case 52: 7954 return "4"; 7954 return "4"; 7955 case 53: 7955 case 53: 7956 return "5"; 7956 return "5"; 7957 case 54: 7957 case 54: 7958 return "6"; 7958 return "6"; 7959 case 55: 7959 case 55: 7960 return "7"; 7960 return "7"; 7961 case 56: 7961 case 56: 7962 return "8"; 7962 return "8"; 7963 case 57: 7963 case 57: 7964 return "9"; 7964 return "9"; 7965 case 58: 7965 case 58: 7966 return ":"; 7966 return ":"; 7967 case 59: 7967 case 59: 7968 return ";"; 7968 return ";"; 7969 case 60: 7969 case 60: 7970 return "<"; 7970 return "<"; 7971 case 61: 7971 case 61: 7972 return "="; 7972 return "="; 7973 case 62: 7973 case 62: 7974 return ">"; 7974 return ">"; 7975 case 63: 7975 case 63: 7976 return "?"; 7976 return "?"; 7977 case 64: 7977 case 64: 7978 return "@"; 7978 return "@"; 7979 case 65: 7979 case 65: 7980 return "A"; 7980 return "A"; 7981 case 66: 7981 case 66: 7982 return "B"; 7982 return "B"; 7983 case 67: 7983 case 67: 7984 return "C"; 7984 return "C"; 7985 case 68: 7985 case 68: 7986 return "D"; 7986 return "D"; 7987 case 69: 7987 case 69: 7988 return "E"; 7988 return "E"; 7989 case 70: 7989 case 70: 7990 return "F"; 7990 return "F"; 7991 case 71: 7991 case 71: 7992 return "G"; 7992 return "G"; 7993 case 72: 7993 case 72: 7994 return "H"; 7994 return "H"; 7995 case 73: 7995 case 73: 7996 return "I"; 7996 return "I"; 7997 case 74: 7997 case 74: 7998 return "J"; 7998 return "J"; 7999 case 75: 7999 case 75: 8000 return "K"; 8000 return "K"; 8001 case 76: 8001 case 76: 8002 return "L"; 8002 return "L"; 8003 case 77: 8003 case 77: 8004 return "M"; 8004 return "M"; 8005 case 78: 8005 case 78: 8006 return "N"; 8006 return "N"; 8007 case 79: 8007 case 79: 8008 return "O"; 8008 return "O"; 8009 case 80: 8009 case 80: 8010 return "P"; 8010 return "P"; 8011 case 81: 8011 case 81: 8012 return "Q"; 8012 return "Q"; 8013 case 82: 8013 case 82: 8014 return "R"; 8014 return "R"; 8015 case 83: 8015 case 83: 8016 return "S"; 8016 return "S"; 8017 case 84: 8017 case 84: 8018 return "T"; 8018 return "T"; 8019 case 85: 8019 case 85: 8020 return "U"; 8020 return "U"; 8021 case 86: 8021 case 86: 8022 return "V"; 8022 return "V"; 8023 case 87: 8023 case 87: 8024 return "W"; 8024 return "W"; 8025 case 88: 8025 case 88: 8026 return "X"; 8026 return "X"; 8027 case 89: 8027 case 89: 8028 return "Y"; 8028 return "Y"; 8029 case 90: 8029 case 90: 8030 return "Z"; 8030 return "Z"; 8031 case 91: 8031 case 91: 8032 return "["; 8032 return "["; 8033 case 92: 8033 case 92: 8034 return "\\\\"; 8034 return "\\\\"; 8035 case 93: 8035 case 93: 8036 return "]"; 8036 return "]"; 8037 case 94: 8037 case 94: 8038 return "^"; 8038 return "^"; 8039 case 95: 8039 case 95: 8040 return "_"; 8040 return "_"; 8041 case 96: 8041 case 96: 8042 return "`"; 8042 return "`"; 8043 case 97: 8043 case 97: 8044 return "a"; 8044 return "a"; 8045 case 98: 8045 case 98: 8046 return "b"; 8046 return "b"; 8047 case 99: 8047 case 99: 8048 return "c"; 8048 return "c"; 8049 case 100: 8049 case 100: 8050 return "d"; 8050 return "d"; 8051 case 101: 8051 case 101: 8052 return "e"; 8052 return "e"; 8053 case 102: 8053 case 102: 8054 return "f"; 8054 return "f"; 8055 case 103: 8055 case 103: 8056 return "g"; 8056 return "g"; 8057 case 104: 8057 case 104: 8058 return "h"; 8058 return "h"; 8059 case 105: 8059 case 105: 8060 return "i"; 8060 return "i"; 8061 case 106: 8061 case 106: 8062 return "j"; 8062 return "j"; 8063 case 107: 8063 case 107: 8064 return "k"; 8064 return "k"; 8065 case 108: 8065 case 108: 8066 return "l"; 8066 return "l"; 8067 case 109: 8067 case 109: 8068 return "m"; 8068 return "m"; 8069 case 110: 8069 case 110: 8070 return "n"; 8070 return "n"; 8071 case 111: 8071 case 111: 8072 return "o"; 8072 return "o"; 8073 case 112: 8073 case 112: 8074 return "p"; 8074 return "p"; 8075 case 113: 8075 case 113: 8076 return "q"; 8076 return "q"; 8077 case 114: 8077 case 114: 8078 return "r"; 8078 return "r"; 8079 case 115: 8079 case 115: 8080 return "s"; 8080 return "s"; 8081 case 116: 8081 case 116: 8082 return "t"; 8082 return "t"; 8083 case 117: 8083 case 117: 8084 return "u"; 8084 return "u"; 8085 case 118: 8085 case 118: 8086 return "v"; 8086 return "v"; 8087 case 119: 8087 case 119: 8088 return "w"; 8088 return "w"; 8089 case 120: 8089 case 120: 8090 return "x"; 8090 return "x"; 8091 case 121: 8091 case 121: 8092 return "y"; 8092 return "y"; 8093 case 122: 8093 case 122: 8094 return "z"; 8094 return "z"; 8095 case 123: 8095 case 123: 8096 return "{"; 8096 return "{"; 8097 case 124: 8097 case 124: 8098 return "|"; 8098 return "|"; 8099 case 125: 8099 case 125: 8100 return "}"; 8100 return "}"; 8101 case 126: 8101 case 126: 8102 return "~"; 8102 return "~"; 8103 case 127: 8103 case 127: 8104 return "\\x7F"; 8104 return "\\x7F"; 8105 case 128: 8105 case 128: 8106 return "\\x80"; 8106 return "\\x80"; 8107 case 129: 8107 case 129: 8108 return "\\x81"; 8108 return "\\x81"; 8109 case 130: 8109 case 130: 8110 return "\\x82"; 8110 return "\\x82"; 8111 case 131: 8111 case 131: 8112 return "\\x83"; 8112 return "\\x83"; 8113 case 132: 8113 case 132: 8114 return "\\x84"; 8114 return "\\x84"; 8115 case 133: 8115 case 133: 8116 return "\\x85"; 8116 return "\\x85"; 8117 case 134: 8117 case 134: 8118 return "\\x86"; 8118 return "\\x86"; 8119 case 135: 8119 case 135: 8120 return "\\x87"; 8120 return "\\x87"; 8121 case 136: 8121 case 136: 8122 return "\\x88"; 8122 return "\\x88"; 8123 case 137: 8123 case 137: 8124 return "\\x89"; 8124 return "\\x89"; 8125 case 138: 8125 case 138: 8126 return "\\x8A"; 8126 return "\\x8A"; 8127 case 139: 8127 case 139: 8128 return "\\x8B"; 8128 return "\\x8B"; 8129 case 140: 8129 case 140: 8130 return "\\x8C"; 8130 return "\\x8C"; 8131 case 141: 8131 case 141: 8132 return "\\x8D"; 8132 return "\\x8D"; 8133 case 142: 8133 case 142: 8134 return "\\x8E"; 8134 return "\\x8E"; 8135 case 143: 8135 case 143: 8136 return "\\x8F"; 8136 return "\\x8F"; 8137 case 144: 8137 case 144: 8138 return "\\x90"; 8138 return "\\x90"; 8139 case 145: 8139 case 145: 8140 return "\\x91"; 8140 return "\\x91"; 8141 case 146: 8141 case 146: 8142 return "\\x92"; 8142 return "\\x92"; 8143 case 147: 8143 case 147: 8144 return "\\x93"; 8144 return "\\x93"; 8145 case 148: 8145 case 148: 8146 return "\\x94"; 8146 return "\\x94"; 8147 case 149: 8147 case 149: 8148 return "\\x95"; 8148 return "\\x95"; 8149 case 150: 8149 case 150: 8150 return "\\x96"; 8150 return "\\x96"; 8151 case 151: 8151 case 151: 8152 return "\\x97"; 8152 return "\\x97"; 8153 case 152: 8153 case 152: 8154 return "\\x98"; 8154 return "\\x98"; 8155 case 153: 8155 case 153: 8156 return "\\x99"; 8156 return "\\x99"; 8157 case 154: 8157 case 154: 8158 return "\\x9A"; 8158 return "\\x9A"; 8159 case 155: 8159 case 155: 8160 return "\\x9B"; 8160 return "\\x9B"; 8161 case 156: 8161 case 156: 8162 return "\\x9C"; 8162 return "\\x9C"; 8163 case 157: 8163 case 157: 8164 return "\\x9D"; 8164 return "\\x9D"; 8165 case 158: 8165 case 158: 8166 return "\\x9E"; 8166 return "\\x9E"; 8167 case 159: 8167 case 159: 8168 return "\\x9F"; 8168 return "\\x9F"; 8169 case 160: 8169 case 160: 8170 return "\\xA0"; 8170 return "\\xA0"; 8171 case 161: 8171 case 161: 8172 return "\\xA1"; 8172 return "\\xA1"; 8173 case 162: 8173 case 162: 8174 return "\\xA2"; 8174 return "\\xA2"; 8175 case 163: 8175 case 163: 8176 return "\\xA3"; 8176 return "\\xA3"; 8177 case 164: 8177 case 164: 8178 return "\\xA4"; 8178 return "\\xA4"; 8179 case 165: 8179 case 165: 8180 return "\\xA5"; 8180 return "\\xA5"; 8181 case 166: 8181 case 166: 8182 return "\\xA6"; 8182 return "\\xA6"; 8183 case 167: 8183 case 167: 8184 return "\\xA7"; 8184 return "\\xA7"; 8185 case 168: 8185 case 168: 8186 return "\\xA8"; 8186 return "\\xA8"; 8187 case 169: 8187 case 169: 8188 return "\\xA9"; 8188 return "\\xA9"; 8189 case 170: 8189 case 170: 8190 return "\\xAA"; 8190 return "\\xAA"; 8191 case 171: 8191 case 171: 8192 return "\\xAB"; 8192 return "\\xAB"; 8193 case 172: 8193 case 172: 8194 return "\\xAC"; 8194 return "\\xAC"; 8195 case 173: 8195 case 173: 8196 return "\\xAD"; 8196 return "\\xAD"; 8197 case 174: 8197 case 174: 8198 return "\\xAE"; 8198 return "\\xAE"; 8199 case 175: 8199 case 175: 8200 return "\\xAF"; 8200 return "\\xAF"; 8201 case 176: 8201 case 176: 8202 return "\\xB0"; 8202 return "\\xB0"; 8203 case 177: 8203 case 177: 8204 return "\\xB1"; 8204 return "\\xB1"; 8205 case 178: 8205 case 178: 8206 return "\\xB2"; 8206 return "\\xB2"; 8207 case 179: 8207 case 179: 8208 return "\\xB3"; 8208 return "\\xB3"; 8209 case 180: 8209 case 180: 8210 return "\\xB4"; 8210 return "\\xB4"; 8211 case 181: 8211 case 181: 8212 return "\\xB5"; 8212 return "\\xB5"; 8213 case 182: 8213 case 182: 8214 return "\\xB6"; 8214 return "\\xB6"; 8215 case 183: 8215 case 183: 8216 return "\\xB7"; 8216 return "\\xB7"; 8217 case 184: 8217 case 184: 8218 return "\\xB8"; 8218 return "\\xB8"; 8219 case 185: 8219 case 185: 8220 return "\\xB9"; 8220 return "\\xB9"; 8221 case 186: 8221 case 186: 8222 return "\\xBA"; 8222 return "\\xBA"; 8223 case 187: 8223 case 187: 8224 return "\\xBB"; 8224 return "\\xBB"; 8225 case 188: 8225 case 188: 8226 return "\\xBC"; 8226 return "\\xBC"; 8227 case 189: 8227 case 189: 8228 return "\\xBD"; 8228 return "\\xBD"; 8229 case 190: 8229 case 190: 8230 return "\\xBE"; 8230 return "\\xBE"; 8231 case 191: 8231 case 191: 8232 return "\\xBF"; 8232 return "\\xBF"; 8233 case 192: 8233 case 192: 8234 return "\\xC0"; 8234 return "\\xC0"; 8235 case 193: 8235 case 193: 8236 return "\\xC1"; 8236 return "\\xC1"; 8237 case 194: 8237 case 194: 8238 return "\\xC2"; 8238 return "\\xC2"; 8239 case 195: 8239 case 195: 8240 return "\\xC3"; 8240 return "\\xC3"; 8241 case 196: 8241 case 196: 8242 return "\\xC4"; 8242 return "\\xC4"; 8243 case 197: 8243 case 197: 8244 return "\\xC5"; 8244 return "\\xC5"; 8245 case 198: 8245 case 198: 8246 return "\\xC6"; 8246 return "\\xC6"; 8247 case 199: 8247 case 199: 8248 return "\\xC7"; 8248 return "\\xC7"; 8249 case 200: 8249 case 200: 8250 return "\\xC8"; 8250 return "\\xC8"; 8251 case 201: 8251 case 201: 8252 return "\\xC9"; 8252 return "\\xC9"; 8253 case 202: 8253 case 202: 8254 return "\\xCA"; 8254 return "\\xCA"; 8255 case 203: 8255 case 203: 8256 return "\\xCB"; 8256 return "\\xCB"; 8257 case 204: 8257 case 204: 8258 return "\\xCC"; 8258 return "\\xCC"; 8259 case 205: 8259 case 205: 8260 return "\\xCD"; 8260 return "\\xCD"; 8261 case 206: 8261 case 206: 8262 return "\\xCE"; 8262 return "\\xCE"; 8263 case 207: 8263 case 207: 8264 return "\\xCF"; 8264 return "\\xCF"; 8265 case 208: 8265 case 208: 8266 return "\\xD0"; 8266 return "\\xD0"; 8267 case 209: 8267 case 209: 8268 return "\\xD1"; 8268 return "\\xD1"; 8269 case 210: 8269 case 210: 8270 return "\\xD2"; 8270 return "\\xD2"; 8271 case 211: 8271 case 211: 8272 return "\\xD3"; 8272 return "\\xD3"; 8273 case 212: 8273 case 212: 8274 return "\\xD4"; 8274 return "\\xD4"; 8275 case 213: 8275 case 213: 8276 return "\\xD5"; 8276 return "\\xD5"; 8277 case 214: 8277 case 214: 8278 return "\\xD6"; 8278 return "\\xD6"; 8279 case 215: 8279 case 215: 8280 return "\\xD7"; 8280 return "\\xD7"; 8281 case 216: 8281 case 216: 8282 return "\\xD8"; 8282 return "\\xD8"; 8283 case 217: 8283 case 217: 8284 return "\\xD9"; 8284 return "\\xD9"; 8285 case 218: 8285 case 218: 8286 return "\\xDA"; 8286 return "\\xDA"; 8287 case 219: 8287 case 219: 8288 return "\\xDB"; 8288 return "\\xDB"; 8289 case 220: 8289 case 220: 8290 return "\\xDC"; 8290 return "\\xDC"; 8291 case 221: 8291 case 221: 8292 return "\\xDD"; 8292 return "\\xDD"; 8293 case 222: 8293 case 222: 8294 return "\\xDE"; 8294 return "\\xDE"; 8295 case 223: 8295 case 223: 8296 return "\\xDF"; 8296 return "\\xDF"; 8297 case 224: 8297 case 224: 8298 return "\\xE0"; 8298 return "\\xE0"; 8299 case 225: 8299 case 225: 8300 return "\\xE1"; 8300 return "\\xE1"; 8301 case 226: 8301 case 226: 8302 return "\\xE2"; 8302 return "\\xE2"; 8303 case 227: 8303 case 227: 8304 return "\\xE3"; 8304 return "\\xE3"; 8305 case 228: 8305 case 228: 8306 return "\\xE4"; 8306 return "\\xE4"; 8307 case 229: 8307 case 229: 8308 return "\\xE5"; 8308 return "\\xE5"; 8309 case 230: 8309 case 230: 8310 return "\\xE6"; 8310 return "\\xE6"; 8311 case 231: 8311 case 231: 8312 return "\\xE7"; 8312 return "\\xE7"; 8313 case 232: 8313 case 232: 8314 return "\\xE8"; 8314 return "\\xE8"; 8315 case 233: 8315 case 233: 8316 return "\\xE9"; 8316 return "\\xE9"; 8317 case 234: 8317 case 234: 8318 return "\\xEA"; 8318 return "\\xEA"; 8319 case 235: 8319 case 235: 8320 return "\\xEB"; 8320 return "\\xEB"; 8321 case 236: 8321 case 236: 8322 return "\\xEC"; 8322 return "\\xEC"; 8323 case 237: 8323 case 237: 8324 return "\\xED"; 8324 return "\\xED"; 8325 case 238: 8325 case 238: 8326 return "\\xEE"; 8326 return "\\xEE"; 8327 case 239: 8327 case 239: 8328 return "\\xEF"; 8328 return "\\xEF"; 8329 case 240: 8329 case 240: 8330 return "\\xF0"; 8330 return "\\xF0"; 8331 case 241: 8331 case 241: 8332 return "\\xF1"; 8332 return "\\xF1"; 8333 case 242: 8333 case 242: 8334 return "\\xF2"; 8334 return "\\xF2"; 8335 case 243: 8335 case 243: 8336 return "\\xF3"; 8336 return "\\xF3"; 8337 case 244: 8337 case 244: 8338 return "\\xF4"; 8338 return "\\xF4"; 8339 case 245: 8339 case 245: 8340 return "\\xF5"; 8340 return "\\xF5"; 8341 case 246: 8341 case 246: 8342 return "\\xF6"; 8342 return "\\xF6"; 8343 case 247: 8343 case 247: 8344 return "\\xF7"; 8344 return "\\xF7"; 8345 case 248: 8345 case 248: 8346 return "\\xF8"; 8346 return "\\xF8"; 8347 case 249: 8347 case 249: 8348 return "\\xF9"; 8348 return "\\xF9"; 8349 case 250: 8349 case 250: 8350 return "\\xFA"; 8350 return "\\xFA"; 8351 case 251: 8351 case 251: 8352 return "\\xFB"; 8352 return "\\xFB"; 8353 case 252: 8353 case 252: 8354 return "\\xFC"; 8354 return "\\xFC"; 8355 case 253: 8355 case 253: 8356 return "\\xFD"; 8356 return "\\xFD"; 8357 case 254: 8357 case 254: 8358 return "\\xFE"; 8358 return "\\xFE"; 8359 case 255: 8359 case 255: 8360 return "\\xFF"; 8360 return "\\xFF"; 8361 default: 8361 default: 8362 assert(0); /* never gets here */ 8362 assert(0); /* never gets here */ 8363 return "dead code"; 8363 return "dead code"; 8364 } 8364 } 8365 assert(0); /* never gets here */ 8365 assert(0); /* never gets here */ 8366 } 8366 } 8367 8367 8368 #endif /* XML_DTD */ 8368 #endif /* XML_DTD */ 8369 8369 8370 static unsigned long 8370 static unsigned long 8371 getDebugLevel(const char *variableName, unsig 8371 getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) { 8372 const char *const valueOrNull = getenv(vari 8372 const char *const valueOrNull = getenv(variableName); 8373 if (valueOrNull == NULL) { 8373 if (valueOrNull == NULL) { 8374 return defaultDebugLevel; 8374 return defaultDebugLevel; 8375 } 8375 } 8376 const char *const value = valueOrNull; 8376 const char *const value = valueOrNull; 8377 8377 8378 errno = 0; 8378 errno = 0; 8379 char *afterValue = (char *)value; 8379 char *afterValue = (char *)value; 8380 unsigned long debugLevel = strtoul(value, & 8380 unsigned long debugLevel = strtoul(value, &afterValue, 10); 8381 if ((errno != 0) || (afterValue[0] != '\0') 8381 if ((errno != 0) || (afterValue[0] != '\0')) { 8382 errno = 0; 8382 errno = 0; 8383 return defaultDebugLevel; 8383 return defaultDebugLevel; 8384 } 8384 } 8385 8385 8386 return debugLevel; 8386 return debugLevel; 8387 } 8387 } 8388 8388